@lmctl-ai/lmctl 0.1.342 → 0.2.3
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/CHANGELOG.md +116 -0
- package/README.md +11 -51
- package/data/price-aliases.json +1 -0
- package/data/price-data.json +1 -1
- package/dist/cli/batch.d.ts +2 -0
- package/dist/cli/busy-evidence.d.ts +27 -0
- package/dist/cli/chat-cycle.d.ts +59 -0
- package/dist/cli/chat-exec.d.ts +83 -0
- package/dist/cli/chat-policy.d.ts +22 -0
- package/dist/cli/chat.d.ts +23 -0
- package/dist/cli/code-resolver.d.ts +8 -0
- package/dist/cli/common.d.ts +54 -0
- package/dist/cli/context.d.ts +12 -0
- package/dist/cli/cost.d.ts +2 -0
- package/dist/cli/export.d.ts +2 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +1062 -1400
- package/dist/cli/infra.d.ts +78 -0
- package/dist/cli/ls.d.ts +2 -0
- package/dist/cli/mailbox-cli.d.ts +6 -0
- package/dist/cli/managed.d.ts +62 -0
- package/dist/cli/mcp-install.d.ts +23 -0
- package/dist/cli/mcp.d.ts +2 -0
- package/dist/cli/paths.d.ts +50 -0
- package/dist/cli/plan-wizard.d.ts +42 -0
- package/dist/cli/plan.d.ts +20 -0
- package/dist/cli/queue-delivery.d.ts +107 -0
- package/dist/cli/ratelimit.d.ts +3 -0
- package/dist/cli/remote-fetch.d.ts +7 -0
- package/dist/cli/run-queries.d.ts +82 -0
- package/dist/cli/running.d.ts +5 -0
- package/dist/cli/schema.sql +20 -1
- package/dist/cli/script.d.ts +6 -0
- package/dist/cli/script.js +2097 -0
- package/dist/cli/self-identity.d.ts +25 -0
- package/dist/cli/session-idle.d.ts +118 -0
- package/dist/cli/status.d.ts +22 -0
- package/dist/cli/tail.d.ts +18 -0
- package/dist/cli/target-resolver.d.ts +139 -0
- package/dist/cli/team-status.d.ts +91 -0
- package/dist/cli/teamfile-compat.d.ts +71 -0
- package/dist/cli/teamfile-store.d.ts +18 -0
- package/dist/cli/teamfile-template.d.ts +40 -0
- package/dist/cli/template-env.d.ts +25 -0
- package/dist/cli/terminal-lock.d.ts +25 -0
- package/dist/cli/terminal.d.ts +23 -0
- package/dist/cli/time-filter.d.ts +10 -0
- package/dist/cli/update-notifier.d.ts +11 -0
- package/dist/cli/version-util.d.ts +2 -0
- package/dist/config/seed_templates.d.ts +1 -0
- package/dist/db/backfill-event-log.d.ts +26 -0
- package/dist/db/delegation.d.ts +37 -0
- package/dist/db/escalation_vocab.d.ts +45 -0
- package/dist/db/event-log.d.ts +40 -0
- package/dist/db/index.d.ts +1213 -0
- package/dist/db/inflight-acquire.d.ts +70 -0
- package/dist/db/invocation-event-projections.d.ts +65 -0
- package/dist/db/ledger-identity.test.d.ts +1 -0
- package/dist/db/live-event-projections.d.ts +92 -0
- package/dist/db/migrate.d.ts +51 -0
- package/dist/db/open-readonly.d.ts +2 -0
- package/dist/db/process-liveness.d.ts +37 -0
- package/dist/db/sqlite.d.ts +47 -0
- package/dist/db/sqlite.test.d.ts +1 -0
- package/dist/db/terminal-lock.d.ts +14 -0
- package/dist/db/tracked-invocation-reconcile.d.ts +52 -0
- package/dist/db/tracked-invocation.d.ts +116 -0
- package/dist/mcp/dispatch.d.ts +45 -0
- package/dist/mcp/mediation.d.ts +128 -0
- package/dist/mcp/path-warning.d.ts +7 -0
- package/dist/mcp/server.d.ts +63 -0
- package/dist/mcp/tools.d.ts +24 -0
- package/dist/providers/adapter.d.ts +265 -0
- package/dist/providers/adapters/agy-adapter.d.ts +17 -0
- package/dist/providers/adapters/claude-adapter.d.ts +20 -0
- package/dist/providers/adapters/codex-adapter.d.ts +22 -0
- package/dist/providers/adapters/copilot-adapter.d.ts +16 -0
- package/dist/providers/adapters/dsh-adapter.d.ts +89 -0
- package/dist/providers/adapters/gemini-adapter.d.ts +44 -0
- package/dist/providers/adapters/hermes-adapter.d.ts +71 -0
- package/dist/providers/adapters/index.d.ts +35 -0
- package/dist/providers/adapters/kimi-adapter.d.ts +16 -0
- package/dist/providers/adapters/lmplayer-adapter.d.ts +14 -0
- package/dist/providers/adapters/opencode-adapter.d.ts +11 -0
- package/dist/providers/adapters/pi-adapter.d.ts +17 -0
- package/dist/providers/adapters/print-turn.d.ts +29 -0
- package/dist/providers/adapters/qwen-adapter.d.ts +11 -0
- package/dist/providers/agy.d.ts +32 -0
- package/dist/providers/base-adapter.d.ts +107 -0
- package/dist/providers/base.d.ts +12 -0
- package/dist/providers/binary-check.d.ts +102 -0
- package/dist/providers/bundle.d.ts +118 -0
- package/dist/providers/claude-mock.d.ts +90 -0
- package/dist/providers/claude.d.ts +21 -0
- package/dist/providers/codex-config.d.ts +15 -0
- package/dist/providers/codex.d.ts +25 -0
- package/dist/providers/config/model-selection-lint.d.ts +45 -0
- package/dist/providers/config/team-config.d.ts +183 -0
- package/dist/providers/config/types.d.ts +146 -0
- package/dist/providers/config/user-config.d.ts +88 -0
- package/dist/providers/copilot.d.ts +21 -0
- package/dist/providers/debug.d.ts +128 -0
- package/dist/providers/dsh-sidecar.d.ts +65 -0
- package/dist/providers/dsh-zstd.d.ts +27 -0
- package/dist/providers/dsh.d.ts +37 -0
- package/dist/providers/frontmatter.d.ts +46 -0
- package/dist/providers/gemini-session-reader.d.ts +151 -0
- package/dist/providers/gemini.d.ts +39 -0
- package/dist/providers/hermes.d.ts +90 -0
- package/dist/providers/index.d.ts +421 -0
- package/dist/providers/kimi.d.ts +37 -0
- package/dist/providers/model-catalog.d.ts +141 -0
- package/dist/providers/one-shot-timeout.d.ts +1 -0
- package/dist/providers/opencode-config.d.ts +62 -0
- package/dist/providers/opencode.d.ts +40 -0
- package/dist/providers/parsers/acp.d.ts +47 -0
- package/dist/providers/parsers/codex-app-server.d.ts +60 -0
- package/dist/providers/parsers/stream-json.d.ts +57 -0
- package/dist/providers/passive-readers/agy.d.ts +155 -0
- package/dist/providers/passive-readers/copilot.d.ts +173 -0
- package/dist/providers/passive-readers/dsh.d.ts +34 -0
- package/dist/providers/passive-readers/kimi.d.ts +44 -0
- package/dist/providers/passive-readers/opencode.d.ts +89 -0
- package/dist/providers/passive-readers/qwen.d.ts +151 -0
- package/dist/providers/passive-readers/shared.d.ts +138 -0
- package/dist/providers/passive-session-reader.d.ts +188 -0
- package/dist/providers/path-utils.d.ts +1 -0
- package/dist/providers/pi.d.ts +32 -0
- package/dist/providers/pricing.d.ts +107 -0
- package/dist/providers/qwen.d.ts +22 -0
- package/dist/providers/ratelimit-readings.d.ts +32 -0
- package/dist/providers/registry.d.ts +31 -0
- package/dist/providers/resume.d.ts +43 -0
- package/dist/providers/seed-instruction.d.ts +3 -0
- package/dist/providers/self-session-env.d.ts +21 -0
- package/dist/providers/session-limit.d.ts +9 -0
- package/dist/providers/strip-ansi.d.ts +5 -0
- package/dist/providers/transport-errors.d.ts +94 -0
- package/dist/providers/transport-lifecycle.d.ts +63 -0
- package/dist/providers/transport-wrappers.d.ts +110 -0
- package/dist/providers/transports/acp-profiles/config-option-step.d.ts +24 -0
- package/dist/providers/transports/acp-profiles/copilot.d.ts +12 -0
- package/dist/providers/transports/acp-profiles/gemini.d.ts +22 -0
- package/dist/providers/transports/acp-profiles/hermes.d.ts +27 -0
- package/dist/providers/transports/acp-profiles/index.d.ts +19 -0
- package/dist/providers/transports/acp-profiles/kimi.d.ts +24 -0
- package/dist/providers/transports/acp-profiles/opencode.d.ts +26 -0
- package/dist/providers/transports/acp-profiles/types.d.ts +258 -0
- package/dist/providers/transports/acp-rpc.d.ts +18 -0
- package/dist/providers/transports/acp.d.ts +215 -0
- package/dist/providers/transports/codex-app-server.d.ts +190 -0
- package/dist/providers/transports/hold-open.d.ts +120 -0
- package/dist/providers/transports/manager.d.ts +21 -0
- package/dist/providers/transports/stream-json.d.ts +162 -0
- package/dist/providers/transports/types.d.ts +56 -0
- package/dist/providers/types.d.ts +154 -0
- package/dist/providers/yolo-contract.d.ts +131 -0
- package/dist/script/adapter.d.ts +101 -0
- package/dist/script/batch-script.d.ts +7 -0
- package/dist/script/index.d.ts +3 -0
- package/dist/script/lmscript.d.ts +550 -0
- package/dist/shared/policy.d.ts +74 -0
- package/dist/shared-lib/db.d.ts +25 -0
- package/dist/shared-lib/passive-session-reader.d.ts +2 -0
- package/dist/shared-lib/provider-parse.d.ts +6 -0
- package/dist/templates/basedir.d.ts +52 -0
- package/dist/uri/lmctl_uri.d.ts +38 -0
- package/durable-memory/model_selection.md +122 -25
- package/examples/README.md +103 -0
- package/examples/anonymous-panel.lms +3 -0
- package/examples/batch-prompts.txt +9 -0
- package/examples/batchscript.lms +67 -0
- package/examples/n8n/agent-lib.lms +56 -0
- package/examples/n8n/git-lib.lms +93 -0
- package/examples/n8n/mock-support.db +0 -0
- package/examples/n8n/multi-agent-review.lms +107 -0
- package/examples/n8n/news-digest.lms +159 -0
- package/examples/n8n/rag-search.lms +163 -0
- package/examples/n8n/support-agent.lms +88 -0
- package/examples/n8n/ticket-triage.lms +156 -0
- package/package.json +13 -17
- package/dist/cli/side_effect_classifier.json +0 -19
|
@@ -0,0 +1,2097 @@
|
|
|
1
|
+
var Jd=Object.create;var Zi=Object.defineProperty;var Vd=Object.getOwnPropertyDescriptor;var Kd=Object.getOwnPropertyNames;var Yd=Object.getPrototypeOf,zd=Object.prototype.hasOwnProperty;var Qd=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var Zd=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Kd(e))!zd.call(t,s)&&s!==r&&Zi(t,s,{get:()=>e[s],enumerable:!(n=Vd(e,s))||n.enumerable});return t};var eo=(t,e,r)=>(r=t!=null?Jd(Yd(t)):{},Zd(e||!t||!t.__esModule?Zi(r,"default",{value:t,enumerable:!0}):r,t));var As=Qd(me=>{"use strict";function Yr(t){if(!Array.isArray(t))throw new TypeError("Each row and headers must be an array of cells");return Array.from(t,e=>{let r=e==null?"":String(e);if(/[\x00-\x1f\x7f-\x9f]/u.test(r))throw new TypeError("Cells must be single-line text without terminal control characters");return r})}function kf(t){if(t===void 0)return[];if(!Array.isArray(t))throw new TypeError('align must be an array of "left" or "right" per column');return t.map(e=>{if(e!=="left"&&e!=="right")throw new TypeError('align entries must be "left" or "right"');return e})}function Ge(t){let e=0;for(let r of t){let n=r.codePointAt(0);if(!(n>=768&&n<=879||n>=6832&&n<=6911||n>=7616&&n<=7679||n>=8400&&n<=8447||n>=65024&&n<=65039||n>=65056&&n<=65071||n===8203||n>=917760&&n<=917999)){if(n>=4352&&n<=4447||n>=11904&&n<=12350||n>=12353&&n<=13311||n>=13312&&n<=19903||n>=19968&&n<=40959||n>=40960&&n<=42191||n>=44032&&n<=55203||n>=63744&&n<=64255||n>=65072&&n<=65135||n>=65280&&n<=65376||n>=65504&&n<=65510||n>=9728&&n<=10175||n>=126976&&n<=129791||n>=131072&&n<=262141){e+=2;continue}e+=1}}return e}function Pa(t,e,r){let n=" ".repeat(Math.max(0,e-Ge(t)));return r?n+t:t+n}function Lf(t){if(Array.isArray(t))return{rows:t};if(t!==null&&typeof t=="object"&&Array.isArray(t.rows))return t;throw new TypeError("each grid must be a rows array or { rows, headers }")}function Cf(t){if(t===void 0)return"\u2026";if(typeof t!="string"||/[\x00-\x1f\x7f-\x9f]/u.test(t))throw new TypeError("ellipsis must be a single-line string without terminal control characters");return t}function Of(t,e,r="\u2026"){if(Ge(t)<=e)return t;let n=Ge(r)>e?"\u2026":r,s=Ge(n);if(e<=s)return n;let i="",o=0;for(let a of t){let l=Ge(a);if(o+l>e-s)break;i+=a,o+=l}return`${i}${n}`}function Df(t){if(t===void 0)return[];if(!Array.isArray(t))throw new TypeError("max must be an array of per-column width caps");return t.map(e=>{if(e!=null){if(typeof e!="number"||!Number.isInteger(e)||e<1)throw new TypeError("max entries must be positive integers, null, or undefined");return e}})}function $a(t,{max:e}={}){if(!Array.isArray(t))throw new TypeError("grids must be an array of grids");let r=Df(e),n=[],s=(i,o)=>{n[i]=Math.max(n[i]??0,o)};for(let i of t){let o=Lf(i);o.headers!==void 0&&Yr(o.headers).forEach((a,l)=>{s(l,Ge(a))});for(let a of o.rows.map(Yr))a.forEach((l,c)=>{s(c,Ge(l))})}return n.map((i,o)=>{let a=r[o];return a===void 0?i:Math.min(i,a)})}me.measureColumns=$a;function Mf(t){if(t===void 0)return"";if(typeof t=="number"&&Number.isInteger(t)&&t>=0)return" ".repeat(t);if(typeof t=="string"&&!/[\x00-\x1f\x7f-\x9f]/u.test(t))return t;throw new TypeError("margin must be a number of spaces or a single-line string")}function ja(t,{widths:e,headers:r,align:n,truncate:s=!0,truncateTrailing:i=!1,margin:o,max:a,ellipsis:l}={}){if(!Array.isArray(t))throw new TypeError("rows must be an array of row arrays");if(e!==void 0&&!Array.isArray(e))throw new TypeError("widths must be an array of column widths");if(e!==void 0&&a!==void 0)throw new TypeError("pass widths or max, not both (max caps a measurement)");let c=Mf(o),u=kf(n),d=Cf(l),p=e??$a([{rows:t,headers:r}],{max:a}),m=t.map(Yr);r!==void 0&&m.unshift(Yr(r));let h=m.map(g=>{let y=g.length-1;for(;y>=0&&g[y]==="";)y--;return g.slice(0,y+1).map((f,T)=>{let E=p[T]||0,I=s&&E>0&&(T!==y||i)?Of(f,E,d):f;return u[T]==="right"?Pa(I,E,!0):T===y?I:Pa(I,E,!1)}).join(" ")}).join(`
|
|
2
|
+
`);return h===""||c===""?h:`${c}${h.split(`
|
|
3
|
+
`).join(`
|
|
4
|
+
${c}`)}`}me.renderGrid=ja;function Ba(t,{headers:e,align:r,truncate:n,truncateTrailing:s,margin:i,max:o,ellipsis:a}={}){return ja(t,{headers:e,align:r,truncate:n,truncateTrailing:s,margin:i,max:o,ellipsis:a})}function Ff(t,{headers:e,align:r,truncate:n,truncateTrailing:s,margin:i,max:o,ellipsis:a,stream:l=process.stdout}={}){let c=Ba(t,{headers:e,align:r,truncate:n,truncateTrailing:s,margin:i,max:o,ellipsis:a});c&&l.write(`${c}
|
|
5
|
+
`)}me.formatTable=Ba;me.printTable=Ff;function Ua(t){return t instanceof Date?t.getTime():typeof t=="number"?t:typeof t=="string"&&t.trim()?Date.parse(t):NaN}function Pf(t,{now:e=Date.now()}={}){let r=Ua(e);if(!Number.isFinite(r))throw new TypeError("now must be a valid timestamp");let n=Ua(t);if(!Number.isFinite(n))return"unknown";let s=n-r,i=Math.floor(Math.abs(s)/1e3);if(i===0)return"now";for(let[o,a]of[["w",604800],["d",86400],["h",3600],["m",60],["s",1]])if(i>=a)return`${Math.floor(i/a)}${o}${s<0?" ago":""}`}me.formatRelativeTime=Pf;function Uf(t){if(typeof t!="number"||!Number.isFinite(t))return"unknown";let e=t<0?"-":"",r=Math.abs(t);if(r<1e3)return String(t);let n=Math.round(r/1e3);return n<1e3?`${e}${n}K`:`${e}${(r/1e6).toFixed(1)}M`}me.formatCount=Uf;var Is=[["w",604800],["d",86400],["h",3600],["m",60],["s",1]];function $f(t,{maxUnit:e="w",style:r="spaced"}={}){if(typeof t!="number"||!Number.isFinite(t))return"unknown";let n=Is.findIndex(([a])=>a===e);if(n===-1)throw new TypeError('maxUnit must be one of "w", "d", "h", "m", "s"');if(r!=="spaced"&&r!=="compact")throw new TypeError('style must be "spaced" or "compact"');let s=Math.floor(Math.max(0,t)/1e3);if(r==="compact"){let a=Is.slice(n).filter(([d])=>d!=="s");if(a.length===0||s<60)return"<1m";let l=[],c=s,u=!1;for(let[d,p]of a){let m=Math.floor(c/p);if(c-=m*p,m>0&&!u){let h=d==="d"||d==="w"?`${m}${d}`:`${ke(m)}${d}`;l.push({text:h,zero:!1}),u=!0}else u&&l.push({text:`${ke(m)}${d}`,zero:m===0})}for(;l.length>0&&l[l.length-1].zero;)l.pop();return l.map(d=>d.text).join("")}let i=s,o=[];for(let[a,l]of Is.slice(n))if(i>=l||a==="s"&&o.length===0){let c=Math.floor(i/l);if(i-=c*l,o.push(`${c}${a}`),o.length===2)break}return o.join(" ")}me.formatDuration=$f;function Wa(t){return t===void 0?new Date:t instanceof Date?t:typeof t=="number"||typeof t=="string"?new Date(t):new Date(NaN)}function ke(t){return String(t).padStart(2,"0")}function Ha(t){let e=Wa(t);return Number.isNaN(e.getTime())?"unknown":`${ke(e.getHours())}:${ke(e.getMinutes())}:${ke(e.getSeconds())}`}me.formatClock=Ha;function jf(t){let e=Wa(t);return Number.isNaN(e.getTime())?"unknown":`${`${e.getFullYear()}-${ke(e.getMonth()+1)}-${ke(e.getDate())}`} ${Ha(e)}`}me.formatLocalTimestamp=jf;function Bf(t){return typeof t=="number"&&Number.isFinite(t)?`${Math.round(t*100)}%`:"?%"}me.formatPercent=Bf;function Wf(t,{width:e=10,fill:r="#",empty:n=" ",unknown:s="?"}={}){if(typeof e!="number"||!Number.isInteger(e)||e<1)throw new TypeError("width must be a positive integer");for(let[o,a]of[["fill",r],["empty",n],["unknown",s]])if(typeof a!="string"||[...a].length!==1||/[\x00-\x1f\x7f-\x9f]/u.test(a)||Ge(a)!==1)throw new TypeError(`${o} must be a single character with terminal display width 1`);if(typeof t!="number"||!Number.isFinite(t))return s.repeat(e);let i=Math.min(e,Math.max(0,Math.round(t*e)));return`${r.repeat(i)}${n.repeat(e-i)}`}me.formatBar=Wf;function Hf(t){if(typeof t!="number"||!Number.isFinite(t))return"unknown";let e=Math.floor(Math.max(0,t)/1e3),r=Math.floor(e/86400);e-=r*86400;let n=Math.floor(e/3600);e-=n*3600;let s=Math.floor(e/60);e-=s*60;let i=`${ke(n)}:${ke(s)}:${ke(e)}`;return r>0?`${r}d ${i}`:i}me.formatTimer=Hf;function Xf(t){return(t==null?"":String(t)).replace(/[\x00-\x1f\x7f-\x9f]/gu,r=>r===`
|
|
6
|
+
`?"\\n":r===" "?"\\t":r==="\r"?"\\r":`\\x${r.codePointAt(0).toString(16).padStart(2,"0")}`)}me.escapeCell=Xf});import{spawn as to,spawnSync as Yn}from"node:child_process";import{randomUUID as eu}from"node:crypto";import{tmpdir as tu}from"node:os";import*as F from"node:fs";import*as de from"node:path";import*as ao from"node:readline";import{fileURLToPath as lo}from"node:url";var C=class extends Error{message;line;column;stage;file;constructor(e,r,n,s,i){let o=i&&i!=="<main>"?`${i}:${r}:${n}`:`${r}:${n}`;super(`[${s} Error at ${o}] ${e}`),this.name="LMScriptError",this.message=e,this.line=r,this.column=n,this.stage=s,this.file=i}},pe=class extends Error{isControlFlow=!0;exitCode;constructor(e=0){super(`LMScript exited with code ${e}`),this.name="LMScriptExit",this.exitCode=e}};function co(t,e){let r=t.file&&t.file!=="<main>"?`${t.file}:${t.line}:${t.column}`:`${t.line}:${t.column}`,n=e;if(t.file&&(!n||n&&t.file!=="<main>"&&t.file!=="<std>"))try{F.existsSync(t.file)&&F.statSync(t.file).isFile()&&(n=F.readFileSync(t.file,"utf-8"))}catch{}if(!n)return`[${t.severity.toUpperCase()} at ${r}] ${t.message}`;let s=n.split(`
|
|
7
|
+
`),i=String(t.line),o=t.line-1,a=s[o]??"",l=" | ",c=` ${i.padStart(4," ")} | `,u=" ".repeat(Math.max(0,t.column-1));return`[${t.severity.toUpperCase()} at ${r}] ${t.message}
|
|
8
|
+
`+l+`
|
|
9
|
+
${c}${a}
|
|
10
|
+
${l}${u}^`}function uo(t){if(typeof t!="string"||t.length!==1||/["\r\n]/.test(t))throw new Error("CSV delimiter must be one character other than a quote or newline")}function Re(t,e){return t!=null&&Object.hasOwn(t,e)?t[e]:void 0}function je(t,e,r){String(e)==="__proto__"?Object.defineProperty(t,e,{value:r,writable:!0,enumerable:!0,configurable:!0}):t[e]=r}var zn=10*1024*1024;function mo(t){if(typeof t!="string"||!t.trim())throw new Error("urlget() requires a non-empty URL string");let e;try{e=new URL(t)}catch{throw new Error("urlget() requires a valid HTTP(S) URL")}if(e.protocol!=="http:"&&e.protocol!=="https:"||e.username||e.password)throw new Error("urlget() only permits HTTP(S) URLs without embedded credentials");let r=`
|
|
11
|
+
const target = process.argv[1];
|
|
12
|
+
const maxBytes = ${zn};
|
|
13
|
+
const controller = new AbortController();
|
|
14
|
+
const timer = setTimeout(() => controller.abort(), 30000);
|
|
15
|
+
try {
|
|
16
|
+
const response = await fetch(target, { method: "GET", redirect: "follow", signal: controller.signal });
|
|
17
|
+
if (!response.ok) throw new Error("HTTP " + response.status + " " + response.statusText);
|
|
18
|
+
const reader = response.body?.getReader();
|
|
19
|
+
const chunks = [];
|
|
20
|
+
let total = 0;
|
|
21
|
+
if (reader) {
|
|
22
|
+
while (true) {
|
|
23
|
+
const part = await reader.read();
|
|
24
|
+
if (part.done) break;
|
|
25
|
+
total += part.value.byteLength;
|
|
26
|
+
if (total > maxBytes) throw new Error("response exceeds 10 MiB limit");
|
|
27
|
+
chunks.push(Buffer.from(part.value));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
process.stdout.write(Buffer.concat(chunks));
|
|
31
|
+
} catch (error) {
|
|
32
|
+
controller.abort();
|
|
33
|
+
process.stderr.write(error?.message || String(error));
|
|
34
|
+
process.exitCode = 1;
|
|
35
|
+
} finally {
|
|
36
|
+
clearTimeout(timer);
|
|
37
|
+
}
|
|
38
|
+
`,n=Yn(process.execPath,["--input-type=module","-e",r,t],{encoding:"utf8",shell:!1,timeout:35e3,maxBuffer:zn+4096,windowsHide:!0});if(n.error)throw n.error.code==="ETIMEDOUT"?new Error("urlget() request timed out"):new Error(`urlget() failed: ${n.error.message}`);if(n.status!==0)throw new Error(`urlget() failed: ${String(n.stderr||"child process exited")}`.trim());return String(n.stdout||"")}async function ru(t){if(typeof t!="string"||!t.trim())throw new Error("urlget() requires a non-empty URL string");let e;try{e=new URL(t)}catch{throw new Error("urlget() requires a valid HTTP(S) URL")}if(e.protocol!=="http:"&&e.protocol!=="https:"||e.username||e.password)throw new Error("urlget() only permits HTTP(S) URLs without embedded credentials");let r=new AbortController,n=setTimeout(()=>r.abort(),3e4),s;try{let i=await fetch(e.toString(),{method:"GET",redirect:"follow",signal:r.signal});if(!i.ok)throw r.abort(),new Error("HTTP "+i.status+" "+i.statusText);s=i.body?.getReader();let o=[],a=0;if(s)for(;;){let l=await s.read();if(l.done)break;if(a+=l.value.byteLength,a>zn)throw await s.cancel().catch(()=>{}),r.abort(),new Error("response exceeds 10 MiB limit");o.push(l.value)}return Buffer.concat(o).toString("utf-8")}catch(i){if(r.abort(),s)try{await s.cancel().catch(()=>{})}catch{}throw i.name==="AbortError"?new Error("urlget() request timed out"):new Error(`urlget() failed: ${i?.message||String(i)}`)}finally{clearTimeout(n)}}var xr=new Set,Ir=1e3;process.on("exit",()=>{for(let t of xr)try{process.platform!=="win32"&&t.pid?process.kill(-t.pid,"SIGKILL"):t.kill("SIGKILL")}catch{}xr.clear()});function Rr(t,e,r,n=null,s=!1,i=0,o=null){return{stdout:t,stderr:e,code:r,signal:n,timed_out:s,duration_ms:i,pid:o}}function fo(t){let e=String(t);return e.length>0&&/^[a-zA-Z0-9_./@=-]+$/.test(e)?e:"'"+e.replace(/'/g,"'\\''")+"'"}function po(t,e=6e4){if(!Number.isSafeInteger(e)||e<0)throw new Error("system() timeout must be a non-negative safe integer in milliseconds");let r=performance.now(),n;if(Array.isArray(t)){if(t.length===0)throw new Error("system() argv array must not be empty");let u=String(t[0]),d=t.slice(1).map(String);n=Yn(u,d,{shell:!1,encoding:"utf-8",timeout:e>0?e:void 0,maxBuffer:10*1024*1024,killSignal:"SIGKILL"})}else n=Yn(t,{shell:!0,encoding:"utf-8",timeout:e>0?e:void 0,maxBuffer:10*1024*1024,killSignal:"SIGKILL"});let s=Math.max(0,Math.round(performance.now()-r)),i=typeof n.pid=="number"?n.pid:null;if(n.error){if(n.error.code==="ETIMEDOUT"){let u=n.stdout!=null?String(n.stdout):"",d=n.stderr!=null?String(n.stderr):"";return Rr(u,d,null,n.signal||"SIGKILL",!0,s,i)}throw n.error}let o=n.stdout!=null?String(n.stdout):"",a=n.stderr!=null?String(n.stderr):"",l=n.status!==null?n.status:null,c=n.signal!==null?String(n.signal):null;return Rr(o,a,l,c,!1,s,i)}function ho(t,e=6e4){return new Promise((r,n)=>{if(!Number.isSafeInteger(e)||e<0){n(new Error("system() timeout must be a non-negative safe integer in milliseconds"));return}let s=performance.now();try{let i=process.platform!=="win32",o;if(Array.isArray(t)){if(t.length===0){n(new Error("system() argv array must not be empty"));return}let E=String(t[0]),I=t.slice(1).map(String);o=to(E,I,{shell:!1,detached:i,stdio:["ignore","pipe","pipe"]})}else o=to(t,{shell:!0,detached:i,stdio:["ignore","pipe","pipe"]});xr.add(o);let a="",l="",c=null,u=null,d=0,p=!1,m=!1,h,g=!1,y,f=()=>{if(g)return;g=!0,xr.delete(o),y&&clearTimeout(y);try{o.stdout?.destroy(),o.stderr?.destroy()}catch{}let E=Math.max(0,Math.round(performance.now()-s)),I=typeof o.pid=="number"?o.pid:null;if(h){n(h);return}if(m){r(Rr(a,l,null,u||"SIGKILL",!0,E,I));return}r(Rr(a,l,c,u,!1,E,I))};e>0&&(y=setTimeout(()=>{m=!0,u="SIGKILL";try{if(i&&o.pid)try{process.kill(-o.pid,"SIGKILL")}catch{o.kill("SIGKILL")}else o.kill("SIGKILL")}catch{}f()},e));let T=10*1024*1024;o.stdout?.setEncoding("utf-8"),o.stderr?.setEncoding("utf-8"),o.stdout?.on("data",E=>{let I=Buffer.byteLength(E,"utf-8");if(d+I>T){if(!p){p=!0;try{if(i&&o.pid)try{process.kill(-o.pid,"SIGKILL")}catch{o.kill("SIGKILL")}else o.kill("SIGKILL")}catch{}l+=(l&&!l.endsWith(`
|
|
39
|
+
`)?`
|
|
40
|
+
`:"")+"system() output exceeds 10 MiB limit",h=new Error("system() output exceeds 10 MiB limit"),f()}return}d+=I,a+=E}),o.stderr?.on("data",E=>{let I=Buffer.byteLength(E,"utf-8");if(d+I>T){if(!p){p=!0;try{if(i&&o.pid)try{process.kill(-o.pid,"SIGKILL")}catch{o.kill("SIGKILL")}else o.kill("SIGKILL")}catch{}l+=(l&&!l.endsWith(`
|
|
41
|
+
`)?`
|
|
42
|
+
`:"")+"system() output exceeds 10 MiB limit",h=new Error("system() output exceeds 10 MiB limit"),f()}return}d+=I,l+=E}),o.on("error",E=>{h||(h=E)}),o.on("close",(E,I)=>{E!==null?(c=E,u=null):(c=null,u=I?String(I):null),f()})}catch(i){n(i instanceof Error?i:new Error(String(i)))}})}function nu(t,e=null){if(typeof t!="string")return t??e;let r=t.trim();if(r.length===0)return e;try{return JSON.parse(r)}catch{}let n=r.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);if(n&&n[1])try{return JSON.parse(n[1].trim())}catch{}let s=r.indexOf("{"),i=r.lastIndexOf("}");if(s!==-1&&i>s)try{return JSON.parse(r.slice(s,i+1))}catch{}let o=r.indexOf("["),a=r.lastIndexOf("]");if(o!==-1&&a>o)try{return JSON.parse(r.slice(o,a+1))}catch{}return e}function Wt(t){if(typeof process>"u"||!process.stdin||!process.stdin.isTTY)return null;t!=null&&process.stdout&&typeof process.stdout.write=="function"&&process.stdout.write(String(t));try{let e=Buffer.alloc(1024),r="";for(;;){let n=0;try{n=F.readSync(0,e,0,1,null)}catch{return r.length>0?r:null}if(n===0)return r.length>0?r:null;let s=e.toString("utf-8",0,n);if(s===`
|
|
43
|
+
`)return r.endsWith("\r")&&(r=r.slice(0,-1)),r;r+=s}}catch{return null}}function Ht(t,e=typeof process<"u"?process.stdin:null,r=typeof process<"u"?process.stdout:null){return new Promise(n=>{if(!e||typeof e.on!="function"){n(null);return}if(e.destroyed||e.readableEnded){n(null);return}if(e.isTTY===!1||typeof process<"u"&&e===process.stdin&&!process.stdin.isTTY){n(null);return}t!=null&&r&&typeof r.write=="function"&&r.write(String(t));let s=ao.createInterface({input:e,output:r,terminal:!!e.isTTY}),i=!1,o=()=>{s.close()};s.question("",a=>{i||(i=!0,o(),n(a))}),s.on("close",()=>{i||(i=!0,n(null))}),s.on("error",()=>{i||(i=!0,o(),n(null))})})}function ro(t,e=!0,r=","){uo(r);let n=[],s=[],i="",o=!1,a=!1,l=!1;for(let d=0;d<t.length;d++){let p=t[d],m=t[d+1];if(l=!0,o)p==='"'?m==='"'?(i+='"',d++):(o=!1,a=!0):i+=p;else{if(a&&p!==r&&p!=="\r"&&p!==`
|
|
44
|
+
`)throw new Error("Invalid CSV: unexpected character after closing quote");if(p==='"'){if(i.length>0)throw new Error("Invalid CSV: quote inside unquoted field");o=!0}else p===r?(a=!1,s.push(i),i=""):p==="\r"?(m===`
|
|
45
|
+
`&&d++,s.push(i),n.push(s),s=[],i="",a=!1,l=!1):p===`
|
|
46
|
+
`?(s.push(i),n.push(s),s=[],i="",a=!1,l=!1):i+=p}}if(o)throw new Error("Invalid CSV: unterminated quoted field");if(l&&(s.push(i),n.push(s)),!e)return n.map(d=>d.map(no));if(n.length===0)return[];let c=n[0].map(d=>d.trim()),u=[];for(let d=1;d<n.length;d++){let p=n[d],m={};for(let h=0;h<c.length;h++)je(m,c[h],h<p.length?no(p[h]):null);u.push(m)}return u}function no(t){let e=t.trim();if(e==="")return"";if(/^-?\d+$/.test(e)){let r=Number(e);if(!Number.isNaN(r))return r}if(/^-?\d+\.\d+$/.test(e)){let r=Number(e);if(!Number.isNaN(r))return r}return e.toLowerCase()==="true"?!0:e.toLowerCase()==="false"?!1:e.toLowerCase()==="null"?null:t}function so(t,e=","){if(uo(e),!Array.isArray(t)||t.length===0)return"";let r=t[0];if(Array.isArray(r))return t.map(n=>n.map(s=>Ar(s,e)).join(e)).join(`
|
|
47
|
+
`);if(typeof r=="object"&&r!==null){let n=Object.keys(r),s=n.map(o=>Ar(o,e)).join(e),i=t.map(o=>n.map(a=>Ar(Re(o,a)??"",e)).join(e));return[s,...i].join(`
|
|
48
|
+
`)}return t.map(n=>Ar(n,e)).join(`
|
|
49
|
+
`)}function Ar(t,e){let r=t==null?"":String(t);return r===""||r.includes(e)||r.includes('"')||r.includes(`
|
|
50
|
+
`)||r.includes("\r")?`"${r.replaceAll('"','""')}"`:r}var io={fn:"FN",function:"FN",let:"LET",if:"IF",else:"ELSE",while:"WHILE",for:"FOR",return:"RETURN",break:"BREAK",continue:"CONTINUE",true:"TRUE",false:"FALSE",null:"NULL",parallel:"PARALLEL",sync:"SYNC",import:"IMPORT"},jt=class{source;length;file;pos=0;line=1;column=1;constructor(e,r){this.source=e,this.length=e.length,this.file=r}tokenize(){let e=[];for(;this.pos<this.length&&(this.skipWhitespaceAndComments(),!(this.pos>=this.length));){let r=this.line,n=this.column,s=this.peek();if(this.isDigit(s)||s==="."&&this.isDigit(this.peekNext())){e.push(this.readNumber(r,n));continue}if(s==='"'||s==="'"){e.push(this.readString(s,r,n));continue}if(s==="<"&&this.peekNext()==="<"){let i=this.tryReadHeredoc(r,n);if(i){e.push(i);continue}}if(this.isAlpha(s)){e.push(this.readIdentifier(r,n));continue}switch(this.advance(),s){case".":e.push({type:"DOT",value:".",line:r,column:n});break;case":":e.push({type:"COLON",value:":",line:r,column:n});break;case"(":e.push({type:"LPAREN",value:"(",line:r,column:n});break;case")":e.push({type:"RPAREN",value:")",line:r,column:n});break;case"{":e.push({type:"LBRACE",value:"{",line:r,column:n});break;case"}":e.push({type:"RBRACE",value:"}",line:r,column:n});break;case"[":e.push({type:"LBRACKET",value:"[",line:r,column:n});break;case"]":e.push({type:"RBRACKET",value:"]",line:r,column:n});break;case",":e.push({type:"COMMA",value:",",line:r,column:n});break;case";":e.push({type:"SEMICOLON",value:";",line:r,column:n});break;case"+":e.push({type:"PLUS",value:"+",line:r,column:n});break;case"-":e.push({type:"MINUS",value:"-",line:r,column:n});break;case"*":e.push({type:"STAR",value:"*",line:r,column:n});break;case"/":e.push({type:"SLASH",value:"/",line:r,column:n});break;case"%":e.push({type:"PERCENT",value:"%",line:r,column:n});break;case"=":this.match("=")?e.push({type:"EQUAL",value:"==",line:r,column:n}):e.push({type:"ASSIGN",value:"=",line:r,column:n});break;case"!":this.match("=")?e.push({type:"NOT_EQUAL",value:"!=",line:r,column:n}):e.push({type:"NOT",value:"!",line:r,column:n});break;case"<":this.match("=")?e.push({type:"LESS_EQUAL",value:"<=",line:r,column:n}):e.push({type:"LESS",value:"<",line:r,column:n});break;case">":this.match("=")?e.push({type:"GREATER_EQUAL",value:">=",line:r,column:n}):e.push({type:"GREATER",value:">",line:r,column:n});break;case"&":if(this.match("&"))e.push({type:"AND",value:"&&",line:r,column:n});else throw new C("Unexpected character '&'. Did you mean '&&'?",r,n,"LEXER",this.file);break;case"|":if(this.match("|"))e.push({type:"OR",value:"||",line:r,column:n});else throw new C("Unexpected character '|'. Did you mean '||'?",r,n,"LEXER",this.file);break;default:throw new C(`Unexpected character: '${s}'`,r,n,"LEXER",this.file)}}return e.push({type:"EOF",value:"",line:this.line,column:this.column}),e}peek(){return this.source[this.pos]||""}peekNext(){return this.source[this.pos+1]||""}advance(){let e=this.source[this.pos++];return e===`
|
|
51
|
+
`?(this.line++,this.column=1):this.column++,e}match(e){return this.pos>=this.length||this.source[this.pos]!==e?!1:(this.advance(),!0)}isDigit(e){return e>="0"&&e<="9"}isAlpha(e){return e>="a"&&e<="z"||e>="A"&&e<="Z"||e==="_"}isAlphaNumeric(e){return this.isAlpha(e)||this.isDigit(e)}skipWhitespaceAndComments(){for(;this.pos<this.length;){let e=this.peek();if(e===" "||e===" "||e==="\r"||e===`
|
|
52
|
+
`)this.advance();else if(e==="/"&&this.peekNext()==="/"||e==="#")for(;this.pos<this.length&&this.peek()!==`
|
|
53
|
+
`;)this.advance();else if(e==="/"&&this.peekNext()==="*"){let r=this.line,n=this.column;this.advance(),this.advance();let s=!1;for(;this.pos<this.length;){if(this.peek()==="*"&&this.peekNext()==="/"){this.advance(),this.advance(),s=!0;break}this.advance()}if(!s)throw new C("Unterminated block comment",r,n,"LEXER",this.file)}else break}}readNumber(e,r){let n="";for(;this.pos<this.length&&this.isDigit(this.peek());)n+=this.advance();if(this.peek()==="."&&this.isDigit(this.peekNext()))for(n+=this.advance();this.pos<this.length&&this.isDigit(this.peek());)n+=this.advance();return{type:"NUMBER",value:n,literal:parseFloat(n),line:e,column:r}}readString(e,r,n){this.advance();let s="";for(;this.pos<this.length&&this.peek()!==e;){if(this.peek()===`
|
|
54
|
+
`)throw new C("Unterminated string literal across newline",r,n,"LEXER",this.file);if(this.peek()==="\\"){this.advance();let i=this.advance();switch(i){case"n":s+=`
|
|
55
|
+
`;break;case"t":s+=" ";break;case"r":s+="\r";break;case"\\":s+="\\";break;case'"':s+='"';break;case"'":s+="'";break;default:s+=i;break}}else s+=this.advance()}if(this.pos>=this.length)throw new C("Unterminated string literal at end of file",r,n,"LEXER",this.file);return this.advance(),{type:"STRING",value:s,literal:s,line:r,column:n}}tryReadHeredoc(e,r){let n=this.pos+2;if(!this.isAlpha(this.source[n]))return;for(n++;n<this.length&&this.isAlphaNumeric(this.source[n]);)n++;let s=this.source.slice(this.pos+2,n),i=this.source[n]==="\r"&&this.source[n+1]===`
|
|
56
|
+
`?2:this.source[n]===`
|
|
57
|
+
`?1:0;if(i===0)return;let o=n+i-this.pos;for(let l=0;l<o;l++)this.advance();let a=this.pos;for(;this.pos<this.length;){let l=this.pos,c=this.pos;for(;c<this.length&&this.source[c]!=="\r"&&this.source[c]!==`
|
|
58
|
+
`;)c++;let u=this.source.slice(l,c),d=u===`${s};`;if(u===s||d){let h=this.source[c]==="\r"&&this.source[c+1]===`
|
|
59
|
+
`?2:this.source[c]===`
|
|
60
|
+
`||this.source[c]==="\r"?1:0,g=this.source.slice(a,l),f=s.length+(d?0:h);for(let T=0;T<f;T++)this.advance();return{type:"STRING",value:g,literal:g,line:e,column:r}}let p=this.source[c]==="\r"&&this.source[c+1]===`
|
|
61
|
+
`?2:c<this.length?1:0,m=c+p-this.pos;for(let h=0;h<m;h++)this.advance()}throw new C(`Unterminated heredoc; expected closing marker '${s}'`,e,r,"LEXER",this.file)}readIdentifier(e,r){let n="";for(;this.pos<this.length&&this.isAlphaNumeric(this.peek());)n+=this.advance();let s=Object.hasOwn(io,n)?io[n]:void 0;if(s){let i;return s==="TRUE"&&(i=!0),s==="FALSE"&&(i=!1),s==="NULL"&&(i=null),{type:s,value:n,literal:i,line:e,column:r}}return{type:"IDENTIFIER",value:n,line:e,column:r}}};function Qn(t,e){if(!(!t||typeof t!="object")){"line"in t&&"column"in t&&!t.file&&(t.file=e);for(let r of Object.keys(t)){let n=t[r];if(Array.isArray(n))for(let s of n)Qn(s,e);else n&&typeof n=="object"&&Qn(n,e)}}}var Bt=class{tokens;current=0;file;constructor(e,r){this.tokens=e,this.file=r}parse(){let e=[],r=this.peek();for(;!this.isAtEnd();)e.push(this.parseDeclaration(!0));let n={kind:"Program",statements:e,line:r.line,column:r.column,file:this.file};return this.file&&Qn(n,this.file),n}parseDeclaration(e=!1){try{if(this.match("FN"))return this.parseFunctionDecl();if(this.match("LET"))return this.parseVarDecl();if(this.match("IMPORT")){if(!e)throw new C("'import' statement is only allowed at the top level of a file",this.previous().line,this.previous().column,"PARSER",this.file);return this.parseImportStmt()}return this.parseStatement()}catch(r){throw r instanceof C?r:new C(r instanceof Error?r.message:String(r),this.peek().line,this.peek().column,"PARSER",this.file)}}parseImportStmt(){let e=this.previous(),r=this.consume("STRING","Expected file path string after 'import'");return this.consumeOptionalSemicolon(),{kind:"ImportStmt",path:r.value,line:e.line,column:e.column,file:this.file}}parseFunctionDecl(){let e=this.previous(),r=this.consume("IDENTIFIER","Expected function name after 'fn'");this.consume("LPAREN","Expected '(' after function name");let n=[];if(!this.check("RPAREN"))do{let i=this.consume("IDENTIFIER","Expected parameter name");n.push(i.value)}while(this.match("COMMA"));this.consume("RPAREN","Expected ')' after parameters"),this.consume("LBRACE","Expected '{' before function body");let s=this.parseBlockBody(this.previous());return{kind:"FunctionDeclStmt",name:r.value,params:n,body:s,line:e.line,column:e.column}}parseVarDecl(){let e=this.previous();if(this.match("LPAREN","LBRACKET")){let s=this.previous().type==="LPAREN"?"RPAREN":"RBRACKET",i=[];if(!this.check(s))do{let a=this.consume("IDENTIFIER","Expected variable name in destructuring");i.push(a.value)}while(this.match("COMMA"));this.consume(s,`Expected '${s==="RPAREN"?")":"]"}' after variable list`),this.consume("ASSIGN","Expected '=' after destructuring variable list");let o=this.parseExpression();return this.consumeOptionalSemicolon(),{kind:"TupleVarDeclStmt",names:i,initializer:o,line:e.line,column:e.column}}let r=this.consume("IDENTIFIER","Expected variable name after 'let'"),n;return this.match("ASSIGN")&&(n=this.parseExpression()),this.consumeOptionalSemicolon(),{kind:"VarDeclStmt",name:r.value,initializer:n,line:e.line,column:e.column}}parseStatement(){if(this.match("IMPORT"))throw new C("'import' statement is only allowed at the top level of a file",this.previous().line,this.previous().column,"PARSER",this.file);return this.match("SYNC")?this.parseSyncStatement():this.match("IF")?this.parseIfStatement():this.match("WHILE")?this.parseWhileStatement():this.match("FOR")?this.parseForStatement():this.match("RETURN")?this.parseReturnStatement():this.match("BREAK")?this.parseBreakStatement():this.match("CONTINUE")?this.parseContinueStatement():this.match("LBRACE")?this.parseBlockBody(this.previous()):this.parseExpressionStatement()}parseSyncStatement(){let e=this.previous(),r=this.parseExpression();if(this.consumeOptionalSemicolon(),r.kind==="AssignExpr")return{kind:"SyncAssignStmt",target:r.target,value:r.value,line:e.line,column:e.column};if(r.kind==="IndexAssignExpr")return{kind:"SyncIndexAssignStmt",target:r.target,index:r.index,value:r.value,line:e.line,column:e.column};if(r.kind==="CallExpr")return{kind:"SyncCallStmt",call:r,line:e.line,column:e.column};throw new C("Invalid 'sync' statement target; expected variable assignment ('sync a = ...'), member/index assignment ('sync obj.k = ...'), or container mutation call ('sync push(arr, ...)').",e.line,e.column,"PARSER",this.file)}parseIfStatement(){let e=this.previous();this.consume("LPAREN","Expected '(' after 'if'");let r=this.parseExpression();this.consume("RPAREN","Expected ')' after if condition");let n=this.parseStatement(),s;return this.match("ELSE")&&(s=this.parseStatement()),{kind:"IfStmt",condition:r,thenBranch:n,elseBranch:s,line:e.line,column:e.column}}parseWhileStatement(){let e=this.previous();this.consume("LPAREN","Expected '(' after 'while'");let r=this.parseExpression();this.consume("RPAREN","Expected ')' after while condition");let n=this.parseStatement();return{kind:"WhileStmt",condition:r,body:n,line:e.line,column:e.column}}parseForStatement(){let e=this.previous();this.consume("LPAREN","Expected '(' after 'for'");let r;if(this.match("SEMICOLON"))r=void 0;else if(this.match("LET"))r=this.parseVarDecl();else{let o=this.parseExpression();this.consume("SEMICOLON","Expected ';' after for-loop initializer"),r={kind:"ExprStmt",expr:o,line:o.line,column:o.column}}let n;this.check("SEMICOLON")||(n=this.parseExpression()),this.consume("SEMICOLON","Expected ';' after for-loop condition");let s;this.check("RPAREN")||(s=this.parseExpression()),this.consume("RPAREN","Expected ')' after for clauses");let i=this.parseStatement();return{kind:"ForStmt",init:r,condition:n,update:s,body:i,line:e.line,column:e.column}}parseReturnStatement(){let e=this.previous(),r;return!this.check("SEMICOLON")&&!this.check("RBRACE")&&!this.isAtEnd()&&(r=this.parseExpression()),this.consumeOptionalSemicolon(),{kind:"ReturnStmt",value:r,line:e.line,column:e.column}}parseBreakStatement(){let e=this.previous();return this.consumeOptionalSemicolon(),{kind:"BreakStmt",line:e.line,column:e.column}}parseContinueStatement(){let e=this.previous();return this.consumeOptionalSemicolon(),{kind:"ContinueStmt",line:e.line,column:e.column}}parseBlockBody(e){let r=[];for(;!this.check("RBRACE")&&!this.isAtEnd();)r.push(this.parseDeclaration());return this.consume("RBRACE","Expected '}' after block"),{kind:"BlockStmt",statements:r,line:e.line,column:e.column}}parseExpressionStatement(){let e=this.parseExpression();return this.consumeOptionalSemicolon(),{kind:"ExprStmt",expr:e,line:e.line,column:e.column}}parseExpression(){return this.parseAssignment()}parseAssignment(){let e=this.parseLogicalOr();if(this.match("ASSIGN")){let r=this.previous(),n=this.parseAssignment();if(e.kind==="IdentifierExpr")return{kind:"AssignExpr",target:e.name,value:n,line:r.line,column:r.column};if(e.kind==="IndexExpr")return{kind:"IndexAssignExpr",target:e.target,index:e.index,value:n,line:r.line,column:r.column};if(e.kind==="TupleExpr"||e.kind==="ArrayExpr"){let s=[];for(let i of e.elements){if(i.kind!=="IdentifierExpr")throw new C("Destructuring assignment target must be an identifier",i.line,i.column,"PARSER",this.file);s.push(i.name)}return{kind:"TupleAssignExpr",targets:s,value:n,line:r.line,column:r.column}}throw new C("Invalid assignment target",e.line,e.column,"PARSER",this.file)}return e}parseLogicalOr(){let e=this.parseLogicalAnd();for(;this.match("OR");){let r=this.previous(),n=this.parseLogicalAnd();e={kind:"BinaryExpr",operator:"||",left:e,right:n,line:r.line,column:r.column}}return e}parseLogicalAnd(){let e=this.parseEquality();for(;this.match("AND");){let r=this.previous(),n=this.parseEquality();e={kind:"BinaryExpr",operator:"&&",left:e,right:n,line:r.line,column:r.column}}return e}parseEquality(){let e=this.parseRelational();for(;this.match("EQUAL","NOT_EQUAL");){let r=this.previous(),n=r.type==="EQUAL"?"==":"!=",s=this.parseRelational();e={kind:"BinaryExpr",operator:n,left:e,right:s,line:r.line,column:r.column}}return e}parseRelational(){let e=this.parseAdditive();for(;this.match("LESS","LESS_EQUAL","GREATER","GREATER_EQUAL");){let r=this.previous(),n=r.type==="LESS"?"<":r.type==="LESS_EQUAL"?"<=":r.type==="GREATER"?">":">=",s=this.parseAdditive();e={kind:"BinaryExpr",operator:n,left:e,right:s,line:r.line,column:r.column}}return e}parseAdditive(){let e=this.parseMultiplicative();for(;this.match("PLUS","MINUS");){let r=this.previous(),n=r.type==="PLUS"?"+":"-",s=this.parseMultiplicative();e={kind:"BinaryExpr",operator:n,left:e,right:s,line:r.line,column:r.column}}return e}parseMultiplicative(){let e=this.parseUnary();for(;this.match("STAR","SLASH","PERCENT");){let r=this.previous(),n=r.type==="STAR"?"*":r.type==="SLASH"?"/":"%",s=this.parseUnary();e={kind:"BinaryExpr",operator:n,left:e,right:s,line:r.line,column:r.column}}return e}parseUnary(){if(this.match("NOT","MINUS")){let e=this.previous(),r=e.type==="NOT"?"!":"-",n=this.parseUnary();return{kind:"UnaryExpr",operator:r,operand:n,line:e.line,column:e.column}}return this.parseCallAndIndex()}parseCallAndIndex(){let e=this.parsePrimary();for(;;)if(this.match("LPAREN")){if(e.kind!=="IdentifierExpr")throw new C("Only identifiers can be called directly as functions",e.line,e.column,"PARSER",this.file);let r=[];if(!this.check("RPAREN"))do r.push(this.parseExpression());while(this.match("COMMA"));this.consume("RPAREN","Expected ')' after function arguments"),e={kind:"CallExpr",callee:e.name,args:r,line:e.line,column:e.column}}else if(this.match("LBRACKET")){let r=this.parseExpression();this.consume("RBRACKET","Expected ']' after index expression"),e={kind:"IndexExpr",target:e,index:r,line:e.line,column:e.column}}else if(this.match("DOT")){let r=this.consume("IDENTIFIER","Expected property name after '.'");e={kind:"IndexExpr",target:e,index:{kind:"LiteralExpr",value:r.value,line:r.line,column:r.column},line:r.line,column:r.column}}else break;return e}parsePrimary(){let e=this.peek();if(this.match("NUMBER","STRING","TRUE","FALSE","NULL"))return{kind:"LiteralExpr",value:this.previous().literal,line:e.line,column:e.column};if(this.match("PARALLEL")){let r=this.previous();this.consume("LPAREN","Expected '(' after 'parallel'"),this.consume("LBRACKET","Expected '[' starting array of function calls in 'parallel([ ... ])'");let n=[];if(!this.check("RBRACKET"))do{let s=this.parseExpression();if(s.kind!=="CallExpr")throw new C("Each task in parallel([...]) must be a direct function call expression",s.line,s.column,"PARSER",this.file);n.push(s)}while(this.match("COMMA"));return this.consume("RBRACKET","Expected ']' closing array in 'parallel([ ... ])'"),this.consume("RPAREN","Expected ')' closing 'parallel(...)'"),{kind:"ParallelExpr",tasks:n,line:r.line,column:r.column}}if(this.match("IDENTIFIER"))return{kind:"IdentifierExpr",name:this.previous().value,line:e.line,column:e.column};if(this.match("LPAREN")){let r=this.previous(),n=[],s=!1;if(!this.check("RPAREN"))do if(n.push(this.parseExpression()),this.match("COMMA"))s=!0;else break;while(!this.check("RPAREN")&&!this.isAtEnd());return this.consume("RPAREN","Expected ')' after expression"),n.length===1&&!s?{kind:"GroupingExpr",expression:n[0],line:r.line,column:r.column}:{kind:"TupleExpr",elements:n,line:r.line,column:r.column}}if(this.match("LBRACKET")){let r=[];if(!this.check("RBRACKET"))do r.push(this.parseExpression());while(this.match("COMMA"));return this.consume("RBRACKET","Expected ']' after array elements"),{kind:"ArrayExpr",elements:r,line:e.line,column:e.column}}if(this.match("LBRACE")){let r=this.previous(),n=[];if(!this.check("RBRACE"))do{let s="";if(this.match("IDENTIFIER","STRING"))s=this.previous().value;else throw new C("Expected object key (identifier or string)",this.peek().line,this.peek().column,"PARSER",this.file);this.consume("COLON","Expected ':' after object key");let i=this.parseExpression();n.push({key:s,value:i})}while(this.match("COMMA"));return this.consume("RBRACE","Expected '}' after object literal"),{kind:"ObjectExpr",properties:n,line:r.line,column:r.column}}throw new C(`Unexpected token '${e.value||e.type}' in expression`,e.line,e.column,"PARSER",this.file)}match(...e){for(let r of e)if(this.check(r))return this.advance(),!0;return!1}check(e){return this.isAtEnd()?!1:this.peek().type===e}advance(){return this.isAtEnd()||this.current++,this.previous()}isAtEnd(){return this.peek().type==="EOF"}peek(){return this.tokens[this.current]}previous(){return this.tokens[this.current-1]}consume(e,r){if(this.check(e))return this.advance();let n=this.peek();throw new C(r,n.line,n.column,"PARSER",this.file)}consumeOptionalSemicolon(){this.check("SEMICOLON")&&this.advance()}},su=`# LMScript Standard Library (std.lms)
|
|
62
|
+
|
|
63
|
+
# String Utilities
|
|
64
|
+
fn is_blank(s) {
|
|
65
|
+
if (s == null) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
return len(trim(s)) == 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
# Array Utilities
|
|
72
|
+
fn chunk(arr, size) {
|
|
73
|
+
if (size <= 0) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
res = [];
|
|
77
|
+
current = [];
|
|
78
|
+
for (i = 0; i < len(arr); i = i + 1) {
|
|
79
|
+
push(current, arr[i]);
|
|
80
|
+
if (len(current) == size) {
|
|
81
|
+
push(res, current);
|
|
82
|
+
current = [];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (len(current) > 0) {
|
|
86
|
+
push(res, current);
|
|
87
|
+
}
|
|
88
|
+
return res;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
fn compact(arr) {
|
|
92
|
+
res = [];
|
|
93
|
+
for (i = 0; i < len(arr); i = i + 1) {
|
|
94
|
+
item = arr[i];
|
|
95
|
+
if (item != null) {
|
|
96
|
+
push(res, item);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return res;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
fn zip(arr1, arr2) {
|
|
103
|
+
res = [];
|
|
104
|
+
limit = len(arr1);
|
|
105
|
+
if (len(arr2) < limit) {
|
|
106
|
+
limit = len(arr2);
|
|
107
|
+
}
|
|
108
|
+
for (i = 0; i < limit; i = i + 1) {
|
|
109
|
+
push(res, [arr1[i], arr2[i]]);
|
|
110
|
+
}
|
|
111
|
+
return res;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
fn take(arr, n) {
|
|
115
|
+
res = [];
|
|
116
|
+
limit = n;
|
|
117
|
+
if (limit > len(arr)) {
|
|
118
|
+
limit = len(arr);
|
|
119
|
+
}
|
|
120
|
+
for (i = 0; i < limit; i = i + 1) {
|
|
121
|
+
push(res, arr[i]);
|
|
122
|
+
}
|
|
123
|
+
return res;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
fn drop(arr, n) {
|
|
127
|
+
res = [];
|
|
128
|
+
start = n;
|
|
129
|
+
if (start < 0) {
|
|
130
|
+
start = 0;
|
|
131
|
+
}
|
|
132
|
+
for (i = start; i < len(arr); i = i + 1) {
|
|
133
|
+
push(res, arr[i]);
|
|
134
|
+
}
|
|
135
|
+
return res;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
# Math Utilities
|
|
139
|
+
fn clamp(val, low, high) {
|
|
140
|
+
if (val < low) {
|
|
141
|
+
return low;
|
|
142
|
+
}
|
|
143
|
+
if (val > high) {
|
|
144
|
+
return high;
|
|
145
|
+
}
|
|
146
|
+
return val;
|
|
147
|
+
}
|
|
148
|
+
`,Kn=null;function iu(){if(!Kn){let e=new jt(su,"<std>").tokenize(),n=new Bt(e,"<std>").parse();for(let s of n.statements)s.kind==="FunctionDeclStmt"&&(s.isStdlib=!0);Kn=n}return{kind:"Program",statements:[...Kn.statements],line:1,column:1,file:"<std>"}}function ou(t,e={}){let r=e.file||"<main>",n=e.baseDir||(e.file?de.dirname(de.resolve(e.file)):process.cwd()),s=new Map,i=new Set;function o(y,f){if(e.moduleResolver)return e.moduleResolver(y,f).path;let T=n;f&&f!=="<main>"&&f!=="<std>"&&(T=de.dirname(f));let E=de.resolve(T,y);try{return F.realpathSync(E)}catch{return E}}function a(y,f){let T,E;if(e.moduleResolver){let S=e.moduleResolver(y,f);T=S.path,E=S.source}else{if(T=o(y,f),s.has(T))return s.get(T);if(i.has(T))return{kind:"Program",statements:[],line:1,column:1,file:T};try{E=F.readFileSync(T,"utf-8")}catch(S){throw new C(`Cannot resolve import '${y}': ${S?.message||String(S)}`,1,1,"PARSER",f)}}if(s.has(T))return s.get(T);if(i.has(T))return{kind:"Program",statements:[],line:1,column:1,file:T};i.add(T);let w=new jt(E,T).tokenize(),v=new Bt(w,T).parse();for(let S of v.statements)if(S.kind!=="FunctionDeclStmt"&&S.kind!=="ImportStmt")throw new C(`Library '${T}' cannot contain top-level executable statements; libraries must only declare functions. Found '${S.kind}'.`,S.line,S.column,"CHECKER",T);for(let S of v.statements)S.kind==="ImportStmt"&&a(S.path,T);return i.delete(T),s.set(T,v),v}let c=new jt(t,r).tokenize(),d=new Bt(c,r).parse(),p=r!=="<main>"?o(r):"<main>";s.set(p,d);for(let y of d.statements)y.kind==="ImportStmt"&&a(y.path,r);let m=[];if(!e.noStdlib){let y=iu();for(let f of y.statements)f.kind==="FunctionDeclStmt"&&m.push(f)}for(let[y,f]of s.entries())if(y!==p)for(let T of f.statements)T.kind==="FunctionDeclStmt"&&m.push(T);for(let y of d.statements)y.kind!=="ImportStmt"&&m.push(y);let h={kind:"Program",statements:m,line:d.line,column:d.column,file:r},g=Array.from(s.keys());return{program:h,loadedFiles:g}}var rt=class{variables=new Set;parent;constructor(e){this.parent=e}define(e){this.variables.add(e)}hasInCurrent(e){return this.variables.has(e)}resolve(e){return this.variables.has(e)?!0:this.parent?this.parent.resolve(e):!1}},Zn=class{diagnostics=[];hostFunctions=new Map;options;functions=new Map;currentScope=new rt;loopDepth=0;inFunction=!1;hasConcurrency=!1;constructor(e,r={}){this.options=r;for(let[n,s]of e.entries())this.hostFunctions.set(n,s),this.functions.set(n,{name:n,paramCount:typeof s.arity=="number"?s.arity:-1,params:[],isHost:!0,line:0,column:0})}check(e){if(this.diagnostics=[],this.hasConcurrency=!1,this.loopDepth=0,this.inFunction=!1,this.currentScope=new rt,this.options.globals)for(let r of this.options.globals)this.currentScope.define(r);this.functions.clear();for(let[r,n]of this.hostFunctions.entries())this.functions.set(r,{name:r,paramCount:typeof n.arity=="number"?n.arity:-1,params:[],isHost:!0,line:0,column:0});for(let r of e.statements)r.kind==="FunctionDeclStmt"&&this.collectFunction(r);for(let r of e.statements)this.checkStmt(r);return this.diagnostics}addError(e,r,n,s){this.diagnostics.push({message:e,line:r,column:n,severity:"error",file:s})}collectFunction(e){if(this.functions.has(e.name)){let n=this.functions.get(e.name);if(n.isHost){this.addError(`Cannot redefine host function '${e.name}'`,e.line,e.column,e.file);return}if(n.isStdlib){this.functions.set(e.name,{name:e.name,paramCount:e.params.length,params:e.params,isHost:!1,isStdlib:!1,file:e.file,line:e.line,column:e.column});return}let s=n.file?`${n.file}:${n.line}`:`line ${n.line}`;this.addError(`Duplicate function declaration '${e.name}' (already defined at ${s})`,e.line,e.column,e.file);return}let r=new Set;for(let n of e.params)r.has(n)&&this.addError(`Duplicate parameter name '${n}' in function '${e.name}'`,e.line,e.column,e.file),r.add(n);this.functions.set(e.name,{name:e.name,paramCount:e.params.length,params:e.params,isHost:!1,isStdlib:e.isStdlib||!1,file:e.file,line:e.line,column:e.column})}checkStmt(e){switch(e.kind){case"ImportStmt":break;case"FunctionDeclStmt":{if(this.inFunction||this.currentScope.parent){this.addError("Function declarations are only allowed at top level",e.line,e.column,e.file);break}let r=this.currentScope,n=this.inFunction;this.inFunction=!0,this.currentScope=new rt(r);for(let s of e.params)this.currentScope.define(s);for(let s of e.body.statements)this.checkStmt(s);this.inFunction=n,this.currentScope=r;break}case"VarDeclStmt":{this.currentScope.hasInCurrent(e.name)&&this.addError(`Variable '${e.name}' is already declared in this scope`,e.line,e.column,e.file),e.initializer&&this.checkExpr(e.initializer),this.currentScope.define(e.name);break}case"TupleVarDeclStmt":{this.checkExpr(e.initializer);for(let r of e.names)this.currentScope.hasInCurrent(r)&&this.addError(`Variable '${r}' is already declared in this scope`,e.line,e.column,e.file),this.currentScope.define(r);break}case"IfStmt":{this.checkExpr(e.condition),this.checkStmt(e.thenBranch),e.elseBranch&&this.checkStmt(e.elseBranch);break}case"WhileStmt":{this.checkExpr(e.condition),this.loopDepth++,this.checkStmt(e.body),this.loopDepth--;break}case"ForStmt":{let r=this.currentScope;this.currentScope=new rt(r),e.init&&this.checkStmt(e.init),e.condition&&this.checkExpr(e.condition),e.update&&this.checkExpr(e.update),this.loopDepth++,this.checkStmt(e.body),this.loopDepth--,this.currentScope=r;break}case"ReturnStmt":{this.inFunction||this.addError("'return' statement is only allowed inside a function",e.line,e.column,e.file),e.value&&this.checkExpr(e.value);break}case"BreakStmt":{this.loopDepth===0&&this.addError("'break' statement is only allowed inside a loop",e.line,e.column,e.file);break}case"ContinueStmt":{this.loopDepth===0&&this.addError("'continue' statement is only allowed inside a loop",e.line,e.column,e.file);break}case"BlockStmt":{let r=this.currentScope;this.currentScope=new rt(r);for(let n of e.statements)this.checkStmt(n);this.currentScope=r;break}case"SyncAssignStmt":{this.hasConcurrency=!0,this.currentScope.resolve(e.target)||this.addError(`Synchronized assignment target '${e.target}' must be declared beforehand`,e.line,e.column,e.file),this.checkExpr(e.value);break}case"SyncIndexAssignStmt":{this.hasConcurrency=!0,this.checkExpr(e.target),this.checkExpr(e.index),this.checkExpr(e.value);break}case"SyncCallStmt":{this.hasConcurrency=!0;let r=e.call;r.args.length===0&&this.addError(`Synchronized call '${r.callee}' requires at least one argument (the target container)`,e.line,e.column,e.file);let n=this.hostFunctions.get(r.callee);(!n||!n.isContainerMutation)&&this.addError(`Synchronized call '${r.callee}' is not an authorized container mutation operation`,e.line,e.column,e.file),this.checkExpr(e.call);break}case"ExprStmt":{this.checkExpr(e.expr);break}}}checkReadPath(e){let r=e.args[0];for(;r.kind==="GroupingExpr";)r=r.expression;if(r.kind!=="LiteralExpr"){this.diagnostics.push({message:`Cannot preflight dynamic file path in '${e.callee}'; check it at runtime with file_exists(path)`,line:e.line,column:e.column,severity:"warning",file:e.file});return}if(typeof r.value!="string"){this.addError(`File path in '${e.callee}' must be a string`,e.line,e.column,e.file);return}try{if(!F.statSync(r.value).isFile())throw new Error("path is not a regular file");F.accessSync(r.value,F.constants.R_OK)}catch(n){this.addError(`Cannot read file ${JSON.stringify(r.value)}: ${n instanceof Error?n.message:String(n)}`,e.line,e.column,e.file)}}checkExpr(e){switch(e.kind){case"LiteralExpr":break;case"IdentifierExpr":{this.currentScope.resolve(e.name)||this.addError(`Undeclared variable '${e.name}'`,e.line,e.column,e.file);break}case"AssignExpr":{this.checkExpr(e.value),this.currentScope.resolve(e.target)||this.currentScope.define(e.target);break}case"TupleAssignExpr":{this.checkExpr(e.value);for(let r of e.targets)this.currentScope.resolve(r)||this.currentScope.define(r);break}case"IndexAssignExpr":{this.checkExpr(e.target),this.checkExpr(e.index),this.checkExpr(e.value);break}case"UnaryExpr":{this.checkExpr(e.operand);break}case"BinaryExpr":{this.checkExpr(e.left),this.checkExpr(e.right);break}case"GroupingExpr":{this.checkExpr(e.expression);break}case"TupleExpr":{for(let r of e.elements)this.checkExpr(r);break}case"ArrayExpr":{for(let r of e.elements)this.checkExpr(r);break}case"ObjectExpr":{for(let r of e.properties)this.checkExpr(r.value);break}case"IndexExpr":{this.checkExpr(e.target),this.checkExpr(e.index);break}case"ParallelExpr":{this.hasConcurrency=!0;for(let r of e.tasks)this.checkExpr(r);break}case"CallExpr":{let r=this.functions.get(e.callee);r?r.paramCount>=0&&e.args.length!==r.paramCount&&this.addError(`Function '${e.callee}' expects ${r.paramCount} argument(s), but received ${e.args.length}`,e.line,e.column,e.file):this.addError(`Call to undefined function '${e.callee}'`,e.line,e.column,e.file);let n=this.hostFunctions.get(e.callee),s=n?.arity;typeof s=="object"&&(e.args.length<s.min||e.args.length>(s.max??1/0))&&this.addError(`Function '${e.callee}' expects ${s.min}..${s.max??"unlimited"} argument(s), but received ${e.args.length}`,e.line,e.column,e.file),this.options.checkFiles&&n?.readsFile&&e.args.length>0&&this.checkReadPath(e);for(let i of e.args)this.checkExpr(i);break}}}},yt=class{value;constructor(e){this.value=e}},Ue=class{},$e=class{},Ie=class t{static nextId=1;id=t.nextId++;values=new Map;parent;constructor(e){this.parent=e}resolveBinding(e){if(this.values.has(e))return{env:this,name:e};if(this.parent)return this.parent.resolveBinding(e)}define(e,r){this.values.set(e,r)}get(e){if(this.values.has(e))return this.values.get(e);if(this.parent)return this.parent.get(e)}has(e){return this.values.has(e)||(this.parent?.has(e)??!1)}set(e,r){if(this.values.has(e)){this.values.set(e,r);return}if(this.parent?.has(e)){this.parent.set(e,r);return}this.values.set(e,r)}},br=class{holderTaskId;depth=0;waiters=[];acquire(e=0,r=1e4){return this.depth===0?(this.holderTaskId=e,this.depth=1,Promise.resolve()):this.holderTaskId===e?(this.depth++,Promise.resolve()):new Promise((n,s)=>{let i;r>0&&(i=setTimeout(()=>{let a=this.waiters.findIndex(l=>l.resolve===o);a!==-1&&(this.waiters.splice(a,1),s(new Error(`Lock acquisition timed out after ${r}ms (possible deadlock)`)))},r));let o=()=>{i&&clearTimeout(i),this.holderTaskId=e,this.depth=1,n()};this.waiters.push({taskId:e,resolve:o})})}release(){this.depth<=0||(this.depth--,this.depth===0&&(this.holderTaskId=void 0,this.waiters.length>0&&this.waiters.shift().resolve()))}async withLock(e,r=0,n=1e4){await this.acquire(r,n);try{return await e()}finally{this.release()}}},es=class{bindingLocks=new Map;objectLocks=new WeakMap;getBindingLock(e){let r=this.bindingLocks.get(e);return r||(r=new br,this.bindingLocks.set(e,r)),r}getObjectLock(e){let r=this.objectLocks.get(e);return r||(r=new br,this.objectLocks.set(e,r)),r}},Nr=class{globalEnv;userFunctions=new Map;hostFunctions;stdout;stderr;lockManager=new es;isAsync;nextTaskId=1;initialGlobals;callDepth=0;asyncCallDepth=new Map;recordedErrors=[];constructor(e,r=o=>console.log(o),n=!1,s,i){this.stdout=r,this.stderr=i,this.isAsync=n,this.initialGlobals=s,this.globalEnv=new Ie,this.hostFunctions=new Map(e);let o=e.get("print");(!o||o.isDefault)&&this.hostFunctions.set("print",{fn:(...g)=>{let y=g.map(f=>typeof f=="object"?JSON.stringify(f):String(f)).join(" ");return this.stdout(y),y},description:"Prints formatted values to output log",isDefault:!0});let a=e.get("println");(!a||a.isDefault)&&this.hostFunctions.set("println",{fn:(...g)=>{let y=g.map(f=>typeof f=="object"?JSON.stringify(f):String(f)).join(" ");return this.stdout(y),y},description:"Prints line to output log",isDefault:!0});let l=e.get("error");(!l||l.isDefault)&&this.hostFunctions.set("error",{fn:(...g)=>{let y=g.map(f=>typeof f=="object"?JSON.stringify(f):String(f)).join(" ");return this.stderr?this.stderr(`error: ${y}`):typeof process<"u"&&process.stderr?process.stderr.write(`error: ${y}
|
|
149
|
+
`):console.error(`error: ${y}`),this.recordedErrors.push(y),y},description:"Prints error message to stderr and records it for execution error summary",isDefault:!0});let c=e.get("system");(!c||c.isDefault)&&this.hostFunctions.set("system",{fn:(g,y=6e4)=>{if(!Number.isSafeInteger(y)||y<0)throw new Error("system() timeout must be a non-negative safe integer in milliseconds");return this.isAsync?ho(g,y):po(g,y)},arity:{min:1,max:2},description:"Executes shell command or argv array directly with shell:false and optional timeoutMs (default 60000), returning {stdout, stderr, code, signal, timed_out, duration_ms, pid}",isDefault:!0});let u=e.get("prompt_human");(!u||u.isDefault)&&this.hostFunctions.set("prompt_human",{fn:g=>this.isAsync?Ht(g):Wt(g),arity:{min:0,max:1},description:"Prompts operator on stdin/terminal, returning input string or null if closed/non-interactive",isDefault:!0});let d=e.get("shell_quote");(!d||d.isDefault)&&this.hostFunctions.set("shell_quote",{fn:g=>fo(g),arity:1,description:"Quotes string safely for POSIX shell command execution",isDefault:!0});let p=e.get("run_script");(!p||p.isDefault)&&this.hostFunctions.set("run_script",{fn:(g,y=[])=>{let f=de.resolve(String(g));if(!F.existsSync(f))throw new Error(`run_script: file not found: '${f}'`);let T=F.readFileSync(f,"utf-8"),E=Array.isArray(y)?y.map(String):[],I=new Me;for(let[w,_]of this.hostFunctions)I.hasFunction(w)?_.isDefault||I.registerFunction(w,_.fn,_.arity,{description:_.description,allowOverwrite:!0},!1,_.isContainerMutation):I.registerFunction(w,_.fn,_.arity,_.description,_.isDefault,_.isContainerMutation);if(I.setGlobal("args",[...E]),I.setGlobal("ARGV",[f,...E]),this.isAsync)return(async()=>{let w=await I.runAsync(T,{file:f}),_=w.output.join(`
|
|
150
|
+
`)+(w.output.length>0?`
|
|
151
|
+
`:""),v=w.exitCode!==void 0?w.exitCode:w.success?0:1,S={success:w.success&&v===0,stdout:_,output:[...w.output],value:w.value,exit_code:v,code:v,errors:w.errors??[]};return S.toString=()=>_,S})();{let w=I.run(T,{file:f}),_=w.output.join(`
|
|
152
|
+
`)+(w.output.length>0?`
|
|
153
|
+
`:""),v=w.exitCode!==void 0?w.exitCode:w.success?0:1,S={success:w.success&&v===0,stdout:_,output:[...w.output],value:w.value,exit_code:v,code:v,errors:w.errors??[]};return S.toString=()=>_,S}},arity:{min:1,max:2},description:"Executes another LMScript file in-process and returns execution result with .stdout, .output, .success, .exit_code",isDefault:!0});let m=e.get("urlget");(!m||m.isDefault)&&this.hostFunctions.set("urlget",{fn:g=>this.isAsync?ru(g):mo(g),arity:1,description:"Downloads UTF-8 text from a public HTTP(S) URL",isDefault:!0});let h=e.get("sleep");(!h||h.isDefault)&&this.hostFunctions.set("sleep",{fn:g=>{if(typeof g!="number"||!Number.isFinite(g)||g<0)throw new Error("sleep() duration must be a non-negative finite number");if(g>2147483647)throw new Error("sleep() duration exceeds maximum supported timeout (2147483647 ms)");if(this.isAsync)return new Promise(f=>setTimeout(f,g));let y=Date.now()+g;for(;Date.now()<y;);return null},arity:1,description:"Sleeps for the specified milliseconds",isDefault:!0})}evaluateProgram(e){if(this.globalEnv=new Ie,this.initialGlobals)for(let[n,s]of this.initialGlobals.entries())this.globalEnv.define(n,s);this.userFunctions.clear(),this.callDepth=0;for(let n of e.statements)n.kind==="FunctionDeclStmt"&&this.userFunctions.set(n.name,n);let r;for(let n of e.statements)n.kind!=="FunctionDeclStmt"&&(r=this.execStmt(n,this.globalEnv));return r}execStmt(e,r){switch(e.kind){case"ImportStmt":return;case"BlockStmt":{let n=new Ie(r);for(let s of e.statements)this.execStmt(s,n);return}case"VarDeclStmt":{let n=null;return e.initializer&&(n=this.evalExpr(e.initializer,r)),r.define(e.name,n),n}case"TupleVarDeclStmt":{let n=this.evalExpr(e.initializer,r);if(!Array.isArray(n))throw new C(`Cannot destructure non-array value (got ${typeof n})`,e.line,e.column,"RUNTIME",e.file);for(let s=0;s<e.names.length;s++){let i=s<n.length?n[s]:null;r.define(e.names[s],i)}return n}case"IfStmt":{let n=this.evalExpr(e.condition,r);return this.isTruthy(n)?this.execStmt(e.thenBranch,r):e.elseBranch?this.execStmt(e.elseBranch,r):void 0}case"WhileStmt":{let n=0;for(;this.isTruthy(this.evalExpr(e.condition,r));){if(++n>1e6)throw new C("Execution fuel exhausted: while loop exceeded maximum iterations limit (1000000)",e.line,e.column,"RUNTIME");try{this.execStmt(e.body,r)}catch(s){if(s instanceof Ue)break;if(s instanceof $e)continue;throw s}}return}case"ForStmt":{let n=new Ie(r);e.init&&this.execStmt(e.init,n);let s=0;for(;;){if(e.condition){let i=this.evalExpr(e.condition,n);if(!this.isTruthy(i))break}if(++s>1e6)throw new C("Execution fuel exhausted: for loop exceeded maximum iterations limit (1000000)",e.line,e.column,"RUNTIME");try{this.execStmt(e.body,n)}catch(i){if(i instanceof Ue)break;if(!(i instanceof $e))throw i}e.update&&this.evalExpr(e.update,n)}return}case"ReturnStmt":{let n=e.value?this.evalExpr(e.value,r):null;throw new yt(n)}case"BreakStmt":throw new Ue;case"ContinueStmt":throw new $e;case"SyncAssignStmt":case"SyncIndexAssignStmt":case"SyncCallStmt":throw new C("Synchronized statements require asynchronous execution via engine.runAsync()",e.line,e.column,"RUNTIME",e.file);case"ExprStmt":return this.evalExpr(e.expr,r);default:return}}evalExpr(e,r){switch(e.kind){case"ParallelExpr":throw new C("'parallel(...)' requires asynchronous execution via engine.runAsync()",e.line,e.column,"RUNTIME",e.file);case"LiteralExpr":return e.value;case"IdentifierExpr":return r.get(e.name);case"AssignExpr":{let n=this.evalExpr(e.value,r);return r.set(e.target,n),n}case"TupleAssignExpr":{let n=this.evalExpr(e.value,r);if(!Array.isArray(n))throw new C(`Cannot destructure non-array value (got ${typeof n})`,e.line,e.column,"RUNTIME",e.file);for(let s=0;s<e.targets.length;s++){let i=s<n.length?n[s]:null;r.set(e.targets[s],i)}return n}case"IndexAssignExpr":{let n=this.evalExpr(e.target,r),s=this.evalExpr(e.index,r),i=this.evalExpr(e.value,r);if(Array.isArray(n)||typeof n=="object"&&n!==null)return Array.isArray(n)&&typeof s=="number"&&s<0&&(s=n.length+s),je(n,s,i),i;throw new C("Cannot index-assign to non-array / non-object",e.line,e.column,"RUNTIME",e.file)}case"GroupingExpr":return this.evalExpr(e.expression,r);case"TupleExpr":return e.elements.map(n=>this.evalExpr(n,r));case"ArrayExpr":return e.elements.map(n=>this.evalExpr(n,r));case"ObjectExpr":{let n={};for(let s of e.properties)je(n,s.key,this.evalExpr(s.value,r));return n}case"IndexExpr":{let n=this.evalExpr(e.target,r),s=this.evalExpr(e.index,r);if(n==null)throw new C("Cannot read property of null or undefined",e.line,e.column,"RUNTIME",e.file);return Array.isArray(n)&&typeof s=="number"&&s<0?n[n.length+s]:Re(n,s)}case"UnaryExpr":{let n=this.evalExpr(e.operand,r),s=e.operator;if(s==="!")return!this.isTruthy(n);if(s==="-")return-n;throw new C(`Unknown unary operator: ${s}`,e.line,e.column,"RUNTIME",e.file)}case"BinaryExpr":{if(e.operator==="&&"){let o=this.evalExpr(e.left,r);return this.isTruthy(o)?this.evalExpr(e.right,r):o}if(e.operator==="||"){let o=this.evalExpr(e.left,r);return this.isTruthy(o)?o:this.evalExpr(e.right,r)}let n=this.evalExpr(e.left,r),s=this.evalExpr(e.right,r),i=e.operator;switch(i){case"+":return typeof n=="string"||typeof s=="string"?String(n)+String(s):n+s;case"-":return n-s;case"*":return n*s;case"/":if(s===0)throw new C("Division by zero",e.line,e.column,"RUNTIME",e.file);return n/s;case"%":return n%s;case"==":return n===s;case"!=":return n!==s;case"<":return n<s;case"<=":return n<=s;case">":return n>s;case">=":return n>=s;default:throw new C(`Unknown binary operator: ${i}`,e.line,e.column,"RUNTIME",e.file)}}case"CallExpr":{let n=e.args.map(s=>this.evalExpr(s,r));if(this.userFunctions.has(e.callee)){let s=this.userFunctions.get(e.callee);if(this.callDepth++,this.callDepth>Ir)throw this.callDepth--,new C(`Execution fuel exhausted: maximum function call depth exceeded (${Ir})`,e.line,e.column,"RUNTIME",e.file);let i=new Ie(this.globalEnv);for(let o=0;o<s.params.length;o++)i.define(s.params[o],n[o]);try{for(let o of s.body.statements)this.execStmt(o,i)}catch(o){if(o instanceof yt)return o.value;throw o}finally{this.callDepth--}return null}if(this.hostFunctions.has(e.callee)){let s=this.hostFunctions.get(e.callee);try{return s.fn(...n)}catch(i){throw i instanceof pe||i?.name==="LMScriptExit"||i?.isControlFlow?i:new C(`Error in host function '${e.callee}': ${i?.message||String(i)}`,e.line,e.column,"RUNTIME",e.file)}}throw new C(`Undefined function '${e.callee}'`,e.line,e.column,"RUNTIME",e.file)}}}isTruthy(e){return!(e==null||e===!1||e===0||e==="")}async evaluateProgramAsync(e){if(this.globalEnv=new Ie,this.initialGlobals)for(let[s,i]of this.initialGlobals.entries())this.globalEnv.define(s,i);this.userFunctions.clear(),this.asyncCallDepth.clear();for(let s of e.statements)s.kind==="FunctionDeclStmt"&&this.userFunctions.set(s.name,s);let r=this.nextTaskId++,n;for(let s of e.statements)s.kind!=="FunctionDeclStmt"&&(n=await this.execStmtAsync(s,this.globalEnv,r));return n}async execStmtAsync(e,r,n){switch(e.kind){case"ImportStmt":return;case"BlockStmt":{let s=new Ie(r);for(let i of e.statements)await this.execStmtAsync(i,s,n);return}case"VarDeclStmt":{let s=null;return e.initializer&&(s=await this.evalExprAsync(e.initializer,r,n)),r.define(e.name,s),s}case"TupleVarDeclStmt":{let s=await this.evalExprAsync(e.initializer,r,n);if(!Array.isArray(s))throw new C(`Cannot destructure non-array value (got ${typeof s})`,e.line,e.column,"RUNTIME",e.file);for(let i=0;i<e.names.length;i++){let o=i<s.length?s[i]:null;r.define(e.names[i],o)}return s}case"IfStmt":{let s=await this.evalExprAsync(e.condition,r,n);return this.isTruthy(s)?await this.execStmtAsync(e.thenBranch,r,n):e.elseBranch?await this.execStmtAsync(e.elseBranch,r,n):void 0}case"WhileStmt":{let s=0;for(;this.isTruthy(await this.evalExprAsync(e.condition,r,n));){if(++s>1e6)throw new C("Execution fuel exhausted: while loop exceeded maximum iterations limit (1000000)",e.line,e.column,"RUNTIME");try{await this.execStmtAsync(e.body,r,n)}catch(i){if(i instanceof Ue)break;if(i instanceof $e)continue;throw i}}return}case"ForStmt":{let s=new Ie(r);e.init&&await this.execStmtAsync(e.init,s,n);let i=0;for(;;){if(e.condition){let o=await this.evalExprAsync(e.condition,s,n);if(!this.isTruthy(o))break}if(++i>1e6)throw new C("Execution fuel exhausted: for loop exceeded maximum iterations limit (1000000)",e.line,e.column,"RUNTIME");try{await this.execStmtAsync(e.body,s,n)}catch(o){if(o instanceof Ue)break;if(!(o instanceof $e))throw o}e.update&&await this.evalExprAsync(e.update,s,n)}return}case"ReturnStmt":{let s=e.value?await this.evalExprAsync(e.value,r,n):null;throw new yt(s)}case"BreakStmt":throw new Ue;case"ContinueStmt":throw new $e;case"SyncAssignStmt":{let s=r.resolveBinding(e.target);if(!s)throw new C(`Synchronized assignment target '${e.target}' is not defined`,e.line,e.column,"RUNTIME",e.file);let i=`bind:${s.env.id}:${s.name}`;await this.lockManager.getBindingLock(i).withLock(async()=>{let a=await this.evalExprAsync(e.value,r,n);s.env.set(s.name,a)},n);return}case"SyncIndexAssignStmt":{let s=await this.evalExprAsync(e.target,r,n);if(s==null||typeof s!="object"&&typeof s!="function")throw new C("Cannot perform synchronized assignment on non-object",e.line,e.column,"RUNTIME",e.file);await this.lockManager.getObjectLock(s).withLock(async()=>{let o=await this.evalExprAsync(e.index,r,n),a=await this.evalExprAsync(e.value,r,n);Array.isArray(s)&&typeof o=="number"&&o<0&&(o=s.length+o),je(s,o,a)},n);return}case"SyncCallStmt":{let s=e.call;if(s.args.length===0)throw new C("Synchronized call requires at least one argument (the target container)",e.line,e.column,"RUNTIME",e.file);let i=this.hostFunctions.get(s.callee);if(!i||!i.isContainerMutation)throw new C(`Function '${s.callee}' is not an authorized container mutation operation`,e.line,e.column,"RUNTIME",e.file);let o=await this.evalExprAsync(s.args[0],r,n);if(o==null||typeof o!="object"&&typeof o!="function")throw new C("Target of synchronized call must be an array or map",e.line,e.column,"RUNTIME",e.file);await this.lockManager.getObjectLock(o).withLock(async()=>{let l=[];for(let c=1;c<s.args.length;c++)l.push(await this.evalExprAsync(s.args[c],r,n));await this.invokeCallAsync(s.callee,[o,...l],r,e.line,e.column,n,e.file)},n);return}case"ExprStmt":return await this.evalExprAsync(e.expr,r,n);default:return}}async evalExprAsync(e,r,n){switch(e.kind){case"LiteralExpr":return e.value;case"IdentifierExpr":return r.get(e.name);case"AssignExpr":{let s=await this.evalExprAsync(e.value,r,n);return r.set(e.target,s),s}case"TupleAssignExpr":{let s=await this.evalExprAsync(e.value,r,n);if(!Array.isArray(s))throw new C(`Cannot destructure non-array value (got ${typeof s})`,e.line,e.column,"RUNTIME",e.file);for(let i=0;i<e.targets.length;i++){let o=i<s.length?s[i]:null;r.set(e.targets[i],o)}return s}case"IndexAssignExpr":{let s=await this.evalExprAsync(e.target,r,n),i=await this.evalExprAsync(e.index,r,n),o=await this.evalExprAsync(e.value,r,n);if(Array.isArray(s)||typeof s=="object"&&s!==null)return Array.isArray(s)&&typeof i=="number"&&i<0&&(i=s.length+i),je(s,i,o),o;throw new C("Cannot index-assign to non-array / non-object",e.line,e.column,"RUNTIME",e.file)}case"GroupingExpr":return await this.evalExprAsync(e.expression,r,n);case"TupleExpr":{let s=[];for(let i of e.elements)s.push(await this.evalExprAsync(i,r,n));return s}case"ArrayExpr":{let s=[];for(let i of e.elements)s.push(await this.evalExprAsync(i,r,n));return s}case"ObjectExpr":{let s={};for(let i of e.properties)je(s,i.key,await this.evalExprAsync(i.value,r,n));return s}case"ParallelExpr":{if(e.tasks.length===0)return[];let s=this.asyncCallDepth.get(n)??0,i=e.tasks.map(async c=>{let u=this.nextTaskId++;return this.asyncCallDepth.set(u,s),await this.evalExprAsync(c,r,u)}),o=await Promise.allSettled(i),a=[],l;for(let c of o)c.status==="fulfilled"?a.push(c.value):l||(l=c.reason);if(l)throw l;return a}case"IndexExpr":{let s=await this.evalExprAsync(e.target,r,n),i=await this.evalExprAsync(e.index,r,n);if(s==null)throw new C("Cannot read property of null or undefined",e.line,e.column,"RUNTIME",e.file);return Array.isArray(s)&&typeof i=="number"&&i<0?s[s.length+i]:Re(s,i)}case"UnaryExpr":{let s=await this.evalExprAsync(e.operand,r,n),i=e.operator;if(i==="!")return!this.isTruthy(s);if(i==="-")return-s;throw new C(`Unknown unary operator: ${i}`,e.line,e.column,"RUNTIME",e.file)}case"BinaryExpr":{if(e.operator==="&&"){let a=await this.evalExprAsync(e.left,r,n);return this.isTruthy(a)?await this.evalExprAsync(e.right,r,n):a}if(e.operator==="||"){let a=await this.evalExprAsync(e.left,r,n);return this.isTruthy(a)?a:await this.evalExprAsync(e.right,r,n)}let s=await this.evalExprAsync(e.left,r,n),i=await this.evalExprAsync(e.right,r,n),o=e.operator;switch(o){case"+":return typeof s=="string"||typeof i=="string"?String(s)+String(i):s+i;case"-":return s-i;case"*":return s*i;case"/":if(i===0)throw new C("Division by zero",e.line,e.column,"RUNTIME",e.file);return s/i;case"%":return s%i;case"==":return s===i;case"!=":return s!==i;case"<":return s<i;case"<=":return s<=i;case">":return s>i;case">=":return s>=i;default:throw new C(`Unknown binary operator: ${o}`,e.line,e.column,"RUNTIME",e.file)}}case"CallExpr":{let s=[];for(let i of e.args)s.push(await this.evalExprAsync(i,r,n));return await this.invokeCallAsync(e.callee,s,r,e.line,e.column,n,e.file)}}}async invokeCallAsync(e,r,n,s,i,o,a){if(this.userFunctions.has(e)){let l=this.userFunctions.get(e),c=(this.asyncCallDepth.get(o)??0)+1;if(this.asyncCallDepth.set(o,c),c>Ir)throw this.asyncCallDepth.set(o,c-1),new C(`Execution fuel exhausted: maximum function call depth exceeded (${Ir})`,s,i,"RUNTIME",a);let u=new Ie(this.globalEnv);for(let d=0;d<l.params.length;d++)u.define(l.params[d],r[d]);try{for(let d of l.body.statements)await this.execStmtAsync(d,u,o)}catch(d){if(d instanceof yt)return d.value;throw d}finally{this.asyncCallDepth.set(o,c-1)}return null}if(this.hostFunctions.has(e)){let l=this.hostFunctions.get(e);try{let c=l.fn(...r);return c instanceof Promise?await c:c}catch(c){throw c instanceof pe||c?.name==="LMScriptExit"||c?.isControlFlow?c:new C(`Error in host function '${e}': ${c?.message||String(c)}`,s,i,"RUNTIME",a)}}throw new C(`Undefined function '${e}'`,s,i,"RUNTIME",a)}getRecordedErrors(){return[...this.recordedErrors]}},au=[{name:"if",category:"Language Constructs",signature:"if (condition) { ... } else { ... }",description:"Conditional branching flow control.",example:'if (x > 0) { print("yes"); } else { print("no"); }'},{name:"while",category:"Language Constructs",signature:"while (condition) { ... }",description:"Looping flow control that repeats while condition is true.",example:"while (i < 10) { i = i + 1; }"},{name:"for",category:"Language Constructs",signature:"for (init; condition; update) { ... }",description:"C-style for loop for iteration.",example:"for (let i = 0; i < len(arr); i = i + 1) { print(arr[i]); }"},{name:"fn",category:"Language Constructs",signature:"fn name(arg1, arg2) { ... }",description:"Defines a custom function.",example:"fn add(a, b) { return a + b; }"},{name:"import",category:"Language Constructs",signature:'import "path"',description:"Imports and executes another script file.",example:'import "utils.lm"'},{name:"parallel",category:"Language Constructs",signature:"parallel([ call1(), call2() ])",description:"Executes an array of function calls concurrently, returning an array of results.",example:'(a,b) = parallel([ system("echo 1"), system("echo 2") ]);'},{name:"sync",category:"Language Constructs",signature:"sync expr",description:"Forces sequential execution of an assignment or container mutation inside a parallel block.",example:'sync push(results, "done");'},{name:"break",category:"Language Constructs",signature:"break",description:"Exits the innermost loop.",example:"while (true) { break; }"},{name:"continue",category:"Language Constructs",signature:"continue",description:"Skips to the next iteration of the innermost loop.",example:"for (let i = 0; i < 2; i = i + 1) { if (i == 0) { continue; } }"},{name:"return",category:"Language Constructs",signature:"return expr",description:"Returns a value from a function or script.",example:"return 42;"}],lu=[{name:"read_file",category:"File I/O",signature:"read_file(path: string): string",description:"Reads the entire contents of a file as a UTF-8 string.",example:'content = read_file("config.json");'},{name:"read",category:"File I/O",signature:"read(path: string): string",description:"Reads the entire contents of a file as a UTF-8 string (alias for read_file).",example:'content = read("data.txt");'},{name:"read_lines",category:"File I/O",signature:"read_lines(path: string): array",description:"Reads a file and returns an array of string lines.",example:'lines = read_lines("items.txt");'},{name:"write_lines",category:"File I/O",signature:"write_lines(path: string, lines: array): boolean",description:"Writes an array of lines to a file with trailing newline, round-tripping with read_lines.",example:'write_lines("out.txt", ["a", "b"]);'},{name:"glob",category:"File I/O",signature:"glob(pattern: string): array",description:"Finds files matching a glob pattern and returns an array of matching paths.",example:'files = glob("~/repos/*/*.lmctl");'},{name:"list_dir",category:"File I/O",signature:"list_dir(path: string): array",description:"Lists filenames in a directory.",example:'entries = list_dir(".");'},{name:"write_file",category:"File I/O",signature:"write_file(path: string, content: any): boolean",description:"Writes content to a file, creating or overwriting it.",example:'write_file("out.txt", "hello");'},{name:"write",category:"File I/O",signature:"write(path: string, content: any): boolean",description:"Writes content to a file (alias for write_file).",example:'write("out.txt", "data");'},{name:"append_file",category:"File I/O",signature:"append_file(path: string, content: any): boolean",description:"Appends string content to the end of a file.",example:'append_file("log.txt", "step completed\\n");'},{name:"read_json",category:"File I/O",signature:"read_json(path: string): any",description:"Reads a JSON file from disk and parses it into an object or array.",example:'data = read_json("package.json");'},{name:"write_json",category:"File I/O",signature:"write_json(path: string, data: any, [indent: number = 2]): boolean",description:"Serializes data as formatted JSON and writes it to a file.",example:'write_json("out.json", { "status": "ok" }, 2);'},{name:"read_csv",category:"File I/O",signature:'read_csv(path: string, [hasHeader: boolean = true], [delimiter: string = ","]): array',description:"Reads an RFC 4180 CSV file and parses it into an array of objects or rows.",example:'rows = read_csv("data.csv");'},{name:"write_csv",category:"File I/O",signature:'write_csv(path: string, data: array, [delimiter: string = ","]): boolean',description:"Serializes an array of objects or rows to CSV and writes to a file.",example:'write_csv("out.csv", [{ name: "Alice", age: 30 }]);'},{name:"csv_parse",category:"File I/O",signature:'csv_parse(text: string, [hasHeader: boolean = true], [delimiter: string = ","]): array',description:"Parses inline CSV text into an array of objects or rows.",example:'records = csv_parse("name,score\\nBob,95");'},{name:"csv_stringify",category:"File I/O",signature:'csv_stringify(data: array, [delimiter: string = ","]): string',description:"Serializes an array of objects or rows into RFC 4180 CSV text.",example:"csv_text = csv_stringify(records);"},{name:"file_exists",category:"File I/O",signature:"file_exists(path: string): boolean",description:"Checks if a file exists at the given path.",example:'if (file_exists("log.txt")) { print("found"); }'},{name:"temp_file",category:"File I/O",signature:"temp_file(): string",description:"Creates an empty temporary file and returns its absolute path.",example:"tmp = temp_file();"},{name:"split",category:"Strings",signature:'split(s: string, [delimiter: string = ""]): array',description:"Splits a string by delimiter into an array of substrings.",example:'parts = split("a,b,c", ",");'},{name:"lines",category:"Strings",signature:"lines(s: string): array",description:"Splits a string into an array of lines.",example:'arr = lines("line1\\nline2");'},{name:"last_line_as_status",category:"Strings",signature:"last_line_as_status(s: string): string|null",description:"Returns the last non-blank line of a string if it is a valid state word (DONE, NOTHING_TO_DO, BLOCKED, OTHER), otherwise returns null.",example:"status = last_line_as_status(reply);"},{name:"words",category:"Strings",signature:"words(s: string): array",description:"Splits a string into non-whitespace words.",example:'w = words("hello world from lmscript");'},{name:"join",category:"Strings",signature:'join(arr: array, [separator: string = ", "]): string',description:"Joins array elements into a string separated by delimiter.",example:'s = join(["apple", "banana"], ", ");'},{name:"trim",category:"Strings",signature:"trim(s: string): string",description:"Trims whitespace from both ends of a string.",example:'clean = trim(" hello ");'},{name:"trim_start",category:"Strings",signature:"trim_start(s: string): string",description:"Trims whitespace from the beginning of a string.",example:'s = trim_start(" hello");'},{name:"trim_end",category:"Strings",signature:"trim_end(s: string): string",description:"Trims whitespace from the end of a string.",example:'s = trim_end("hello ");'},{name:"to_upper",category:"Strings",signature:"to_upper(s: string): string",description:"Converts all characters in string to uppercase.",example:'u = to_upper("hello");'},{name:"upper",category:"Strings",signature:"upper(s: string): string",description:"Converts all characters in string to uppercase (alias for to_upper).",example:'u = upper("hello");'},{name:"to_lower",category:"Strings",signature:"to_lower(s: string): string",description:"Converts all characters in string to lowercase.",example:'l = to_lower("HELLO");'},{name:"lower",category:"Strings",signature:"lower(s: string): string",description:"Converts all characters in string to lowercase (alias for to_lower).",example:'l = lower("HELLO");'},{name:"capitalize",category:"Strings",signature:"capitalize(s: string): string",description:"Capitalizes the first character of a string.",example:'c = capitalize("hello");'},{name:"title_case",category:"Strings",signature:"title_case(s: string): string",description:"Converts words in a string to Title Case.",example:'t = title_case("hello world");'},{name:"contains",category:"Strings",signature:"contains(haystack: string|array, needle: any): boolean",description:"Checks if a string or array contains an item or substring.",example:'if (contains("hello", "ell")) { print("matched"); }'},{name:"includes",category:"Strings",signature:"includes(haystack: string|array, needle: any): boolean",description:"Alias for contains.",example:'if (includes([1, 2, 3], 2)) { print("found"); }'},{name:"starts_with",category:"Strings",signature:"starts_with(s: string, prefix: string): boolean",description:"Checks if a string starts with the given prefix.",example:'if (starts_with("prefix_name", "prefix_")) { ... }'},{name:"ends_with",category:"Strings",signature:"ends_with(s: string, suffix: string): boolean",description:"Checks if a string ends with the given suffix.",example:'if (ends_with("file.txt", ".txt")) { ... }'},{name:"index_of",category:"Strings",signature:"index_of(haystack: string|array, needle: any, [fromIndex: number]): number",description:"Finds the first index of a substring or item, or -1 if not found.",example:'idx = index_of("banana", "a");'},{name:"last_index_of",category:"Strings",signature:"last_index_of(haystack: string|array, needle: any): number",description:"Finds the last index of a substring or item, or -1 if not found.",example:'idx = last_index_of("banana", "a");'},{name:"count_matches",category:"Strings",signature:"count_matches(s: string, sub: string): number",description:"Counts non-overlapping occurrences of a substring.",example:'n = count_matches("banana", "a");'},{name:"substr",category:"Strings",signature:"substr(s: string, start: number, [length: number]): string",description:"Returns a substring starting from start index of specified length.",example:'sub = substr("hello", 1, 3);'},{name:"substring",category:"Strings",signature:"substring(s: string, start: number, [end: number]): string",description:"Returns a substring between start and end indices.",example:'sub = substring("hello", 1, 4);'},{name:"slice",category:"Strings",signature:"slice(target: string|array, start: number, [end: number]): string|array",description:"Extracts a section of a string or array.",example:"part = slice([1, 2, 3, 4], 1, 3);"},{name:"char_at",category:"Strings",signature:"char_at(s: string, index: number): string",description:"Returns the character at the specified index.",example:'c = char_at("hello", 0);'},{name:"char_code",category:"Strings",signature:"char_code(s: string, [index: number = 0]): number",description:"Returns the Unicode code point at index.",example:'code = char_code("A");'},{name:"from_char_code",category:"Strings",signature:"from_char_code(...codes: number): string",description:"Returns string from character codes.",example:"s = from_char_code(65, 66, 67);"},{name:"replace",category:"Strings",signature:"replace(s: string, search: string, replacement: string): string",description:"Replaces the first occurrence of search substring.",example:'s = replace("hello world", "world", "lmscript");'},{name:"replace_all",category:"Strings",signature:"replace_all(s: string, search: string, replacement: string): string",description:"Replaces all occurrences of search substring.",example:'s = replace_all("foo bar foo", "foo", "baz");'},{name:"repeat",category:"Strings",signature:"repeat(s: string, count: number): string",description:"Repeats a string count times.",example:'stars = repeat("*", 10);'},{name:"pad_start",category:"Strings",signature:'pad_start(s: string, targetLength: number, [padChar: string = " "]): string',description:"Left-pads string to target length.",example:'num_str = pad_start("5", 3, "0");'},{name:"pad_end",category:"Strings",signature:'pad_end(s: string, targetLength: number, [padChar: string = " "]): string',description:"Right-pads string to target length.",example:'row = pad_end("title", 20, ".");'},{name:"reverse_str",category:"Strings",signature:"reverse_str(s: string): string",description:"Reverses characters in a string.",example:'rev = reverse_str("abc");'},{name:"is_empty",category:"Strings",signature:"is_empty(val: any): boolean",description:"Checks if a string, array, or object is empty or null.",example:'if (is_empty(arr)) { print("empty"); }'},{name:"is_digit",category:"Strings",signature:"is_digit(s: string): boolean",description:"Checks if a string contains only digits.",example:'if (is_digit("123")) { print("all digits"); }'},{name:"is_alpha",category:"Strings",signature:"is_alpha(s: string): boolean",description:"Checks if a string contains only alphabetic characters.",example:'if (is_alpha("abc")) { ... }'},{name:"is_alnum",category:"Strings",signature:"is_alnum(s: string): boolean",description:"Checks if a string contains only letters and digits.",example:'if (is_alnum("item42")) { ... }'},{name:"format",category:"Strings",signature:"format(template: string, ...args: any): string",description:"Formats a template string replacing {{}} brace escapes, positional {0}, auto {}, and {key} map placeholders.",example:'msg = format("Hello, {}! You have {} tasks.", "User", 3);'},{name:"shell_quote",category:"Strings",signature:"shell_quote(val: any): string",description:"Quotes string safely for POSIX shell command execution.",example:'escaped = shell_quote("arg with spaces");'},{name:"len",category:"Lists & Arrays",signature:"len(item: any): number",description:"Returns the length of a string, array, or number of object keys.",example:"n = len([10, 20, 30]);"},{name:"push",category:"Lists & Arrays",signature:"push(arr: array, item: any): array",description:"Appends an element to the end of an array and returns the array.",example:'push(items, "new_item");'},{name:"pop",category:"Lists & Arrays",signature:"pop(arr: array): any",description:"Removes and returns the last element of an array.",example:"last = pop(items);"},{name:"shift",category:"Lists & Arrays",signature:"shift(arr: array): any",description:"Removes and returns the first element of an array.",example:"first = shift(items);"},{name:"unshift",category:"Lists & Arrays",signature:"unshift(arr: array, item: any): array",description:"Prepends an element to the beginning of an array.",example:'unshift(items, "header");'},{name:"insert",category:"Lists & Arrays",signature:"insert(arr: array, index: number, item: any): array",description:"Inserts an element at the specified index in an array.",example:'insert(items, 1, "inserted");'},{name:"remove_at",category:"Lists & Arrays",signature:"remove_at(arr: array, index: number): any",description:"Removes and returns the element at the specified index.",example:"removed = remove_at(items, 0);"},{name:"concat",category:"Lists & Arrays",signature:"concat(a: array, b: array): array",description:"Concatenates two arrays into a new array.",example:"all = concat(arr1, arr2);"},{name:"reverse",category:"Lists & Arrays",signature:"reverse(arr: array): array",description:"Reverses elements of an array in place.",example:"reverse(items);"},{name:"sort",category:"Lists & Arrays",signature:"sort(arr: array, [key: string]): array",description:"Sorts array elements numerically, alphabetically, or by object key.",example:'sorted = sort(users, "age");'},{name:"unique",category:"Lists & Arrays",signature:"unique(arr: array): array",description:"Returns a new array with duplicate elements removed.",example:"deduped = unique([1, 2, 2, 3]);"},{name:"flatten",category:"Lists & Arrays",signature:"flatten(arr: array): array",description:"Flattens a nested array by one level.",example:"flat = flatten([[1, 2], [3, 4]]);"},{name:"first",category:"Lists & Arrays",signature:"first(arr: array): any",description:"Returns the first element of an array, or null if empty.",example:"top = first(items);"},{name:"last",category:"Lists & Arrays",signature:"last(arr: array): any",description:"Returns the last element of an array, or null if empty.",example:"tail = last(items);"},{name:"sum",category:"Lists & Arrays",signature:"sum(arr: array): number",description:"Computes the arithmetic sum of numeric elements in an array.",example:"total = sum([1, 2, 3, 4]);"},{name:"avg",category:"Lists & Arrays",signature:"avg(arr: array): number",description:"Computes the arithmetic mean of numeric elements in an array.",example:"mean = avg([10, 20, 30]);"},{name:"range",category:"Lists & Arrays",signature:"range(start: number, [end: number], [step: number = 1]): array",description:"Generates an array of numbers from start to end by step.",example:"nums = range(0, 5);"},{name:"keys",category:"Maps & Key-Value",signature:"keys(obj: object): array",description:"Returns an array of own property keys of an object.",example:"k = keys({ a: 1, b: 2 });"},{name:"values",category:"Maps & Key-Value",signature:"values(obj: object): array",description:"Returns an array of own property values of an object.",example:"v = values({ a: 1, b: 2 });"},{name:"entries",category:"Maps & Key-Value",signature:"entries(obj: object): array",description:"Returns an array of [key, value] pairs for an object.",example:"pairs = entries({ a: 1, b: 2 });"},{name:"from_entries",category:"Maps & Key-Value",signature:"from_entries(pairs: array): object",description:"Constructs an object from an array of [key, value] pairs.",example:'obj = from_entries([["name", "Bob"], ["age", 25]]);'},{name:"has_key",category:"Maps & Key-Value",signature:"has_key(obj: object, key: string): boolean",description:"Checks if an object has the specified own property key.",example:'if (has_key(config, "port")) { ... }'},{name:"has",category:"Maps & Key-Value",signature:"has(obj: object, key: string): boolean",description:"Checks if an object has the specified key (alias for has_key).",example:'if (has(user, "email")) { ... }'},{name:"get",category:"Maps & Key-Value",signature:"get(obj: any, path: string|array, [defaultVal: any]): any",description:"Retrieves a nested property safely using a dot or array path.",example:'val = get(config, "database.host", "localhost");'},{name:"set",category:"Maps & Key-Value",signature:"set(obj: object, path: string|array, value: any): object",description:"Sets a nested property on an object using a dot or array path.",example:'set(config, "server.port", 8080);'},{name:"delete_key",category:"Maps & Key-Value",signature:"delete_key(obj: object, key: string): object",description:"Deletes a key from an object.",example:'delete_key(data, "temp");'},{name:"merge",category:"Maps & Key-Value",signature:"merge(a: object, b: object): object",description:"Shallow merges two objects into a new object.",example:"combined = merge(defaults, overrides);"},{name:"clone",category:"Maps & Key-Value",signature:"clone(val: any): any",description:"Deep clones an object or array via JSON serialization.",example:"copy = clone(original);"},{name:"json",category:"JSON & Data",signature:"json(str: string): any",description:"Parses a JSON string into an object or array.",example:'data = json("{\\"key\\": \\"value\\"}");'},{name:"json_parse",category:"JSON & Data",signature:"json_parse(str: string): any",description:"Alias for json.",example:"data = json_parse(text);"},{name:"json_parse_safe",category:"JSON & Data",signature:"json_parse_safe(str: string, [fallback: any = null]): any",description:"Safely parses JSON with markdown fence and preamble tolerance, returning fallback (default null) without throwing.",example:'data = json_parse_safe(llm_output); if (data == null) { print("parse failed"); }'},{name:"json_stringify",category:"JSON & Data",signature:"json_stringify(val: any, [indent: number = 2]): string",description:"Serializes a value to formatted JSON string.",example:"text = json_stringify(obj, 2);"},{name:"pluck",category:"JSON & Data",signature:"pluck(arr: array, key: string): array",description:"Extracts the specified key from each object in an array.",example:'names = pluck(users, "name");'},{name:"filter_by",category:"JSON & Data",signature:"filter_by(arr: array, key: string, value: any): array",description:"Filters an array of objects where item[key] == value.",example:'active = filter_by(users, "active", true);'},{name:"find_by",category:"JSON & Data",signature:"find_by(arr: array, key: string, value: any): any",description:"Finds the first object in an array where item[key] == value.",example:'user = find_by(users, "id", 42);'},{name:"num",category:"Math",signature:"num(val: any): number",description:"Converts a value to a numeric type.",example:'n = num("42.5");'},{name:"round",category:"Math",signature:"round(n: number): number",description:"Rounds a number to the nearest integer.",example:"r = round(3.7);"},{name:"floor",category:"Math",signature:"floor(n: number): number",description:"Returns the largest integer less than or equal to a number.",example:"f = floor(3.9);"},{name:"ceil",category:"Math",signature:"ceil(n: number): number",description:"Returns the smallest integer greater than or equal to a number.",example:"c = ceil(3.1);"},{name:"min",category:"Math",signature:"min(...nums: number|array): number",description:"Returns the minimum value from numbers or a number array.",example:"m = min(10, 5, 20);"},{name:"max",category:"Math",signature:"max(...nums: number|array): number",description:"Returns the maximum value from numbers or a number array.",example:"m = max([10, 5, 20]);"},{name:"abs",category:"Math",signature:"abs(n: number): number",description:"Returns the absolute value of a number.",example:"a = abs(-42);"},{name:"sqrt",category:"Math",signature:"sqrt(n: number): number",description:"Returns the square root of a number.",example:"s = sqrt(16);"},{name:"pow",category:"Math",signature:"pow(base: number, exp: number): number",description:"Calculates base raised to exponent.",example:"p = pow(2, 8);"},{name:"random",category:"Math",signature:"random(): number",description:"Returns a pseudo-random floating point number in [0, 1).",example:"r = random();"},{name:"system",category:"System & Process",signature:"system(command: string|array, [timeoutMs: number = 60000]): SystemResult",description:"Executes a shell command string or argv array directly with shell:false, returning a structured process execution record.",parameters:[{name:"command",type:"string|array",description:"Shell command string or argv array to execute"},{name:"timeoutMs",type:"number",description:"(optional) Execution timeout in milliseconds (default: 60000)"}],returns:{type:"SystemResult",description:"{ stdout: string, stderr: string, code: number|null, signal: string|null, timed_out: bool, duration_ms: number, pid: number|null }"},example:'res = system(["git", "log", "-n", "1"]); if (res.code == 0) { print(res.stdout); }'},{name:"prompt_human",category:"System & Process",signature:"prompt_human([question: string]): string|null",description:"Pauses execution to prompt an operator on terminal stdin, returning the entered input line or null if stdin is closed/non-interactive.",example:'guidance = prompt_human("Enter instructions (or Enter to halt): "); if (guidance != null) { process(guidance); }'},{name:"error",category:"System & Process",signature:"error(...args: any): string",description:"Formats and logs an error to stderr and records it for the execution error summary.",example:'error("Operation failed:", reason);'},{name:"exit",category:"System & Process",signature:"exit([code: number = 0]): never",description:"Terminates script execution immediately with exit code.",example:"exit(0);"},{name:"print",category:"System & Process",signature:"print(...args: any): string",description:"Formats and logs values to output.",example:'print("Result:", val);'},{name:"println",category:"System & Process",signature:"println(...args: any): string",description:"Formats and logs values followed by a newline.",example:'println("Done.");'},{name:"sleep",category:"System & Process",signature:"sleep(ms: number): void",description:"Pauses execution for specified milliseconds.",example:"sleep(1000);"},{name:"clock",category:"System & Process",signature:"clock(): number",description:"Returns current epoch timestamp in milliseconds.",example:"start = clock();"},{name:"str",category:"System & Process",signature:"str(val: any): string",description:"Converts a value to its string representation.",example:"s = str(123);"},{name:"type",category:"System & Process",signature:"type(val: any): string",description:"Returns the runtime type of a value ('string', 'number', 'boolean', 'array', 'object', 'null').",example:"t = type(data);"},{name:"assert",category:"System & Process",signature:"assert(condition: any, [message: string]): boolean",description:"Throws an error if condition is falsy.",example:'assert(len(items) > 0, "Items list must not be empty");'},{name:"urlget",category:"System & Process",signature:"urlget(url: string): string",description:"Performs HTTP(S) GET request and returns response body string.",example:'html = urlget("https://example.com");'}],cu=[{name:"is_blank",category:"Strings",signature:"is_blank(s: any): boolean",description:"Returns true if string is null, empty, or whitespace only.",example:'if (is_blank(user_input)) { println("input required"); }'},{name:"chunk",category:"Lists & Arrays",signature:"chunk(arr: array, size: number): array",description:"Splits an array into chunks of specified size.",example:"batches = chunk(items, 10);"},{name:"compact",category:"Lists & Arrays",signature:"compact(arr: array): array",description:"Returns a new array with all null elements removed.",example:"valid = compact([1, null, 2, null, 3]);"},{name:"zip",category:"Lists & Arrays",signature:"zip(arr1: array, arr2: array): array",description:"Combines two arrays into an array of pairs [[a1, b1], [a2, b2], ...].",example:'pairs = zip(["a", "b"], [1, 2]);'},{name:"take",category:"Lists & Arrays",signature:"take(arr: array, n: number): array",description:"Returns the first n elements of an array.",example:"first_three = take(items, 3);"},{name:"drop",category:"Lists & Arrays",signature:"drop(arr: array, n: number): array",description:"Returns a new array with the first n elements omitted.",example:"rest = drop(items, 3);"},{name:"clamp",category:"Math",signature:"clamp(val: number, low: number, high: number): number",description:"Restricts a numeric value to lie within [low, high] bounds.",example:"bounded = clamp(score, 0, 100);"}],Me=class t{hostFunctions=new Map;functionDocs=new Map;registeredModules=new Map;functionOriginModule=new Map;currentRegisteringModule="core";outputLogs=[];isAsyncMode=!1;constructor(){this.registeredModules.set("core",{name:"core",description:"LMScript core language built-ins and standard library"}),this.registerPredefinedFunctions(),this.registerDefaultDocs()}registerDefaultDocs(){for(let e of au)this.functionDocs.set(e.name,{...e,module:e.module??"core"});for(let e of lu)this.functionDocs.set(e.name,{...e,module:e.module??"core"});for(let e of cu)this.functionDocs.set(e.name,{...e,module:e.module??"core"})}registerFunctionDoc(e){return this.functionDocs.set(e.name,{...e,module:e.module??this.currentRegisteringModule}),this}registerModule(e,r){if(this.registeredModules.has(e.name))throw new Error(`Module '${e.name}' is already registered`);this.registeredModules.set(e.name,e);let n=this.currentRegisteringModule;this.currentRegisteringModule=e.name;try{if(e.docs)for(let s of e.docs)this.registerFunctionDoc({...s,module:s.module??e.name});typeof e.register=="function"&&e.register(this,r)}finally{this.currentRegisteringModule=n}return this}getModules(){return Array.from(this.registeredModules.values())}getModule(e){return this.registeredModules.get(e)}getFunctionsByModule(e){return Array.from(this.functionDocs.values()).filter(r=>(r.module??"core").toLowerCase()===e.toLowerCase())}getFunctionDocs(){return Array.from(this.functionDocs.values())}getFunctionDoc(e){return this.functionDocs.get(e)}getFunctionCategories(){let e=new Set;for(let r of this.functionDocs.values())e.add(r.category);return Array.from(e)}getFunctionsByCategory(e){return Array.from(this.functionDocs.values()).filter(r=>r.category.toLowerCase()===e.toLowerCase())}registerPredefinedFunctions(){this.registerFunction("read_file",e=>F.readFileSync(e,"utf-8"),1,"Reads entire file as UTF-8 string"),this.registerFunction("read",e=>F.readFileSync(e,"utf-8"),1,"Reads entire file as UTF-8 string"),this.registerFunction("read_lines",e=>{let r=F.readFileSync(e,"utf-8"),n=r.length>0;return r.endsWith(`\r
|
|
154
|
+
`)?r=r.slice(0,-2):r.endsWith(`
|
|
155
|
+
`)&&(r=r.slice(0,-1)),n?r.length===0?[""]:r.split(/\r?\n/):[]},1,"Reads file as an array of string lines"),this.registerFunction("write_lines",(e,r)=>{if(!Array.isArray(r))throw new Error("write_lines: second argument must be an array of lines");let n=r.length===0?"":r.map(String).join(`
|
|
156
|
+
`)+`
|
|
157
|
+
`;return F.writeFileSync(e,n,"utf-8"),!0},2,"Writes an array of lines to a file with trailing newline"),this.registerFunction("glob",e=>{try{return Array.from(F.globSync(e))}catch{return[]}},1,"Finds files matching a glob pattern and returns an array of matching paths"),this.registerFunction("list_dir",e=>{try{return F.readdirSync(de.resolve(String(e)))}catch{return[]}},1,"Lists filenames in a directory"),this.registerFunction("write_file",(e,r)=>(F.writeFileSync(e,String(r),"utf-8"),!0),2,"Writes string content to file"),this.registerFunction("write",(e,r)=>(F.writeFileSync(e,String(r),"utf-8"),!0),2,"Writes string content to file"),this.registerFunction("append_file",(e,r)=>(F.appendFileSync(e,String(r),"utf-8"),!0),2,"Appends string content to file"),this.registerFunction("read_json",e=>{let r=F.readFileSync(e,"utf-8");return JSON.parse(r)},1,"Reads file and parses JSON content"),this.registerFunction("write_json",(e,r,n=2)=>(F.writeFileSync(e,JSON.stringify(r,null,n),"utf-8"),!0),{min:2,max:3},"Serializes data and writes formatted JSON to file"),this.registerFunction("read_csv",(e,r=!0,n=",")=>{let s=F.readFileSync(e,"utf-8");return ro(s,r,n)},{min:1,max:3},"Reads CSV file and parses into array of objects or rows"),this.registerFunction("write_csv",(e,r,n=",")=>(F.writeFileSync(e,so(r,n),"utf-8"),!0),{min:2,max:3},"Writes array of objects or rows to CSV file"),this.registerFunction("csv_parse",ro,{min:1,max:3},"Parses inline CSV text into records or rows"),this.registerFunction("csv_stringify",so,{min:1,max:2},"Serializes records or rows to CSV text");for(let e of["read","read_file","read_lines","read_json","read_csv","glob","list_dir"])this.hostFunctions.get(e).readsFile=!0;this.registerFunction("temp_file",()=>{let e=de.resolve(tu(),`lmscript-${eu()}`),r=F.openSync(e,"wx",384);return F.closeSync(r),e},0,"Creates an empty temporary file and returns its absolute path; caller deletes it"),this.registerFunction("file_exists",e=>F.existsSync(e),1,"Checks if file exists"),this.registerFunction("exit",(e=0)=>{throw new pe(Number(e))},{min:0,max:1},"Terminates script execution with an optional exit code (default: 0)"),this.registerFunction("delete_file",e=>F.existsSync(e)?(F.unlinkSync(e),!0):!1,1,"Deletes file if it exists"),this.registerFunction("remove_file",e=>F.existsSync(e)?(F.unlinkSync(e),!0):!1,1,"Deletes file if it exists"),this.registerFunction("list",(...e)=>e,void 0,"Creates a new list/array"),this.registerFunction("array",(...e)=>e,void 0,"Creates a new list/array"),this.registerFunction("push",(e,...r)=>(e.push(...r),e.length),void 0,"Pushes item(s) to end of array",!0,!0),this.registerFunction("pop",e=>e.pop(),1,"Pops item from end of array",!0,!0),this.registerFunction("shift",e=>e.shift(),1,"Removes and returns first element",!0,!0),this.registerFunction("unshift",(e,...r)=>(e.unshift(...r),e.length),void 0,"Adds item(s) to front of array",!0,!0),this.registerFunction("insert",(e,r,n)=>{let s=r<0?e.length+r:r;return e.splice(s,0,n),e.length},3,"Inserts item at index",!0,!0),this.registerFunction("remove_at",(e,r)=>{let n=r<0?e.length+r:r,s=e.splice(n,1);return s.length>0?s[0]:null},2,"Removes element at index",!0,!0),this.registerFunction("concat",(e,...r)=>e.concat(...r),void 0,"Concatenates arrays"),this.registerFunction("reverse",e=>Array.isArray(e)?[...e].reverse():e,1,"Returns reversed array"),this.registerFunction("sort",(e,r)=>{if(!Array.isArray(e))return e;let n=[...e];return r?n.sort((s,i)=>{let o=s?s[r]:void 0,a=i?i[r]:void 0;return o<a?-1:o>a?1:0}):n.sort((s,i)=>typeof s=="number"&&typeof i=="number"?s-i:String(s).localeCompare(String(i)))},void 0,"Sorts array numerically, alphabetically, or by object key"),this.registerFunction("unique",e=>Array.isArray(e)?Array.from(new Set(e)):[],1,"Removes duplicate elements"),this.registerFunction("flatten",e=>Array.isArray(e)?e.flat():[],1,"Flattens array one level"),this.registerFunction("first",e=>Array.isArray(e)&&e.length>0?e[0]:null,1,"Returns first element"),this.registerFunction("last",e=>Array.isArray(e)&&e.length>0?e[e.length-1]:null,1,"Returns last element"),this.registerFunction("sum",e=>Array.isArray(e)?e.reduce((r,n)=>r+(typeof n=="number"?n:Number(n)||0),0):0,1,"Calculates sum of array"),this.registerFunction("avg",e=>!Array.isArray(e)||e.length===0?0:e.reduce((n,s)=>n+(typeof s=="number"?s:Number(s)||0),0)/e.length,1,"Calculates average of array"),this.registerFunction("map",()=>({}),0,"Creates a new empty map/hash"),this.registerFunction("hash",()=>({}),0,"Creates a new empty map/hash"),this.registerFunction("from_entries",e=>Array.isArray(e)?Object.fromEntries(e):{},1,"Creates map from [key, value] pairs"),this.registerFunction("clear",e=>{if(Array.isArray(e))return e.length=0,e;if(e&&typeof e=="object"){for(let r of Object.keys(e))delete e[r];return e}return e},1,"Clears array or map",!0,!0),this.registerFunction("size",e=>Array.isArray(e)||typeof e=="string"?e.length:e&&typeof e=="object"?Object.keys(e).length:0,1,"Returns number of elements in array, string, or map"),this.registerFunction("system",(e,r=6e4)=>{if(!Number.isSafeInteger(r)||r<0)throw new Error("system() timeout must be a non-negative safe integer in milliseconds");return this.isAsyncMode?ho(e,r):po(e,r)},{min:1,max:2},"Executes shell command or argv array directly with shell:false and optional timeoutMs (default 60000), returning {stdout, stderr, code, signal, timed_out, duration_ms, pid}",!0),this.registerFunction("run_script",(e,r=[])=>{let n=de.resolve(String(e));if(!F.existsSync(n))throw new Error(`run_script: file not found: '${n}'`);let s=F.readFileSync(n,"utf-8"),i=Array.isArray(r)?r.map(String):[],o=new t;for(let[a,l]of this.hostFunctions)o.hasFunction(a)?l.isDefault||o.registerFunction(a,l.fn,l.arity,{description:l.description,allowOverwrite:!0},!1,l.isContainerMutation):o.registerFunction(a,l.fn,l.arity,l.description,l.isDefault,l.isContainerMutation);if(o.setGlobal("args",[...i]),o.setGlobal("ARGV",[n,...i]),this.isAsyncMode)return(async()=>{let a=await o.runAsync(s,{file:n}),l=a.output.join(`
|
|
158
|
+
`)+(a.output.length>0?`
|
|
159
|
+
`:""),c=a.exitCode!==void 0?a.exitCode:a.success?0:1,u={success:a.success&&c===0,stdout:l,output:[...a.output],value:a.value,exit_code:c,code:c,errors:a.errors??[]};return u.toString=()=>l,u})();{let a=o.run(s,{file:n}),l=a.output.join(`
|
|
160
|
+
`)+(a.output.length>0?`
|
|
161
|
+
`:""),c=a.exitCode!==void 0?a.exitCode:a.success?0:1,u={success:a.success&&c===0,stdout:l,output:[...a.output],value:a.value,exit_code:c,code:c,errors:a.errors??[]};return u.toString=()=>l,u}},{min:1,max:2},"Executes another LMScript file in-process and returns execution result with .stdout, .output, .success, .exit_code",!0),this.registerFunction("error",(...e)=>{let r=e.map(n=>typeof n=="object"?JSON.stringify(n):String(n)).join(" ");return typeof process<"u"&&process.stderr?process.stderr.write(`error: ${r}
|
|
162
|
+
`):console.error(`error: ${r}`),r},void 0,"Formats and logs an error to stderr and records it for the execution error summary",!0),this.registerFunction("urlget",e=>mo(e),1,"Downloads UTF-8 text from a public HTTP(S) URL",!0),this.registerFunction("sleep",e=>{if(typeof e!="number"||!Number.isFinite(e)||e<0)throw new Error("sleep() duration must be a non-negative finite number");if(e>2147483647)throw new Error("sleep() duration exceeds maximum supported timeout (2147483647 ms)");let r=Date.now()+e;for(;Date.now()<r;);return null},1,"Sleeps for the specified milliseconds",!0),this.registerFunction("prompt_human",e=>this.isAsyncMode?Ht(e):Wt(e),{min:0,max:1},"Prompts operator on stdin/terminal, returning input string or null if closed/non-interactive",!0),this.registerFunction("json",(e,r)=>{if(typeof e=="string")try{return JSON.parse(e)}catch(n){throw new Error(`Invalid JSON string: ${n.message}`)}return JSON.stringify(e,null,r)},{min:1,max:2},"Parses JSON string into object/array, or stringifies data to JSON string"),this.registerFunction("json_parse",e=>{try{return JSON.parse(String(e))}catch(r){throw new Error(`JSON parse error: ${r.message}`)}},1,"Parses JSON string into object/array"),this.registerFunction("json_parse_safe",(e,r=null)=>nu(e,r),{min:1,max:2},"Safely parses JSON string with preamble/fence recovery, returning fallback (default null) on failure without throwing",!0),this.registerFunction("json_stringify",(e,r)=>JSON.stringify(e,null,r),{min:1,max:2},"Serializes value into JSON string"),this.registerFunction("keys",e=>e&&typeof e=="object"?Object.keys(e):[],1,"Returns array of object keys"),this.registerFunction("values",e=>e&&typeof e=="object"?Object.values(e):[],1,"Returns array of object values"),this.registerFunction("entries",e=>e&&typeof e=="object"?Object.entries(e):[],1,"Returns array of [key, value] pairs"),this.registerFunction("has_key",(e,r)=>e&&typeof e=="object"?Object.hasOwn(e,r):!1,2,"Checks if object has key"),this.registerFunction("has",(e,r)=>e&&typeof e=="object"?Object.hasOwn(e,r):!1,2,"Checks if object has key"),this.registerFunction("get",(e,r,n=null)=>{if(e==null)return n;let s=Array.isArray(r)?r:String(r).replace(/\[(\w+)\]/g,".$1").split(".").filter(Boolean),i=e;for(let o of s){if(i==null||typeof i!="object")return n;i=Re(i,o)}return i!==void 0?i:n},void 0,"Safely extracts nested property by path (e.g. 'user.address.city')"),this.registerFunction("set",(e,r,n)=>{if(e==null||typeof e!="object")return e;let s=Array.isArray(r)?r:String(r).replace(/\[(\w+)\]/g,".$1").split(".").filter(Boolean),i=e;for(let o=0;o<s.length-1;o++){let a=s[o];(Re(i,a)==null||typeof Re(i,a)!="object")&&je(i,a,{}),i=Re(i,a)}return s.length>0&&je(i,s[s.length-1],n),e},3,"Sets nested property by path",!0,!0),this.registerFunction("pluck",(e,r)=>Array.isArray(e)?e.map(n=>Re(n,r)):[],2,"Extracts key from array of objects"),this.registerFunction("filter_by",(e,r,n)=>Array.isArray(e)?e.filter(s=>s!=null&&Re(s,r)===n):[],3,"Filters array of objects where item[key] == value"),this.registerFunction("find_by",(e,r,n)=>{if(!Array.isArray(e))return null;let s=e.find(i=>i!=null&&Re(i,r)===n);return s!==void 0?s:null},3,"Finds first object in array where item[key] == value"),this.registerFunction("merge",(e,r)=>({...e,...r}),2,"Shallow merges two objects"),this.registerFunction("clone",e=>e==null||typeof e!="object"?e:JSON.parse(JSON.stringify(e)),1,"Deep clones an object or array"),this.registerFunction("delete_key",(e,r)=>(e&&typeof e=="object"&&delete e[r],e),2,"Deletes key from object",!0,!0),this.registerFunction("print",(...e)=>{let r=e.map(n=>typeof n=="object"?JSON.stringify(n):String(n)).join(" ");return this.outputLogs.push(r),r},void 0,"Prints formatted values to output log",!0),this.registerFunction("println",(...e)=>{let r=e.map(n=>typeof n=="object"?JSON.stringify(n):String(n)).join(" ");return this.outputLogs.push(r),r},void 0,"Prints line to output log",!0),this.registerFunction("split",(e,r="")=>String(e).split(r),void 0,"Splits string by delimiter"),this.registerFunction("lines",e=>String(e).split(/\r?\n/),1,"Splits string into array of lines"),this.registerFunction("last_line_as_status",e=>{if(typeof e!="string")return null;let r=e.split(/\r?\n/);for(let n=r.length-1;n>=0;n--){let s=r[n].trim();if(s.length>0)return s==="DONE"||s==="NOTHING_TO_DO"||s==="BLOCKED"||s==="OTHER"?s:null}return null},1,"Returns the last non-blank line of a string if it is a valid state word (DONE, NOTHING_TO_DO, BLOCKED, OTHER), else null"),this.registerFunction("words",e=>String(e).trim().split(/\s+/).filter(Boolean),1,"Splits string into words"),this.registerFunction("join",(e,r=", ")=>Array.isArray(e)?e.join(r):String(e),void 0,"Joins array into string"),this.registerFunction("trim",e=>String(e).trim(),1,"Trims whitespace from both ends"),this.registerFunction("trim_start",e=>String(e).trimStart(),1,"Trims leading whitespace"),this.registerFunction("trim_end",e=>String(e).trimEnd(),1,"Trims trailing whitespace"),this.registerFunction("to_upper",e=>String(e).toUpperCase(),1,"Converts string to uppercase"),this.registerFunction("upper",e=>String(e).toUpperCase(),1,"Converts string to uppercase"),this.registerFunction("to_lower",e=>String(e).toLowerCase(),1,"Converts string to lowercase"),this.registerFunction("lower",e=>String(e).toLowerCase(),1,"Converts string to lowercase"),this.registerFunction("capitalize",e=>{let r=String(e);return r.length===0?"":r.charAt(0).toUpperCase()+r.slice(1)},1,"Capitalizes first letter"),this.registerFunction("title_case",e=>String(e).replace(/\b\w/g,r=>r.toUpperCase()),1,"Converts string to Title Case"),this.registerFunction("contains",(e,r)=>Array.isArray(e)?e.includes(r):String(e).includes(String(r)),2,"Checks if string or array contains item"),this.registerFunction("includes",(e,r)=>Array.isArray(e)?e.includes(r):String(e).includes(String(r)),2,"Checks if string or array contains item"),this.registerFunction("starts_with",(e,r)=>String(e).startsWith(r),2,"Checks if string starts with prefix"),this.registerFunction("ends_with",(e,r)=>String(e).endsWith(r),2,"Checks if string ends with suffix"),this.registerFunction("index_of",(e,r,n)=>String(e).indexOf(r,n),void 0,"Finds index of substring"),this.registerFunction("last_index_of",(e,r)=>String(e).lastIndexOf(r),2,"Finds last index of substring"),this.registerFunction("count_matches",(e,r)=>r?String(e).split(r).length-1:0,2,"Counts occurrences of substring"),this.registerFunction("substr",(e,r,n)=>{let s=String(e);return n===void 0?s.substring(r):s.substring(r,r+n)},void 0,"Returns substring by start and length"),this.registerFunction("substring",(e,r,n)=>String(e).substring(r,n),void 0,"Returns substring between indices"),this.registerFunction("slice",(e,r,n)=>e!=null?e.slice(r,n):"",void 0,"Slices string or array"),this.registerFunction("char_at",(e,r)=>String(e).charAt(r),2,"Returns character at index"),this.registerFunction("char_code",(e,r=0)=>String(e).charCodeAt(r),void 0,"Returns character code at index"),this.registerFunction("from_char_code",(...e)=>String.fromCharCode(...e),void 0,"Returns string from character codes"),this.registerFunction("replace",(e,r,n)=>String(e).replace(r,n),3,"Replaces first occurrence"),this.registerFunction("replace_all",(e,r,n)=>String(e).replaceAll(r,n),3,"Replaces all occurrences"),this.registerFunction("repeat",(e,r)=>String(e).repeat(r),2,"Repeats string count times"),this.registerFunction("pad_start",(e,r,n=" ")=>String(e).padStart(r,n),void 0,"Left-pads string"),this.registerFunction("pad_end",(e,r,n=" ")=>String(e).padEnd(r,n),void 0,"Right-pads string"),this.registerFunction("reverse_str",e=>String(e).split("").reverse().join(""),1,"Reverses string"),this.registerFunction("is_empty",e=>e==null?!0:typeof e=="string"?e.trim().length===0:Array.isArray(e)?e.length===0:typeof e=="object"?Object.keys(e).length===0:!1,1,"Checks if string, array, or map is empty"),this.registerFunction("is_digit",e=>/^\d+$/.test(String(e)),1,"Checks if string contains only digits"),this.registerFunction("is_alpha",e=>/^[a-zA-Z]+$/.test(String(e)),1,"Checks if string contains only letters"),this.registerFunction("is_alnum",e=>/^[a-zA-Z0-9]+$/.test(String(e)),1,"Checks if string contains only letters and digits"),this.registerFunction("shell_quote",e=>fo(e),1,"Quotes string safely for POSIX shell command execution",!0),this.registerFunction("format",(e,...r)=>{let n=String(e),s=r.length===1&&typeof r[0]=="object"&&r[0]!==null&&!Array.isArray(r[0])?r[0]:void 0,i=0,o="",a=l=>typeof l=="object"&&l!==null?JSON.stringify(l):String(l);for(let l=0;l<n.length;){let c=n[l];if(c==="{"&&n[l+1]==="{"){o+="{",l+=2;continue}if(c==="}"&&n[l+1]==="}"){o+="}",l+=2;continue}if(c!=="{"){o+=c,l+=1;continue}let u=n.indexOf("}",l+1);if(u<0){o+=c,l+=1;continue}let d=n.slice(l+1,u);if(d==="")o+=i<r.length?a(r[i++]):"{}";else if(/^\d+$/.test(d)){let p=Number(d);o+=p<r.length?a(r[p]):`{${d}}`}else s&&/^[a-zA-Z0-9_]+$/.test(d)&&Object.hasOwn(s,d)?o+=a(s[d]):o+=`{${d}}`;l=u+1}return o},void 0,"Formats string with arguments, supporting {{ and }} brace escapes, positional {0}, auto {}, and {key} map substitution"),this.registerFunction("len",e=>typeof e=="string"||Array.isArray(e)?e.length:e&&typeof e=="object"?Object.keys(e).length:0,1,"Returns length of string, array, or object"),this.registerFunction("range",(e,r,n=1)=>{let s=r===void 0?0:e,i=r===void 0?e:r,o=[];if(n>0)for(let a=s;a<i;a+=n)o.push(a);else if(n<0)for(let a=s;a>i;a+=n)o.push(a);return o},void 0,"Generates an array of numbers"),this.registerFunction("abs",e=>Math.abs(e),1,"Absolute value"),this.registerFunction("min",(...e)=>{let r=e.length===1&&Array.isArray(e[0])?e[0]:e;return Math.min(...r)},void 0,"Minimum value"),this.registerFunction("max",(...e)=>{let r=e.length===1&&Array.isArray(e[0])?e[0]:e;return Math.max(...r)},void 0,"Maximum value"),this.registerFunction("floor",e=>Math.floor(e),1,"Floor value"),this.registerFunction("ceil",e=>Math.ceil(e),1,"Ceil value"),this.registerFunction("round",e=>Math.round(e),1,"Round value"),this.registerFunction("sqrt",e=>Math.sqrt(e),1,"Square root"),this.registerFunction("pow",(e,r)=>Math.pow(e,r),2,"Power calculation"),this.registerFunction("random",()=>Math.random(),0,"Random float between 0 and 1"),this.registerFunction("clock",()=>Date.now(),0,"Returns current epoch in ms"),this.registerFunction("str",e=>e===null?"null":String(e),1,"Converts value to string"),this.registerFunction("num",e=>Number(e),1,"Converts value to number"),this.registerFunction("type",e=>e===null?"null":Array.isArray(e)?"array":typeof e,1,"Returns runtime type of value"),this.registerFunction("assert",(e,r="Assertion failed")=>{if(!e)throw new Error(r);return!0},void 0,"Throws error if condition is falsy")}registerFunction(e,r,n,s,i=!1,o=!1){let a=typeof s=="string"?s:s?.description,l=typeof s=="object"?!!s.isDefault:i,c=typeof s=="object"?!!s.isContainerMutation:o,u=typeof s=="object"?s.doc:void 0,d=typeof s=="object"?!!s.allowOverwrite:!1,p=typeof s=="object"&&s.module?s.module:this.currentRegisteringModule,m=this.functionOriginModule.get(e);if(m&&m!==p&&!d)throw new Error(`Cannot register function '${e}' from module '${p}': already registered by module '${m}'`);return this.functionOriginModule.set(e,p),this.hostFunctions.set(e,{fn:r,arity:n,description:a,isDefault:l,isContainerMutation:c,doc:u}),u&&this.functionDocs.set(e,{...u,module:u.module??p}),this}getFunctionOriginModule(e){return this.functionOriginModule.get(e)}initialGlobals=new Map;setGlobal(e,r){return this.initialGlobals.set(e,r),this}getGlobal(e){return this.initialGlobals.get(e)}scanAndCheck(e,r={}){try{let{program:n}=ou(e,r),s=[...this.initialGlobals.keys(),...r.globals||[]],i=new Zn(this.hostFunctions,{...r,globals:s}),o=i.check(n);return{ast:n,diagnostics:o,hasConcurrency:i.hasConcurrency}}catch(n){return n instanceof C?{ast:null,diagnostics:[{message:n.message,line:n.line,column:n.column,severity:"error",file:n.file||r.file}],hasConcurrency:!1}:{ast:null,diagnostics:[{message:n instanceof Error?n.message:String(n),line:1,column:1,severity:"error",file:r.file}],hasConcurrency:!1}}}run(e,r={}){let n=[],{ast:s,diagnostics:i,hasConcurrency:o}=this.scanAndCheck(e,r);if(i.filter(c=>c.severity==="error").length>0||!s)return this.outputLogs=n,{success:!1,diagnostics:i,output:n};if(o)return this.outputLogs=n,{success:!1,diagnostics:[...i,{message:"Concurrency constructs ('parallel', 'sync') require asynchronous execution via engine.runAsync()",line:1,column:1,severity:"error",file:r.file}],output:n};let l;try{l=new Nr(this.hostFunctions,d=>n.push(d),!1,this.initialGlobals,r.stderr);let c=l.evaluateProgram(s);this.outputLogs=[...n];let u=l.getRecordedErrors();return this.lastRecordedErrors=u,{success:!0,value:c,diagnostics:i,output:n,errors:u}}catch(c){let u=l?l.getRecordedErrors():[];if(this.lastRecordedErrors=u,c instanceof pe||c?.name==="LMScriptExit"||c?.isControlFlow){this.outputLogs=[...n];let h=typeof c.exitCode=="number"?c.exitCode:0;return{success:h===0,value:h,exitCode:h,diagnostics:i,output:n,errors:u}}let d=c instanceof C?c.line:1,p=c instanceof C?c.column:1,m=c instanceof C&&c.file||r.file;return this.outputLogs=[...n],{success:!1,diagnostics:[...i,{message:c?.message||String(c),line:d,column:p,severity:"error",file:m}],output:n,errors:u}}}async runAsync(e,r={}){let n=[],{ast:s,diagnostics:i}=this.scanAndCheck(e,r);if(i.filter(l=>l.severity==="error").length>0||!s)return this.outputLogs=n,this.lastRecordedErrors=[],{success:!1,diagnostics:i,output:n,errors:[]};let a;try{a=new Nr(this.hostFunctions,u=>n.push(u),!0,this.initialGlobals,r.stderr);let l=await a.evaluateProgramAsync(s);this.outputLogs=[...n];let c=a.getRecordedErrors();return this.lastRecordedErrors=c,{success:!0,value:l,diagnostics:i,output:n,errors:c}}catch(l){let c=a?a.getRecordedErrors():[];if(this.lastRecordedErrors=c,l instanceof pe||l?.name==="LMScriptExit"||l?.isControlFlow){this.outputLogs=[...n];let m=typeof l.exitCode=="number"?l.exitCode:0;return{success:m===0,value:m,exitCode:m,diagnostics:i,output:n,errors:c}}let u=l instanceof C?l.line:1,d=l instanceof C?l.column:1,p=l instanceof C&&l.file||r.file;return this.outputLogs=[...n],{success:!1,diagnostics:[...i,{message:l?.message||String(l),line:u,column:d,severity:"error",file:p}],output:n,errors:c}}}lastRecordedErrors=[];getRecordedErrors(){return[...this.lastRecordedErrors]}hasFunction(e){return this.hostFunctions.has(e)}getRegisteredFunctions(){return Array.from(this.hostFunctions.keys())}};async function du(){console.log("================================================="),console.log(" LMScript Verification & Full Feature Test Suite "),console.log(`=================================================
|
|
163
|
+
`);let t=new Me,e=!0;console.log("Test Suite 1: Functions, Recursion, and Control Flow");let n=t.run(`
|
|
164
|
+
fn factorial(n) {
|
|
165
|
+
if (n <= 1) {
|
|
166
|
+
return 1;
|
|
167
|
+
}
|
|
168
|
+
return n * factorial(n - 1);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
let fact5 = factorial(5);
|
|
172
|
+
print("factorial(5) =", fact5);
|
|
173
|
+
assert(fact5 == 120, "factorial(5) must be 120");
|
|
174
|
+
|
|
175
|
+
let sumVal = 0;
|
|
176
|
+
for (let i = 1; i <= 5; i = i + 1) {
|
|
177
|
+
if (i == 3) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
sumVal = sumVal + i;
|
|
181
|
+
}
|
|
182
|
+
print("sum skipping 3 =", sumVal);
|
|
183
|
+
assert(sumVal == 12, "sum must be 12");
|
|
184
|
+
`);n.success?(console.log(n.output.map(T=>" [out] "+T).join(`
|
|
185
|
+
`)),console.log(` -> Passed!
|
|
186
|
+
`)):(console.error(" -> Failed:",n.diagnostics),e=!1),console.log("Test Suite 2: TS Predefined Builtins & Host Registration"),t.registerFunction("base64Encode",T=>Buffer.from(T).toString("base64"),1,"Base64 encodes a string"),t.registerFunction("addVectors",(T,E)=>T.map((I,w)=>I+(E[w]||0)),2,"Adds two numeric arrays element-wise");let i=t.run(`
|
|
187
|
+
let text = "TypeScript Engine";
|
|
188
|
+
let encoded = base64Encode(text);
|
|
189
|
+
print("Encoded base64:", encoded);
|
|
190
|
+
|
|
191
|
+
let v1 = [10, 20, 30];
|
|
192
|
+
let v2 = [1, 2, 3];
|
|
193
|
+
let vSum = addVectors(v1, v2);
|
|
194
|
+
print("Vector sum:", vSum);
|
|
195
|
+
|
|
196
|
+
push(vSum, 99);
|
|
197
|
+
print("vSum after push:", vSum, "length:", len(vSum));
|
|
198
|
+
|
|
199
|
+
print("sqrt(16) =", sqrt(16));
|
|
200
|
+
print("min(5, 2, 9) =", min(5, 2, 9));
|
|
201
|
+
`);i.success?(console.log(i.output.map(T=>" [out] "+T).join(`
|
|
202
|
+
`)),console.log(` -> Passed!
|
|
203
|
+
`)):(console.error(" -> Failed:",i.diagnostics),e=!1),console.log("Test Suite 3: Static Analysis Validation (Zero Execution on Error)");let o=`
|
|
204
|
+
let x = 10;
|
|
205
|
+
let x = 20; // ERROR 1: Duplicate variable declaration
|
|
206
|
+
|
|
207
|
+
fn testReturn() {
|
|
208
|
+
// ok
|
|
209
|
+
}
|
|
210
|
+
return 42; // ERROR 2: return outside function
|
|
211
|
+
|
|
212
|
+
while (x > 0) {
|
|
213
|
+
// ok
|
|
214
|
+
}
|
|
215
|
+
continue; // ERROR 3: continue outside loop
|
|
216
|
+
|
|
217
|
+
undefinedFunctionCall(); // ERROR 4: undefined function
|
|
218
|
+
base64Encode("hello", "extra_arg"); // ERROR 5: arity mismatch
|
|
219
|
+
`,a=t.run(o);console.log(" Executed successfully?",a.success),console.log(" Formatted visual diagnostics caught BEFORE execution:");for(let T of a.diagnostics)console.log(" "+co(T,o).split(`
|
|
220
|
+
`).join(`
|
|
221
|
+
`));!a.success&&a.diagnostics.length===5?console.log(` -> Passed! (All 5 static errors caught upfront with visual carets)
|
|
222
|
+
`):(console.error(" -> Failed! Expected 5 diagnostics, got",a.diagnostics.length),e=!1),console.log("Test Suite 4: Forward Function Declarations & Mutual Recursion");let c=t.run(`
|
|
223
|
+
print("even(6):", even(6));
|
|
224
|
+
print("odd(6):", odd(6));
|
|
225
|
+
|
|
226
|
+
fn even(n) {
|
|
227
|
+
if (n == 0) { return true; }
|
|
228
|
+
return odd(n - 1);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
fn odd(n) {
|
|
232
|
+
if (n == 0) { return false; }
|
|
233
|
+
return even(n - 1);
|
|
234
|
+
}
|
|
235
|
+
`);c.success?(console.log(c.output.map(T=>" [out] "+T).join(`
|
|
236
|
+
`)),console.log(` -> Passed!
|
|
237
|
+
`)):(console.error(" -> Failed:",c.diagnostics),e=!1),console.log("Test Suite 5: Perl-style system() & String Operations");let d=t.run(`
|
|
238
|
+
res = system("ls -ltr");
|
|
239
|
+
out = res.stdout;
|
|
240
|
+
err = res.stderr;
|
|
241
|
+
print("Command executed. stdout length:", len(out), "stderr length:", len(err));
|
|
242
|
+
|
|
243
|
+
let outLines = lines(out);
|
|
244
|
+
print("STDOUT lines count:", len(outLines));
|
|
245
|
+
print("First line:", outLines[0]);
|
|
246
|
+
|
|
247
|
+
let sample = " apple, banana, cherry, date ";
|
|
248
|
+
let cleaned = trim(sample);
|
|
249
|
+
print("Trimmed:", cleaned);
|
|
250
|
+
print("Upper:", to_upper(cleaned));
|
|
251
|
+
print("Contains 'banana':", contains(cleaned, "banana"));
|
|
252
|
+
|
|
253
|
+
let fruits = split(cleaned, ", ");
|
|
254
|
+
print("Split fruits array:", fruits);
|
|
255
|
+
print("Joined fruits:", join(fruits, " | "));
|
|
256
|
+
print("Title Case:", title_case("hello world of scripts"));
|
|
257
|
+
`);d.success?(console.log(d.output.map(T=>" [out] "+T).join(`
|
|
258
|
+
`)),console.log(` -> Passed!
|
|
259
|
+
`)):(console.error(" -> Failed:",d.diagnostics),e=!1),console.log("Test Suite 6: JSON Parsing & Object Primitive Methods");let m=t.run(`
|
|
260
|
+
res = system("echo '{\\"status\\": \\"ok\\", \\"code\\": 200, \\"users\\": [{\\"id\\": 1, \\"name\\": \\"Alice\\", \\"active\\": true}, {\\"id\\": 2, \\"name\\": \\"Bob\\", \\"active\\": false}], \\"server\\": {\\"host\\": \\"localhost\\", \\"port\\": 8080}}'");
|
|
261
|
+
|
|
262
|
+
data = json(res.stdout);
|
|
263
|
+
|
|
264
|
+
print("Extracted status:", data.status);
|
|
265
|
+
print("Extracted code:", data.code);
|
|
266
|
+
print("Extracted server.host:", data.server.host);
|
|
267
|
+
print("Extracted server.port:", data.server.port);
|
|
268
|
+
print("First user name:", data.users[0].name);
|
|
269
|
+
|
|
270
|
+
print("Object keys(data):", keys(data));
|
|
271
|
+
print("Object keys(data.server):", keys(data.server));
|
|
272
|
+
print("Object values(data.server):", values(data.server));
|
|
273
|
+
print("has_key(data, 'server'):", has_key(data, "server"));
|
|
274
|
+
print("has_key(data, 'database'):", has_key(data, "database"));
|
|
275
|
+
|
|
276
|
+
print("Deep get host:", get(data, "server.host"));
|
|
277
|
+
print("Deep get fallback:", get(data, "server.ssl", false));
|
|
278
|
+
|
|
279
|
+
let userNames = pluck(data.users, "name");
|
|
280
|
+
print("Plucked names:", userNames);
|
|
281
|
+
|
|
282
|
+
let activeUsers = filter_by(data.users, "active", true);
|
|
283
|
+
print("Active users count:", len(activeUsers), "Name:", activeUsers[0].name);
|
|
284
|
+
|
|
285
|
+
let bob = find_by(data.users, "name", "Bob");
|
|
286
|
+
print("Found Bob ID:", bob.id);
|
|
287
|
+
|
|
288
|
+
data.server.port = 9000;
|
|
289
|
+
let serialized = json(data);
|
|
290
|
+
print("Re-serialized JSON length:", len(serialized));
|
|
291
|
+
|
|
292
|
+
let localConfig = {
|
|
293
|
+
app: "LMScript",
|
|
294
|
+
version: 1.0,
|
|
295
|
+
tags: ["json", "compiler"]
|
|
296
|
+
};
|
|
297
|
+
print("Local config dot access:", localConfig.app, "tags:", localConfig.tags[0]);
|
|
298
|
+
`);m.success?(console.log(m.output.map(T=>" [out] "+T).join(`
|
|
299
|
+
`)),console.log(` -> Passed!
|
|
300
|
+
`)):(console.error(" -> Failed:",m.diagnostics),e=!1),console.log("Test Suite 7: File I/O & Advanced Data Structures");let g=t.run(`
|
|
301
|
+
// 1. Raw file write and read
|
|
302
|
+
let tmpFile = "scratch_test.txt";
|
|
303
|
+
write_file(tmpFile, "line 1\\nline 2\\nline 3");
|
|
304
|
+
print("File exists?", file_exists(tmpFile));
|
|
305
|
+
print("Read content:\\n" + read_file(tmpFile));
|
|
306
|
+
let fileLines = read_lines(tmpFile);
|
|
307
|
+
print("Read lines count:", len(fileLines));
|
|
308
|
+
assert(fileLines[1] == "line 2", "Second line must be 'line 2'");
|
|
309
|
+
|
|
310
|
+
// 2. JSON file write and read
|
|
311
|
+
let jsonFile = "scratch_test.json";
|
|
312
|
+
let originalData = { title: "Report", count: 42, tags: ["ts", "script"] };
|
|
313
|
+
write_json(jsonFile, originalData);
|
|
314
|
+
let loadedJson = read_json(jsonFile);
|
|
315
|
+
print("Loaded JSON title:", loadedJson.title, "count:", loadedJson.count);
|
|
316
|
+
assert(loadedJson.count == 42, "JSON count must match 42");
|
|
317
|
+
|
|
318
|
+
// 3. CSV file write and read
|
|
319
|
+
let csvFile = "scratch_test.csv";
|
|
320
|
+
let usersList = [
|
|
321
|
+
{ name: "Alice", age: 30, city: "New York" },
|
|
322
|
+
{ name: "Bob", age: 25, city: "San Francisco" },
|
|
323
|
+
{ name: "Charlie", age: 35, city: "Chicago" }
|
|
324
|
+
];
|
|
325
|
+
write_csv(csvFile, usersList);
|
|
326
|
+
let parsedCsv = read_csv(csvFile);
|
|
327
|
+
print("Parsed CSV rows count:", len(parsedCsv));
|
|
328
|
+
print("Parsed CSV row 0:", parsedCsv[0].name, "age:", parsedCsv[0].age, "city:", parsedCsv[0].city);
|
|
329
|
+
assert(parsedCsv[0].age == 30, "Alice age must be coerced to numeric 30");
|
|
330
|
+
|
|
331
|
+
// Clean up temporary files
|
|
332
|
+
delete_file(tmpFile);
|
|
333
|
+
delete_file(jsonFile);
|
|
334
|
+
delete_file(csvFile);
|
|
335
|
+
|
|
336
|
+
// 4. List / Array data structures
|
|
337
|
+
let numbers = [5, 2, 8, 1, 9];
|
|
338
|
+
push(numbers, 3);
|
|
339
|
+
print("After push:", numbers);
|
|
340
|
+
let popped = pop(numbers);
|
|
341
|
+
print("Popped:", popped);
|
|
342
|
+
shift(numbers); // removes 5
|
|
343
|
+
unshift(numbers, 10); // adds 10 to front
|
|
344
|
+
print("After shift/unshift:", numbers);
|
|
345
|
+
print("Sorted numbers:", sort(numbers));
|
|
346
|
+
print("Reversed numbers:", reverse(numbers));
|
|
347
|
+
print("First:", first(numbers), "Last:", last(numbers), "Negative index [-1]:", numbers[-1]);
|
|
348
|
+
print("Sum:", sum(numbers), "Avg:", avg(numbers));
|
|
349
|
+
print("Unique [1,1,2,3,3]:", unique([1, 1, 2, 3, 3]));
|
|
350
|
+
|
|
351
|
+
// 5. Hash / Map data structures
|
|
352
|
+
let userMap = map();
|
|
353
|
+
userMap.name = "Diana";
|
|
354
|
+
userMap["department"] = "Engineering";
|
|
355
|
+
set(userMap, "contact.email", "diana@example.com");
|
|
356
|
+
print("User map name:", userMap.name);
|
|
357
|
+
print("User map contact email:", get(userMap, "contact.email"));
|
|
358
|
+
print("User map keys:", keys(userMap));
|
|
359
|
+
print("Has department?", has_key(userMap, "department"));
|
|
360
|
+
delete_key(userMap, "department");
|
|
361
|
+
print("After delete_key has department?", has_key(userMap, "department"));
|
|
362
|
+
`);g.success?(console.log(g.output.map(T=>" [out] "+T).join(`
|
|
363
|
+
`)),console.log(` -> Passed!
|
|
364
|
+
`)):(console.error(" -> Failed:",g.diagnostics),e=!1),console.log("Test Suite 8: Concurrency & Synchronized State Access");let f=await t.runAsync(`
|
|
365
|
+
let counter = 0;
|
|
366
|
+
let list = [];
|
|
367
|
+
let state = map();
|
|
368
|
+
|
|
369
|
+
fn worker(id, val) {
|
|
370
|
+
sleep(10);
|
|
371
|
+
sync counter = counter + 1;
|
|
372
|
+
sync push(list, val);
|
|
373
|
+
sync state[id] = val;
|
|
374
|
+
return id;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
(res1, res2, res3) = parallel([worker("a", 100), worker("b", 200), worker("c", 300)]);
|
|
378
|
+
print("Parallel results:", res1, res2, res3);
|
|
379
|
+
print("Final counter:", counter);
|
|
380
|
+
print("List size:", len(list));
|
|
381
|
+
print("State keys:", keys(state));
|
|
382
|
+
|
|
383
|
+
assert(counter == 3, "counter must be 3");
|
|
384
|
+
assert(len(list) == 3, "list length must be 3");
|
|
385
|
+
assert(state.a == 100, "state.a must be 100");
|
|
386
|
+
assert(res1 == "a" && res2 == "b" && res3 == "c", "parallel results must match return values");
|
|
387
|
+
`);return f.success?(console.log(f.output.map(T=>" [out] "+T).join(`
|
|
388
|
+
`)),console.log(` -> Passed!
|
|
389
|
+
`)):(console.error(" -> Failed:",f.diagnostics),e=!1),e}async function uu(){let t=process.argv.slice(2);if(t.length===0||t.length===1&&t[0]==="--test"){await du()||(process.exitCode=1);return}let e="Usage: lmscript.ts [--check|--dry-run|--lint] [--check-files] <file> | [check options] -e <source> | --test | --help";if(t.length===1&&t[0]==="--help"){console.log(e);return}let r=!1,n=!1;for(;["--check","--dry-run","--lint","--check-files"].includes(t[0]);)r=!0,t.shift()==="--check-files"&&(n=!0);let s=t[0]==="-e";if(s?t.length!==2:t.length!==1||t[0].startsWith("-")){console.error(e),process.exitCode=1;return}try{let i=s?void 0:de.resolve(t[0]),o=s?t[1]:F.readFileSync(i,"utf-8"),a=new Me,l=r?a.scanAndCheck(o,{checkFiles:n,file:i}):await a.runAsync(o,{file:i});if("output"in l)for(let c of l.output)console.log(c);for(let c of l.diagnostics)console.error(co(c,o));l.diagnostics.some(c=>c.severity==="error")&&(process.exitCode=1)}catch(i){console.error(`Execution failed: ${i instanceof Error?i.message:String(i)}`),process.exitCode=1}}var oo=de.basename(lo(import.meta.url));(oo==="lmscript.ts"||oo==="lmscript.js")&&process.argv[1]&&F.existsSync(process.argv[1])&&F.realpathSync(lo(import.meta.url))===F.realpathSync(de.resolve(process.argv[1]))&&uu();import{readFileSync as GE}from"node:fs";import{createInterface as JE}from"node:readline";import{existsSync as ku}from"node:fs";import{dirname as vo}from"node:path";import{readFileSync as fu,writeFileSync as dy,renameSync as uy,existsSync as pu}from"node:fs";import{basename as hu,resolve as Lr,dirname as ts}from"node:path";var kr=["title","description","members"],mu=new Set(kr),be=class extends Error{constructor(e){super(e),this.name="FrontmatterError"}};function go(t){if(t.length===0||!t.startsWith("---"))throw new be("frontmatter must start at line 1 with `---` on its own line");let e=t.split(`
|
|
390
|
+
`);if(e[0]!=="---")throw new be("frontmatter must start at line 1 with `---` on its own line");let r={},n=-1;for(let o=1;o<e.length;o++){let a=e[o];if(a==="---"){n=o;break}if(a.trim()==="")continue;let l=a.match(/^([a-zA-Z][a-zA-Z0-9_-]*)\s*:\s*(.*)$/);if(!l)throw new be(`malformed frontmatter line ${o+1}: ${JSON.stringify(a)} (expected "key: value" or "---")`);let c=l[1],u=l[2].trim();if(!mu.has(c))throw new be(`unknown frontmatter key "${c}" \u2014 allowed keys: ${kr.join(", ")}`);r[c]=u}if(n===-1)throw new be("frontmatter not closed (missing trailing `---` on its own line)");for(let o of kr)if(r[o]===void 0)throw new be(`missing required frontmatter key "${o}" \u2014 required: ${kr.join(", ")}`);let s=0;for(let o=0;o<=n;o++)s+=e[o].length+1;s>t.length&&(s=t.length);let i=r.members.split(",").map(o=>o.trim()).filter(Boolean);return{title:r.title,description:r.description,members:i,bodyOffset:s}}var gu="Lead";function _u(t){let e={},r=/(\w+)=(?:"([^"]*)"|([\S]*))/g,n;for(;(n=r.exec(t))!==null;){let s=n[1],i=n[2]!==void 0?n[2]:n[3];e[s]=i}return e}function Eu(t){return/^\s*_MEMBER_\s+\S/.test(t)}function yu(t){return/^\s*_SESSION_\s+\S/.test(t)}function Tu(t){return/^\s*_SKILL_(?:\s|$)/.test(t)}function rs(t){let e=hu(t);return e.endsWith(".lmctl")?e.slice(0,-6):e}function Xt(t){let e=fu(t,"utf-8"),r=ts(Lr(t)),n=ns(e,rs(t),{baseDir:r,sourcePath:Lr(t)});for(let s of n.members)s.sessiondir&&!s.sessiondir.startsWith("/")&&(s.sessiondir=Lr(r,s.sessiondir));return n}var _o=["alias","provider","sessionid","sessiondir","teamfile","model","effort"];function ns(t,e,r={}){let n=[],s=[];r.sourcePath,r.baseDir;let i=t;if(i.startsWith("#teamfile:")){let l=i.indexOf(`
|
|
391
|
+
`);i=l>=0?i.slice(l+1):""}let o=null;if(i.startsWith("---"))try{o=go(i)}catch(l){if(l instanceof be)s.push(`frontmatter: ${l.message}`);else throw l}let a=t.split(`
|
|
392
|
+
`);for(let l=0;l<a.length;l++){let c=a[l],u=l+1;if(yu(c))throw new Error(`line ${u}: _SESSION_ is the legacy prefix. Rename to _MEMBER_. (line: ${c.trim()})`);if(Tu(c)||!Eu(c))continue;let d=_u(c);for(let m of Object.keys(d))if(!_o.includes(m))throw new Error(`line ${u}: unknown key "${m}" on _MEMBER_ line: ${c.trim()}
|
|
393
|
+
allowed keys: ${_o.join(", ")}`);if(!d.provider&&!d.teamfile){s.push(`line ${u}: member line missing provider (or teamfile): ${c.trim()}`);continue}if(!d.alias){s.push(`line ${u}: member line missing required alias: ${c.trim()}`);continue}let p={alias:d.alias,provider:d.provider||"",extra:{}};d.sessionid&&(p.session=d.sessionid),Object.prototype.hasOwnProperty.call(d,"sessiondir")&&(p.sessiondir=d.sessiondir),d.teamfile&&(p.teamfile=d.teamfile),d.model&&(p.model=d.model),d.effort&&(p.effort=d.effort),n.push(p)}return{name:e,members:n,rawText:t,parseErrors:s,frontmatter:o}}function qt(t){return t.members.find(e=>e.alias.toLowerCase()===gu.toLowerCase())}function ss(t,e,r,n={}){let s=n.requireSession??!0;if(!t.teamfile)throw new Error(`Member "${t.alias}" is not a team reference`);let i=Lr(e,t.teamfile),o=r??new Set;if(o.has(i))throw new Error(`Circular team reference: ${t.alias} \u2192 ${i} (already visited: ${[...o].join(" \u2192 ")})`);if(o.add(i),!pu(i))throw new Error(`Teamfile not found: ${i} (referenced by alias "${t.alias}")`);let a=Xt(i),l=qt(a);if(!l)throw new Error(`Team at ${i} has no lead session`);if(l.teamfile)return ss(l,ts(i),o,n);if(s&&!l.session)throw new Error(`Team at ${i} lead has no session ID. Run: lmctl seed`);return{provider:l.provider,session:l.session??"",sessiondir:l.sessiondir||ts(i),alias:t.alias,resolvedFrom:i,model:l.model,effort:l.effort}}function Eo(t,e){return t.members.find(r=>r.alias===e)??t.members.find(r=>r.alias.toLowerCase()===e.toLowerCase())}import{createHash as Su}from"node:crypto";import{existsSync as yo,readFileSync as To,realpathSync as wu}from"node:fs";import{dirname as vu,resolve as So}from"node:path";var is=5,Cr=class extends Error{constructor(e){super(e),this.name="ForeignSessionidOwnershipError"}};function nt(t,e){let r=So(t);if(yo(r))return wu(r);if(e!==void 0){let n=Au(t,r,e);if(n!==null)return n}return r}function wo(t,e){let r=vu(e),n=ns(t,rs(e),{baseDir:r});for(let s of n.members)s.sessiondir!==void 0&&!s.sessiondir.startsWith("/")&&(s.sessiondir=So(r,s.sessiondir));return n}function Tt(t,e,r=n=>{process.stderr.write(`warning: ${n}
|
|
394
|
+
`)}){let n=nt(t,Iu(e)?e:void 0);if(yo(n)){let i=To(n,"utf8"),o=wo(i,n);return e!==void 0&&"upsertRootTeam"in e&&e.getRootTeam(n)===null&&xu(o)&&Nu(e,n,o,i,r),o}let s=e?.getRootTeam(n)??null;throw s!==null?new Error(`teamfile missing on disk: ${n} (registered ${s.registered_at}; the file was renamed or deleted \u2014 seed the team at its new path)`):new Error(`teamfile not found: ${t}`)}function Iu(t){return typeof t=="object"&&t!==null&&"getRootTeam"in t&&"listRootTeams"in t}function Au(t,e,r){let n=r.getRootTeam(t)??r.getRootTeam(e);return n===null?null:n.teamfile_path}function xu(t){return t.parseErrors.length>0?!1:t.members.every(e=>e.teamfile!==void 0?!0:e.session!==void 0&&e.session.length>=is)}function Ru(t,e,r){let n=nt(e),s=r.members.filter(i=>i.teamfile===void 0&&i.session!==void 0&&i.session.length>=is);if(s.length!==0)for(let i of t.listRootTeams()){let o,a;try{if(o=nt(i.teamfile_path),o===n)continue;a=To(o,"utf8")}catch(c){if(bu(c))continue;throw c}let l=wo(a,o);for(let c of s){let u=l.members.find(d=>d.teamfile===void 0&&d.session===c.session&&(d.session?.length??0)>=is);if(u!==void 0)throw new Cr(`sessionid ownership conflict: ${n}:${c.alias} and ${o}:${u.alias} both use sessionid "${c.session}"`)}}}function bu(t){let e=t?.code;return e==="ENOENT"||e==="ENOTDIR"}function Nu(t,e,r,n,s){try{Ru(t,e,r)}catch(o){if(!(o instanceof Cr))throw o;s(`${o.message}; skipping automatic registration`);return}let i={teamfile_path:e,name:r.name,raw_text:n,raw_sha256:Su("sha256").update(n).digest("hex"),registered_at:new Date().toISOString(),last_seeded_at:null};t.upsertRootTeam(i)}var Te=class extends Error{constructor(e){super(e),this.name="ChatTargetError"}};var os=/^[A-Za-z][A-Za-z0-9_-]*$/;function Lu(t){return os.test(t)}function as(t){if(!t.includes(":"))return null;let e=t.lastIndexOf(":"),r=t.slice(0,e),n=t.slice(e+1);return!r.endsWith(".lmctl")||!os.test(n)?null:{teamfile:r,alias:n}}function st(t,e,r){if(!t.endsWith(".lmctl"))throw new Te(`lmctl: "${t}" doesn't look like a teamfile (expected .lmctl extension).`);if(!Lu(e))throw new Te(`lmctl: "${e}" is not a valid alias (must match ${os.source}).`);let n=nt(t,r);if(r===void 0&&!ku(n))throw new Te(`lmctl: teamfile not found: ${t}`);let s;try{s=Tt(n,r)}catch(o){throw new Te(`lmctl: ${t}: ${o instanceof Error?o.message:String(o)}`)}if(s.parseErrors.length>0)throw new Te(`lmctl: ${t}: ${s.parseErrors.join("; ")}`);let i=Eo(s,e);if(i===void 0){let o=s.members.map(a=>a.alias).join(", ")||"(none)";throw new Te(`lmctl: alias "${e}" not found in ${t}.
|
|
395
|
+
Known aliases: ${o}`)}if(i.teamfile!==void 0){let o=ss(i,vo(n));return{teamfile:n,alias:i.alias,provider:o.provider,sessionid:o.session,sessiondir:o.sessiondir,isLead:!0,...o.model??i.model?{model:o.model??i.model}:{},...o.effort??i.effort?{effort:o.effort??i.effort}:{}}}if(i.session===void 0)throw new Te(`lmctl: alias "${i.alias}" in ${t} has no session ID yet.
|
|
396
|
+
Run: lmctl seed ${t}`);return{teamfile:n,alias:i.alias,provider:i.provider,sessionid:i.session,sessiondir:i.sessiondir??vo(n),isLead:qt(s)?.alias===i.alias,...i.model!==void 0?{model:i.model}:{},...i.effort!==void 0?{effort:i.effort}:{}}}import{existsSync as Wu,mkdirSync as Hu,readFileSync as Xu,renameSync as qu,unlinkSync as Gu,writeFileSync as Ju}from"node:fs";import{homedir as No}from"node:os";import{dirname as Gt,join as le,resolve as Vu}from"node:path";import{readFileSync as xo,appendFileSync as Cu,mkdirSync as Ou,existsSync as xy,readdirSync as Ry,unlinkSync as by}from"node:fs";import{join as Dr,dirname as Du}from"node:path";import{homedir as Mu}from"node:os";var Ro=!1,Io=!1,Ao=0,Fu=5e3;function ls(){return Dr(Mu(),".lmctl")}function K(){if(Ro||process.env.LMCTL_DEBUG==="1")return!0;let t=Date.now();return t-Ao>=Fu&&(Io=$u(),Ao=t),Io}function Pu(){let t=new Date,e=t.getTimezoneOffset(),r=e<=0?"+":"-",n=String(Math.floor(Math.abs(e)/60)).padStart(2,"0"),s=String(Math.abs(e)%60).padStart(2,"0");return new Date(t.getTime()-e*6e4).toISOString().replace("Z",`${r}${n}:${s}`)}var Or=null;function he(t,e){if(e?.verbose){if(!Ro)return}else if(!e?.always&&!K())return;try{Uu();let r={ts:new Date().toISOString(),pid:process.pid,vti:process.env.LMCTL_VTI??null,autocode_run_id:process.env.LMCTL_AUTOCODE_RUN_ID??void 0,...t};Cu(Or,JSON.stringify(r)+`
|
|
397
|
+
`)}catch{}}function Uu(){if(!Or){let e=Pu().slice(0,13).replace("T","-");Or=Dr(ls(),`debug-${e}.log`)}Ou(Du(Or),{recursive:!0})}function ge(...t){he({event:"legacy",msg:t.join(" ")})}function ne(...t){he({event:"legacy",msg:t.join(" ")},{verbose:!0})}function R(t){he(t,{always:!0})}function $u(){return ju()||Bu()}function ju(){try{let t=xo(Dr(ls(),"config.toml"),"utf-8");for(let e of t.split(`
|
|
398
|
+
`)){let r=e.trim();if(!r||r.startsWith("#"))continue;if(r.startsWith("["))break;let n=/^debug\s*=\s*(.+)$/.exec(r);if(n){let s=n[1].trim().toLowerCase().replace(/^["']|["']$/g,"");return s==="true"||s==="1"}}}catch{}return!1}function Bu(){try{let t=xo(Dr(ls(),"config.json"),"utf-8"),e=JSON.parse(t);return e!==null&&typeof e=="object"&&!Array.isArray(e)&&e.debug===!0}catch{}return!1}var Mr="lmctl",Fr="lmctl0",Ku={existsSync:Wu,mkdirSync:Hu,readFileSync:Xu,writeFileSync:Ju,renameSync:qu,unlinkSync:Gu},Se=Ku,cs;function ko(t,e,r){let n=Gt(Vu(r)),s=new Set,i=new Map;for(let o of e.members){if(s.add(o.provider),o.teamfile!==void 0)continue;let a=o.sessiondir??n,l=i.get(a)??new Set;l.add(o.provider),i.set(a,l)}for(let[o,a]of i.entries())Ne(le(o,".mcp.json"),"mcpServers",[Be(),We()]),a.has("opencode")&&Ne(le(o,".opencode","opencode.json"),"mcp",[Lo(),Co()]),a.has("kimi")&&Ne(le(o,".kimi-code","mcp.json"),"mcpServers",[Be(),We()]);for(let o of s)Zu(o)}function Yu(t=cs??No()){return le(t,".copilot","mcp-config.json")}function zu(t,e){Se.mkdirSync(Gt(t),{recursive:!0});let r=le(Gt(t),`.mcp-config.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);try{Se.writeFileSync(r,`${JSON.stringify(e,null,2)}
|
|
399
|
+
`,"utf8"),Se.renameSync(r,t)}catch(n){try{Se.unlinkSync(r)}catch{}throw n}}function Qu(t,e){Se.mkdirSync(Gt(t),{recursive:!0});let r=le(Gt(t),`.mcp-config.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);try{Se.writeFileSync(r,e,"utf8"),Se.renameSync(r,t)}catch(n){try{Se.unlinkSync(r)}catch{}throw n}}function Ne(t,e,r){try{if(!Se.existsSync(t))return;let n=JSON.parse(Se.readFileSync(t,"utf8"));if(!St(n)||!St(n[e]))return;let s={...n[e]},i=[];for(let{name:o,shouldRemove:a}of r)Object.prototype.hasOwnProperty.call(s,o)&&a(s[o])&&(delete s[o],i.push(o));if(i.length===0)return;n[e]=s,zu(t,n),R({event:"mcp_cleanup",path:t,removed:i})}catch{}}function Be(){return{name:Fr,shouldRemove:am}}function Lo(){return{name:Fr,shouldRemove:lm}}function We(){return{name:Mr,shouldRemove:im}}function Co(){return{name:Mr,shouldRemove:om}}function Zu(t){let e=cs??No();switch(t){case"copilot":Ne(Yu(e),"mcpServers",[Be(),We()]);return;case"claude":Ne(le(e,".claude.json"),"mcpServers",[Be(),We()]);return;case"gemini":Ne(le(e,".gemini","settings.json"),"mcpServers",[Be(),We()]);return;case"qwen":Ne(le(e,".qwen","settings.json"),"mcpServers",[Be(),We()]);return;case"agy":Ne(le(e,".gemini","antigravity-cli","settings.json"),"mcpServers",[Be(),We()]);return;case"opencode":Ne(le(e,".config","opencode","opencode.json"),"mcp",[Lo(),Co()]);return;case"kimi":Ne(le(cs===void 0?process.env.KIMI_CODE_HOME??le(e,".kimi-code"):le(e,".kimi-code"),"mcp.json"),"mcpServers",[Be(),We()]);return;case"codex":em(le(e,".codex","config.toml"));return;default:return}}function em(t){try{if(!Se.existsSync(t))return;let e=Se.readFileSync(t,"utf8"),r=tm(e);if(r===null)return;let n=e.split(/\n/),s=[],i=new Set,o=!1,a;for(let l of n){let c=Oo(l);if(c===null)return;if(c!==void 0){if(bo(c,r)){o=!0,a=c[1],i.add(a);continue}o=!1,a=void 0,s.push(l);continue}if(o){if(/^\s*(?:#.*)?$/.test(l)){s.push(l);continue}a!==void 0&&i.add(a);continue}let u=nm(l);if(u===null)return;if(u!==void 0&&bo(u,r)){i.add(u[1]);continue}s.push(l)}if(i.size===0)return;Qu(t,s.join(`
|
|
400
|
+
`)),R({event:"mcp_cleanup",path:t,removed:[...i]})}catch{}}function bo(t,e){return t.length<2||t[0]!=="mcp_servers"?!1:e.has(t[1])}function tm(t){let e=new Map,r;for(let s of t.split(/\n/)){let i=Oo(s);if(i===null)return null;if(i!==void 0){r=i;continue}let o=s.indexOf("=");if(o<0)continue;let a=s.slice(0,o).trim(),l=s.slice(o+1).trim(),c=rm(a,r);if(c===null)return null;if(c===void 0||c.length!==3||c[0]!=="mcp_servers"||c[1]!==Mr&&c[1]!==Fr)continue;let u=e.get(c[1])??{};if(c[2]==="command"){let d=Do(l);if(d===null)return null;u.command=d}else if(c[2]==="args"){let d=sm(l);if(d===null)return null;u.args=d}e.set(c[1],u)}let n=new Set;for(let[s,i]of e.entries())s===Mr&&Fo(i.command,i.args)&&n.add(s),s===Fr&&Po(i.command,i.args)&&n.add(s);return n}function rm(t,e){if(t.startsWith("mcp_servers"))return Pr(t);if(e===void 0||e.length<2||e[0]!=="mcp_servers")return;let r=Pr(t);return r===null?null:[...e,...r]}function Oo(t){if(!/^\s*\[/.test(t))return;let e=/^\s*\[([^\]\r\n]+)\]\s*(?:#.*)?$/.exec(t);return e===null?null:Pr(e[1])}function nm(t){let e=t.indexOf("=");if(e<0)return;let r=t.slice(0,e).trim();if(!(r.length===0||!r.startsWith("mcp_servers")))return Pr(r)}function Pr(t){let e=[],r=0,n=()=>{for(;r<t.length&&/\s/.test(t[r]);)r+=1};for(;r<t.length;){if(n(),r>=t.length)return null;if(t[r]==='"'){r+=1;let s="",i=!1;for(;r<t.length;){let o=t[r];if(o==="\\"){if(r+1>=t.length)return null;s+=t[r+1],r+=2;continue}if(o==='"'){r+=1,i=!0;break}s+=o,r+=1}if(!i)return null;e.push(s)}else{let s=r;for(;r<t.length&&/[A-Za-z0-9_-]/.test(t[r]);)r+=1;if(r===s)return null;e.push(t.slice(s,r))}if(n(),r>=t.length)break;if(t[r]!==".")return null;r+=1}return e.length>0?e:null}function Do(t){let e=Mo(t).trim();if(e.startsWith('"'))try{let r=JSON.parse(e);return typeof r=="string"?r:null}catch{return null}return e.startsWith("'")&&e.endsWith("'")&&e.length>=2?e.slice(1,-1):null}function sm(t){let e=Mo(t).trim();if(!e.startsWith("[")||!e.endsWith("]"))return null;let r=e.slice(1,-1).trim();if(r.length===0)return[];let n=r.split(",").map(s=>Do(s.trim()));return n.some(s=>s===null)?null:n}function Mo(t){let e;for(let r=0;r<t.length;r+=1){let n=t[r];if(e!==void 0){if(e==='"'&&n==="\\"){r+=1;continue}n===e&&(e=void 0);continue}if(n==='"'||n==="'"){e=n;continue}if(n==="#")return t.slice(0,r)}return t}function im(t){return St(t)?t.type==="stdio"&&typeof t.command=="string"&&Fo(t.command,t.args):!1}function om(t){return!St(t)||!Array.isArray(t.command)?!1:t.command.length===2&&typeof t.command[0]=="string"&&typeof t.command[1]=="string"&&$o(t.command[0])&&t.command[1]==="mcp"||t.command.length===3&&typeof t.command[0]=="string"&&typeof t.command[1]=="string"&&typeof t.command[2]=="string"&&Uo(t.command[0],[t.command[1],t.command[2]])}function am(t){return St(t)?t.type==="stdio"&&Po(t.command,t.args):!1}function lm(t){return!St(t)||!Array.isArray(t.command)?!1:t.command.length===2&&typeof t.command[0]=="string"&&typeof t.command[1]=="string"&&jo(t.command[0])&&t.command[1]==="mcp"}function Fo(t,e){return $o(t)&&Bo(e)||Uo(t,e)}function Po(t,e){return jo(t)&&Bo(e)}function Uo(t,e){return cm(t)&&Array.isArray(e)&&e.length===2&&dm(e[0])&&e[1]==="mcp"}function $o(t){return typeof t=="string"&&ds(t)==="lmctl"}function jo(t){return typeof t=="string"&&ds(t)==="lmctl0"}function cm(t){if(typeof t!="string")return!1;let e=ds(t).toLowerCase();return e==="node"||e==="node.exe"}function dm(t){if(typeof t!="string")return!1;let e=t.replace(/\\/g,"/");return e==="lmctl-cli/dist/index.js"||e.endsWith("/lmctl-cli/dist/index.js")}function ds(t){let e=t.replace(/\\/g,"/");return e.split("/").filter(n=>n.length>0).at(-1)??e}function Bo(t){return Array.isArray(t)&&t.length===1&&t[0]==="mcp"}function St(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}function Xo(t){let e=Wo(t.registry,t.fromTeamfile);if(e===void 0)return wt(`sender team is not registered in policy graph: ${t.fromTeamfile}`);if(!Ho(e,t.fromAlias))return wt(`sender alias "${t.fromAlias}" not found in ${t.fromTeamfile}`);let r=Wo(t.registry,t.toTeamfile);return r===void 0?wt(`target team is not registered in policy graph: ${t.toTeamfile}`):Ho(r,t.toAlias)?t.toTeamfile===t.fromTeamfile?{allowed:!0,outOfPolicy:!1,reason:"same team"}:e.leadAlias===null?wt(`sender team has no Lead: ${t.fromTeamfile}`):t.fromAlias!==e.leadAlias?wt(`cross-team sends may only originate from Lead; got "${t.fromAlias}" in ${t.fromTeamfile}`):{allowed:!0,outOfPolicy:!1,reason:"cross-team send from Lead"}:wt(`target alias "${t.toAlias}" not found in ${t.toTeamfile}`)}function Wo(t,e){return t.teams.find(r=>r.teamfile===e)}function Ho(t,e){return t.aliases.some(r=>r===e)}function wt(t){return{allowed:!1,outOfPolicy:!0,reason:t}}import{basename as um}from"node:path";var mm=6e4,fm=2,qo=8*60*60*1e3;function Jo(t,e){let r=new Date(e.now.getTime()-vt()).toISOString(),n=Yo(t,r).filter(m=>!m.sender.teamfile.startsWith("prompt:")),s=hm(e.sender,n),i=gm(e.sender,n);i!==null&&i.teamfile===e.root&&!Go(s[0],i)&&s.unshift({...i,at:null});let o={teamfile:e.receiverTeamfile,alias:e.receiverAlias,at:e.now.getTime()},a=[...s,o],l=s.filter(m=>Go(m,o)),c=l.map(m=>m.at).filter(m=>m!==null).sort((m,h)=>h-m)[0]??null,u=c!==null&&e.now.getTime()-c<mm,d=us(e.sender,n).length;return{stop:l.length>=1&&u&&d>=fm,chain:_m(a)}}function Vo(t,e){let r=new Date(e.now.getTime()-vt()).toISOString(),n=Yo(t,r),s=us(e.sender,n);if(s.length===0)return null;let i=s[0];return i.sender.teamfile.startsWith("prompt:")?i.receiver.teamfile:i.sender.teamfile}function vt(t=process.env){let e=t.LMCTL_INFLIGHT_TTL_MS;if(e===void 0||e.trim()==="")return qo;let r=Number(e);return!Number.isFinite(r)||r<=0?qo:r}function Ko(t){return`cross-team cycle detected (${t}); stopping to prevent a runaway loop.`}function pm(t){return{sender:{teamfile:t.sender_teamfile,alias:t.sender_alias},receiver:{teamfile:t.receiver_teamfile,alias:t.receiver_alias},at:Date.parse(t.started_at)}}function Yo(t,e){return t.clearAgentInflightOlderThan(e),t.listAgentInflight().map(pm).filter(r=>Number.isFinite(r.at)&&new Date(r.at).toISOString()>=e).sort((r,n)=>r.at-n.at)}function hm(t,e,r={}){let n=new Map;for(let a of e)n.set(it(a.receiver),a);let s=[{...t,at:null}],i=t,o=new Set([it(t)]);for(let a=0;a<64;a+=1){let l=n.get(it(i));if(l===void 0)break;s[0]={...s[0],at:s[0].at??l.at};let c={...l.sender,at:l.at};if(l.sender.teamfile.startsWith("prompt:")&&r.includePromptSender!==!0)break;let u=it(l.sender);if(o.has(u))break;s.unshift(c),o.add(u),i=l.sender}return s}function us(t,e){let r=it(t),n=new Set([r]),s=[r],i=[];for(let o=0;s.length>0&&o<128;o+=1){let a=s.shift();for(let l of e){let c=it(l.sender),u=it(l.receiver);c!==a&&u!==a||(i.includes(l)||i.push(l),n.has(c)||(n.add(c),s.push(c)),n.has(u)||(n.add(u),s.push(u)))}}return i.sort((o,a)=>o.at-a.at)}function gm(t,e){let r=us(t,e);if(r.length===0)return null;let n=r[0];return n.sender.teamfile.startsWith("prompt:")?n.receiver:n.sender}function Go(t,e){return t.teamfile===e.teamfile&&t.alias===e.alias}function it(t){return`${t.teamfile}\0${t.alias}`}function _m(t){return t.map(e=>`${um(e.teamfile)}:${e.alias}`).join(" \u2192 ")}import{randomUUID as ka}from"node:crypto";import{existsSync as Ma,mkdirSync as ff,renameSync as pf,rmdirSync as hf}from"node:fs";import{hostname as vs}from"node:os";import{existsSync as Em}from"node:fs";import{createRequire as ym}from"node:module";var ms=null;function Tm(){return ms===null&&(ms=ym(import.meta.url)("node:sqlite").DatabaseSync),ms}var ps=class{name;handle;transactionDepth=0;savepointId=0;constructor(e,r={}){if(r.fileMustExist===!0&&e!==":memory:"&&!Em(e))throw new Error("unable to open database file");this.name=e,this.handle=new(Tm())(e,{readOnly:r.readonly===!0}),this.exec("PRAGMA busy_timeout = 5000")}prepare(e){return new hs(this.handle.prepare(e))}exec(e){this.handle.exec(e),this.updateTransactionDepth(e)}pragma(e,r){let n=`PRAGMA ${e}`;if(e.includes("=")){this.exec(n);return}let s=this.prepare(n).get();return r?.simple===!0?s===void 0?void 0:Object.values(s)[0]:s}transaction(e){return(...r)=>{if(this.transactionDepth===0){this.exec("BEGIN");try{let s=e(...r);return this.exec("COMMIT"),s}catch(s){throw this.inTransaction&&this.exec("ROLLBACK"),s}}let n=`lmctl_sp_${this.savepointId+=1}`;this.exec(`SAVEPOINT ${n}`);try{let s=e(...r);return this.exec(`RELEASE ${n}`),s}catch(s){throw this.inTransaction&&(this.exec(`ROLLBACK TO ${n}`),this.exec(`RELEASE ${n}`)),s}}}get inTransaction(){return this.transactionDepth>0}close(){this.handle.close()}updateTransactionDepth(e){let r=e.trim().match(/^([A-Za-z]+)/)?.[1]?.toUpperCase();if(r!==void 0){if(r==="BEGIN"||r==="SAVEPOINT"){this.transactionDepth+=1;return}if(r==="COMMIT"){this.transactionDepth=Math.max(0,this.transactionDepth-1);return}if(r==="RELEASE"){this.transactionDepth=Math.max(0,this.transactionDepth-1);return}r==="ROLLBACK"&&!/^ROLLBACK\s+TO\b/i.test(e.trim())&&(this.transactionDepth=0)}}},Ur=ps,hs=class{handle;rawMode=!1;constructor(e){this.handle=e,this.handle.setAllowBareNamedParameters(!0)}get(...e){let r=this.handle.get(...fs(e));return this.normalizeRow(r)}all(...e){return this.handle.all(...fs(e)).map(r=>this.normalizeRow(r))}run(...e){let r=this.handle.run(...fs(e));return{changes:Number(r.changes),lastInsertRowid:Number(r.lastInsertRowid)}}raw(){return this.rawMode=!0,this}normalizeRow(e){return e==null?e:this.rawMode&&gs(e)?Object.values(e):gs(e)?{...e}:e}};function fs(t){return t.length===1&&Sm(t[0])?[t[0]]:t}function Sm(t){if(!gs(t))return!1;let e=Object.getPrototypeOf(t);return e===Object.prototype||e===null}function gs(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}import{existsSync as Cm,mkdirSync as Om,readFileSync as ea}from"node:fs";import{randomUUID as Dm}from"node:crypto";import{homedir as Mm}from"node:os";import{dirname as ta,join as Fm,resolve as ra}from"node:path";import{fileURLToPath as Pm,pathToFileURL as Um}from"node:url";import{createHash as Im}from"node:crypto";import{createHash as wm}from"node:crypto";function vm(t,e,r){return wm("sha256").update(`${t}\0${e}\0${r}`).digest("hex")}function ue(t,e,r){let n=vm(e.stream_id,e.intentKey??e.event_type,e.observedLastSeq),s=t.prepare(`INSERT INTO message_event (event_id, ts, stream_id, event_type, payload)
|
|
401
|
+
VALUES (?, ?, ?, ?, ?)
|
|
402
|
+
ON CONFLICT(event_id) DO NOTHING`),i=t.prepare("SELECT seq FROM message_event WHERE event_id = ?");return t.transaction(()=>{let a=s.run(n,e.ts??new Date().toISOString(),e.stream_id,e.event_type,JSON.stringify(e.payload));if(a.changes===0)return{appended:!1,seq:i.get(n).seq,event_id:n};let l=Number(a.lastInsertRowid);return r(l),{appended:!0,seq:l,event_id:n}})()}var H={CREATE:"CREATE",ENQUEUE:"ENQUEUE",DELIVER_CLAIM:"DELIVER_CLAIM",DELIVER_CLAIM_RELEASE:"DELIVER_CLAIM_RELEASE",DELIVERED:"DELIVERED",HANDLED:"HANDLED",WAIT_REGISTER:"WAIT_REGISTER",RESPONSE_CREATE:"RESPONSE_CREATE",RESPONSE_ENQUEUE:"RESPONSE_ENQUEUE",RESPONSE_DELIVERED:"RESPONSE_DELIVERED",INFLIGHT_TAKE:"INFLIGHT_TAKE",INFLIGHT_RELEASE:"INFLIGHT_RELEASE",INFLIGHT_RECLAIM:"INFLIGHT_RECLAIM",TERMINAL_LOCK_TAKE:"TERMINAL_LOCK_TAKE",TERMINAL_LOCK_RELEASE:"TERMINAL_LOCK_RELEASE",TERMINAL_LOCK_EXPIRE:"TERMINAL_LOCK_EXPIRE",INVOCATION_START:"INVOCATION_START",INVOCATION_FINISH:"INVOCATION_FINISH",INVOCATION_NOTIFY_CLAIM:"INVOCATION_NOTIFY_CLAIM"};function ot(t,e){return t==null?null:{teamfile:t,alias:e??""}}function Am(t,e,r){return`lease_${Im("sha256").update(`${t}\0${e}\0${r}`).digest("hex").slice(0,16)}`}function $r(t,e,r,n){r.forEach((s,i)=>{ue(t,{stream_id:e,event_type:s.event_type,payload:s.payload,observedLastSeq:i,ts:s.ts},()=>{}).appended?n.appended+=1:n.skipped+=1})}function xm(t){let e=`msg_tcl_${t.id}`,r=ot(t.sender_teamfile,t.sender_alias),n=ot(t.receiver_teamfile,t.receiver_alias),s={table:"team_chat_log",id:t.id},i={message_id:e,sender:r,receiver:n,root_teamfile:t.root_teamfile,legacy:s},o=[{event_type:H.CREATE,ts:t.created_at,payload:{...i,message_type:"request",content:t.message,origin:t.origin,correlation_status:"legacy-unavailable"}}];return t.status!=="running"&&o.push({event_type:H.HANDLED,ts:t.created_at,payload:{...i,outcome:t.status,receipt:t.response,error:t.error_detail,truncated:t.truncated===1}}),{streamId:e,events:o}}function Rm(t){let e=`msg_mbx_${t.id}`,r=ot(t.sender_teamfile,t.sender_alias),n=ot(t.receiver_teamfile,t.receiver_alias),s={table:"agent_mailbox",id:t.id},i={message_id:e,sender:r,receiver:n,root_teamfile:t.root_teamfile,legacy:s},o=[];if(t.message_type==="response"){let a=t.request_mailbox_id!==null?`msg_mbx_${t.request_mailbox_id}`:null;return o.push({event_type:H.RESPONSE_CREATE,ts:t.created_at,payload:{...i,message_type:"response",content:t.payload,in_reply_to_message_id:a,correlation_status:"legacy-unavailable"}}),o.push({event_type:H.RESPONSE_ENQUEUE,ts:t.created_at,payload:{...i,message_type:"response",in_reply_to_message_id:a}}),t.delivered_at!==null&&o.push({event_type:H.RESPONSE_DELIVERED,ts:t.delivered_at,payload:{...i,message_type:"response",receipt:t.receipt}}),{streamId:e,events:o}}return o.push({event_type:H.CREATE,ts:t.created_at,payload:{...i,message_type:"request",content:t.payload,correlation_status:"legacy-unavailable"}}),o.push({event_type:H.ENQUEUE,ts:t.created_at,payload:{...i,message_type:"request"}}),t.waited_at!==null&&o.push({event_type:H.WAIT_REGISTER,ts:t.waited_at,payload:{...i,waited_by:t.waited_by}}),(t.delivering_at!==null||t.delivery_holder_pid!==null)&&o.push({event_type:H.DELIVER_CLAIM,ts:t.delivering_at??t.created_at,payload:{...i,pid:t.delivery_holder_pid,host:t.delivery_holder_host}}),t.delivered_at!==null&&o.push({event_type:H.DELIVERED,ts:t.delivered_at,payload:{...i,receipt:t.receipt}}),{streamId:e,events:o}}function bm(t){let e=`inv_${t.id}`,r=ot(t.target_teamfile,t.target_alias),n={table:"tracked_invocation",id:t.id},s=[{event_type:H.INVOCATION_START,ts:t.started_at,payload:{invocation_id:e,kind:t.kind,origin:t.origin,launch_source:t.launch_source,from_identity:t.from_identity,target:r,root_teamfile:t.root_teamfile,scope_teamfile:t.scope_teamfile,cwd:t.cwd,command:t.command,request_payload:t.request_payload,started_at:t.started_at,request_message_id:t.team_chat_log_id!==null?`msg_tcl_${t.team_chat_log_id}`:null,holder_pid:t.holder_pid,holder_host:t.holder_host,legacy:n}}];return t.notified_by!==null&&s.push({event_type:H.INVOCATION_NOTIFY_CLAIM,ts:t.notified_at??t.started_at,payload:{invocation_id:e,notified_by:t.notified_by,notified_at:t.notified_at,legacy:n}}),t.status!=="running"&&s.push({event_type:H.INVOCATION_FINISH,ts:t.ended_at??t.started_at,payload:{invocation_id:e,status:t.status,ended_at:t.ended_at,exit_code:t.exit_code,signal:t.signal,result_summary:t.result_summary,error:t.error,legacy:n}}),{streamId:e,events:s}}function Nm(t){let e=Am(t.receiver_teamfile,t.receiver_alias,t.started_at),r=ot(t.receiver_teamfile,t.receiver_alias),n=ot(t.sender_teamfile,t.sender_alias);return{streamId:e,events:[{event_type:H.INFLIGHT_TAKE,ts:t.started_at,payload:{lease_id:e,receiver:r,sender:n,holder_pid:t.holder_pid,holder_host:null,started_at:t.started_at,legacy:{table:"agent_inflight",receiver_teamfile:t.receiver_teamfile,receiver_alias:t.receiver_alias}}}]}}function jr(t,e){return t.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?").get(e)!==void 0}function zo(t){let e={appended:0,skipped:0},r={team_chat_log:0,agent_mailbox:0,tracked_invocation:0,agent_inflight:0};t.transaction(()=>{if(jr(t,"team_chat_log"))for(let i of t.prepare("SELECT * FROM team_chat_log ORDER BY id").all()){let o=e.appended+e.skipped,{streamId:a,events:l}=xm(i);$r(t,a,l,e),r.team_chat_log+=e.appended+e.skipped-o}if(jr(t,"agent_mailbox"))for(let i of t.prepare("SELECT * FROM agent_mailbox ORDER BY id").all()){let o=e.appended+e.skipped,{streamId:a,events:l}=Rm(i);$r(t,a,l,e),r.agent_mailbox+=e.appended+e.skipped-o}if(jr(t,"tracked_invocation"))for(let i of t.prepare("SELECT * FROM tracked_invocation ORDER BY id").all()){let o=e.appended+e.skipped,{streamId:a,events:l}=bm(i);$r(t,a,l,e),r.tracked_invocation+=e.appended+e.skipped-o}if(jr(t,"agent_inflight"))for(let i of t.prepare("SELECT * FROM agent_inflight ORDER BY receiver_teamfile, receiver_alias").all()){let o=e.appended+e.skipped,{streamId:a,events:l}=Nm(i);$r(t,a,l,e),r.agent_inflight+=e.appended+e.skipped-o}km(t)})();let s=i=>t.prepare(`SELECT count(*) AS n FROM ${i}`).get().n;return{appended:e.appended,skipped:e.skipped,bySource:r,projections:{agent_state:s("agent_state"),message_pending:s("message_pending"),invocation_state:s("invocation_state")}}}function km(t){t.exec("DELETE FROM agent_state"),t.exec("DELETE FROM message_pending"),t.exec("DELETE FROM invocation_state");let e=t.prepare("SELECT seq, stream_id, event_type, payload FROM message_event ORDER BY seq").all();for(let r of e){let n=JSON.parse(r.payload);Lm(t,r.seq,r.stream_id,r.event_type,n)}}function ee(t,e,r){let n=t[e];return n!=null?n[r]??null:null}function Lm(t,e,r,n,s){switch(n){case H.ENQUEUE:case H.RESPONSE_ENQUEUE:{let i=n===H.RESPONSE_ENQUEUE;t.prepare(`INSERT INTO message_pending
|
|
403
|
+
(message_id, message_type, in_reply_to, sender_teamfile, sender_alias,
|
|
404
|
+
receiver_teamfile, receiver_alias, lifecycle_state, created_seq, last_seq)
|
|
405
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, 'queued', ?, ?)
|
|
406
|
+
ON CONFLICT(message_id) DO UPDATE SET lifecycle_state='queued', last_seq=excluded.last_seq`).run(r,i?"response":"request",i?s.in_reply_to_message_id??null:null,ee(s,"sender","teamfile"),ee(s,"sender","alias"),ee(s,"receiver","teamfile"),ee(s,"receiver","alias"),e,e);break}case H.DELIVER_CLAIM:t.prepare(`UPDATE message_pending SET lifecycle_state='claimed', delivery_lease_id=?, delivery_holder_pid=?, last_seq=?
|
|
407
|
+
WHERE message_id=?`).run(s.lease_id??null,s.pid??null,e,r);break;case H.DELIVER_CLAIM_RELEASE:t.prepare(`UPDATE message_pending
|
|
408
|
+
SET lifecycle_state='queued', delivery_lease_id=NULL,
|
|
409
|
+
delivery_holder_pid=NULL, last_seq=?
|
|
410
|
+
WHERE message_id=?`).run(e,r);break;case H.DELIVERED:case H.RESPONSE_DELIVERED:t.prepare("DELETE FROM message_pending WHERE message_id=?").run(r);break;case H.INFLIGHT_TAKE:t.prepare(`INSERT INTO agent_state
|
|
411
|
+
(receiver_teamfile, receiver_alias, lease_id, sender_teamfile, sender_alias, holder_pid, holder_host, started_at, last_seq)
|
|
412
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
413
|
+
ON CONFLICT(receiver_teamfile, receiver_alias) DO UPDATE SET
|
|
414
|
+
lease_id=excluded.lease_id, sender_teamfile=excluded.sender_teamfile, sender_alias=excluded.sender_alias,
|
|
415
|
+
holder_pid=excluded.holder_pid, holder_host=excluded.holder_host, started_at=excluded.started_at, last_seq=excluded.last_seq`).run(ee(s,"receiver","teamfile"),ee(s,"receiver","alias"),s.lease_id??null,ee(s,"sender","teamfile"),ee(s,"sender","alias"),s.holder_pid??null,s.holder_host??null,s.started_at??null,e);break;case H.INFLIGHT_RELEASE:t.prepare("DELETE FROM agent_state WHERE receiver_teamfile=? AND receiver_alias=? AND terminal_lock_id IS NULL AND terminal_invocation_id IS NULL").run(ee(s,"receiver","teamfile"),ee(s,"receiver","alias"));break;case H.INFLIGHT_RECLAIM:t.prepare(`UPDATE agent_state SET lease_id=?, sender_teamfile=?, sender_alias=?, holder_pid=?, holder_host=?, last_seq=?
|
|
416
|
+
WHERE receiver_teamfile=? AND receiver_alias=?`).run(s.lease_id??null,ee(s,"sender","teamfile"),ee(s,"sender","alias"),s.holder_pid??null,s.holder_host??null,e,ee(s,"receiver","teamfile"),ee(s,"receiver","alias"));break;case H.TERMINAL_LOCK_TAKE:t.prepare(`INSERT INTO agent_state
|
|
417
|
+
(receiver_teamfile, receiver_alias, terminal_lock_id, last_seq)
|
|
418
|
+
VALUES (?, ?, ?, ?)
|
|
419
|
+
ON CONFLICT(receiver_teamfile, receiver_alias) DO UPDATE SET
|
|
420
|
+
terminal_lock_id=excluded.terminal_lock_id, last_seq=excluded.last_seq`).run(ee(s,"receiver","teamfile"),ee(s,"receiver","alias"),s.lock_id??r,e);break;case H.TERMINAL_LOCK_RELEASE:case H.TERMINAL_LOCK_EXPIRE:t.prepare(`UPDATE agent_state SET terminal_lock_id=NULL, last_seq=?
|
|
421
|
+
WHERE receiver_teamfile=? AND receiver_alias=?`).run(e,ee(s,"receiver","teamfile"),ee(s,"receiver","alias"));break;case H.INVOCATION_START:t.prepare(`INSERT INTO invocation_state
|
|
422
|
+
(invocation_id, kind, origin, launch_source, from_identity, target_teamfile, target_alias, root_teamfile,
|
|
423
|
+
cwd, command, request_message_id, request_payload, holder_pid, holder_host, status, started_at, last_seq)
|
|
424
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'running', ?, ?)
|
|
425
|
+
ON CONFLICT(invocation_id) DO NOTHING`).run(r,s.kind??"chat",s.origin??"unknown",s.launch_source??"",s.from_identity??"",ee(s,"target","teamfile"),ee(s,"target","alias"),s.root_teamfile??null,s.cwd??null,s.command??null,s.request_message_id??null,s.request_payload??null,s.holder_pid??null,s.holder_host??null,s.started_at??"",e);break;case H.INVOCATION_FINISH:t.prepare(`UPDATE invocation_state SET status=?, ended_at=?, result_summary=?, error=?, last_seq=?
|
|
426
|
+
WHERE invocation_id=?`).run(s.status??"done",s.ended_at??null,s.result_summary??null,s.error??null,e,r);break;case H.INVOCATION_NOTIFY_CLAIM:t.prepare("UPDATE invocation_state SET notified_by=?, notified_at=?, last_seq=? WHERE invocation_id=?").run(s.notified_by??null,s.notified_at??null,e,r);break;default:break}}var na=ta(Pm(import.meta.url)),sa=ra(na,"schema.sql"),$m=ra(na,"migrations"),Xe=61,Jt=class extends Error{dbPath;dbVersion;buildVersion;constructor(e,r,n=Xe){super(`${e}: state.db is v${r}; this build understands v${n} -- refusing to proceed rather than risk misreading newer data or corrupting it. Update: npm install -g @lmctl-ai/lmctl@latest -- or, only if you must run THIS exact build against this db right now, re-run with --allow-schema-skew (best-effort; newer data/features may be invisible).`),this.name="SchemaSkewError",this.dbPath=e,this.dbVersion=r,this.buildVersion=n}};function Br(t){t.dbPath!==":memory:"&&Om(ta(t.dbPath),{recursive:!0});let e=new Ur(t.dbPath);try{e.pragma("journal_mode = WAL"),e.pragma("synchronous = NORMAL"),e.pragma("foreign_keys = ON");let r=ia(e),n=t.buildVersionForTests??Xe;if(r===0)e.exec(ea(sa,"utf8")),e.pragma(`user_version = ${Xe}`);else if(r>n){let s=Wm(e,r);if(Xm={dbVersion:r,buildVersion:n},s>n&&!t.allowSchemaSkew)throw e.close(),new Jt(t.dbPath,r,n);return Hm(t.dbPath,r,n),e}return jm(e,r),Bm(e),e}catch(r){try{e.close()}catch{}throw r}}function jm(t,e){let r=e;if(r<2&&r!==0&&(t.exec(`
|
|
427
|
+
CREATE TABLE IF NOT EXISTS session_size (
|
|
428
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
429
|
+
team_name TEXT NOT NULL,
|
|
430
|
+
alias TEXT NOT NULL,
|
|
431
|
+
sessionid TEXT NOT NULL,
|
|
432
|
+
input_tokens INTEGER,
|
|
433
|
+
cache_tokens INTEGER,
|
|
434
|
+
output_tokens INTEGER,
|
|
435
|
+
total_tokens INTEGER,
|
|
436
|
+
observed_at TEXT NOT NULL
|
|
437
|
+
);
|
|
438
|
+
CREATE INDEX IF NOT EXISTS idx_session_size_member ON session_size(team_name, alias, observed_at DESC);
|
|
439
|
+
CREATE INDEX IF NOT EXISTS idx_session_size_session ON session_size(sessionid, observed_at DESC);
|
|
440
|
+
CREATE INDEX IF NOT EXISTS idx_session_size_observed ON session_size(observed_at DESC);
|
|
441
|
+
`),t.pragma("user_version = 2"),r=2),r<3&&r!==0&&(t.prepare("PRAGMA table_info(project)").all().some(s=>s.name==="intake_config")||t.exec("ALTER TABLE project ADD COLUMN intake_config TEXT"),t.pragma("user_version = 3"),r=3),r<4&&r!==0&&(t.prepare("PRAGMA table_info(job)").all().some(s=>s.name==="concurrency_key_resolved")||t.exec("ALTER TABLE job ADD COLUMN concurrency_key_resolved TEXT"),t.exec("CREATE INDEX IF NOT EXISTS idx_job_concurrency_running ON job(concurrency_key_resolved, status)"),t.pragma("user_version = 4"),r=4),r<5&&r!==0&&(t.prepare("PRAGMA table_info(run)").all().some(s=>s.name==="paused_at")||t.exec("ALTER TABLE run ADD COLUMN paused_at TEXT"),t.pragma("user_version = 5"),r=5),r<6&&r!==0&&(t.prepare("PRAGMA table_info(attention)").all().some(s=>s.name==="requires_user")||t.exec("ALTER TABLE attention ADD COLUMN requires_user INTEGER NOT NULL DEFAULT 0"),t.pragma("user_version = 6"),r=6),r<7&&r!==0&&(t.prepare("PRAGMA table_info(project)").all().some(s=>s.name==="test_argv")||t.exec("ALTER TABLE project ADD COLUMN test_argv TEXT"),t.exec(`
|
|
442
|
+
CREATE TABLE IF NOT EXISTS candidate_issue (
|
|
443
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
444
|
+
triage_run_id INTEGER NOT NULL REFERENCES run(id),
|
|
445
|
+
repo TEXT NOT NULL,
|
|
446
|
+
issue_url TEXT NOT NULL,
|
|
447
|
+
issue_number INTEGER NOT NULL,
|
|
448
|
+
title TEXT,
|
|
449
|
+
status TEXT NOT NULL,
|
|
450
|
+
reason TEXT,
|
|
451
|
+
confidence REAL,
|
|
452
|
+
local_path TEXT,
|
|
453
|
+
likely_files TEXT,
|
|
454
|
+
test_command TEXT,
|
|
455
|
+
lmdedup_summary TEXT,
|
|
456
|
+
created_at TEXT NOT NULL,
|
|
457
|
+
approved_at TEXT,
|
|
458
|
+
fix_job_id INTEGER REFERENCES job(id),
|
|
459
|
+
UNIQUE(triage_run_id, issue_url)
|
|
460
|
+
);
|
|
461
|
+
CREATE INDEX IF NOT EXISTS idx_candidate_issue_run ON candidate_issue(triage_run_id);
|
|
462
|
+
CREATE INDEX IF NOT EXISTS idx_candidate_issue_status ON candidate_issue(status);
|
|
463
|
+
|
|
464
|
+
CREATE TABLE IF NOT EXISTS submitted_pr (
|
|
465
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
466
|
+
repo TEXT NOT NULL,
|
|
467
|
+
pr_url TEXT NOT NULL UNIQUE,
|
|
468
|
+
issue_url TEXT,
|
|
469
|
+
local_path TEXT,
|
|
470
|
+
branch TEXT,
|
|
471
|
+
head_sha TEXT,
|
|
472
|
+
status TEXT NOT NULL DEFAULT 'watching',
|
|
473
|
+
submitted_at TEXT NOT NULL,
|
|
474
|
+
last_scanned_at TEXT,
|
|
475
|
+
last_followup_at TEXT,
|
|
476
|
+
last_known_state TEXT,
|
|
477
|
+
last_known_checks TEXT,
|
|
478
|
+
last_known_review TEXT,
|
|
479
|
+
visibility_status TEXT,
|
|
480
|
+
created_by_run_id INTEGER REFERENCES run(id)
|
|
481
|
+
);
|
|
482
|
+
CREATE INDEX IF NOT EXISTS idx_submitted_pr_status ON submitted_pr(status);
|
|
483
|
+
CREATE INDEX IF NOT EXISTS idx_submitted_pr_scanned ON submitted_pr(last_scanned_at);
|
|
484
|
+
|
|
485
|
+
CREATE TABLE IF NOT EXISTS pr_followup_event (
|
|
486
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
487
|
+
submitted_pr_id INTEGER NOT NULL REFERENCES submitted_pr(id),
|
|
488
|
+
run_id INTEGER REFERENCES run(id),
|
|
489
|
+
event_kind TEXT NOT NULL,
|
|
490
|
+
source_url TEXT,
|
|
491
|
+
actor TEXT,
|
|
492
|
+
author_association TEXT,
|
|
493
|
+
body_hash TEXT,
|
|
494
|
+
classification TEXT,
|
|
495
|
+
action_required TEXT,
|
|
496
|
+
created_at TEXT NOT NULL,
|
|
497
|
+
seen_at TEXT,
|
|
498
|
+
resolved_at TEXT,
|
|
499
|
+
UNIQUE(submitted_pr_id, body_hash)
|
|
500
|
+
);
|
|
501
|
+
CREATE INDEX IF NOT EXISTS idx_pr_followup_event_pr ON pr_followup_event(submitted_pr_id);
|
|
502
|
+
CREATE INDEX IF NOT EXISTS idx_pr_followup_event_kind ON pr_followup_event(event_kind);
|
|
503
|
+
`),t.pragma("user_version = 7"),r=7),r<8&&r!==0&&(t.prepare("PRAGMA table_info(step_artifact)").all().some(s=>s.name==="provider_call_mode")||t.exec("ALTER TABLE step_artifact ADD COLUMN provider_call_mode TEXT"),t.pragma("user_version = 8"),r=8),r<9&&r!==0){let n=j(t,"team_member");n.has("state")||t.exec("ALTER TABLE team_member ADD COLUMN state TEXT NOT NULL DEFAULT 'idle' CHECK(state IN ('idle','in_chat','attention_needed','retired'))"),n.has("state_reason")||t.exec("ALTER TABLE team_member ADD COLUMN state_reason TEXT"),n.has("state_updated_at")||t.exec("ALTER TABLE team_member ADD COLUMN state_updated_at TEXT"),n.has("role_prompt")||t.exec("ALTER TABLE team_member ADD COLUMN role_prompt TEXT"),n.has("prompt_snapshot")||t.exec("ALTER TABLE team_member ADD COLUMN prompt_snapshot TEXT"),j(t,"team").has("lead_seed_prompt")||t.exec("ALTER TABLE team ADD COLUMN lead_seed_prompt TEXT"),j(t,"run").has("parent_run_id")||t.exec("ALTER TABLE run ADD COLUMN parent_run_id INTEGER REFERENCES run(id)"),j(t,"project").has("memory_mode")||t.exec("ALTER TABLE project ADD COLUMN memory_mode TEXT NOT NULL DEFAULT 'folder' CHECK(memory_mode IN ('folder','db'))"),t.pragma("user_version = 9"),r=9}if(r<10&&r!==0&&(t.exec(`
|
|
504
|
+
CREATE TABLE IF NOT EXISTS memory (
|
|
505
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
506
|
+
project_id INTEGER NOT NULL REFERENCES project(id),
|
|
507
|
+
type TEXT NOT NULL CHECK (type IN ('user', 'feedback', 'project', 'reference')),
|
|
508
|
+
name TEXT NOT NULL,
|
|
509
|
+
description TEXT,
|
|
510
|
+
body TEXT NOT NULL,
|
|
511
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
512
|
+
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
513
|
+
UNIQUE(project_id, name)
|
|
514
|
+
);
|
|
515
|
+
CREATE INDEX IF NOT EXISTS idx_memory_project_type ON memory(project_id, type);
|
|
516
|
+
CREATE INDEX IF NOT EXISTS idx_memory_project_name ON memory(project_id, name);
|
|
517
|
+
`),t.pragma("user_version = 10"),r=10),r<11&&r!==0&&(t.exec(`
|
|
518
|
+
CREATE TABLE IF NOT EXISTS session_event (
|
|
519
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
520
|
+
run_id INTEGER NOT NULL REFERENCES run(id),
|
|
521
|
+
step_id INTEGER REFERENCES step(id),
|
|
522
|
+
kind TEXT NOT NULL,
|
|
523
|
+
timestamp_ms INTEGER NOT NULL,
|
|
524
|
+
payload TEXT NOT NULL,
|
|
525
|
+
payload_truncated INTEGER NOT NULL DEFAULT 0,
|
|
526
|
+
overflow_artifact_id INTEGER REFERENCES step_artifact(id)
|
|
527
|
+
);
|
|
528
|
+
CREATE INDEX IF NOT EXISTS idx_session_event_run ON session_event(run_id);
|
|
529
|
+
CREATE INDEX IF NOT EXISTS idx_session_event_kind_step ON session_event(kind, step_id);
|
|
530
|
+
CREATE INDEX IF NOT EXISTS idx_session_event_timestamp ON session_event(timestamp_ms);
|
|
531
|
+
|
|
532
|
+
CREATE TABLE IF NOT EXISTS rollup_stats (
|
|
533
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
534
|
+
run_id INTEGER NOT NULL REFERENCES run(id),
|
|
535
|
+
step_id INTEGER REFERENCES step(id),
|
|
536
|
+
metric_kind TEXT NOT NULL,
|
|
537
|
+
value REAL NOT NULL,
|
|
538
|
+
bucket_start_ms INTEGER NOT NULL,
|
|
539
|
+
bucket_end_ms INTEGER NOT NULL,
|
|
540
|
+
updated_at INTEGER NOT NULL,
|
|
541
|
+
UNIQUE(run_id, step_id, metric_kind, bucket_start_ms)
|
|
542
|
+
);
|
|
543
|
+
CREATE INDEX IF NOT EXISTS idx_rollup_run_metric ON rollup_stats(run_id, metric_kind);
|
|
544
|
+
CREATE INDEX IF NOT EXISTS idx_rollup_bucket ON rollup_stats(bucket_start_ms);
|
|
545
|
+
|
|
546
|
+
CREATE TABLE IF NOT EXISTS drift_signal (
|
|
547
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
548
|
+
team_member_id INTEGER NOT NULL REFERENCES team_member(id),
|
|
549
|
+
project_id INTEGER REFERENCES project(id),
|
|
550
|
+
signal_kind TEXT NOT NULL,
|
|
551
|
+
severity TEXT NOT NULL CHECK (severity IN ('low', 'medium', 'high')),
|
|
552
|
+
description TEXT NOT NULL,
|
|
553
|
+
detected_at INTEGER NOT NULL,
|
|
554
|
+
expires_at INTEGER,
|
|
555
|
+
acknowledged_at INTEGER,
|
|
556
|
+
payload TEXT
|
|
557
|
+
);
|
|
558
|
+
CREATE INDEX IF NOT EXISTS idx_drift_member ON drift_signal(team_member_id);
|
|
559
|
+
CREATE INDEX IF NOT EXISTS idx_drift_unacked ON drift_signal(team_member_id) WHERE acknowledged_at IS NULL;
|
|
560
|
+
|
|
561
|
+
CREATE TABLE IF NOT EXISTS rollup_cursor (
|
|
562
|
+
key TEXT PRIMARY KEY,
|
|
563
|
+
value INTEGER NOT NULL DEFAULT 0
|
|
564
|
+
);
|
|
565
|
+
`),t.pragma("user_version = 11"),r=11),r<12&&r!==0&&(t.exec(`
|
|
566
|
+
CREATE TABLE IF NOT EXISTS interactive_session (
|
|
567
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
568
|
+
run_id INTEGER NOT NULL REFERENCES run(id),
|
|
569
|
+
step_id INTEGER NOT NULL REFERENCES step(id),
|
|
570
|
+
state_name TEXT NOT NULL,
|
|
571
|
+
turn_count INTEGER NOT NULL DEFAULT 0,
|
|
572
|
+
last_agent_output TEXT,
|
|
573
|
+
last_operator_input TEXT,
|
|
574
|
+
status TEXT NOT NULL CHECK (status IN ('waiting_operator', 'waiting_agent', 'done', 'timeout')),
|
|
575
|
+
started_at INTEGER NOT NULL,
|
|
576
|
+
last_activity_at INTEGER NOT NULL,
|
|
577
|
+
UNIQUE(step_id)
|
|
578
|
+
);
|
|
579
|
+
CREATE INDEX IF NOT EXISTS idx_interactive_status ON interactive_session(status);
|
|
580
|
+
CREATE INDEX IF NOT EXISTS idx_interactive_run_state ON interactive_session(run_id, state_name);
|
|
581
|
+
`),t.pragma("user_version = 12"),r=12),r<13&&r!==0&&(t.exec("ALTER TABLE team DROP COLUMN lead_seed_prompt"),t.pragma("user_version = 13"),r=13),r<14&&r!==0&&(t.exec("ALTER TABLE memory RENAME TO durable_memory"),t.exec("ALTER TABLE project RENAME COLUMN memory_mode TO durable_memory_mode"),t.exec("DROP INDEX IF EXISTS idx_memory_project_type"),t.exec("DROP INDEX IF EXISTS idx_memory_project_name"),t.exec("CREATE INDEX IF NOT EXISTS idx_durable_memory_project_type ON durable_memory(project_id, type)"),t.exec("CREATE INDEX IF NOT EXISTS idx_durable_memory_project_name ON durable_memory(project_id, name)"),t.pragma("user_version = 14"),r=14),r<15&&r!==0&&(t.exec(`
|
|
582
|
+
CREATE TABLE IF NOT EXISTS workflow_version (
|
|
583
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
584
|
+
workflow_id INTEGER NOT NULL REFERENCES workflow(id),
|
|
585
|
+
version INTEGER NOT NULL,
|
|
586
|
+
definition TEXT NOT NULL,
|
|
587
|
+
author TEXT,
|
|
588
|
+
created_at TEXT NOT NULL,
|
|
589
|
+
UNIQUE(workflow_id, version)
|
|
590
|
+
);
|
|
591
|
+
CREATE INDEX IF NOT EXISTS idx_workflow_version_wf ON workflow_version(workflow_id, version DESC);
|
|
592
|
+
`),j(t,"workflow").has("active_version_id")||t.exec("ALTER TABLE workflow ADD COLUMN active_version_id INTEGER REFERENCES workflow_version(id)"),j(t,"run").has("workflow_version_id")||t.exec("ALTER TABLE run ADD COLUMN workflow_version_id INTEGER REFERENCES workflow_version(id)"),t.pragma("user_version = 15"),r=15),r<16&&r!==0&&(t.exec(`
|
|
593
|
+
CREATE TABLE IF NOT EXISTS trigger_instance (
|
|
594
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
595
|
+
workflow_id INTEGER NOT NULL REFERENCES workflow(id),
|
|
596
|
+
trigger_id TEXT NOT NULL,
|
|
597
|
+
trigger_type TEXT NOT NULL,
|
|
598
|
+
parameters TEXT NOT NULL,
|
|
599
|
+
enabled INTEGER NOT NULL DEFAULT 1 CHECK(enabled IN (0,1)),
|
|
600
|
+
cursor TEXT,
|
|
601
|
+
last_poll_at TEXT,
|
|
602
|
+
last_failure_at TEXT,
|
|
603
|
+
last_failure TEXT,
|
|
604
|
+
created_at TEXT NOT NULL,
|
|
605
|
+
UNIQUE(workflow_id, trigger_id)
|
|
606
|
+
);
|
|
607
|
+
CREATE INDEX IF NOT EXISTS idx_trigger_instance_wf ON trigger_instance(workflow_id);
|
|
608
|
+
CREATE INDEX IF NOT EXISTS idx_trigger_instance_enabled ON trigger_instance(enabled) WHERE enabled = 1;
|
|
609
|
+
`),j(t,"step").has("parent_step_id")||t.exec("ALTER TABLE step ADD COLUMN parent_step_id INTEGER REFERENCES step(id)"),t.exec("CREATE INDEX IF NOT EXISTS idx_step_parent ON step(parent_step_id)"),t.pragma("user_version = 16"),r=16),r<17&&r!==0&&(t.exec(`
|
|
610
|
+
CREATE TABLE IF NOT EXISTS project_workflow (
|
|
611
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
612
|
+
project_id INTEGER NOT NULL REFERENCES project(id),
|
|
613
|
+
workflow_id INTEGER NOT NULL REFERENCES workflow(id),
|
|
614
|
+
condition TEXT,
|
|
615
|
+
parameters_override TEXT,
|
|
616
|
+
enabled INTEGER NOT NULL DEFAULT 1 CHECK(enabled IN (0,1)),
|
|
617
|
+
priority INTEGER NOT NULL DEFAULT 100,
|
|
618
|
+
created_at TEXT NOT NULL,
|
|
619
|
+
UNIQUE(project_id, workflow_id, condition)
|
|
620
|
+
);
|
|
621
|
+
CREATE INDEX IF NOT EXISTS idx_project_workflow_project ON project_workflow(project_id, enabled);
|
|
622
|
+
`),j(t,"job").has("workflow_id_override")||t.exec("ALTER TABLE job ADD COLUMN workflow_id_override INTEGER REFERENCES workflow(id)"),t.pragma("user_version = 17"),r=17),r<18&&r!==0&&(t.exec(`
|
|
623
|
+
CREATE TABLE IF NOT EXISTS project_issue (
|
|
624
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
625
|
+
project_id INTEGER NOT NULL REFERENCES project(id),
|
|
626
|
+
title TEXT NOT NULL,
|
|
627
|
+
body TEXT NOT NULL,
|
|
628
|
+
status TEXT NOT NULL DEFAULT 'open' CHECK(status IN ('open','assigned','closed','reopened')),
|
|
629
|
+
severity TEXT NOT NULL DEFAULT 'medium' CHECK(severity IN ('low','medium','high','critical')),
|
|
630
|
+
labels TEXT,
|
|
631
|
+
ai_test_path TEXT,
|
|
632
|
+
source_run_id INTEGER REFERENCES run(id),
|
|
633
|
+
assigned_run_id INTEGER REFERENCES run(id),
|
|
634
|
+
closed_run_id INTEGER REFERENCES run(id),
|
|
635
|
+
commit_hash TEXT,
|
|
636
|
+
created_at TEXT NOT NULL,
|
|
637
|
+
updated_at TEXT NOT NULL,
|
|
638
|
+
closed_at TEXT
|
|
639
|
+
);
|
|
640
|
+
CREATE INDEX IF NOT EXISTS idx_project_issue_status
|
|
641
|
+
ON project_issue(project_id, status);
|
|
642
|
+
CREATE INDEX IF NOT EXISTS idx_project_issue_ai_test
|
|
643
|
+
ON project_issue(project_id, ai_test_path) WHERE ai_test_path IS NOT NULL;
|
|
644
|
+
`),t.pragma("user_version = 18"),r=18),r<19&&r!==0&&(t.exec(`
|
|
645
|
+
CREATE TABLE IF NOT EXISTS webui_session (
|
|
646
|
+
session_id TEXT PRIMARY KEY,
|
|
647
|
+
user_id TEXT NOT NULL,
|
|
648
|
+
current_node TEXT NOT NULL,
|
|
649
|
+
node_params TEXT,
|
|
650
|
+
prev_node_stack TEXT,
|
|
651
|
+
pending_form TEXT,
|
|
652
|
+
chatbot_session_id TEXT,
|
|
653
|
+
auth_state TEXT NOT NULL,
|
|
654
|
+
last_transition_at TEXT NOT NULL,
|
|
655
|
+
created_at TEXT NOT NULL
|
|
656
|
+
);
|
|
657
|
+
CREATE INDEX IF NOT EXISTS webui_session_user_idx ON webui_session(user_id);
|
|
658
|
+
|
|
659
|
+
CREATE TABLE IF NOT EXISTS chatbot_session (
|
|
660
|
+
chatbot_session_id TEXT PRIMARY KEY,
|
|
661
|
+
user_id TEXT NOT NULL,
|
|
662
|
+
title TEXT,
|
|
663
|
+
created_at TEXT NOT NULL,
|
|
664
|
+
last_active_at TEXT NOT NULL,
|
|
665
|
+
status TEXT NOT NULL DEFAULT 'active'
|
|
666
|
+
);
|
|
667
|
+
CREATE INDEX IF NOT EXISTS chatbot_session_user_idx ON chatbot_session(user_id, last_active_at DESC);
|
|
668
|
+
|
|
669
|
+
CREATE TABLE IF NOT EXISTS chatbot_message (
|
|
670
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
671
|
+
chatbot_session_id TEXT NOT NULL REFERENCES chatbot_session(chatbot_session_id) ON DELETE CASCADE,
|
|
672
|
+
role TEXT NOT NULL,
|
|
673
|
+
content TEXT NOT NULL,
|
|
674
|
+
tool_calls TEXT,
|
|
675
|
+
created_at TEXT NOT NULL
|
|
676
|
+
);
|
|
677
|
+
CREATE INDEX IF NOT EXISTS chatbot_message_session_idx ON chatbot_message(chatbot_session_id, id);
|
|
678
|
+
`),t.pragma("user_version = 19"),r=19),r<20&&r!==0&&(t.exec(`
|
|
679
|
+
CREATE TABLE IF NOT EXISTS lmctl_config (
|
|
680
|
+
key TEXT PRIMARY KEY,
|
|
681
|
+
value TEXT NOT NULL,
|
|
682
|
+
updated_at TEXT NOT NULL
|
|
683
|
+
);
|
|
684
|
+
`),t.pragma("user_version = 20"),r=20),r<21&&r!==0){let n=j(t,"project");n.has("active_run_id")||t.exec("ALTER TABLE project ADD COLUMN active_run_id INTEGER REFERENCES run(id)"),n.has("active_locked_at")||t.exec("ALTER TABLE project ADD COLUMN active_locked_at TEXT"),n.has("active_locked_by")||t.exec("ALTER TABLE project ADD COLUMN active_locked_by TEXT"),t.pragma("user_version = 21"),r=21}if(r<22&&r!==0&&(j(t,"project").has("active_locked_expires_at")||t.exec("ALTER TABLE project ADD COLUMN active_locked_expires_at TEXT"),t.exec("CREATE INDEX IF NOT EXISTS idx_project_active_lock_expires ON project(active_locked_expires_at) WHERE active_locked_expires_at IS NOT NULL"),t.pragma("user_version = 22"),r=22),r<23&&r!==0){t.exec("DROP INDEX IF EXISTS idx_project_active_lock_expires");let n=j(t,"project");n.has("active_locked_expires_at")&&t.exec("ALTER TABLE project DROP COLUMN active_locked_expires_at"),n.has("active_locked_by")&&t.exec("ALTER TABLE project DROP COLUMN active_locked_by"),n.has("active_locked_at")&&t.exec("ALTER TABLE project DROP COLUMN active_locked_at"),n.has("active_run_id")&&t.exec("ALTER TABLE project DROP COLUMN active_run_id"),t.pragma("user_version = 23"),r=23}if(r<24&&r!==0){let n=j(t,"team_member");n.size>0&&!n.has("provider_resolved")&&t.exec("ALTER TABLE team_member ADD COLUMN provider_resolved TEXT"),t.pragma("user_version = 24"),r=24}if(r<25&&r!==0&&(t.exec(`
|
|
685
|
+
CREATE TABLE IF NOT EXISTS composition_unit (
|
|
686
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
687
|
+
name TEXT NOT NULL,
|
|
688
|
+
version INTEGER NOT NULL,
|
|
689
|
+
lang TEXT NOT NULL,
|
|
690
|
+
source TEXT NOT NULL,
|
|
691
|
+
source_sha TEXT NOT NULL,
|
|
692
|
+
compiled_workflow_version_id INTEGER REFERENCES workflow_version(id),
|
|
693
|
+
created_at TEXT NOT NULL,
|
|
694
|
+
UNIQUE(name, version)
|
|
695
|
+
);
|
|
696
|
+
CREATE INDEX IF NOT EXISTS idx_composition_unit_name ON composition_unit(name, version DESC);
|
|
697
|
+
`),t.pragma("user_version = 25"),r=25),r<26&&r!==0){let n=j(t,"workflow");n.size>0&&!n.has("source_uri")&&t.exec("ALTER TABLE workflow ADD COLUMN source_uri TEXT"),n.size>0&&!n.has("source_sha256")&&t.exec("ALTER TABLE workflow ADD COLUMN source_sha256 TEXT"),t.pragma("user_version = 26"),r=26}if(r<27&&r!==0){let n=j(t,"run");n.size>0&&!n.has("pending_escalation_decision")&&t.exec("ALTER TABLE run ADD COLUMN pending_escalation_decision TEXT"),t.pragma("user_version = 27"),r=27}if(r<28&&r!==0&&(t.exec(`
|
|
698
|
+
CREATE TABLE IF NOT EXISTS prompt_dispatch (
|
|
699
|
+
prompt_id TEXT PRIMARY KEY,
|
|
700
|
+
project_id INTEGER NOT NULL REFERENCES project(id),
|
|
701
|
+
job_id INTEGER NOT NULL REFERENCES job(id),
|
|
702
|
+
text TEXT NOT NULL,
|
|
703
|
+
context_json TEXT,
|
|
704
|
+
created_at TEXT NOT NULL,
|
|
705
|
+
completed_at TEXT
|
|
706
|
+
);
|
|
707
|
+
CREATE INDEX IF NOT EXISTS idx_prompt_dispatch_project ON prompt_dispatch(project_id, created_at DESC);
|
|
708
|
+
CREATE INDEX IF NOT EXISTS idx_prompt_dispatch_job ON prompt_dispatch(job_id);
|
|
709
|
+
`),t.pragma("user_version = 28"),r=28),r<29&&r!==0&&(t.exec(`
|
|
710
|
+
CREATE TABLE IF NOT EXISTS workspace (
|
|
711
|
+
id TEXT PRIMARY KEY,
|
|
712
|
+
name TEXT NOT NULL,
|
|
713
|
+
idle_threshold_ms INTEGER NOT NULL DEFAULT 600000,
|
|
714
|
+
created_at TEXT NOT NULL,
|
|
715
|
+
deleted_at TEXT
|
|
716
|
+
);
|
|
717
|
+
CREATE TABLE IF NOT EXISTS web_project (
|
|
718
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
719
|
+
workspace_id TEXT NOT NULL REFERENCES workspace(id),
|
|
720
|
+
name TEXT NOT NULL,
|
|
721
|
+
repo_path TEXT NOT NULL,
|
|
722
|
+
config_json TEXT,
|
|
723
|
+
linked_v4_project_id INTEGER REFERENCES project(id),
|
|
724
|
+
last_active_at TEXT,
|
|
725
|
+
created_at TEXT NOT NULL,
|
|
726
|
+
deleted_at TEXT
|
|
727
|
+
);
|
|
728
|
+
CREATE INDEX IF NOT EXISTS idx_web_project_workspace ON web_project(workspace_id, deleted_at);
|
|
729
|
+
CREATE INDEX IF NOT EXISTS idx_web_project_v4_link ON web_project(linked_v4_project_id) WHERE linked_v4_project_id IS NOT NULL;
|
|
730
|
+
INSERT OR IGNORE INTO workspace (id, name, idle_threshold_ms, created_at)
|
|
731
|
+
VALUES ('default', 'Default workspace', 600000, '1970-01-01T00:00:00.000Z');
|
|
732
|
+
`),t.pragma("user_version = 29"),r=29),r<30&&r!==0&&(t.exec(`
|
|
733
|
+
CREATE TABLE IF NOT EXISTS mailbox_cursor (
|
|
734
|
+
user_id TEXT PRIMARY KEY,
|
|
735
|
+
last_processed_version_id TEXT,
|
|
736
|
+
last_processed_at TEXT NOT NULL
|
|
737
|
+
);
|
|
738
|
+
`),t.pragma("user_version = 30"),r=30),r<31&&r!==0&&(t.prepare("PRAGMA table_info(project)").all().some(s=>s.name==="test_command")||t.exec("ALTER TABLE project ADD COLUMN test_command TEXT"),t.pragma("user_version = 31"),r=31),r<32&&r!==0&&(t.exec(`
|
|
739
|
+
-- Path-keyed root-team registry (NOT a reuse of team/team_member)
|
|
740
|
+
CREATE TABLE IF NOT EXISTS root_team (
|
|
741
|
+
teamfile_path TEXT PRIMARY KEY,
|
|
742
|
+
name TEXT,
|
|
743
|
+
raw_text TEXT NOT NULL,
|
|
744
|
+
raw_sha256 TEXT NOT NULL,
|
|
745
|
+
registered_at TEXT NOT NULL,
|
|
746
|
+
last_seeded_at TEXT
|
|
747
|
+
);
|
|
748
|
+
|
|
749
|
+
-- One row per request->response exchange
|
|
750
|
+
CREATE TABLE IF NOT EXISTS team_chat_log (
|
|
751
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
752
|
+
root_teamfile TEXT NOT NULL,
|
|
753
|
+
sender_teamfile TEXT NOT NULL,
|
|
754
|
+
sender_alias TEXT NOT NULL,
|
|
755
|
+
receiver_teamfile TEXT NOT NULL,
|
|
756
|
+
receiver_alias TEXT NOT NULL,
|
|
757
|
+
message TEXT NOT NULL,
|
|
758
|
+
response TEXT,
|
|
759
|
+
status TEXT NOT NULL,
|
|
760
|
+
error_detail TEXT,
|
|
761
|
+
truncated INTEGER NOT NULL DEFAULT 0,
|
|
762
|
+
created_at TEXT NOT NULL
|
|
763
|
+
);
|
|
764
|
+
CREATE INDEX IF NOT EXISTS idx_team_chat_log_root_time
|
|
765
|
+
ON team_chat_log(root_teamfile, created_at);
|
|
766
|
+
|
|
767
|
+
-- Per-receiver in-flight marker for single-sender serialization (\xA75)
|
|
768
|
+
CREATE TABLE IF NOT EXISTS agent_inflight (
|
|
769
|
+
receiver_teamfile TEXT NOT NULL,
|
|
770
|
+
receiver_alias TEXT NOT NULL,
|
|
771
|
+
sender_teamfile TEXT NOT NULL,
|
|
772
|
+
sender_alias TEXT NOT NULL,
|
|
773
|
+
started_at TEXT NOT NULL,
|
|
774
|
+
PRIMARY KEY(receiver_teamfile, receiver_alias)
|
|
775
|
+
);
|
|
776
|
+
`),t.pragma("user_version = 32"),r=32),r<33&&r!==0&&(j(t,"mailbox_cursor").has("mailbox_key")?t.exec(`
|
|
777
|
+
CREATE TABLE IF NOT EXISTS mailbox_cursor_v33 (
|
|
778
|
+
user_id TEXT NOT NULL,
|
|
779
|
+
mailbox_key TEXT NOT NULL,
|
|
780
|
+
last_processed_version_id TEXT,
|
|
781
|
+
last_processed_at TEXT NOT NULL,
|
|
782
|
+
PRIMARY KEY(user_id, mailbox_key)
|
|
783
|
+
);
|
|
784
|
+
INSERT OR IGNORE INTO mailbox_cursor_v33 (
|
|
785
|
+
user_id,
|
|
786
|
+
mailbox_key,
|
|
787
|
+
last_processed_version_id,
|
|
788
|
+
last_processed_at
|
|
789
|
+
)
|
|
790
|
+
SELECT
|
|
791
|
+
user_id,
|
|
792
|
+
mailbox_key,
|
|
793
|
+
last_processed_version_id,
|
|
794
|
+
last_processed_at
|
|
795
|
+
FROM mailbox_cursor;
|
|
796
|
+
DROP TABLE mailbox_cursor;
|
|
797
|
+
ALTER TABLE mailbox_cursor_v33 RENAME TO mailbox_cursor;
|
|
798
|
+
`):t.exec(`
|
|
799
|
+
CREATE TABLE IF NOT EXISTS mailbox_cursor_v33 (
|
|
800
|
+
user_id TEXT NOT NULL,
|
|
801
|
+
mailbox_key TEXT NOT NULL,
|
|
802
|
+
last_processed_version_id TEXT,
|
|
803
|
+
last_processed_at TEXT NOT NULL,
|
|
804
|
+
PRIMARY KEY(user_id, mailbox_key)
|
|
805
|
+
);
|
|
806
|
+
INSERT OR IGNORE INTO mailbox_cursor_v33 (
|
|
807
|
+
user_id,
|
|
808
|
+
mailbox_key,
|
|
809
|
+
last_processed_version_id,
|
|
810
|
+
last_processed_at
|
|
811
|
+
)
|
|
812
|
+
SELECT
|
|
813
|
+
user_id,
|
|
814
|
+
'mailbox/' || user_id || '.json',
|
|
815
|
+
last_processed_version_id,
|
|
816
|
+
last_processed_at
|
|
817
|
+
FROM mailbox_cursor;
|
|
818
|
+
DROP TABLE mailbox_cursor;
|
|
819
|
+
ALTER TABLE mailbox_cursor_v33 RENAME TO mailbox_cursor;
|
|
820
|
+
`),t.pragma("user_version = 33"),r=33),r<34&&r!==0&&(t.exec(`
|
|
821
|
+
-- Per-mailbox durable watermark for daemon team_chat_log pushes. First-ever
|
|
822
|
+
-- start seeds this at current MAX(team_chat_log.id) to skip historic backlog;
|
|
823
|
+
-- subsequent restarts resume from the last successfully published id.
|
|
824
|
+
CREATE TABLE IF NOT EXISTS team_chat_log_cursor (
|
|
825
|
+
cursor_key TEXT PRIMARY KEY,
|
|
826
|
+
last_pushed_id INTEGER NOT NULL,
|
|
827
|
+
updated_at TEXT NOT NULL
|
|
828
|
+
);
|
|
829
|
+
`),t.pragma("user_version = 34"),r=34),r<35&&r!==0&&(j(t,"mailbox_cursor").has("last_processed_seq")||t.exec("ALTER TABLE mailbox_cursor ADD COLUMN last_processed_seq INTEGER;"),t.pragma("user_version = 35"),r=35),r<36&&r!==0&&(t.exec(`
|
|
830
|
+
CREATE TABLE IF NOT EXISTS usage_meter (
|
|
831
|
+
user_id TEXT NOT NULL,
|
|
832
|
+
device_id TEXT NOT NULL,
|
|
833
|
+
period TEXT NOT NULL,
|
|
834
|
+
put_count INTEGER NOT NULL DEFAULT 0,
|
|
835
|
+
get_count INTEGER NOT NULL DEFAULT 0,
|
|
836
|
+
list_count INTEGER NOT NULL DEFAULT 0,
|
|
837
|
+
updated_at TEXT NOT NULL,
|
|
838
|
+
PRIMARY KEY(user_id, device_id, period)
|
|
839
|
+
);
|
|
840
|
+
`),t.pragma("user_version = 36"),r=36),r<37&&r!==0&&(Ae(t,"team_connection")&&t.exec(`
|
|
841
|
+
CREATE TABLE IF NOT EXISTS team_connection_v37 (
|
|
842
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
843
|
+
source_teamfile TEXT NOT NULL,
|
|
844
|
+
target_name TEXT NOT NULL,
|
|
845
|
+
target_teamfile TEXT NOT NULL,
|
|
846
|
+
created_at TEXT NOT NULL,
|
|
847
|
+
UNIQUE(source_teamfile, target_name, target_teamfile)
|
|
848
|
+
);
|
|
849
|
+
INSERT OR IGNORE INTO team_connection_v37 (
|
|
850
|
+
id,
|
|
851
|
+
source_teamfile,
|
|
852
|
+
target_name,
|
|
853
|
+
target_teamfile,
|
|
854
|
+
created_at
|
|
855
|
+
)
|
|
856
|
+
SELECT
|
|
857
|
+
id,
|
|
858
|
+
source_teamfile,
|
|
859
|
+
target_name,
|
|
860
|
+
target_teamfile,
|
|
861
|
+
created_at
|
|
862
|
+
FROM team_connection
|
|
863
|
+
ORDER BY id ASC;
|
|
864
|
+
DROP TABLE team_connection;
|
|
865
|
+
ALTER TABLE team_connection_v37 RENAME TO team_connection;
|
|
866
|
+
`),t.pragma("user_version = 37"),r=37),r<38&&r!==0&&(j(t,"agent_inflight").has("active_count")||t.exec("ALTER TABLE agent_inflight ADD COLUMN active_count INTEGER NOT NULL DEFAULT 1;"),t.exec("DROP TABLE IF EXISTS team_connection;"),t.pragma("user_version = 38"),r=38),r<39&&r!==0&&(j(t,"agent_inflight").has("holder_pid")||t.exec("ALTER TABLE agent_inflight ADD COLUMN holder_pid INTEGER;"),t.pragma("user_version = 39"),r=39),r<40&&r!==0&&(t.exec(`
|
|
867
|
+
CREATE TABLE IF NOT EXISTS delegation_job (
|
|
868
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
869
|
+
teamfile TEXT NOT NULL,
|
|
870
|
+
alias TEXT NOT NULL,
|
|
871
|
+
from_identity TEXT NOT NULL,
|
|
872
|
+
root_teamfile TEXT NOT NULL,
|
|
873
|
+
prompt TEXT NOT NULL,
|
|
874
|
+
status TEXT NOT NULL CHECK(status IN ('pending', 'running', 'done', 'error', 'busy', 'cancelled')),
|
|
875
|
+
created_at TEXT NOT NULL,
|
|
876
|
+
started_at TEXT,
|
|
877
|
+
ended_at TEXT,
|
|
878
|
+
locked_by TEXT,
|
|
879
|
+
worker_pid INTEGER,
|
|
880
|
+
locked_until TEXT,
|
|
881
|
+
result_text TEXT,
|
|
882
|
+
error TEXT,
|
|
883
|
+
team_chat_log_id INTEGER REFERENCES team_chat_log(id),
|
|
884
|
+
attempt_count INTEGER NOT NULL DEFAULT 0
|
|
885
|
+
);
|
|
886
|
+
CREATE INDEX IF NOT EXISTS idx_delegation_job_status_created
|
|
887
|
+
ON delegation_job(status, created_at DESC);
|
|
888
|
+
CREATE INDEX IF NOT EXISTS idx_delegation_job_team_created
|
|
889
|
+
ON delegation_job(teamfile, created_at DESC);
|
|
890
|
+
CREATE INDEX IF NOT EXISTS idx_delegation_job_from_created
|
|
891
|
+
ON delegation_job(from_identity, created_at DESC);
|
|
892
|
+
|
|
893
|
+
CREATE TABLE IF NOT EXISTS delegation_event (
|
|
894
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
895
|
+
delegation_job_id INTEGER NOT NULL REFERENCES delegation_job(id) ON DELETE CASCADE,
|
|
896
|
+
ts TEXT NOT NULL,
|
|
897
|
+
kind TEXT NOT NULL,
|
|
898
|
+
payload TEXT NOT NULL
|
|
899
|
+
);
|
|
900
|
+
CREATE INDEX IF NOT EXISTS idx_delegation_event_job_id
|
|
901
|
+
ON delegation_event(delegation_job_id, id);
|
|
902
|
+
`),t.pragma("user_version = 40"),r=40),r<41&&r!==0){let n=j(t,"delegation_job");n.has("permission_mode")||t.exec("ALTER TABLE delegation_job ADD COLUMN permission_mode TEXT;"),n.has("idle_timeout_ms")||t.exec("ALTER TABLE delegation_job ADD COLUMN idle_timeout_ms INTEGER;"),t.pragma("user_version = 41"),r=41}if(r<42&&r!==0&&(j(t,"delegation_job").has("delivered_at")||t.exec("ALTER TABLE delegation_job ADD COLUMN delivered_at TEXT;"),t.pragma("user_version = 42"),r=42),r<43&&r!==0&&(j(t,"delegation_job").has("meta")||t.exec("ALTER TABLE delegation_job ADD COLUMN meta TEXT;"),t.exec(`
|
|
903
|
+
CREATE TABLE IF NOT EXISTS runtime_state (
|
|
904
|
+
scope TEXT NOT NULL,
|
|
905
|
+
key TEXT NOT NULL,
|
|
906
|
+
kind TEXT NOT NULL,
|
|
907
|
+
data TEXT NOT NULL,
|
|
908
|
+
updated_at TEXT NOT NULL,
|
|
909
|
+
PRIMARY KEY(scope, key, kind)
|
|
910
|
+
);
|
|
911
|
+
`),t.pragma("user_version = 43"),r=43),r<44&&r!==0&&(t.exec(`
|
|
912
|
+
CREATE TABLE IF NOT EXISTS tracked_invocation (
|
|
913
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
914
|
+
kind TEXT NOT NULL CHECK(kind IN ('chat', 'exec')),
|
|
915
|
+
origin TEXT NOT NULL CHECK(origin IN ('agent', 'operator', 'mcp', 'unknown')),
|
|
916
|
+
scope_teamfile TEXT,
|
|
917
|
+
from_identity TEXT NOT NULL,
|
|
918
|
+
target_teamfile TEXT,
|
|
919
|
+
target_alias TEXT,
|
|
920
|
+
root_teamfile TEXT,
|
|
921
|
+
cwd TEXT,
|
|
922
|
+
command TEXT,
|
|
923
|
+
status TEXT NOT NULL CHECK(status IN ('running', 'done', 'error', 'busy', 'cancelled')),
|
|
924
|
+
started_at TEXT NOT NULL,
|
|
925
|
+
ended_at TEXT,
|
|
926
|
+
holder_pid INTEGER,
|
|
927
|
+
holder_host TEXT,
|
|
928
|
+
last_heartbeat_at TEXT,
|
|
929
|
+
exit_code INTEGER,
|
|
930
|
+
signal TEXT,
|
|
931
|
+
result_summary TEXT,
|
|
932
|
+
error TEXT,
|
|
933
|
+
team_chat_log_id INTEGER,
|
|
934
|
+
meta TEXT
|
|
935
|
+
);
|
|
936
|
+
CREATE INDEX IF NOT EXISTS idx_tracked_invocation_status_started
|
|
937
|
+
ON tracked_invocation(status, started_at);
|
|
938
|
+
CREATE INDEX IF NOT EXISTS idx_tracked_invocation_from_status_started
|
|
939
|
+
ON tracked_invocation(from_identity, status, started_at);
|
|
940
|
+
CREATE INDEX IF NOT EXISTS idx_tracked_invocation_scope_status_started
|
|
941
|
+
ON tracked_invocation(scope_teamfile, status, started_at);
|
|
942
|
+
CREATE INDEX IF NOT EXISTS idx_tracked_invocation_status_ended
|
|
943
|
+
ON tracked_invocation(status, ended_at);
|
|
944
|
+
`),t.pragma("user_version = 44"),r=44),r<45&&r!==0&&(t.exec(`
|
|
945
|
+
CREATE TABLE IF NOT EXISTS agent_mailbox (
|
|
946
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
947
|
+
receiver_teamfile TEXT NOT NULL,
|
|
948
|
+
receiver_alias TEXT NOT NULL,
|
|
949
|
+
sender_teamfile TEXT,
|
|
950
|
+
sender_alias TEXT,
|
|
951
|
+
root_teamfile TEXT,
|
|
952
|
+
payload TEXT NOT NULL,
|
|
953
|
+
created_at TEXT NOT NULL,
|
|
954
|
+
remote_transport TEXT,
|
|
955
|
+
remote_message_id TEXT,
|
|
956
|
+
remote_thread_id TEXT,
|
|
957
|
+
meta TEXT
|
|
958
|
+
);
|
|
959
|
+
CREATE INDEX IF NOT EXISTS idx_agent_mailbox_receiver_id
|
|
960
|
+
ON agent_mailbox(receiver_teamfile, receiver_alias, id);
|
|
961
|
+
CREATE INDEX IF NOT EXISTS idx_agent_mailbox_sender_created
|
|
962
|
+
ON agent_mailbox(sender_teamfile, sender_alias, created_at);
|
|
963
|
+
CREATE INDEX IF NOT EXISTS idx_agent_mailbox_created
|
|
964
|
+
ON agent_mailbox(created_at);
|
|
965
|
+
`),t.pragma("user_version = 45"),r=45),r<46&&r!==0&&(Ae(t,"team_chat_log")?Qo(t):t.exec(`
|
|
966
|
+
CREATE TABLE IF NOT EXISTS team_chat_log (
|
|
967
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
968
|
+
root_teamfile TEXT NOT NULL,
|
|
969
|
+
sender_teamfile TEXT,
|
|
970
|
+
sender_alias TEXT,
|
|
971
|
+
receiver_teamfile TEXT NOT NULL,
|
|
972
|
+
receiver_alias TEXT NOT NULL,
|
|
973
|
+
message TEXT NOT NULL,
|
|
974
|
+
response TEXT,
|
|
975
|
+
origin TEXT NOT NULL CHECK(origin IN ('agent','operator','mcp','unknown')),
|
|
976
|
+
status TEXT NOT NULL,
|
|
977
|
+
error_detail TEXT,
|
|
978
|
+
truncated INTEGER NOT NULL DEFAULT 0,
|
|
979
|
+
created_at TEXT NOT NULL
|
|
980
|
+
);
|
|
981
|
+
`),t.exec(`
|
|
982
|
+
CREATE INDEX IF NOT EXISTS idx_team_chat_log_root_time
|
|
983
|
+
ON team_chat_log(root_teamfile, created_at);
|
|
984
|
+
`),t.pragma("user_version = 46"),r=46),r>=46&&Ae(t,"team_chat_log")&&!j(t,"team_chat_log").has("origin")&&Qo(t),r<47&&r!==0){if(He(t,"tracked_invocation"),Ae(t,"agent_mailbox")){let s=j(t,"agent_mailbox");s.has("delivered_at")||t.exec("ALTER TABLE agent_mailbox ADD COLUMN delivered_at TEXT;"),s.has("receipt")||t.exec("ALTER TABLE agent_mailbox ADD COLUMN receipt TEXT;")}let n=j(t,"tracked_invocation");n.has("notified_by")||t.exec("ALTER TABLE tracked_invocation ADD COLUMN notified_by TEXT;"),n.has("notified_at")||t.exec("ALTER TABLE tracked_invocation ADD COLUMN notified_at TEXT;"),t.pragma("user_version = 47"),r=47}if(r<48&&r!==0){if(Ae(t,"agent_mailbox")){let n=j(t,"agent_mailbox");n.has("delivering_at")||t.exec("ALTER TABLE agent_mailbox ADD COLUMN delivering_at TEXT;"),n.has("delivery_holder_pid")||t.exec("ALTER TABLE agent_mailbox ADD COLUMN delivery_holder_pid INTEGER;"),n.has("delivery_holder_host")||t.exec("ALTER TABLE agent_mailbox ADD COLUMN delivery_holder_host TEXT;"),n.has("waited_at")||t.exec("ALTER TABLE agent_mailbox ADD COLUMN waited_at TEXT;"),n.has("waited_by")||t.exec("ALTER TABLE agent_mailbox ADD COLUMN waited_by TEXT;"),t.exec(`
|
|
985
|
+
CREATE INDEX IF NOT EXISTS idx_agent_mailbox_sender_delivery_wait
|
|
986
|
+
ON agent_mailbox(sender_teamfile, sender_alias, delivered_at, waited_at, id);
|
|
987
|
+
CREATE INDEX IF NOT EXISTS idx_agent_mailbox_lane_delivery
|
|
988
|
+
ON agent_mailbox(sender_teamfile, sender_alias, receiver_teamfile, receiver_alias, delivered_at, delivering_at, id);
|
|
989
|
+
`)}t.pragma("user_version = 48"),r=48}if(r<49&&r!==0&&(He(t,"tracked_invocation"),t.exec(`
|
|
990
|
+
UPDATE tracked_invocation
|
|
991
|
+
SET notified_by = 'migration-baseline',
|
|
992
|
+
notified_at = COALESCE(ended_at, started_at)
|
|
993
|
+
WHERE status IN ('done', 'error', 'busy', 'cancelled')
|
|
994
|
+
AND notified_by IS NULL;
|
|
995
|
+
`),t.pragma("user_version = 49"),r=49),r<50&&r!==0&&(He(t,"tracked_invocation"),j(t,"tracked_invocation").has("launch_source")||t.exec("ALTER TABLE tracked_invocation ADD COLUMN launch_source TEXT;"),t.pragma("user_version = 50"),r=50),r<51&&r!==0){if(Ae(t,"agent_mailbox")){let n=j(t,"agent_mailbox");n.has("message_type")||t.exec("ALTER TABLE agent_mailbox ADD COLUMN message_type TEXT NOT NULL DEFAULT 'request' CHECK(message_type IN ('request','response'));"),n.has("reply_mode")||t.exec("ALTER TABLE agent_mailbox ADD COLUMN reply_mode TEXT NOT NULL DEFAULT 'pull' CHECK(reply_mode IN ('push','pull'));"),n.has("request_mailbox_id")||t.exec("ALTER TABLE agent_mailbox ADD COLUMN request_mailbox_id INTEGER;"),t.exec(`
|
|
996
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_mailbox_response_request_unique
|
|
997
|
+
ON agent_mailbox(request_mailbox_id)
|
|
998
|
+
WHERE message_type = 'response' AND request_mailbox_id IS NOT NULL;
|
|
999
|
+
CREATE TRIGGER IF NOT EXISTS trg_agent_mailbox_response_request_insert
|
|
1000
|
+
BEFORE INSERT ON agent_mailbox
|
|
1001
|
+
WHEN NEW.message_type = 'response' AND NEW.request_mailbox_id IS NULL
|
|
1002
|
+
BEGIN
|
|
1003
|
+
SELECT RAISE(ABORT, 'agent_mailbox response requires request_mailbox_id');
|
|
1004
|
+
END;
|
|
1005
|
+
CREATE TRIGGER IF NOT EXISTS trg_agent_mailbox_response_request_update
|
|
1006
|
+
BEFORE UPDATE OF message_type, request_mailbox_id ON agent_mailbox
|
|
1007
|
+
WHEN NEW.message_type = 'response' AND NEW.request_mailbox_id IS NULL
|
|
1008
|
+
BEGIN
|
|
1009
|
+
SELECT RAISE(ABORT, 'agent_mailbox response requires request_mailbox_id');
|
|
1010
|
+
END;
|
|
1011
|
+
`)}t.pragma("user_version = 51"),r=51}if(r<52&&r!==0&&(He(t,"tracked_invocation"),j(t,"tracked_invocation").has("request_payload")||t.exec("ALTER TABLE tracked_invocation ADD COLUMN request_payload TEXT;"),t.pragma("user_version = 52"),r=52),r<53&&r!==0&&(t.exec(`
|
|
1012
|
+
CREATE TABLE IF NOT EXISTS message_event (
|
|
1013
|
+
seq INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1014
|
+
event_id TEXT NOT NULL UNIQUE,
|
|
1015
|
+
ts TEXT NOT NULL,
|
|
1016
|
+
stream_id TEXT NOT NULL,
|
|
1017
|
+
event_type TEXT NOT NULL,
|
|
1018
|
+
payload TEXT NOT NULL CHECK(json_valid(payload)),
|
|
1019
|
+
sender_teamfile TEXT GENERATED ALWAYS AS (json_extract(payload, '$.sender.teamfile')) STORED,
|
|
1020
|
+
sender_alias TEXT GENERATED ALWAYS AS (json_extract(payload, '$.sender.alias')) STORED,
|
|
1021
|
+
receiver_teamfile TEXT GENERATED ALWAYS AS (json_extract(payload, '$.receiver.teamfile')) STORED,
|
|
1022
|
+
receiver_alias TEXT GENERATED ALWAYS AS (json_extract(payload, '$.receiver.alias')) STORED
|
|
1023
|
+
);
|
|
1024
|
+
CREATE INDEX IF NOT EXISTS idx_message_event_stream ON message_event(stream_id, seq);
|
|
1025
|
+
CREATE INDEX IF NOT EXISTS idx_message_event_type ON message_event(event_type, seq);
|
|
1026
|
+
CREATE INDEX IF NOT EXISTS idx_message_event_sender ON message_event(sender_teamfile, sender_alias, seq);
|
|
1027
|
+
CREATE INDEX IF NOT EXISTS idx_message_event_receiver ON message_event(receiver_teamfile, receiver_alias, seq);
|
|
1028
|
+
CREATE TABLE IF NOT EXISTS agent_state (
|
|
1029
|
+
receiver_teamfile TEXT NOT NULL,
|
|
1030
|
+
receiver_alias TEXT NOT NULL,
|
|
1031
|
+
lease_id TEXT UNIQUE,
|
|
1032
|
+
sender_teamfile TEXT,
|
|
1033
|
+
sender_alias TEXT,
|
|
1034
|
+
holder_pid INTEGER,
|
|
1035
|
+
holder_host TEXT,
|
|
1036
|
+
started_at TEXT,
|
|
1037
|
+
last_heartbeat_at TEXT,
|
|
1038
|
+
terminal_lock_id TEXT UNIQUE,
|
|
1039
|
+
terminal_invocation_id TEXT UNIQUE,
|
|
1040
|
+
terminal_invocation_pid INTEGER,
|
|
1041
|
+
terminal_invocation_host TEXT,
|
|
1042
|
+
terminal_invocation_heartbeat_at TEXT,
|
|
1043
|
+
last_seq INTEGER NOT NULL,
|
|
1044
|
+
PRIMARY KEY(receiver_teamfile, receiver_alias)
|
|
1045
|
+
);
|
|
1046
|
+
CREATE TABLE IF NOT EXISTS message_pending (
|
|
1047
|
+
message_id TEXT PRIMARY KEY,
|
|
1048
|
+
message_type TEXT NOT NULL CHECK(message_type IN ('request','response')),
|
|
1049
|
+
in_reply_to TEXT UNIQUE,
|
|
1050
|
+
sender_teamfile TEXT,
|
|
1051
|
+
sender_alias TEXT,
|
|
1052
|
+
receiver_teamfile TEXT NOT NULL,
|
|
1053
|
+
receiver_alias TEXT NOT NULL,
|
|
1054
|
+
lifecycle_state TEXT NOT NULL,
|
|
1055
|
+
delivery_lease_id TEXT,
|
|
1056
|
+
delivery_holder_pid INTEGER,
|
|
1057
|
+
created_seq INTEGER NOT NULL,
|
|
1058
|
+
last_seq INTEGER NOT NULL
|
|
1059
|
+
);
|
|
1060
|
+
CREATE INDEX IF NOT EXISTS idx_message_pending_lane
|
|
1061
|
+
ON message_pending(sender_teamfile, sender_alias, receiver_teamfile,
|
|
1062
|
+
receiver_alias, message_type, created_seq)
|
|
1063
|
+
WHERE lifecycle_state = 'queued';
|
|
1064
|
+
CREATE TABLE IF NOT EXISTS invocation_state (
|
|
1065
|
+
invocation_id TEXT PRIMARY KEY,
|
|
1066
|
+
kind TEXT NOT NULL,
|
|
1067
|
+
origin TEXT NOT NULL,
|
|
1068
|
+
launch_source TEXT NOT NULL,
|
|
1069
|
+
from_identity TEXT NOT NULL,
|
|
1070
|
+
target_teamfile TEXT,
|
|
1071
|
+
target_alias TEXT,
|
|
1072
|
+
root_teamfile TEXT,
|
|
1073
|
+
cwd TEXT,
|
|
1074
|
+
command TEXT,
|
|
1075
|
+
request_message_id TEXT,
|
|
1076
|
+
request_payload TEXT,
|
|
1077
|
+
holder_pid INTEGER,
|
|
1078
|
+
holder_host TEXT,
|
|
1079
|
+
status TEXT NOT NULL,
|
|
1080
|
+
started_at TEXT NOT NULL,
|
|
1081
|
+
last_heartbeat_at TEXT,
|
|
1082
|
+
ended_at TEXT,
|
|
1083
|
+
result_summary TEXT,
|
|
1084
|
+
error TEXT,
|
|
1085
|
+
notified_by TEXT,
|
|
1086
|
+
notified_at TEXT,
|
|
1087
|
+
last_seq INTEGER NOT NULL
|
|
1088
|
+
);
|
|
1089
|
+
CREATE INDEX IF NOT EXISTS idx_invocation_state_target_status
|
|
1090
|
+
ON invocation_state(target_teamfile, target_alias, status, launch_source);
|
|
1091
|
+
CREATE INDEX IF NOT EXISTS idx_invocation_state_from_time
|
|
1092
|
+
ON invocation_state(from_identity, started_at DESC);
|
|
1093
|
+
`),t.pragma("user_version = 53"),r=53),r<54&&r!==0&&(He(t,"agent_state"),j(t,"agent_state").has("currently_handling_message_id")||t.exec("ALTER TABLE agent_state ADD COLUMN currently_handling_message_id TEXT;"),t.pragma("user_version = 54"),r=54),r<55&&r!==0&&(He(t,"agent_state"),j(t,"agent_state").has("currently_handling_since")||t.exec("ALTER TABLE agent_state ADD COLUMN currently_handling_since TEXT;"),t.pragma("user_version = 55"),r=55),r<56&&r!==0&&(Ae(t,"tracked_invocation")&&t.exec(`
|
|
1094
|
+
CREATE TABLE tracked_invocation_v56 (
|
|
1095
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1096
|
+
kind TEXT NOT NULL CHECK(kind IN ('chat', 'exec')),
|
|
1097
|
+
origin TEXT NOT NULL CHECK(origin IN ('agent', 'operator', 'mcp', 'unknown')),
|
|
1098
|
+
scope_teamfile TEXT,
|
|
1099
|
+
from_identity TEXT NOT NULL,
|
|
1100
|
+
target_teamfile TEXT,
|
|
1101
|
+
target_alias TEXT,
|
|
1102
|
+
root_teamfile TEXT,
|
|
1103
|
+
cwd TEXT,
|
|
1104
|
+
command TEXT,
|
|
1105
|
+
status TEXT NOT NULL CHECK(status IN ('running', 'done', 'error', 'busy', 'cancelled', 'aborted')),
|
|
1106
|
+
started_at TEXT NOT NULL,
|
|
1107
|
+
ended_at TEXT,
|
|
1108
|
+
holder_pid INTEGER,
|
|
1109
|
+
holder_host TEXT,
|
|
1110
|
+
last_heartbeat_at TEXT,
|
|
1111
|
+
exit_code INTEGER,
|
|
1112
|
+
signal TEXT,
|
|
1113
|
+
result_summary TEXT,
|
|
1114
|
+
error TEXT,
|
|
1115
|
+
team_chat_log_id INTEGER,
|
|
1116
|
+
meta TEXT,
|
|
1117
|
+
notified_by TEXT,
|
|
1118
|
+
notified_at TEXT,
|
|
1119
|
+
launch_source TEXT,
|
|
1120
|
+
request_payload TEXT
|
|
1121
|
+
);
|
|
1122
|
+
INSERT INTO tracked_invocation_v56 (
|
|
1123
|
+
id, kind, origin, scope_teamfile, from_identity, target_teamfile,
|
|
1124
|
+
target_alias, root_teamfile, cwd, command, status, started_at,
|
|
1125
|
+
ended_at, holder_pid, holder_host, last_heartbeat_at, exit_code,
|
|
1126
|
+
signal, result_summary, error, team_chat_log_id, meta, notified_by,
|
|
1127
|
+
notified_at, launch_source, request_payload
|
|
1128
|
+
)
|
|
1129
|
+
SELECT
|
|
1130
|
+
id, kind, origin, scope_teamfile, from_identity, target_teamfile,
|
|
1131
|
+
target_alias, root_teamfile, cwd, command, status, started_at,
|
|
1132
|
+
ended_at, holder_pid, holder_host, last_heartbeat_at, exit_code,
|
|
1133
|
+
signal, result_summary, error, team_chat_log_id, meta, notified_by,
|
|
1134
|
+
notified_at, launch_source, request_payload
|
|
1135
|
+
FROM tracked_invocation
|
|
1136
|
+
ORDER BY id ASC;
|
|
1137
|
+
DROP TABLE tracked_invocation;
|
|
1138
|
+
ALTER TABLE tracked_invocation_v56 RENAME TO tracked_invocation;
|
|
1139
|
+
CREATE INDEX IF NOT EXISTS idx_tracked_invocation_status_started
|
|
1140
|
+
ON tracked_invocation(status, started_at);
|
|
1141
|
+
CREATE INDEX IF NOT EXISTS idx_tracked_invocation_from_status_started
|
|
1142
|
+
ON tracked_invocation(from_identity, status, started_at);
|
|
1143
|
+
CREATE INDEX IF NOT EXISTS idx_tracked_invocation_scope_status_started
|
|
1144
|
+
ON tracked_invocation(scope_teamfile, status, started_at);
|
|
1145
|
+
CREATE INDEX IF NOT EXISTS idx_tracked_invocation_status_ended
|
|
1146
|
+
ON tracked_invocation(status, ended_at);
|
|
1147
|
+
`),t.pragma("user_version = 56"),r=56),r<57&&r!==0&&(Ae(t,"agent_mailbox")&&zo(t),t.exec("DROP TABLE IF EXISTS agent_mailbox;"),t.pragma("user_version = 57"),r=57),r<58&&r!==0&&(He(t,"tracked_invocation"),j(t,"tracked_invocation").has("parent_invocation_id")||t.exec("ALTER TABLE tracked_invocation ADD COLUMN parent_invocation_id INTEGER;"),t.pragma("user_version = 58"),r=58),r<59&&r!==0&&(t.exec(`
|
|
1148
|
+
CREATE TABLE IF NOT EXISTS state_ledger_identity (
|
|
1149
|
+
singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
|
|
1150
|
+
instance_id TEXT NOT NULL,
|
|
1151
|
+
created_at TEXT NOT NULL
|
|
1152
|
+
);
|
|
1153
|
+
`),t.pragma("user_version = 59"),r=59),r<60&&r!==0&&(He(t,"tracked_invocation"),j(t,"tracked_invocation").has("config_warnings")||t.exec("ALTER TABLE tracked_invocation ADD COLUMN config_warnings TEXT;"),t.pragma("user_version = 60"),r=60),r<61&&r!==0){let n=j(t,"team_chat_log");n.size>0&&!n.has("message_type")&&t.exec("ALTER TABLE team_chat_log ADD COLUMN message_type TEXT CHECK(message_type IN ('batch'));"),t.exec(`
|
|
1154
|
+
CREATE TABLE IF NOT EXISTS schema_meta (
|
|
1155
|
+
key TEXT PRIMARY KEY,
|
|
1156
|
+
value TEXT NOT NULL
|
|
1157
|
+
);
|
|
1158
|
+
INSERT OR IGNORE INTO schema_meta (key, value) VALUES ('min_reader_version', '60');
|
|
1159
|
+
`),t.pragma("user_version = 61"),r=61}Cm($m)}function Bm(t){t.prepare("SELECT instance_id FROM state_ledger_identity WHERE singleton = 1").get()===void 0&&t.prepare("INSERT OR IGNORE INTO state_ledger_identity (singleton, instance_id, created_at) VALUES (1, ?, ?)").run(Dm(),new Date().toISOString())}function j(t,e){let r=t.prepare(`PRAGMA table_info(${e})`).all();return new Set(r.map(n=>n.name))}function Ae(t,e){return t.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?").get(e)!==void 0}function He(t,e){if(!Ae(t,e)&&(t.exec(ea(sa,"utf8")),!Ae(t,e)))throw new Error(`schema.sql did not create expected table: ${e}`)}function Qo(t){let e=j(t,"team_chat_log");t.pragma("foreign_keys = OFF");try{t.exec(`
|
|
1160
|
+
DROP TABLE IF EXISTS team_chat_log_v46;
|
|
1161
|
+
CREATE TABLE team_chat_log_v46 (
|
|
1162
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1163
|
+
root_teamfile TEXT NOT NULL,
|
|
1164
|
+
sender_teamfile TEXT,
|
|
1165
|
+
sender_alias TEXT,
|
|
1166
|
+
receiver_teamfile TEXT NOT NULL,
|
|
1167
|
+
receiver_alias TEXT NOT NULL,
|
|
1168
|
+
message TEXT NOT NULL,
|
|
1169
|
+
response TEXT,
|
|
1170
|
+
origin TEXT NOT NULL CHECK(origin IN ('agent','operator','mcp','unknown')),
|
|
1171
|
+
status TEXT NOT NULL,
|
|
1172
|
+
error_detail TEXT,
|
|
1173
|
+
truncated INTEGER NOT NULL DEFAULT 0,
|
|
1174
|
+
created_at TEXT NOT NULL
|
|
1175
|
+
);
|
|
1176
|
+
INSERT INTO team_chat_log_v46 (
|
|
1177
|
+
id, root_teamfile, sender_teamfile, sender_alias, receiver_teamfile, receiver_alias,
|
|
1178
|
+
message, response, origin, status, error_detail, truncated, created_at
|
|
1179
|
+
)
|
|
1180
|
+
SELECT
|
|
1181
|
+
id, root_teamfile, sender_teamfile, sender_alias, receiver_teamfile, receiver_alias,
|
|
1182
|
+
message, response,
|
|
1183
|
+
${e.has("origin")?"origin":"'unknown'"},
|
|
1184
|
+
status, error_detail, truncated, created_at
|
|
1185
|
+
FROM team_chat_log;
|
|
1186
|
+
DROP TABLE team_chat_log;
|
|
1187
|
+
ALTER TABLE team_chat_log_v46 RENAME TO team_chat_log;
|
|
1188
|
+
`)}finally{t.pragma("foreign_keys = ON")}}function ia(t){let e=t.pragma("user_version",{simple:!0});return typeof e=="number"?e:0}function Wm(t,e){try{if(!Ae(t,"schema_meta"))return e;let r=t.prepare("SELECT value FROM schema_meta WHERE key = 'min_reader_version'").get();if(r===void 0)return e;let n=Number.parseInt(r.value,10);return Number.isInteger(n)&&n>0?n:e}catch{return e}}var Zo=!1;function Hm(t,e,r=Xe){Zo||(Zo=!0,process.stderr.write(`warning: ${t}: state.db is v${e}; this build understands v${r} -- some newer data or features may not be visible, proceeding best-effort. Update: npm install -g @lmctl-ai/lmctl@latest
|
|
1189
|
+
`),process.argv.includes("--json")&&process.stderr.write(`${JSON.stringify({schema_skew:{db_version:e,build_version:r,mode:"best_effort"}})}
|
|
1190
|
+
`))}var Xm=null;function qm(){return process.env.LMCTL_DB??Fm(Mm(),".lmctl","state.db")}if(process.argv[1]&&(process.argv[1].endsWith("migrate.ts")||process.argv[1].endsWith("migrate.js"))&&import.meta.url===Um(process.argv[1]).href){let t=Br({dbPath:process.argv[2]??qm()});try{process.stdout.write(`migrated user_version=${ia(t)}
|
|
1191
|
+
`)}finally{t.close()}}function oa(t){return{getAgentInflight:t.prepare("SELECT * FROM agent_inflight WHERE receiver_teamfile = ? AND receiver_alias = ?"),listAgentInflight:t.prepare("SELECT * FROM agent_inflight ORDER BY started_at ASC, receiver_teamfile ASC, receiver_alias ASC"),acquireAgentInflight:t.prepare(`
|
|
1192
|
+
INSERT INTO agent_inflight (receiver_teamfile, receiver_alias, sender_teamfile, sender_alias, started_at, active_count, holder_pid)
|
|
1193
|
+
VALUES (@receiver_teamfile, @receiver_alias, @sender_teamfile, @sender_alias, @started_at, 1, @holder_pid)
|
|
1194
|
+
ON CONFLICT(receiver_teamfile, receiver_alias) DO UPDATE SET
|
|
1195
|
+
sender_teamfile = CASE
|
|
1196
|
+
WHEN @force = 1
|
|
1197
|
+
OR (
|
|
1198
|
+
@stale_before IS NOT NULL
|
|
1199
|
+
AND agent_inflight.holder_pid IS NULL
|
|
1200
|
+
AND agent_inflight.started_at < @stale_before
|
|
1201
|
+
)
|
|
1202
|
+
OR (
|
|
1203
|
+
@reclaim_observed_sender_teamfile IS NOT NULL
|
|
1204
|
+
AND agent_inflight.sender_teamfile = @reclaim_observed_sender_teamfile
|
|
1205
|
+
AND agent_inflight.sender_alias = @reclaim_observed_sender_alias
|
|
1206
|
+
AND agent_inflight.started_at = @reclaim_observed_started_at
|
|
1207
|
+
AND @reclaim_observed_holder_pid IS NOT NULL
|
|
1208
|
+
AND agent_inflight.holder_pid = @reclaim_observed_holder_pid
|
|
1209
|
+
)
|
|
1210
|
+
THEN excluded.sender_teamfile
|
|
1211
|
+
ELSE agent_inflight.sender_teamfile
|
|
1212
|
+
END,
|
|
1213
|
+
sender_alias = CASE
|
|
1214
|
+
WHEN @force = 1
|
|
1215
|
+
OR (
|
|
1216
|
+
@stale_before IS NOT NULL
|
|
1217
|
+
AND agent_inflight.holder_pid IS NULL
|
|
1218
|
+
AND agent_inflight.started_at < @stale_before
|
|
1219
|
+
)
|
|
1220
|
+
OR (
|
|
1221
|
+
@reclaim_observed_sender_teamfile IS NOT NULL
|
|
1222
|
+
AND agent_inflight.sender_teamfile = @reclaim_observed_sender_teamfile
|
|
1223
|
+
AND agent_inflight.sender_alias = @reclaim_observed_sender_alias
|
|
1224
|
+
AND agent_inflight.started_at = @reclaim_observed_started_at
|
|
1225
|
+
AND @reclaim_observed_holder_pid IS NOT NULL
|
|
1226
|
+
AND agent_inflight.holder_pid = @reclaim_observed_holder_pid
|
|
1227
|
+
)
|
|
1228
|
+
THEN excluded.sender_alias
|
|
1229
|
+
ELSE agent_inflight.sender_alias
|
|
1230
|
+
END,
|
|
1231
|
+
started_at = CASE
|
|
1232
|
+
WHEN @force = 1
|
|
1233
|
+
OR (
|
|
1234
|
+
@stale_before IS NOT NULL
|
|
1235
|
+
AND agent_inflight.holder_pid IS NULL
|
|
1236
|
+
AND agent_inflight.started_at < @stale_before
|
|
1237
|
+
)
|
|
1238
|
+
OR (
|
|
1239
|
+
@reclaim_observed_sender_teamfile IS NOT NULL
|
|
1240
|
+
AND agent_inflight.sender_teamfile = @reclaim_observed_sender_teamfile
|
|
1241
|
+
AND agent_inflight.sender_alias = @reclaim_observed_sender_alias
|
|
1242
|
+
AND agent_inflight.started_at = @reclaim_observed_started_at
|
|
1243
|
+
AND @reclaim_observed_holder_pid IS NOT NULL
|
|
1244
|
+
AND agent_inflight.holder_pid = @reclaim_observed_holder_pid
|
|
1245
|
+
)
|
|
1246
|
+
THEN excluded.started_at
|
|
1247
|
+
ELSE agent_inflight.started_at
|
|
1248
|
+
END,
|
|
1249
|
+
active_count = CASE
|
|
1250
|
+
WHEN @force = 1
|
|
1251
|
+
OR (
|
|
1252
|
+
@stale_before IS NOT NULL
|
|
1253
|
+
AND agent_inflight.holder_pid IS NULL
|
|
1254
|
+
AND agent_inflight.started_at < @stale_before
|
|
1255
|
+
)
|
|
1256
|
+
OR (
|
|
1257
|
+
@reclaim_observed_sender_teamfile IS NOT NULL
|
|
1258
|
+
AND agent_inflight.sender_teamfile = @reclaim_observed_sender_teamfile
|
|
1259
|
+
AND agent_inflight.sender_alias = @reclaim_observed_sender_alias
|
|
1260
|
+
AND agent_inflight.started_at = @reclaim_observed_started_at
|
|
1261
|
+
AND @reclaim_observed_holder_pid IS NOT NULL
|
|
1262
|
+
AND agent_inflight.holder_pid = @reclaim_observed_holder_pid
|
|
1263
|
+
)
|
|
1264
|
+
THEN 1
|
|
1265
|
+
ELSE agent_inflight.active_count
|
|
1266
|
+
END,
|
|
1267
|
+
holder_pid = CASE
|
|
1268
|
+
WHEN @force = 1
|
|
1269
|
+
OR (
|
|
1270
|
+
@stale_before IS NOT NULL
|
|
1271
|
+
AND agent_inflight.holder_pid IS NULL
|
|
1272
|
+
AND agent_inflight.started_at < @stale_before
|
|
1273
|
+
)
|
|
1274
|
+
OR (
|
|
1275
|
+
@reclaim_observed_sender_teamfile IS NOT NULL
|
|
1276
|
+
AND agent_inflight.sender_teamfile = @reclaim_observed_sender_teamfile
|
|
1277
|
+
AND agent_inflight.sender_alias = @reclaim_observed_sender_alias
|
|
1278
|
+
AND agent_inflight.started_at = @reclaim_observed_started_at
|
|
1279
|
+
AND @reclaim_observed_holder_pid IS NOT NULL
|
|
1280
|
+
AND agent_inflight.holder_pid = @reclaim_observed_holder_pid
|
|
1281
|
+
)
|
|
1282
|
+
THEN excluded.holder_pid
|
|
1283
|
+
ELSE agent_inflight.holder_pid
|
|
1284
|
+
END
|
|
1285
|
+
WHERE @force = 1
|
|
1286
|
+
OR (
|
|
1287
|
+
@stale_before IS NOT NULL
|
|
1288
|
+
AND agent_inflight.holder_pid IS NULL
|
|
1289
|
+
AND agent_inflight.started_at < @stale_before
|
|
1290
|
+
)
|
|
1291
|
+
OR (
|
|
1292
|
+
@reclaim_observed_sender_teamfile IS NOT NULL
|
|
1293
|
+
AND agent_inflight.sender_teamfile = @reclaim_observed_sender_teamfile
|
|
1294
|
+
AND agent_inflight.sender_alias = @reclaim_observed_sender_alias
|
|
1295
|
+
AND agent_inflight.started_at = @reclaim_observed_started_at
|
|
1296
|
+
AND @reclaim_observed_holder_pid IS NOT NULL
|
|
1297
|
+
AND agent_inflight.holder_pid = @reclaim_observed_holder_pid
|
|
1298
|
+
)
|
|
1299
|
+
RETURNING *
|
|
1300
|
+
`),clearAgentInflight:t.prepare("DELETE FROM agent_inflight WHERE receiver_teamfile = ? AND receiver_alias = ?"),clearAgentInflightIfSender:t.prepare(`
|
|
1301
|
+
DELETE FROM agent_inflight
|
|
1302
|
+
WHERE receiver_teamfile = ?
|
|
1303
|
+
AND receiver_alias = ?
|
|
1304
|
+
AND sender_teamfile = ?
|
|
1305
|
+
AND sender_alias = ?
|
|
1306
|
+
`),clearObservedTerminalAgentInflight:t.prepare(`
|
|
1307
|
+
DELETE FROM agent_inflight
|
|
1308
|
+
WHERE receiver_teamfile = @receiver_teamfile
|
|
1309
|
+
AND receiver_alias = @receiver_alias
|
|
1310
|
+
AND sender_teamfile = @receiver_teamfile
|
|
1311
|
+
AND sender_alias = 'terminal'
|
|
1312
|
+
AND sender_teamfile = @observed_sender_teamfile
|
|
1313
|
+
AND sender_alias = @observed_sender_alias
|
|
1314
|
+
AND started_at = @observed_started_at
|
|
1315
|
+
AND (
|
|
1316
|
+
(holder_pid IS NULL AND @observed_holder_pid IS NULL)
|
|
1317
|
+
OR holder_pid = @observed_holder_pid
|
|
1318
|
+
)
|
|
1319
|
+
`),decrementAgentInflight:t.prepare(`
|
|
1320
|
+
UPDATE agent_inflight
|
|
1321
|
+
SET active_count = active_count - 1
|
|
1322
|
+
WHERE receiver_teamfile = ?
|
|
1323
|
+
AND receiver_alias = ?
|
|
1324
|
+
AND sender_teamfile = ?
|
|
1325
|
+
AND sender_alias = ?
|
|
1326
|
+
AND active_count > 1
|
|
1327
|
+
`),clearAgentInflightOlderThan:t.prepare("DELETE FROM agent_inflight WHERE started_at < ?")}}var aa=`
|
|
1328
|
+
...[truncated]`;function la(t){return{insertTrackedInvocation:t.prepare(`
|
|
1329
|
+
INSERT INTO tracked_invocation (
|
|
1330
|
+
kind, origin, scope_teamfile, from_identity, target_teamfile, target_alias,
|
|
1331
|
+
root_teamfile, cwd, command, status, started_at, holder_pid, holder_host,
|
|
1332
|
+
last_heartbeat_at, meta, launch_source, request_payload, parent_invocation_id
|
|
1333
|
+
)
|
|
1334
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'running', ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1335
|
+
`),getTrackedInvocation:t.prepare("SELECT * FROM tracked_invocation WHERE id = ?"),listAllRunningTrackedInvocations:t.prepare(`
|
|
1336
|
+
SELECT * FROM tracked_invocation
|
|
1337
|
+
WHERE status = 'running'
|
|
1338
|
+
ORDER BY started_at ASC, id ASC
|
|
1339
|
+
`),listRecentlyFinishedTrackedInvocations:t.prepare(`
|
|
1340
|
+
SELECT * FROM tracked_invocation
|
|
1341
|
+
WHERE ended_at IS NOT NULL AND ended_at >= ?
|
|
1342
|
+
ORDER BY ended_at DESC
|
|
1343
|
+
`),finishTrackedInvocation:t.prepare(`
|
|
1344
|
+
UPDATE tracked_invocation
|
|
1345
|
+
SET status = ?,
|
|
1346
|
+
ended_at = ?,
|
|
1347
|
+
exit_code = ?,
|
|
1348
|
+
signal = ?,
|
|
1349
|
+
result_summary = ?,
|
|
1350
|
+
error = ?,
|
|
1351
|
+
team_chat_log_id = ?,
|
|
1352
|
+
meta = COALESCE(?, meta),
|
|
1353
|
+
config_warnings = COALESCE(?, config_warnings),
|
|
1354
|
+
last_heartbeat_at = COALESCE(last_heartbeat_at, ?)
|
|
1355
|
+
WHERE id = ?
|
|
1356
|
+
AND status = 'running'
|
|
1357
|
+
`),reclaimTrackedInvocationIfUnchanged:t.prepare(`
|
|
1358
|
+
UPDATE tracked_invocation
|
|
1359
|
+
SET status = ?,
|
|
1360
|
+
ended_at = ?,
|
|
1361
|
+
exit_code = ?,
|
|
1362
|
+
signal = ?,
|
|
1363
|
+
result_summary = ?,
|
|
1364
|
+
error = ?,
|
|
1365
|
+
team_chat_log_id = ?,
|
|
1366
|
+
meta = COALESCE(?, meta),
|
|
1367
|
+
config_warnings = COALESCE(?, config_warnings),
|
|
1368
|
+
last_heartbeat_at = COALESCE(last_heartbeat_at, ?)
|
|
1369
|
+
WHERE id = ?
|
|
1370
|
+
AND status = 'running'
|
|
1371
|
+
AND holder_pid IS ?
|
|
1372
|
+
AND holder_host IS ?
|
|
1373
|
+
AND started_at = ?
|
|
1374
|
+
AND last_heartbeat_at IS ?
|
|
1375
|
+
`),heartbeatTrackedInvocation:t.prepare(`
|
|
1376
|
+
UPDATE tracked_invocation
|
|
1377
|
+
SET last_heartbeat_at = ?
|
|
1378
|
+
WHERE id = ?
|
|
1379
|
+
AND status = 'running'
|
|
1380
|
+
`),claimTrackedInvocationNotification:t.prepare(`
|
|
1381
|
+
UPDATE tracked_invocation
|
|
1382
|
+
SET notified_by = ?,
|
|
1383
|
+
notified_at = ?
|
|
1384
|
+
WHERE id = ?
|
|
1385
|
+
AND notified_by IS NULL
|
|
1386
|
+
`),updateTrackedInvocationRequestPayload:t.prepare(`
|
|
1387
|
+
UPDATE tracked_invocation
|
|
1388
|
+
SET request_payload = ?
|
|
1389
|
+
WHERE id = ?
|
|
1390
|
+
AND status = 'running'
|
|
1391
|
+
`),linkTrackedInvocationChatLog:t.prepare(`
|
|
1392
|
+
UPDATE tracked_invocation
|
|
1393
|
+
SET team_chat_log_id = ?
|
|
1394
|
+
WHERE id = ?
|
|
1395
|
+
AND status = 'running'
|
|
1396
|
+
AND team_chat_log_id IS NULL
|
|
1397
|
+
`),abortTrackedInvocationIfUnchanged:t.prepare(`
|
|
1398
|
+
UPDATE tracked_invocation
|
|
1399
|
+
SET status = 'aborted',
|
|
1400
|
+
ended_at = ?,
|
|
1401
|
+
error = ?
|
|
1402
|
+
WHERE id = ?
|
|
1403
|
+
AND status = 'running'
|
|
1404
|
+
AND holder_pid IS ?
|
|
1405
|
+
AND holder_host IS ?
|
|
1406
|
+
AND started_at = ?
|
|
1407
|
+
AND last_heartbeat_at IS ?
|
|
1408
|
+
`)}}function we(t){if(t==null)return null;if(Buffer.byteLength(t,"utf8")<=65536)return t;let r=Buffer.byteLength(aa,"utf8"),n=Math.max(0,65536-r),s=Buffer.from(t,"utf8"),i=n;for(;i>0&&(s[i]&192)===128;)i-=1;return`${s.subarray(0,i).toString("utf8")}${aa}`}var Vt="terminal_lock",Kt="member";function Yt(t,e){return JSON.stringify([t,e])}function ca(t){try{let e=JSON.parse(t);return typeof e.lock_id!="string"||typeof e.teamfile!="string"||typeof e.alias!="string"||typeof e.holder_pid!="number"||typeof e.holder_host!="string"||!Array.isArray(e.holder_ips)||!e.holder_ips.every(r=>typeof r=="string")||typeof e.started_at!="string"||typeof e.last_heartbeat!="string"?null:{lock_id:e.lock_id,teamfile:e.teamfile,alias:e.alias,holder_pid:e.holder_pid,holder_host:e.holder_host,holder_ips:e.holder_ips,started_at:e.started_at,last_heartbeat:e.last_heartbeat}}catch{return null}}function _e(t){if(!Number.isInteger(t)||(t??0)<=0)return!1;try{return process.kill(t,0),!0}catch(e){return(e!==null&&typeof e=="object"&&"code"in e?e.code:void 0)!=="ESRCH"}}import{randomUUID as Qm}from"node:crypto";import{hostname as Zm}from"node:os";import{hostname as It}from"node:os";var da=8*60*60*1e3,ua=12e4,Gm=3e4;function Wr(t,e={}){let r=setInterval(()=>{Promise.resolve().then(()=>t(new Date().toISOString())).then(n=>{n||clearInterval(r)}).catch(n=>e.onError?.(n))},e.intervalMs??Gm);return r.unref?.(),r}function Hr(t,e){let r=new Date().toISOString(),n=new Date(Date.now()-e.ttlMs).toISOString(),s={receiver_teamfile:e.receiver_teamfile,receiver_alias:e.receiver_alias,sender_teamfile:e.sender_teamfile,sender_alias:e.sender_alias,started_at:r},i=t.getAgentInflight(e.receiver_teamfile,e.receiver_alias),o=i===null||i.holder_pid===null,a=t.tryAcquireAgentInflight(s,{...o?{stale_before:n}:{},force:e.force,reclaim_reason:e.reclaimReason});if(a.acquired){let c=i===null?null:e.force===!0?e.reclaimReason??"force":i.holder_pid===null&&i.started_at<n?"stale":null;return{acquired:!0,lease:a.current??s,leaseId:a.lease_id,previous:i,reclaimReason:c}}if(!qr(a.current,n))return{acquired:!1,current:a.current};let l=t.tryAcquireAgentInflight(s,a.current.holder_pid===null?{stale_before:n}:{reclaim_observed:{sender_teamfile:a.current.sender_teamfile,sender_alias:a.current.sender_alias,started_at:a.current.started_at,holder_pid:a.current.holder_pid},reclaim_reason:"dead-pid"});return l.acquired?{acquired:!0,lease:l.current??s,leaseId:l.lease_id,previous:a.current,reclaimReason:a.current.holder_pid===null?"stale":"dead-pid"}:{acquired:!1,current:l.current}}function ma(t){return t.status!=="running"?null:t.holder_host===It()&&t.holder_pid!==null&&t.holder_pid>0?_e(t.holder_pid)?"live":"dead":"unknown"}function Xr(t,e,r){let n,s=t.getTerminalLock(e,r);if(s!==null){if(Jm(s))return{busy:!0,reason:"terminal-held",source:"terminal-lock",terminalLock:s};n??={source:"terminal-lock",holder_pid:s.holder_pid,holder_host:s.holder_host,reason:s.holder_host===It()?"dead-pid":"stale"}}let i=Vm(t,e,r);if(i!==null){if(Km(i))return{busy:!0,reason:"terminal-held",source:"terminal-invocation",terminalInvocation:i};n??={source:"terminal-invocation",holder_pid:i.holder_pid,holder_host:i.holder_host,reason:i.holder_pid!==null&&(i.holder_host===null||i.holder_host===It())?"dead-pid":"stale"}}let o=t.getAgentInflight(e,r);if(o!==null){let a=new Date(Date.now()-At()).toISOString();if(!qr(o,a))return{busy:!0,reason:"in-flight",inFlight:o};n??={source:"in-flight",holder_pid:o.holder_pid,holder_host:o.holder_pid===null?null:It(),reason:o.holder_pid===null?"stale":"dead-pid"}}return n===void 0?{busy:!1}:{busy:!1,reclaimable:n}}function Jm(t){if(t.holder_host===It())return _e(t.holder_pid);let e=Date.parse(t.last_heartbeat);return Number.isFinite(e)?Date.now()-e<=zm():!1}function Vm(t,e,r){return t.query(`SELECT id, started_at, last_heartbeat_at, holder_pid, holder_host
|
|
1409
|
+
FROM tracked_invocation
|
|
1410
|
+
WHERE target_teamfile = ?
|
|
1411
|
+
AND target_alias = ?
|
|
1412
|
+
AND status = 'running'
|
|
1413
|
+
AND launch_source = 'terminal'
|
|
1414
|
+
ORDER BY started_at DESC, id DESC
|
|
1415
|
+
LIMIT 1`,e,r)[0]??null}function Km(t){return t.holder_pid!==null&&(t.holder_host===null||t.holder_host===It())?_e(t.holder_pid):Ym(t)}function Ym(t){let e=Date.parse(t.last_heartbeat_at??t.started_at);return Number.isFinite(e)?Date.now()-e<=At():!1}function qr(t,e){return t.holder_pid===null?t.started_at<e:!_e(t.holder_pid)}function At(t=process.env){let e=t.LMCTL_INFLIGHT_TTL_MS;if(e===void 0||e.trim()==="")return da;let r=Number(e);return!Number.isFinite(r)||r<=0?da:r}function zm(t=process.env){let e=t.LMCTL_TERMINAL_LOCK_STALE_MS;if(e===void 0||e.trim()==="")return ua;let r=Number(e);return!Number.isFinite(r)||r<=0?ua:r}var ef=60*60*1e3;function qe(t,e){return{teamfile:t,alias:e}}function fa(t,e,r={}){return{teamfile:t,alias:e,...r.provider===void 0||r.provider===null?{}:{provider:r.provider},...r.sessionId===void 0||r.sessionId===null?{}:{session_id:r.sessionId}}}function _s(t,e){return t===null?null:qe(t,e??"")}function Fe(t){return`msg_tcl_${t}`}function at(t){return`inv_${t}`}function xt(t,e,r){return t.prepare(`SELECT receiver_teamfile, receiver_alias, lease_id, sender_teamfile, sender_alias,
|
|
1416
|
+
holder_pid, holder_host, started_at, terminal_lock_id,
|
|
1417
|
+
terminal_invocation_id, currently_handling_message_id,
|
|
1418
|
+
currently_handling_since, last_seq
|
|
1419
|
+
FROM agent_state
|
|
1420
|
+
WHERE receiver_teamfile = ? AND receiver_alias = ?`).get(e,r)??null}function tf(t,e,r){if(e===null||r===null)return null;let n=t.prepare(`SELECT currently_handling_message_id, currently_handling_since
|
|
1421
|
+
FROM agent_state
|
|
1422
|
+
WHERE receiver_teamfile = ? AND receiver_alias = ?`).get(e,r);if(n?.currently_handling_message_id===null||n?.currently_handling_message_id===void 0||n.currently_handling_since===null)return null;let s=Date.parse(n.currently_handling_since);return!Number.isFinite(s)||Date.now()-s>ef?null:n.currently_handling_message_id}function rf(t,e,r){let n=tf(t,e,r);return n===null?{}:{causation:{request_message_id:n}}}function Es(t,e,r,n,s=new Date().toISOString()){t.prepare(`INSERT INTO agent_state
|
|
1423
|
+
(receiver_teamfile, receiver_alias, currently_handling_message_id,
|
|
1424
|
+
currently_handling_since, last_seq)
|
|
1425
|
+
VALUES (?, ?, ?, ?, 0)
|
|
1426
|
+
ON CONFLICT(receiver_teamfile, receiver_alias) DO UPDATE SET
|
|
1427
|
+
currently_handling_message_id = excluded.currently_handling_message_id,
|
|
1428
|
+
currently_handling_since = excluded.currently_handling_since`).run(e,r,n,s)}function ys(t,e,r,n){return t.prepare(`UPDATE agent_state
|
|
1429
|
+
SET currently_handling_message_id = NULL,
|
|
1430
|
+
currently_handling_since = NULL
|
|
1431
|
+
WHERE receiver_teamfile = ? AND receiver_alias = ?
|
|
1432
|
+
AND currently_handling_message_id = ?`).run(e,r,n).changes===1}function nf(t,e){let r=e??new Date(Date.now()-At()).toISOString();return qr({holder_pid:t.holder_pid,started_at:t.started_at??""},r)}function sf(t,e,r){return e==="force"||e==="session-idle"?e:r?"force":t.holder_pid!==null&&!_e(t.holder_pid)?"dead-pid":"stale"}function of(t){return{sender:_s(t.sender_teamfile,t.sender_alias),holder_pid:t.holder_pid,holder_host:t.holder_host,started_at:t.started_at}}function Rt(t,e){if(t!==1)throw new Error(`event projection CAS failed during ${e}`)}function Ts(t,e,r){let n=Fe(e),s=_s(r.sender_teamfile,r.sender_alias),i=fa(r.receiver_teamfile,r.receiver_alias,{provider:r.receiver_provider,sessionId:r.receiver_session_id}),o={message_id:n,message_type:"request",sender:s,receiver:i,root_teamfile:r.root_teamfile,legacy:{table:"team_chat_log",id:e}};return ue(t,{stream_id:n,event_type:"CREATE",observedLastSeq:0,ts:r.created_at,payload:{...o,content:r.message,provider_prompt:r.provider_prompt??r.message,origin:r.origin,...rf(t,r.sender_teamfile,r.sender_alias)}},()=>{Es(t,r.receiver_teamfile,r.receiver_alias,n,r.created_at)}),n}function Gr(t,e,r){let n=Fe(e),s={message_id:n,message_type:"request",sender:_s(r.sender_teamfile,r.sender_alias),receiver:fa(r.receiver_teamfile,r.receiver_alias,{provider:r.receiver_provider,sessionId:r.receiver_session_id}),root_teamfile:r.root_teamfile,legacy:{table:"team_chat_log",id:e}};return ue(t,{stream_id:n,event_type:"HANDLED",observedLastSeq:1,ts:r.created_at,payload:{...s,outcome:r.status,receipt:r.response,error:r.error_detail,truncated:r.truncated===1}},()=>{ys(t,r.receiver_teamfile,r.receiver_alias,n)}),n}function af(t){return{sender:qe(t.sender_teamfile,t.sender_alias),holder_pid:t.holder_pid,holder_host:null,started_at:t.started_at}}function pa(t,e,r,n){let s=t.prepare(`UPDATE agent_state
|
|
1433
|
+
SET lease_id = NULL, sender_teamfile = NULL, sender_alias = NULL,
|
|
1434
|
+
holder_pid = NULL, holder_host = NULL, started_at = NULL,
|
|
1435
|
+
last_heartbeat_at = NULL, last_seq = ?
|
|
1436
|
+
WHERE receiver_teamfile = ? AND receiver_alias = ?
|
|
1437
|
+
AND lease_id IS ? AND last_seq = ?`).run(r,e.receiver_teamfile,e.receiver_alias,e.lease_id,e.last_seq);Rt(s.changes,n)}function ha(t,e,r,n,s=null,i=!1){let o=Zm();if(r!==null&&n===null)throw new Error("agent inflight takeover is missing a reclaim reason");let a=xt(t,e.receiver_teamfile,e.receiver_alias);if(a!==null&&a.lease_id!==null){if(!(i||nf(a,s)))throw new Error("event projection rejected INFLIGHT_TAKE: receiver already holds a live lease");let d=sf(a,n,i),p=of(a),m=a.lease_id;ue(t,{stream_id:m,event_type:"INFLIGHT_RECLAIM",observedLastSeq:a.last_seq,ts:e.started_at,payload:{receiver:qe(e.receiver_teamfile,e.receiver_alias),reason:d,previous_holder:p}},h=>pa(t,a,h,"INFLIGHT_RECLAIM")),a=xt(t,e.receiver_teamfile,e.receiver_alias)}let l=a?.last_seq??0,c=`lease_${Qm()}`;return ue(t,{stream_id:c,event_type:"INFLIGHT_TAKE",observedLastSeq:l,ts:e.started_at,payload:{lease_id:c,receiver:qe(e.receiver_teamfile,e.receiver_alias),sender:qe(e.sender_teamfile,e.sender_alias),holder_pid:e.holder_pid,holder_host:o,started_at:e.started_at}},u=>{if(a===null){t.prepare(`INSERT INTO agent_state
|
|
1438
|
+
(receiver_teamfile, receiver_alias, lease_id, sender_teamfile,
|
|
1439
|
+
sender_alias, holder_pid, holder_host, started_at,
|
|
1440
|
+
last_heartbeat_at, last_seq)
|
|
1441
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(e.receiver_teamfile,e.receiver_alias,c,e.sender_teamfile,e.sender_alias,e.holder_pid,o,e.started_at,e.started_at,u);return}let d=t.prepare(`UPDATE agent_state
|
|
1442
|
+
SET lease_id = ?, sender_teamfile = ?, sender_alias = ?,
|
|
1443
|
+
holder_pid = ?, holder_host = ?, started_at = ?,
|
|
1444
|
+
last_heartbeat_at = ?, last_seq = ?
|
|
1445
|
+
WHERE receiver_teamfile = ? AND receiver_alias = ?
|
|
1446
|
+
AND lease_id IS NULL AND last_seq = ?`).run(c,e.sender_teamfile,e.sender_alias,e.holder_pid,o,e.started_at,e.started_at,u,e.receiver_teamfile,e.receiver_alias,a.last_seq);Rt(d.changes,"INFLIGHT_TAKE")}),c}function ga(t,e,r,n){return t.prepare(`UPDATE agent_state
|
|
1447
|
+
SET last_heartbeat_at = ?
|
|
1448
|
+
WHERE receiver_teamfile = ? AND receiver_alias = ?
|
|
1449
|
+
AND lease_id = ?
|
|
1450
|
+
AND sender_teamfile = ? AND sender_alias = ?
|
|
1451
|
+
AND started_at = ? AND holder_pid IS ?`).run(n,e.receiver_teamfile,e.receiver_alias,r,e.sender_teamfile,e.sender_alias,e.started_at,e.holder_pid).changes===1}function zt(t,e,r,n){let s=xt(t,e.receiver_teamfile,e.receiver_alias);s===null||s.lease_id===null||ue(t,{stream_id:s.lease_id,event_type:r,observedLastSeq:s.last_seq,payload:{receiver:qe(e.receiver_teamfile,e.receiver_alias),...r==="INFLIGHT_RECLAIM"?{reason:n??"stale",previous_holder:af(e)}:{lease_id:s.lease_id}}},i=>pa(t,s,i,r))}function _a(t,e){let r=xt(t,e.teamfile,e.alias),n=r?.last_seq??0;ue(t,{stream_id:e.lock_id,event_type:"TERMINAL_LOCK_TAKE",observedLastSeq:n,ts:e.started_at,payload:{receiver:qe(e.teamfile,e.alias),lock_id:e.lock_id,holder_pid:e.holder_pid,holder_host:e.holder_host,started_at:e.started_at}},s=>{if(r===null){t.prepare(`INSERT INTO agent_state
|
|
1452
|
+
(receiver_teamfile, receiver_alias, terminal_lock_id, last_seq)
|
|
1453
|
+
VALUES (?, ?, ?, ?)`).run(e.teamfile,e.alias,e.lock_id,s);return}let i=t.prepare(`UPDATE agent_state SET terminal_lock_id = ?, last_seq = ?
|
|
1454
|
+
WHERE receiver_teamfile = ? AND receiver_alias = ?
|
|
1455
|
+
AND terminal_lock_id IS NULL AND last_seq = ?`).run(e.lock_id,s,e.teamfile,e.alias,r.last_seq);Rt(i.changes,"TERMINAL_LOCK_TAKE")})}function Ss(t,e,r=!1){let n=xt(t,e.teamfile,e.alias);n===null||n.terminal_lock_id!==e.lock_id||ue(t,{stream_id:e.lock_id,event_type:r?"TERMINAL_LOCK_EXPIRE":"TERMINAL_LOCK_RELEASE",observedLastSeq:n.last_seq,payload:{receiver:qe(e.teamfile,e.alias),lock_id:e.lock_id,holder_pid:e.holder_pid,holder_host:e.holder_host}},s=>{let i=t.prepare(`UPDATE agent_state SET terminal_lock_id = NULL, last_seq = ?
|
|
1456
|
+
WHERE receiver_teamfile = ? AND receiver_alias = ?
|
|
1457
|
+
AND terminal_lock_id = ? AND last_seq = ?`).run(s,e.teamfile,e.alias,e.lock_id,n.last_seq);Rt(i.changes,r?"TERMINAL_LOCK_EXPIRE":"TERMINAL_LOCK_RELEASE")})}function Ea(t,e,r){let n=xt(t,r.targetTeamfile,r.targetAlias);if(n===null){t.prepare(`INSERT INTO agent_state
|
|
1458
|
+
(receiver_teamfile, receiver_alias, terminal_invocation_id,
|
|
1459
|
+
terminal_invocation_pid, terminal_invocation_host,
|
|
1460
|
+
terminal_invocation_heartbeat_at, last_seq)
|
|
1461
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`).run(r.targetTeamfile,r.targetAlias,r.invocationId,r.holderPid,r.holderHost,r.heartbeatAt,e);return}let s=t.prepare(`UPDATE agent_state
|
|
1462
|
+
SET terminal_invocation_id = ?, terminal_invocation_pid = ?,
|
|
1463
|
+
terminal_invocation_host = ?,
|
|
1464
|
+
terminal_invocation_heartbeat_at = ?, last_seq = ?
|
|
1465
|
+
WHERE receiver_teamfile = ? AND receiver_alias = ?
|
|
1466
|
+
AND terminal_invocation_id IS NULL AND last_seq = ?`).run(r.invocationId,r.holderPid,r.holderHost,r.heartbeatAt,e,r.targetTeamfile,r.targetAlias,n.last_seq);Rt(s.changes,"terminal INVOCATION_START")}function ya(t,e,r){return t.prepare(`UPDATE agent_state
|
|
1467
|
+
SET terminal_invocation_heartbeat_at = ?
|
|
1468
|
+
WHERE terminal_invocation_id = ?`).run(r,e).changes===1}function Ta(t,e,r){let n=t.prepare(`SELECT receiver_teamfile, receiver_alias, lease_id, terminal_lock_id,
|
|
1469
|
+
terminal_invocation_id, last_seq
|
|
1470
|
+
FROM agent_state WHERE terminal_invocation_id = ?`).get(r);if(n===void 0)return;let s=t.prepare(`UPDATE agent_state
|
|
1471
|
+
SET terminal_invocation_id = NULL, terminal_invocation_pid = NULL,
|
|
1472
|
+
terminal_invocation_host = NULL,
|
|
1473
|
+
terminal_invocation_heartbeat_at = NULL, last_seq = ?
|
|
1474
|
+
WHERE receiver_teamfile = ? AND receiver_alias = ?
|
|
1475
|
+
AND terminal_invocation_id = ? AND last_seq = ?`).run(e,n.receiver_teamfile,n.receiver_alias,r,n.last_seq);Rt(s.changes,"terminal INVOCATION_FINISH")}var lf="INVOCATION_START",cf="INVOCATION_FINISH",df="INVOCATION_NOTIFY_CLAIM";function Sa(t,e){return t.prepare("SELECT last_seq FROM invocation_state WHERE invocation_id = ?").get(e)??null}function ws(t){return t.launch_source==="terminal"&&t.target_teamfile!==null}function wa(t,e){let r=at(e.id),n=e.target_teamfile===null?null:{teamfile:e.target_teamfile,alias:e.target_alias??""},s=e.last_heartbeat_at??e.started_at;ue(t,{stream_id:r,event_type:lf,observedLastSeq:0,ts:e.started_at,payload:{invocation_id:r,kind:e.kind,origin:e.origin,launch_source:e.launch_source,from_identity:e.from_identity,target:n,root_teamfile:e.root_teamfile,scope_teamfile:e.scope_teamfile,cwd:e.cwd,command:e.command,request_payload:e.request_payload,request_message_id:e.team_chat_log_id===null?null:`msg_tcl_${e.team_chat_log_id}`,holder_pid:e.holder_pid,holder_host:e.holder_host,started_at:e.started_at,legacy:{table:"tracked_invocation",id:e.id}}},i=>{t.prepare(`INSERT INTO invocation_state
|
|
1476
|
+
(invocation_id, kind, origin, launch_source, from_identity, target_teamfile, target_alias,
|
|
1477
|
+
root_teamfile, cwd, command, request_message_id, request_payload, holder_pid, holder_host,
|
|
1478
|
+
status, started_at, last_heartbeat_at, last_seq)
|
|
1479
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'running', ?, ?, ?)`).run(r,e.kind,e.origin,e.launch_source??e.kind,e.from_identity,e.target_teamfile,e.target_alias,e.root_teamfile,e.cwd,e.command,e.team_chat_log_id===null?null:`msg_tcl_${e.team_chat_log_id}`,e.request_payload,e.holder_pid,e.holder_host,e.started_at,e.last_heartbeat_at,i),ws(e)&&Ea(t,i,{invocationId:r,targetTeamfile:e.target_teamfile,targetAlias:e.target_alias??"",holderPid:e.holder_pid,holderHost:e.holder_host,heartbeatAt:s})})}function Jr(t,e){let r=at(e.id),n=Sa(t,r);return n===null?!1:(ue(t,{stream_id:r,event_type:cf,observedLastSeq:n.last_seq,ts:e.ended_at??e.started_at,payload:{invocation_id:r,status:e.status,ended_at:e.ended_at,exit_code:e.exit_code,signal:e.signal,result_summary:e.result_summary,error:e.error,legacy:{table:"tracked_invocation",id:e.id}}},s=>{if(t.prepare(`UPDATE invocation_state
|
|
1480
|
+
SET status = ?, ended_at = ?, result_summary = ?, error = ?, last_seq = ?
|
|
1481
|
+
WHERE invocation_id = ? AND last_seq = ?`).run(e.status,e.ended_at,e.result_summary,e.error,s,r,n.last_seq).changes!==1)throw new Error(`invocation_state CAS failed during INVOCATION_FINISH for ${r}`);ws(e)&&Ta(t,s,r)}),!0)}function va(t,e,r,n){let s=at(e.id),i=Sa(t,s);return i===null?!1:(ue(t,{stream_id:s,event_type:df,observedLastSeq:i.last_seq,ts:n,payload:{invocation_id:s,notified_by:r,notified_at:n,legacy:{table:"tracked_invocation",id:e.id}}},o=>{if(t.prepare("UPDATE invocation_state SET notified_by = ?, notified_at = ?, last_seq = ? WHERE invocation_id = ? AND last_seq = ?").run(r,n,o,s,i.last_seq).changes!==1)throw new Error(`invocation_state CAS failed during INVOCATION_NOTIFY_CLAIM for ${s}`)}),!0)}function Ia(t,e,r){let n=at(e.id);t.prepare("UPDATE invocation_state SET last_heartbeat_at = ? WHERE invocation_id = ?").run(r,n),ws(e)&&ya(t,n,r)}function Aa(t,e,r){t.prepare("UPDATE invocation_state SET request_payload = ? WHERE invocation_id = ?").run(r,at(e))}function xa(t,e,r){t.prepare("UPDATE invocation_state SET request_message_id = ? WHERE invocation_id = ?").run(r,at(e))}var uf="other",mf=["not_enough_information","dont_know","other_work"],ET=new Set([uf,...mf]),Ra="@abort",ba="invalid_decision";var Na="workflow_escalation";function L(){return new Date().toISOString()}function gf(t){let e={rootTeams:[],config:[]};if(t===":memory:"||!Ma(t))return e;let r;try{r=new Ur(t,{readonly:!0})}catch{return e}try{let n=[];try{n=r.prepare("SELECT teamfile_path, name, raw_text, raw_sha256, registered_at, last_seeded_at FROM root_team").all()}catch{}let s=[];try{s=r.prepare("SELECT key, value FROM lmctl_config").all()}catch{}return{rootTeams:n,config:s}}finally{r.close()}}function _f(t){if(t===":memory:"||!Ma(t))return null;let e=`${t}.bak-${Date.now()}-${process.pid}`;for(let r of["","-wal","-shm"]){let n=`${t}${r}`;try{pf(n,`${e}${r}`)}catch{}}return e}function La(t,e){let r=e instanceof Error?e.message:String(e);try{let n=gf(t),s=_f(t),i=new Vr(Br({dbPath:t}));for(let o of n.rootTeams)i.upsertRootTeam(o);for(let{key:o,value:a}of n.config)i.setConfig(o,a);return process.stderr.write(`lmctl: couldn't migrate ${t} to schema v${Xe} (${r}); started a fresh database instead. Preserved ${n.rootTeams.length} team registration(s) and ${n.config.length} config value(s).`+(s!==null?` Old database backed up at ${s}.
|
|
1482
|
+
`:`
|
|
1483
|
+
`)),i}catch(n){let s=n instanceof Error?n.message:String(n);throw new Error(`${t}: unusable (${r}), and recovery into a fresh database also failed (${s}). Check that the containing directory is writable, or move the file aside manually and retry.`)}}function Ca(t,e){let r;try{return r=Br({dbPath:t,allowSchemaSkew:e}),{dal:new Vr(r)}}catch(n){if(n instanceof Jt)throw n;let s;if(r!==void 0)try{s=r.pragma("user_version",{simple:!0})}catch{}try{r?.close()}catch{}return{cause:n,dbVersion:s}}}var Ef=3,Fa=".recovery.lock",yf=20,Tf=50;function Sf(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}function wf(t){if(t===":memory:")return!0;try{return ff(`${t}${Fa}`),!0}catch{return!1}}function vf(t){if(t!==":memory:")try{hf(`${t}${Fa}`)}catch{}}function lt(t){let e=t.allowSchemaSkew??process.env.LMCTL_ALLOW_SCHEMA_SKEW==="1",r={};for(let n=0;n<Ef;n+=1)if(r=Ca(t.path,e),r.dal!==void 0)return r.dal;if(r.dbVersion!==void 0&&r.dbVersion>Xe){let n=r.cause instanceof Error?r.cause.message:String(r.cause);throw new Error(`${t.path}: state.db schema is v${r.dbVersion}; this build (understands v${Xe}) can no longer operate on it (${n}). Update lmctl: npm install -g @lmctl-ai/lmctl@latest`)}for(let n=0;n<yf;n+=1){if(wf(t.path))try{return La(t.path,r.cause)}finally{vf(t.path)}Sf(Tf);let s=Ca(t.path,e);if(s.dal!==void 0)return s.dal}return La(t.path,r.cause)}var Vr=class{db;stmts;claimTxn;claimWithConcurrencyTxn;claimByIdWithConcurrencyTxn;resumeRunTxn;resumeInteractiveTxn;resumeEscalationTxn;tryAcquireAgentInflightTxn;constructor(e){e.pragma("foreign_keys = ON"),this.db=e,this.stmts=bf(e),this.claimTxn=e.transaction((r,n,s)=>{let i=this.stmts.selectClaimableJob.get(s,s,s);return i===void 0||this.stmts.claimJob.run(r,n,s,i.id,s,s,s).changes!==1?null:this.getJob(i.id)}),this.claimWithConcurrencyTxn=e.transaction((r,n,s,i)=>{let o=this.stmts.selectClaimableJobs.all(s,s,s);for(let a of o){let l=this.getJob(a.id);if(l===null)continue;let c=i(l);if(c.concurrency_key!==null&&(l.concurrency_key_resolved!==c.concurrency_key&&this.stmts.setJobConcurrencyKey.run(c.concurrency_key,l.id),(this.stmts.countRunningByConcurrencyKey.get(c.concurrency_key,s,l.id)?.count??0)>=Math.max(1,c.concurrent_limit)))continue;if(this.stmts.claimJob.run(r,n,s,l.id,s,s,s).changes===1)return this.getJob(l.id)}return null}),this.claimByIdWithConcurrencyTxn=e.transaction((r,n,s,i,o)=>{let a=this.getJob(r);if(a===null)return{claimed:!1,reason:"not_found",job_id:r};if(a.locked_until!==null&&a.locked_until>=i)return{claimed:!1,reason:"locked",job_id:r,status:a.status,locked_by:a.locked_by,locked_until:a.locked_until};let c=a.status==="queued"&&a.available_at<=i,u=a.status==="running"&&a.locked_until!==null&&a.locked_until<i;if(!c&&!u)return{claimed:!1,reason:"not_claimable",job_id:r,status:a.status,locked_by:a.locked_by,locked_until:a.locked_until};let d=o(a);if(d.concurrency_key!==null&&(a.concurrency_key_resolved!==d.concurrency_key&&this.stmts.setJobConcurrencyKey.run(d.concurrency_key,a.id),(this.stmts.countRunningByConcurrencyKey.get(d.concurrency_key,i,a.id)?.count??0)>=Math.max(1,d.concurrent_limit)))return{claimed:!1,reason:"concurrency_limit",job_id:r,status:a.status,locked_by:a.locked_by,locked_until:a.locked_until};if(this.stmts.claimJob.run(n,s,i,a.id,i,i,i).changes!==1){let h=this.getJob(a.id);return{claimed:!1,reason:h?.locked_until!==null&&h?.locked_until!==void 0&&h.locked_until>=i?"locked":"not_claimable",job_id:r,status:h?.status??a.status,locked_by:h?.locked_by??a.locked_by,locked_until:h?.locked_until??a.locked_until}}let m=this.getJob(a.id);return m===null?{claimed:!1,reason:"not_found",job_id:r}:{claimed:!0,job:m}}),this.resumeRunTxn=e.transaction((r,n,s)=>Nf("state_not_found")),this.resumeInteractiveTxn=e.transaction((r,n,s,i)=>{let o=this.getInteractiveSessionByStepId(r);if(o===null)return{resumed:!1,reason:"not_found"};if(o.status!=="waiting_operator")return{resumed:!1,reason:"not_waiting_operator"};let a=this.getRun(o.run_id);if(a===null)return{resumed:!1,reason:"run_not_found"};let l=s?"done":"waiting_agent";return this.stmts.updateInteractiveSession.run(l,n,Date.now(),o.id),this.stmts.resumeRunState.run(o.state_name,a.id),this.stmts.requeuePausedJob.run(i,a.job_id),{resumed:!0,session:this.getInteractiveSessionByStepId(r),run:this.getRun(a.id),job:this.getJob(a.job_id)}}),this.resumeEscalationTxn=e.transaction((r,n,s)=>{let i=this.stmts.getAttention.get(r);if(i===void 0)return{resumed:!1,reason:"not_found"};if(i.kind!==Na)return{resumed:!1,reason:"wrong_kind"};if(i.acknowledged_at!==null)return{resumed:!1,reason:"already_acked"};if(i.run_id===null)return{resumed:!1,reason:"run_not_found"};let o=null,a=[];if(i.payload!==null)try{let u=JSON.parse(i.payload);u.step!==void 0&&typeof u.step.id=="string"&&u.step.id.length>0&&(o=u.step.id),Array.isArray(u.declared_outcomes)&&(a=u.declared_outcomes.filter(d=>typeof d=="string"))}catch{}if(o===null)return{resumed:!1,reason:"no_step"};let l=this.getRun(i.run_id);if(l===null)return{resumed:!1,reason:"run_not_found"};if(n!==Ra&&!a.includes(n))return{resumed:!1,reason:ba};let c={};if(l.pending_escalation_decision!==null)try{let u=JSON.parse(l.pending_escalation_decision);u!==null&&typeof u=="object"&&!Array.isArray(u)&&(c=u)}catch{c={}}return c[o]=n,this.stmts.setRunPendingEscalationDecision.run(JSON.stringify(c),l.id),this.stmts.resumeRunState.run(o,l.id),this.stmts.requeuePausedJob.run(s,l.job_id),this.stmts.ackAttention.run(s,r),{resumed:!0,run:this.getRun(l.id),job:this.getJob(l.job_id)}}),this.tryAcquireAgentInflightTxn=(r,n={})=>{this.db.exec("BEGIN IMMEDIATE");try{let s=this.getAgentInflight(r.receiver_teamfile,r.receiver_alias),i=n.reclaim_observed,o=this.stmts.acquireAgentInflight.get({...r,holder_pid:process.pid,stale_before:n.stale_before??null,force:n.force===!0?1:0,reclaim_observed_sender_teamfile:i?.sender_teamfile??null,reclaim_observed_sender_alias:i?.sender_alias??null,reclaim_observed_started_at:i?.started_at??null,reclaim_observed_holder_pid:typeof i?.holder_pid=="number"?i.holder_pid:null}),a;if(o!==void 0){let l=s===null?null:n.reclaim_reason??(n.force===!0?"force":n.reclaim_observed!==void 0?"dead-pid":"stale"),c=ha(this.db,o,s,l,n.stale_before??null,n.force===!0);a={acquired:!0,current:o,lease_id:c}}else a={acquired:!1,current:this.getAgentInflight(r.receiver_teamfile,r.receiver_alias)??(()=>{throw new Error("agent_inflight conflict row disappeared during acquire")})()};return this.db.exec("COMMIT"),a}catch(s){throw this.db.inTransaction&&this.db.exec("ROLLBACK"),s}}}close(){this.db.close()}query(e,...r){let n=e.trim().toLowerCase();if(!n.startsWith("select")&&!n.startsWith("with")&&!n.startsWith("pragma"))throw new Error("Dal.query only allows read-only SELECT/WITH/PRAGMA statements");return this.db.prepare(e).all(...r)}insertWorkflow(e){Oa(e.name,e.definition,o=>this.getWorkflowByName(o));let r=this.stmts.insertWorkflow.run(e.name,e.version??1,e.definition_schema_version??1,e.definition,L()),n=this.getWorkflow(Number(r.lastInsertRowid)),s=this.stmts.insertWorkflowVersion.run(n.id,n.version,e.definition,e.author??null,L());this.stmts.updateWorkflowActiveVersion.run(s.lastInsertRowid,n.id),(e.source_uri!=null||e.source_sha256!=null)&&this.stmts.setWorkflowSource.run(e.source_uri??null,e.source_sha256??null,n.id);let i=this.getWorkflow(n.id);return this.syncWorkflowTriggers(n.id,e.definition),i}upsertWorkflow(e){Oa(e.name,e.definition,o=>this.getWorkflowByName(o));let r=this.getWorkflowByName(e.name);if(r===null)return this.insertWorkflow({name:e.name,definition_schema_version:e.definition_schema_version,definition:e.definition,author:e.author,source_uri:e.source_uri,source_sha256:e.source_sha256});let s=(this.stmts.getLatestWorkflowVersion.get(r.id)?.version??r.version)+1,i=this.stmts.insertWorkflowVersion.run(r.id,s,e.definition,e.author??null,L());return this.stmts.updateWorkflowActiveVersionDefinitionAndVersion.run(Number(i.lastInsertRowid),e.definition,e.definition_schema_version??r.definition_schema_version,s,r.id),(e.source_uri!=null||e.source_sha256!=null)&&this.stmts.setWorkflowSource.run(e.source_uri??null,e.source_sha256??null,r.id),this.syncWorkflowTriggers(r.id,e.definition),this.getWorkflow(r.id)}insertCompositionUnit(e){this.stmts.insertCompositionUnit.run(e.name,e.version,e.lang,e.source,e.source_sha,e.compiled_workflow_version_id,L())}getWorkflow(e){return this.stmts.getWorkflow.get(e)??null}getWorkflowByName(e,r){return(r===void 0?this.stmts.findWorkflowLatest.get(e):this.stmts.findWorkflowVersion.get(e,r))??null}findWorkflowByName(e,r){return this.getWorkflowByName(e,r)}insertWorkflowVersion(e,r,n){let i=(this.stmts.getLatestWorkflowVersion.get(e)?.version??0)+1,o=this.stmts.insertWorkflowVersion.run(e,i,r,n??null,L());return this.stmts.getWorkflowVersion.get(o.lastInsertRowid)}activateWorkflowVersion(e,r){let n=this.getWorkflowVersionById(r);if(n===null||n.workflow_id!==e)return null;let s=1;try{let i=JSON.parse(n.definition);typeof i.definition_schema_version=="number"&&(s=i.definition_schema_version)}catch{}return this.stmts.updateWorkflowActiveVersionAndDefinition.run(r,n.definition,s,e),this.syncWorkflowTriggers(e,n.definition),this.getWorkflow(e)}getWorkflowVersionById(e){return this.stmts.getWorkflowVersion.get(e)??null}listWorkflowVersions(e){return this.stmts.listWorkflowVersions.all(e)}upsertTriggerInstance(e){return this.stmts.upsertTriggerInstance.run(e.workflow_id,e.trigger_id,e.trigger_type,e.parameters,e.enabled===!1?0:1,L()),this.stmts.getTriggerInstanceByWorkflowAndId.get(e.workflow_id,e.trigger_id)}listTriggerInstancesForWorkflow(e){return this.stmts.listTriggerInstancesForWorkflow.all(e)}listEnabledTriggerInstances(){return this.stmts.listEnabledTriggerInstances.all()}setTriggerCursor(e,r){return this.stmts.setTriggerCursor.run(r,L(),e),this.stmts.getTriggerInstance.get(e)??null}setTriggerFailure(e,r){return this.stmts.setTriggerFailure.run(L(),r,e),this.stmts.getTriggerInstance.get(e)??null}syncWorkflowTriggers(e,r){let n;try{n=JSON.parse(r)}catch{return}if(n===null||typeof n!="object"||Array.isArray(n))return;let s=n.triggers;if(Array.isArray(s))for(let i of s){if(i===null||typeof i!="object"||Array.isArray(i))continue;let o=i;typeof o.id!="string"||o.id.length===0||typeof o.type!="string"||o.type.length===0||this.upsertTriggerInstance({workflow_id:e,trigger_id:o.id,trigger_type:o.type,parameters:JSON.stringify(o.parameters??{})})}}insertTeam(e){let r=this.stmts.insertTeam.run(e.name,L());return this.stmts.getTeam.get(r.lastInsertRowid)}getTeam(e){return this.stmts.getTeam.get(e)??null}findTeamByName(e){return this.stmts.findTeamByName.get(e)??null}listTeams(){return this.stmts.listTeams.all()}insertTeamMember(e){let r=this.stmts.insertTeamMember.run(e.team_id,e.alias,e.role??"agent",e.provider,e.model??null,e.sessionid??null,e.sessiondir,L());return this.stmts.getTeamMember.get(r.lastInsertRowid)}listTeamMembers(e){return this.stmts.listTeamMembers.all(e)}findTeamMemberByAlias(e,r){return this.stmts.findTeamMemberByAlias.get(e,r)??null}updateTeamMemberSession(e,r){return this.stmts.updateTeamMemberSession.run(r,e),this.stmts.getTeamMember.get(e)??null}setMemberState(e,r,n){return this.stmts.setMemberState.run(r,n??null,L(),e),this.stmts.getTeamMember.get(e)??null}listMembersInState(e){return this.stmts.listMembersInState.all(e)}setMemberPromptSnapshot(e,r){return this.stmts.setMemberPromptSnapshot.run(r,e),this.stmts.getTeamMember.get(e)??null}setMemberProviderResolved(e,r){return this.stmts.setMemberProviderResolved.run(r,e),this.stmts.getTeamMember.get(e)??null}setMemberRolePrompt(e,r){return this.stmts.setMemberRolePrompt.run(r,e),this.stmts.getTeamMember.get(e)??null}updateTeamMemberMeta(e,r){let n=this.stmts.getTeamMember.get(e);if(n===void 0)return null;let s=Object.prototype.hasOwnProperty.call(r,"role_prompt"),i=Object.prototype.hasOwnProperty.call(r,"model"),o=Object.prototype.hasOwnProperty.call(r,"provider");return this.stmts.updateTeamMemberMeta.run(s?r.role_prompt??null:n.role_prompt,i?r.model??null:n.model,o?r.provider??n.provider:n.provider,e),this.stmts.getTeamMember.get(e)??null}insertTeamMemberCompanion(e){let r=this.stmts.insertTeamMemberCompanion.run(e.interpreter_id,e.companion_id,L());return this.stmts.getTeamMemberCompanion.get(r.lastInsertRowid)}insertProject(e){let r=this.stmts.insertProject.run(e.name,e.description??null,e.local_path,e.workflow_name,e.team_id,e.default_branch??null,e.intake_config??null,e.test_argv??null,e.test_command??null,e.durable_memory_mode??"folder",L());return this.stmts.getProject.get(r.lastInsertRowid)}listProjects(){return this.stmts.listProjects.all()}getProject(e){return this.stmts.getProject.get(e)??null}findProjectByName(e){return this.stmts.findProjectByName.get(e)??null}setProjectIntakeConfig(e,r){return this.stmts.setProjectIntakeConfig.run(r,e),this.stmts.getProject.get(e)??null}updateProjectSettings(e,r){let n=this.stmts.getProject.get(e);if(n===void 0)return null;let s=Object.prototype.hasOwnProperty.call(r,"local_path"),i=Object.prototype.hasOwnProperty.call(r,"durable_memory_mode"),o=Object.prototype.hasOwnProperty.call(r,"default_branch"),a=Object.prototype.hasOwnProperty.call(r,"intake_config");return this.stmts.updateProjectSettings.run(s?r.local_path:n.local_path,i?r.durable_memory_mode:n.durable_memory_mode,o?r.default_branch??null:n.default_branch,a?r.intake_config??null:n.intake_config,e),this.stmts.getProject.get(e)??null}listProjectsWithIntakeEnabled(){return this.stmts.listProjectsWithIntakeConfig.all().filter(e=>{if(e.intake_config===null)return!1;try{let r=JSON.parse(e.intake_config);return typeof r=="object"&&r!==null&&!Array.isArray(r)&&r.scan_github_issues===!0}catch{return!1}})}getProjectByJob(e){return this.stmts.getProjectByJob.get(e)??null}insertProjectWorkflow(e){let r=e.condition??null,n=this.stmts.findProjectWorkflowUnique.get(e.project_id,e.workflow_id,r);if(n!==void 0)return n;let s=this.stmts.insertProjectWorkflow.run(e.project_id,e.workflow_id,r,e.parameters_override??null,e.enabled===!1?0:1,e.priority??100,L());return s.changes===1?this.stmts.getProjectWorkflow.get(s.lastInsertRowid):this.stmts.findProjectWorkflowUnique.get(e.project_id,e.workflow_id,r)}getProjectWorkflow(e){return this.stmts.getProjectWorkflow.get(e)??null}listProjectWorkflows(e,r={}){return r.enabled_only===!0?this.stmts.listEnabledProjectWorkflows.all(e):this.stmts.listProjectWorkflows.all(e)}removeProjectWorkflow(e){return this.stmts.removeProjectWorkflow.run(e).changes>0}setProjectWorkflowEnabled(e,r){return this.stmts.setProjectWorkflowEnabled.run(r?1:0,e),this.getProjectWorkflow(e)}createIssue(e){let r=L(),n=this.stmts.createIssue.run(e.project_id,e.title,e.body,e.severity??"medium",e.labels??null,e.ai_test_path??null,e.source_run_id??null,r,r);return this.stmts.getIssue.get(n.lastInsertRowid)}getIssue(e){return this.stmts.getIssue.get(e)??null}listIssues(e,r={}){return this.stmts.listIssuesForProject.all(e).filter(n=>!(r.status!==void 0&&!r.status.includes(n.status)||r.severity!==void 0&&!r.severity.includes(n.severity)||r.ai_test_path!==void 0&&n.ai_test_path!==r.ai_test_path))}claimNextIssue(e,r){return this.stmts.claimNextIssue.get(r,L(),e)??null}claimIssue(e,r){return this.stmts.claimIssue.get(r,L(),e)??null}closeIssue(e,r,n){let s=L(),i=this.stmts.closeIssue.get(r,n??null,s,s,e);if(i===void 0)throw new Error(`issue not found: ${e}`);return i}reopenIssue(e,r){let n=this.stmts.reopenIssue.get(r,L(),e);if(n===void 0)throw this.getIssue(e)===null?new Error(`issue not found: ${e}`):new Error(`issue ${e} is not closed`);return n}updateIssue(e,r){let n=this.getIssue(e);if(n===null)throw new Error(`issue not found: ${e}`);let s=Object.prototype.hasOwnProperty.call(r,"labels"),i=Object.prototype.hasOwnProperty.call(r,"ai_test_path"),o=this.stmts.updateIssue.get(r.title??n.title,r.body??n.body,r.severity??n.severity,s?r.labels??null:n.labels,i?r.ai_test_path??null:n.ai_test_path,L(),e);if(o===void 0)throw new Error(`issue not found: ${e}`);return o}listWorkflows(){return this.stmts.listWorkflows.all()}getOrCreateWebuiSession(e,r){let n=this.stmts.getWebuiSession.get(e);if(n!==void 0)return n;let s=L();return this.stmts.insertWebuiSession.run(e,r,"N1",null,null,null,null,"authenticated",s,s),this.stmts.getWebuiSession.get(e)}getWebuiSession(e){return this.stmts.getWebuiSession.get(e)??null}updateWebuiSessionTransition(e,r,n,s,i){if(this.stmts.updateWebuiSessionTransition.run(r,n,s,i,L(),e).changes===0)throw new Error(`webui_session not found: ${e}`);return this.stmts.getWebuiSession.get(e)}setWebuiSessionChatbot(e,r){if(this.stmts.setWebuiSessionChatbot.run(r,L(),e).changes===0)throw new Error(`webui_session not found: ${e}`);return this.stmts.getWebuiSession.get(e)}createChatbotSession(e,r){let n=ka(),s=L();return this.stmts.insertChatbotSession.run(n,e,r??null,s,s,"active"),this.stmts.getChatbotSession.get(n)}getChatbotSession(e){return this.stmts.getChatbotSession.get(e)??null}listChatbotSessions(e){return this.stmts.listChatbotSessionsForUser.all(e)}appendChatbotMessage(e,r,n,s){let i=L(),o=this.stmts.insertChatbotMessage.run(e,r,n,s??null,i);return this.stmts.touchChatbotSession.run(i,e),this.stmts.getChatbotMessage.get(o.lastInsertRowid)}listChatbotMessages(e){return this.stmts.listChatbotMessages.all(e)}getConfig(e){return this.stmts.getConfig.get(e)?.value??null}setConfig(e,r){this.stmts.upsertConfig.run(e,r,L())}getConfigAll(){let e=this.stmts.listConfig.all(),r={};for(let n of e)r[n.key]=n.value;return r}enqueueJob(e){let r=this.stmts.insertJob.run(e.project_id,e.workflow_id_override??null,e.source,e.source_ref??null,e.payload??null,e.priority??0,e.available_at??L(),e.dedupe_key??null,e.concurrency_key??null,L());if(r.changes===1)return this.stmts.getJob.get(r.lastInsertRowid);if(e.dedupe_key===void 0||e.dedupe_key===null)throw new Error("job insert ignored without dedupe key");return this.stmts.findJobByDedupe.get(e.source,e.dedupe_key)}claimNextJob(e){let r=L(),n=new Date(Date.now()+e.lease_ms).toISOString();return this.claimTxn(e.worker_id,n,r)}claimNextJobWithConcurrency(e){let r=L(),n=new Date(Date.now()+e.lease_ms).toISOString();return this.claimWithConcurrencyTxn(e.worker_id,n,r,e.evaluator)}claimJobByIdWithConcurrency(e){let r=L(),n=new Date(Date.now()+e.lease_ms).toISOString();return this.claimByIdWithConcurrencyTxn(e.job_id,e.worker_id,n,r,e.evaluator)}releaseJob(e,r,n){let s=r==="queued"||r==="running"?null:L();return this.stmts.releaseJob.run(r,n??null,s,e),this.getJob(e)}getJob(e){return this.stmts.getJob.get(e)??null}findJobBySourceAndDedupe(e,r){return this.stmts.findJobByDedupe.get(e,r)??null}insertRun(e){let r=this.getWorkflow(e.workflow_id);if(r===null)throw new Error(`workflow not found: ${e.workflow_id}`);let n=this.stmts.insertRun.run(e.job_id,e.workflow_id,e.team_id,e.current_state??null,r.active_version_id,e.parent_run_id??null,L()),s=this.stmts.getRun.get(n.lastInsertRowid);return(e.parent_run_id===void 0||e.parent_run_id===null)&&this.stmts.setJobRun.run(s.id,e.job_id),s}setJobRun(e,r){return this.stmts.setJobRun.run(r,e),this.getJob(e)}insertPromptDispatch(e){return this.stmts.insertPromptDispatch.run(e.prompt_id,e.project_id,e.job_id,e.text,e.context_json??null,L()),this.stmts.getPromptDispatch.get(e.prompt_id)}getPromptDispatch(e){return this.stmts.getPromptDispatch.get(e)??null}setPromptDispatchCompleted(e,r){return this.stmts.setPromptDispatchCompleted.run(r??L(),e),this.getPromptDispatch(e)}getWorkspace(e){return this.stmts.getWorkspace.get(e)??null}ensureWorkspace(e={}){let r=e.id??"default";this.stmts.ensureWorkspace.run(r,e.name??"Default workspace",e.idleThresholdMs??6e5,L());let n=this.getWorkspace(r);if(n===null)throw new Error(`workspace ${r} missing after upsert`);return n}listWebProjectsActive(e){return this.stmts.listWebProjectsActive.all(e)}getWebProject(e){return this.stmts.getWebProject.get(e)??null}insertWebProject(e){let r=L(),n=this.stmts.insertWebProject.run(e.workspace_id,e.name,e.repo_path,e.config_json??null,e.linked_v4_project_id??null,r,r),s=Number(n.lastInsertRowid),i=this.getWebProject(s);if(i===null)throw new Error(`web_project ${s} missing after insert`);return i}updateWebProject(e){let r=this.getWebProject(e.id);return r===null||r.deleted_at!==null?null:(this.stmts.updateWebProject.run(e.name??r.name,e.config_json===void 0?r.config_json:e.config_json,L(),e.id),this.getWebProject(e.id))}softDeleteWebProject(e){return this.stmts.softDeleteWebProject.run(L(),e).changes===1}loadMailboxCursor(e,r){return this.stmts.loadMailboxCursor.get(e,r)??null}saveMailboxCursor(e){this.stmts.saveMailboxCursor.run(e.user_id,e.mailbox_key,e.last_processed_version_id,e.last_processed_seq??null,e.last_processed_at)}addUsage(e){this.stmts.addUsage.run(e.user_id,e.device_id,e.period,e.put,e.get,e.list,e.updated_at)}loadUsage(e,r,n){return this.stmts.loadUsage.get(e,r,n)??null}sumUsageForPeriod(e,r){let n=this.stmts.sumUsageForPeriod.get(e,r);return{put:n?.put??0,get:n?.get??0,list:n?.list??0}}upsertRootTeam(e){this.stmts.upsertRootTeam.run(e.teamfile_path,e.name,e.raw_text,e.raw_sha256,e.registered_at,e.last_seeded_at)}getRootTeam(e){return this.stmts.getRootTeam.get(e)??null}listRootTeams(){return this.stmts.listRootTeams.all()}insertTeamChatLog(e){return this.db.transaction(()=>{let r=this.stmts.insertTeamChatLog.run(e.root_teamfile,e.sender_teamfile,e.sender_alias,e.receiver_teamfile,e.receiver_alias,e.message,e.response,e.origin,e.status,e.error_detail,e.truncated,e.message_type??null,e.created_at),n=Number(r.lastInsertRowid);return Ts(this.db,n,e),Gr(this.db,n,e),n})()}beginTeamChatLog(e){return this.db.transaction(()=>{let r=this.stmts.insertTeamChatLog.run(e.root_teamfile,e.sender_teamfile,e.sender_alias,e.receiver_teamfile,e.receiver_alias,e.message,e.response,e.origin,e.status,e.error_detail,e.truncated,e.message_type??null,e.created_at),n=Number(r.lastInsertRowid);return Ts(this.db,n,e),n})()}finishTeamChatLog(e,r){this.db.transaction(()=>{if(this.stmts.updateTeamChatLogResponse.run(r.response,r.status,r.error_detail,r.truncated,e).changes!==1)throw new Error(`team_chat_log row disappeared during finish: ${e}`);Gr(this.db,e,r)})()}setCurrentlyHandlingMessage(e,r,n){this.db.transaction(()=>{Es(this.db,e,r,n)})()}clearCurrentlyHandlingMessage(e,r,n){return this.db.transaction(()=>ys(this.db,e,r,n))()}listTeamChatLog(e){return this.stmts.listTeamChatLog.all(e)}listTeamChatLogSinceId(e,r=500){return this.stmts.listTeamChatLogSinceId.all(e,Math.max(1,Math.trunc(r)))}getMaxTeamChatLogId(){return this.stmts.getMaxTeamChatLogId.get()?.max_id??0}loadTeamChatLogCursor(e){return this.stmts.loadTeamChatLogCursor.get(e)??null}saveTeamChatLogCursor(e){this.stmts.saveTeamChatLogCursor.run(e.cursor_key,e.last_pushed_id,e.updated_at)}startTrackedInvocation(e){return this.db.transaction(()=>this.startTrackedInvocationInner(e))()}startTrackedInvocationInner(e){let r=e.started_at??L(),n=e.holder_host??vs(),s=e.last_heartbeat_at??r,i=this.stmts.insertTrackedInvocation.run(e.kind,e.origin,e.scope_teamfile??null,e.from_identity,e.target_teamfile??null,e.target_alias??null,e.root_teamfile??null,e.cwd??null,we(e.command),r,e.holder_pid??null,n,s,we(e.meta),e.launch_source??e.kind,e.request_payload??null,e.parent_invocation_id??null),o=this.getTrackedInvocation(Number(i.lastInsertRowid));return wa(this.db,o),o}getTrackedInvocation(e){return this.stmts.getTrackedInvocation.get(e)??null}listTrackedInvocationsForTarget(e,r,n={}){let s=["target_teamfile = ?","target_alias = ?"],i=[e,r];n.sinceMs!==void 0&&(s.push("started_at >= ?"),i.push(new Date(n.sinceMs).toISOString())),n.untilMs!==void 0&&(s.push("started_at <= ?"),i.push(new Date(n.untilMs).toISOString()));let o=Math.max(1,Math.trunc(n.limit??200));return this.db.prepare(`SELECT * FROM tracked_invocation WHERE ${s.join(" AND ")} ORDER BY started_at DESC LIMIT ?`).all(...i,o)}listAllRunningTrackedInvocations(){return this.stmts.listAllRunningTrackedInvocations.all()}listRecentlyFinishedTrackedInvocations(e){return this.stmts.listRecentlyFinishedTrackedInvocations.all(e)}listFinishedTrackedInvocationChildren(e,r){if(e.length===0)return[];let n=e.map(()=>"?").join(", ");return this.db.prepare(`
|
|
1484
|
+
SELECT * FROM tracked_invocation
|
|
1485
|
+
WHERE parent_invocation_id IN (${n})
|
|
1486
|
+
AND ended_at IS NOT NULL
|
|
1487
|
+
AND ended_at >= ?
|
|
1488
|
+
ORDER BY started_at ASC, id ASC
|
|
1489
|
+
`).all(...e,r)}finishTrackedInvocation(e,r){return this.db.transaction(()=>{let n=r.ended_at??L();if(this.stmts.finishTrackedInvocation.run(r.status,n,r.exit_code??null,r.signal??null,we(r.result_summary),we(r.error),r.team_chat_log_id??null,we(r.meta),we(r.config_warnings),n,e).changes!==1)return null;let i=this.getTrackedInvocation(e);return Jr(this.db,i),i})()}reclaimTrackedInvocationIfUnchanged(e,r,n){return this.db.transaction(()=>{let s=n.ended_at??L();if(this.stmts.reclaimTrackedInvocationIfUnchanged.run(n.status,s,n.exit_code??null,n.signal??null,we(n.result_summary),we(n.error),n.team_chat_log_id??null,we(n.meta),we(n.config_warnings),s,e,r.holder_pid,r.holder_host,r.started_at,r.last_heartbeat_at).changes!==1)return null;let o=this.getTrackedInvocation(e);return Jr(this.db,o),o})()}heartbeatTrackedInvocation(e,r=L()){return this.db.transaction(()=>{if(this.stmts.heartbeatTrackedInvocation.run(r,e).changes!==1)return null;let s=this.getTrackedInvocation(e);return Ia(this.db,s,r),s})()}updateTrackedInvocationRequestPayload(e,r){return this.db.transaction(()=>this.stmts.updateTrackedInvocationRequestPayload.run(r,e).changes!==1?null:(Aa(this.db,e,r),this.getTrackedInvocation(e)))()}linkTrackedInvocationMessage(e,r){return this.db.transaction(()=>this.stmts.linkTrackedInvocationChatLog.run(r,e).changes!==1?null:(xa(this.db,e,Fe(r)),this.getTrackedInvocation(e)))()}abortTrackedInvocationAndTerminalizeMessage(e,r,n){return this.db.transaction(()=>{let s=L();if(this.stmts.abortTrackedInvocationIfUnchanged.run(s,we(n),e,r.holder_pid,r.holder_host,r.started_at,r.last_heartbeat_at).changes!==1)return null;let o=this.getTrackedInvocation(e);return Jr(this.db,o),o.team_chat_log_id!==null&&this.terminalizeLinkedChatMessage(o.team_chat_log_id,n),o})()}terminalizeLinkedChatMessage(e,r){let n=this.stmts.getTeamChatLogById.get(e);n===void 0||n.status!=="running"||this.stmts.terminalizeTeamChatLogIfRunning.run("error",r,e).changes!==1||Gr(this.db,e,{root_teamfile:n.root_teamfile,sender_teamfile:n.sender_teamfile,sender_alias:n.sender_alias,receiver_teamfile:n.receiver_teamfile,receiver_alias:n.receiver_alias,message:n.message,response:null,origin:n.origin,status:"error",error_detail:r,truncated:n.truncated,created_at:L()})}listClaimableTerminalTrackedInvocations(e){let r=["status IN ('done', 'error', 'busy', 'cancelled', 'aborted')","ended_at IS NOT NULL","notified_by IS NULL"],n=[];e.from!==void 0&&(r.push("from_identity = ?"),n.push(e.from)),e.scope_teamfile!==void 0&&(r.push("scope_teamfile = ?"),n.push(e.scope_teamfile));let s=Math.max(1,Math.min(1e3,Math.trunc(e.limit??100)));return n.push(s),this.db.prepare(`SELECT * FROM tracked_invocation WHERE ${r.join(" AND ")} ORDER BY ended_at ASC, id ASC LIMIT ?`).all(...n)}claimTrackedInvocationNotification(e,r,n=L()){return this.db.transaction(()=>{if(this.stmts.claimTrackedInvocationNotification.run(r,n,e).changes!==1)return null;let i=this.getTrackedInvocation(e);return va(this.db,i,r,n),i})()}listTrackedInvocations(e={}){let r=[],n=[];e.from!==void 0&&(r.push("from_identity = ?"),n.push(e.from)),e.scope_teamfile!==void 0&&(r.push("scope_teamfile = ?"),n.push(e.scope_teamfile)),e.status!==void 0&&(r.push("status = ?"),n.push(e.status)),e.kind!==void 0&&(r.push("kind = ?"),n.push(e.kind)),e.origin!==void 0&&(r.push("origin = ?"),n.push(e.origin));let s=Math.max(1,Math.min(1e3,Math.trunc(e.limit??100)));n.push(s);let i=r.length===0?"":` WHERE ${r.join(" AND ")}`;return this.db.prepare(`SELECT * FROM tracked_invocation${i} ORDER BY started_at DESC, id DESC LIMIT ?`).all(...n)}maxTrackedInvocationId(e={}){let r=[],n=[];e.from!==void 0&&(r.push("from_identity = ?"),n.push(e.from)),e.scope_teamfile!==void 0&&(r.push("scope_teamfile = ?"),n.push(e.scope_teamfile));let s=r.length===0?"":` WHERE ${r.join(" AND ")}`,i=this.db.prepare(`SELECT COALESCE(MAX(id), 0) AS max_id FROM tracked_invocation${s}`).get(...n);return Number(i?.max_id??0)}listRunningTrackedInvocations(e={}){return this.listTrackedInvocations({...e,status:"running"})}updateTeamChatLogResponse(e,r){this.stmts.updateTeamChatLogResponse.run(r.response,r.status,r.error_detail,r.truncated,e)}getAgentInflight(e,r){return this.stmts.getAgentInflight.get(e,r)??null}listAgentInflight(){return this.stmts.listAgentInflight.all()}tryAcquireAgentInflight(e,r){return this.tryAcquireAgentInflightTxn(e,r)}heartbeatAgentInflight(e,r,n=L()){return this.db.transaction(()=>{let s=this.getAgentInflight(e.receiver_teamfile,e.receiver_alias);return s===null||s.sender_teamfile!==e.sender_teamfile||s.sender_alias!==e.sender_alias||s.started_at!==e.started_at?!1:ga(this.db,s,r,n)})()}clearAgentInflight(e,r){this.db.transaction(()=>{let s=this.getAgentInflight(e,r);if(s===null)return;this.stmts.clearAgentInflight.run(e,r).changes===1&&zt(this.db,s,"INFLIGHT_RECLAIM","stale")})()}clearObservedTerminalAgentInflight(e,r,n){return this.db.transaction(()=>{let i=this.getAgentInflight(e,r),o=this.stmts.clearObservedTerminalAgentInflight.run({receiver_teamfile:e,receiver_alias:r,observed_sender_teamfile:n.sender_teamfile,observed_sender_alias:n.sender_alias,observed_started_at:n.started_at,observed_holder_pid:n.holder_pid});return o.changes===1&&i!==null&&zt(this.db,i,"INFLIGHT_RELEASE"),o.changes===1})()}releaseAgentInflight(e,r){this.db.exec("BEGIN IMMEDIATE");try{let n=this.getAgentInflight(e.receiver_teamfile,e.receiver_alias);if(n===null||n.sender_teamfile!==e.sender_teamfile||n.sender_alias!==e.sender_alias)return this.db.exec("COMMIT"),!1;if(r!==void 0&&this.db.prepare(`SELECT lease_id FROM agent_state
|
|
1490
|
+
WHERE receiver_teamfile = ? AND receiver_alias = ?`).get(e.receiver_teamfile,e.receiver_alias)?.lease_id!==r)return this.db.exec("COMMIT"),!1;if(n.active_count<=1){let i=this.stmts.clearAgentInflightIfSender.run(e.receiver_teamfile,e.receiver_alias,e.sender_teamfile,e.sender_alias);return i.changes===1&&zt(this.db,n,"INFLIGHT_RELEASE"),this.db.exec("COMMIT"),i.changes===1}let s=this.stmts.decrementAgentInflight.run(e.receiver_teamfile,e.receiver_alias,e.sender_teamfile,e.sender_alias);return this.db.exec("COMMIT"),s.changes===1}catch(n){throw this.db.inTransaction&&this.db.exec("ROLLBACK"),n}}clearAgentInflightOlderThan(e){return this.db.transaction(()=>{let n=this.listAgentInflight().filter(i=>i.started_at<e),s=0;for(let i of n)this.stmts.clearAgentInflight.run(i.receiver_teamfile,i.receiver_alias).changes===1&&(zt(this.db,i,"INFLIGHT_RECLAIM","stale"),s+=1);return s})()}getTerminalLock(e,r){let n=this.stmts.getRuntimeState.get(Vt,Yt(e,r),Kt);return n===void 0?null:ca(n.data)}setTerminalLock(e){this.db.transaction(()=>{let n=this.getTerminalLock(e.teamfile,e.alias);n!==null&&n.lock_id!==e.lock_id&&Ss(this.db,n,!0),this.stmts.upsertRuntimeState.run(Vt,Yt(e.teamfile,e.alias),Kt,JSON.stringify(e),e.last_heartbeat),n?.lock_id!==e.lock_id&&_a(this.db,e)})()}heartbeatTerminalLock(e,r,n,s){this.db.exec("BEGIN IMMEDIATE");try{let i=this.getTerminalLock(e,r);if(i===null||i.lock_id!==n)return this.db.exec("COMMIT"),!1;let o={...i,last_heartbeat:s};return this.stmts.upsertRuntimeState.run(Vt,Yt(e,r),Kt,JSON.stringify(o),s),this.db.exec("COMMIT"),!0}catch(i){throw this.db.inTransaction&&this.db.exec("ROLLBACK"),i}}clearTerminalLock(e,r,n){this.db.exec("BEGIN IMMEDIATE");try{let s=this.getTerminalLock(e,r);if(s===null||s.lock_id!==n)return this.db.exec("COMMIT"),!1;let i=this.stmts.deleteRuntimeState.run(Vt,Yt(e,r),Kt);return i.changes===1&&Ss(this.db,s),this.db.exec("COMMIT"),i.changes===1}catch(s){throw this.db.inTransaction&&this.db.exec("ROLLBACK"),s}}getRuntimeProcessLock(e,r,n){let s=this.stmts.getRuntimeState.get(e,r,n);return s===void 0?null:xf(s.data)}tryAcquireRuntimeProcessLock(e,r,n,s,i=L()){this.db.exec("BEGIN IMMEDIATE");try{let o=this.getRuntimeProcessLock(e,r,n);if(o!==null&&!Rf(o,s))return this.db.exec("COMMIT"),{acquired:!1,current:o};let a={lock_id:ka(),holder_pid:process.pid,holder_host:vs(),started_at:i,last_heartbeat:i};return this.stmts.upsertRuntimeState.run(e,r,n,JSON.stringify(a),i),this.db.exec("COMMIT"),{acquired:!0,lock:a,previous:o}}catch(o){throw this.db.inTransaction&&this.db.exec("ROLLBACK"),o}}clearRuntimeProcessLock(e,r,n,s){this.db.exec("BEGIN IMMEDIATE");try{let i=this.getRuntimeProcessLock(e,r,n);if(i===null||i.lock_id!==s)return this.db.exec("COMMIT"),!1;let o=this.stmts.deleteRuntimeState.run(e,r,n);return this.db.exec("COMMIT"),o.changes===1}catch(i){throw this.db.inTransaction&&this.db.exec("ROLLBACK"),i}}getRun(e){return this.stmts.getRun.get(e)??null}setRunCurrentState(e,r){return this.stmts.setRunCurrentState.run(r,e),this.stmts.getRun.get(e)??null}setRunPausedState(e,r,n){return this.stmts.setRunPausedState.run(r,n,e),this.stmts.getRun.get(e)??null}setRunPendingEscalationDecision(e,r){return this.stmts.setRunPendingEscalationDecision.run(r,e),this.stmts.getRun.get(e)??null}setRunTerminalState(e,r){return this.stmts.setRunTerminalState.run(r,L(),e),this.stmts.getRun.get(e)??null}pauseJob(e){return this.stmts.pauseJob.run(e),this.getJob(e)}resumeRun(e,r){return this.resumeRunTxn(e,r,L())}insertStep(e){let r=this.stmts.insertStep.run(e.run_id,e.parent_step_id??null,e.state_name,e.outcome??null,e.status_detail??null,L());return this.stmts.getStep.get(r.lastInsertRowid)}finishStep(e,r,n){return this.stmts.finishStep.run(r??null,n??null,L(),e),this.stmts.getStep.get(e)??null}listStepsForRun(e){return this.stmts.listStepsForRun.all(e)}listLatestStepOutcomesByState(e){let r=this.stmts.listLatestStepOutcomesByState.all(e),n={};for(let s of r)n[s.state_name]=s.outcome;return n}insertSubmittedPr(e){let r=this.stmts.insertSubmittedPr.run(e.repo,e.pr_url,e.issue_url??null,e.local_path??null,e.branch??null,e.head_sha??null,e.status??"watching",e.submitted_at??L(),e.last_known_state??null,e.created_by_run_id??null);return this.stmts.getSubmittedPr.get(r.lastInsertRowid)}listSubmittedPrs(e){return e?.status!==void 0?this.stmts.listSubmittedPrsByStatus.all(e.status):this.stmts.listSubmittedPrs.all()}getSubmittedPr(e){return this.stmts.getSubmittedPr.get(e)??null}findSubmittedPrByUrl(e){return this.stmts.findSubmittedPrByUrl.get(e)??null}insertStepArtifact(e){let r=this.stmts.insertStepArtifact.run(e.step_id,e.kind,e.path??null,e.content??null,e.sha??null,e.provider_call_mode??null,L());return this.stmts.getStepArtifact.get(r.lastInsertRowid)}insertExternalObject(e){let n=this.stmts.insertExternalObject.run(e.type,e.provider,e.project_id,e.run_id??null,e.external_id,e.url??null,e.status??null,e.metadata??null,e.last_seen_at??null,L()).changes===1;return{row:this.stmts.findExternalObjectByUnique.get(e.provider,e.type,e.external_id),inserted:n}}insertExternalSignal(e){let r=this.stmts.insertExternalSignal.run(e.object_id,e.kind,e.source??null,e.occurred_at??null,e.payload??null,e.signal_hash??null,null,L()),n=r.changes===1;return{row:e.signal_hash===void 0||e.signal_hash===null?this.stmts.getExternalSignal.get(r.lastInsertRowid):this.stmts.findExternalSignalByUnique.get(e.object_id,e.kind,e.signal_hash),inserted:n}}raiseAttention(e){let r=this.stmts.insertAttention.run(e.kind,e.severity??"warn",e.project_id??null,e.run_id??null,e.external_object_id??null,e.requires_user===!0?1:0,e.payload??null,L());return this.stmts.getAttention.get(r.lastInsertRowid)}acknowledgeAttention(e){return this.stmts.ackAttention.run(L(),e),this.stmts.getAttention.get(e)??null}upsertDurableMemory(e){let r=L();return this.stmts.upsertDurableMemory.run(e.project_id,e.type,e.name,e.description??null,e.body,r,r),this.stmts.getDurableMemoryByName.get(e.project_id,e.name)}getDurableMemoryByName(e,r){return this.stmts.getDurableMemoryByName.get(e,r)??null}deleteDurableMemory(e,r){return this.stmts.deleteDurableMemory.run(e,r).changes>0}listDurableMemory(e,r){return r!==void 0?this.stmts.listDurableMemoryByType.all(e,r):this.stmts.listDurableMemory.all(e)}indexDurableMemory(e,r){return r!==void 0&&r.length>0?this.stmts.listDurableMemory.all(e).filter(s=>r.includes(s.type)).map(({name:s,description:i,type:o,updated_at:a})=>({name:s,description:i,type:o,updated_at:a})):this.stmts.listDurableMemory.all(e).map(({name:n,description:s,type:i,updated_at:o})=>({name:n,description:s,type:i,updated_at:o}))}recordSessionSize(e){let r=this.stmts.insertSessionSize.run(e.team_name,e.alias,e.sessionid,e.input_tokens??null,e.cache_tokens??null,e.output_tokens??null,e.total_tokens??null,e.observed_at??L());return this.stmts.getSessionSize.get(r.lastInsertRowid)}latestSessionSizes(){return this.stmts.latestSessionSizes.all()}sessionSizeHistory(e,r,n=20){return this.stmts.sessionSizeHistory.all(e,r,n)}insertSessionEvent(e){let r=this.stmts.insertSessionEvent.run(e.run_id,e.step_id??null,e.kind,e.timestamp_ms,e.payload,e.payload_truncated??0,e.overflow_artifact_id??null);return this.stmts.getSessionEvent.get(r.lastInsertRowid)}listSessionEvents(e,r){return r!==void 0?this.stmts.listSessionEventsSince.all(e,r):this.stmts.listSessionEvents.all(e)}listSessionEventsSince(e,r=1e3){return this.stmts.listAllEventsSince.all(e,r)}latestAgentCall(e){let r=this.db.prepare("SELECT payload FROM session_event WHERE run_id = ? AND kind = 'agent_call' ORDER BY id DESC LIMIT 1").get(e);if(r===void 0)return null;try{let n=JSON.parse(r.payload);return typeof n.alias!="string"||typeof n.provider!="string"?null:{alias:n.alias,provider:n.provider,...typeof n.model=="string"?{model:n.model}:{}}}catch{return null}}agentCallTokenTotals(e){let r=this.db.prepare("SELECT payload FROM session_event WHERE run_id = ? AND kind = 'agent_call'").all(e),n=0,s=0,i=0;for(let o of r)try{let a=JSON.parse(o.payload);typeof a.tokens_in=="number"&&(n+=a.tokens_in),typeof a.tokens_out=="number"&&(s+=a.tokens_out),i+=1}catch{}return{totalInputTokens:n,totalOutputTokens:s,agentCallCount:i}}addRollupValue(e){this.stmts.upsertRollupStat.run(e.run_id,e.step_id??null,e.metric_kind,e.value,e.bucket_start_ms,e.bucket_end_ms,e.updated_at)}listRollupStats(e){return this.stmts.listRollupStats.all(e)}getRollupCursor(){return this.stmts.getRollupCursor.get("last_event_id")?.value??0}setRollupCursor(e){this.stmts.setRollupCursor.run("last_event_id",e)}insertDriftSignal(e){let r=this.stmts.insertDriftSignal.run(e.team_member_id,e.project_id??null,e.signal_kind,e.severity,e.description,e.detected_at,e.expires_at??null,e.payload??null);return this.stmts.getDriftSignal.get(r.lastInsertRowid)}listDriftSignals(e={}){return e.team_member_id!==void 0&&e.unacked?this.stmts.listUnackedDriftByMember.all(e.team_member_id):e.team_member_id!==void 0?this.stmts.listDriftByMember.all(e.team_member_id):e.project_id!==void 0?this.stmts.listDriftByProject.all(e.project_id):this.stmts.listAllDrift.all()}hasUnackedDriftSignal(e,r,n){return this.stmts.findUnackedDrift.get(e,r??null,n)!==void 0}acknowledgeDriftSignal(e){return this.stmts.ackDriftSignal.run(Date.now(),e),this.stmts.getDriftSignal.get(e)??null}insertInteractiveSession(e){let r=Date.now();return this.stmts.insertInteractiveSession.run(e.run_id,e.step_id,e.state_name,e.status,r,r),this.stmts.getInteractiveSessionByStepId.get(e.step_id)}getInteractiveSessionByStepId(e){return this.stmts.getInteractiveSessionByStepId.get(e)??null}getInteractiveSessionByRunAndState(e,r){return this.stmts.getInteractiveSessionByRunAndState.get(e,r)??null}setInteractiveAgentOutput(e,r,n){this.stmts.setInteractiveAgentOutput.run(r,n,Date.now(),e)}resumeInteractive(e,r,n){return this.resumeInteractiveTxn(e,r,n,L())}resumeEscalation(e,r){return this.resumeEscalationTxn(e,r,L())}};function Oa(t,e,r){let n=Da(e);if(n.length===0)return;let s=new Set,i=[],o=l=>{if(l===t)return n;let c=r(l);if(c===null)throw new Error(`unknown workflow reference: ${l}`);return Da(c.definition)},a=l=>{let c=i.indexOf(l);if(c>=0)throw new Error(`cycle detected: ${[...i.slice(c),l].join(" -> ")}`);if(!s.has(l)){i.push(l);try{for(let u of o(l))a(u)}finally{i.pop()}s.add(l)}};a(t)}function Da(t){let e=If(t),r=e===null?null:Af(e,"states");if(r===null)return[];let n=[];for(let s of Object.values(r))Kr(s)&&s.type==="Subflow"&&typeof s.workflow_name=="string"&&s.workflow_name.length>0&&n.push(s.workflow_name);return n}function If(t){try{let e=JSON.parse(t);return Kr(e)?e:null}catch{return null}}function Af(t,e){let r=t[e];return Kr(r)?r:null}function Kr(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}function xf(t){try{let e=JSON.parse(t);return!Kr(e)||typeof e.lock_id!="string"||typeof e.holder_pid!="number"||typeof e.holder_host!="string"||typeof e.started_at!="string"||typeof e.last_heartbeat!="string"?null:{lock_id:e.lock_id,holder_pid:e.holder_pid,holder_host:e.holder_host,started_at:e.started_at,last_heartbeat:e.last_heartbeat}}catch{return null}}function Rf(t,e){return t===null?!0:t.holder_host===vs()?!_e(t.holder_pid):t.last_heartbeat<e}function bf(t){return{getRuntimeState:t.prepare("SELECT * FROM runtime_state WHERE scope = ? AND key = ? AND kind = ?"),upsertRuntimeState:t.prepare(`
|
|
1491
|
+
INSERT INTO runtime_state (scope, key, kind, data, updated_at)
|
|
1492
|
+
VALUES (?, ?, ?, ?, ?)
|
|
1493
|
+
ON CONFLICT(scope, key, kind) DO UPDATE SET
|
|
1494
|
+
data = excluded.data,
|
|
1495
|
+
updated_at = excluded.updated_at
|
|
1496
|
+
`),deleteRuntimeState:t.prepare("DELETE FROM runtime_state WHERE scope = ? AND key = ? AND kind = ?"),insertWorkflow:t.prepare(`
|
|
1497
|
+
INSERT INTO workflow (name, version, definition_schema_version, definition, created_at)
|
|
1498
|
+
VALUES (?, ?, ?, ?, ?)
|
|
1499
|
+
`),setWorkflowSource:t.prepare("UPDATE workflow SET source_uri = ?, source_sha256 = ? WHERE id = ?"),getWorkflow:t.prepare("SELECT * FROM workflow WHERE id = ?"),findWorkflowVersion:t.prepare("SELECT * FROM workflow WHERE name = ? AND version = ?"),findWorkflowLatest:t.prepare("SELECT * FROM workflow WHERE name = ? ORDER BY version DESC LIMIT 1"),updateWorkflowActiveVersion:t.prepare("UPDATE workflow SET active_version_id = ? WHERE id = ?"),updateWorkflowActiveVersionAndDefinition:t.prepare(`
|
|
1500
|
+
UPDATE workflow
|
|
1501
|
+
SET active_version_id = ?,
|
|
1502
|
+
definition = ?,
|
|
1503
|
+
definition_schema_version = ?
|
|
1504
|
+
WHERE id = ?
|
|
1505
|
+
`),updateWorkflowActiveVersionDefinitionAndVersion:t.prepare(`
|
|
1506
|
+
UPDATE workflow
|
|
1507
|
+
SET active_version_id = ?,
|
|
1508
|
+
definition = ?,
|
|
1509
|
+
definition_schema_version = ?,
|
|
1510
|
+
version = ?
|
|
1511
|
+
WHERE id = ?
|
|
1512
|
+
`),insertWorkflowVersion:t.prepare(`
|
|
1513
|
+
INSERT INTO workflow_version (workflow_id, version, definition, author, created_at)
|
|
1514
|
+
VALUES (?, ?, ?, ?, ?)
|
|
1515
|
+
`),getWorkflowVersion:t.prepare("SELECT * FROM workflow_version WHERE id = ?"),getLatestWorkflowVersion:t.prepare("SELECT version FROM workflow_version WHERE workflow_id = ? ORDER BY version DESC LIMIT 1"),listWorkflowVersions:t.prepare("SELECT * FROM workflow_version WHERE workflow_id = ? ORDER BY version DESC, id DESC"),upsertTriggerInstance:t.prepare(`
|
|
1516
|
+
INSERT INTO trigger_instance (workflow_id, trigger_id, trigger_type, parameters, enabled, created_at)
|
|
1517
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
1518
|
+
ON CONFLICT(workflow_id, trigger_id) DO UPDATE SET
|
|
1519
|
+
trigger_type = excluded.trigger_type,
|
|
1520
|
+
parameters = excluded.parameters,
|
|
1521
|
+
enabled = excluded.enabled
|
|
1522
|
+
`),getTriggerInstance:t.prepare("SELECT * FROM trigger_instance WHERE id = ?"),getTriggerInstanceByWorkflowAndId:t.prepare("SELECT * FROM trigger_instance WHERE workflow_id = ? AND trigger_id = ?"),listTriggerInstancesForWorkflow:t.prepare("SELECT * FROM trigger_instance WHERE workflow_id = ? ORDER BY trigger_id ASC"),listEnabledTriggerInstances:t.prepare("SELECT * FROM trigger_instance WHERE enabled = 1 ORDER BY id ASC"),setTriggerCursor:t.prepare("UPDATE trigger_instance SET cursor = ?, last_poll_at = ? WHERE id = ?"),setTriggerFailure:t.prepare("UPDATE trigger_instance SET last_failure_at = ?, last_failure = ? WHERE id = ?"),insertTeam:t.prepare("INSERT INTO team (name, created_at) VALUES (?, ?)"),getTeam:t.prepare("SELECT * FROM team WHERE id = ?"),findTeamByName:t.prepare("SELECT * FROM team WHERE name = ?"),listTeams:t.prepare("SELECT * FROM team ORDER BY name ASC, id ASC"),insertTeamMember:t.prepare(`
|
|
1523
|
+
INSERT INTO team_member
|
|
1524
|
+
(team_id, alias, role, provider, model, sessionid, sessiondir, created_at)
|
|
1525
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
1526
|
+
`),getTeamMember:t.prepare("SELECT * FROM team_member WHERE id = ?"),listTeamMembers:t.prepare("SELECT * FROM team_member WHERE team_id = ? ORDER BY id ASC"),findTeamMemberByAlias:t.prepare("SELECT * FROM team_member WHERE team_id = ? AND alias = ?"),updateTeamMemberSession:t.prepare("UPDATE team_member SET sessionid = ? WHERE id = ?"),setMemberState:t.prepare("UPDATE team_member SET state = ?, state_reason = ?, state_updated_at = ? WHERE id = ?"),listMembersInState:t.prepare("SELECT * FROM team_member WHERE state = ? ORDER BY id ASC"),setMemberPromptSnapshot:t.prepare("UPDATE team_member SET prompt_snapshot = ? WHERE id = ?"),setMemberProviderResolved:t.prepare("UPDATE team_member SET provider_resolved = ? WHERE id = ?"),setMemberRolePrompt:t.prepare("UPDATE team_member SET role_prompt = ? WHERE id = ?"),updateTeamMemberMeta:t.prepare(`
|
|
1527
|
+
UPDATE team_member
|
|
1528
|
+
SET role_prompt = ?,
|
|
1529
|
+
model = ?,
|
|
1530
|
+
provider = ?
|
|
1531
|
+
WHERE id = ?
|
|
1532
|
+
`),insertTeamMemberCompanion:t.prepare(`
|
|
1533
|
+
INSERT INTO team_member_companion (interpreter_id, companion_id, created_at)
|
|
1534
|
+
VALUES (?, ?, ?)
|
|
1535
|
+
`),getTeamMemberCompanion:t.prepare("SELECT * FROM team_member_companion WHERE id = ?"),insertProject:t.prepare(`
|
|
1536
|
+
INSERT INTO project
|
|
1537
|
+
(name, description, local_path, workflow_name, team_id, default_branch, intake_config, test_argv, test_command, durable_memory_mode, created_at)
|
|
1538
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1539
|
+
`),insertCompositionUnit:t.prepare(`
|
|
1540
|
+
INSERT INTO composition_unit
|
|
1541
|
+
(name, version, lang, source, source_sha, compiled_workflow_version_id, created_at)
|
|
1542
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
1543
|
+
`),getProject:t.prepare("SELECT * FROM project WHERE id = ?"),findProjectByName:t.prepare("SELECT * FROM project WHERE name = ?"),setProjectIntakeConfig:t.prepare("UPDATE project SET intake_config = ? WHERE id = ?"),updateProjectSettings:t.prepare(`
|
|
1544
|
+
UPDATE project
|
|
1545
|
+
SET local_path = ?,
|
|
1546
|
+
durable_memory_mode = ?,
|
|
1547
|
+
default_branch = ?,
|
|
1548
|
+
intake_config = ?
|
|
1549
|
+
WHERE id = ?
|
|
1550
|
+
`),listProjectsWithIntakeConfig:t.prepare("SELECT * FROM project WHERE intake_config IS NOT NULL ORDER BY name ASC, id ASC"),listProjects:t.prepare("SELECT * FROM project ORDER BY name ASC, id ASC"),getProjectByJob:t.prepare(`
|
|
1551
|
+
SELECT p.*
|
|
1552
|
+
FROM project p
|
|
1553
|
+
JOIN job j ON j.project_id = p.id
|
|
1554
|
+
WHERE j.id = ?
|
|
1555
|
+
`),insertProjectWorkflow:t.prepare(`
|
|
1556
|
+
INSERT OR IGNORE INTO project_workflow
|
|
1557
|
+
(project_id, workflow_id, condition, parameters_override, enabled, priority, created_at)
|
|
1558
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
1559
|
+
`),getProjectWorkflow:t.prepare("SELECT * FROM project_workflow WHERE id = ?"),findProjectWorkflowUnique:t.prepare(`
|
|
1560
|
+
SELECT * FROM project_workflow
|
|
1561
|
+
WHERE project_id = ?
|
|
1562
|
+
AND workflow_id = ?
|
|
1563
|
+
AND condition IS ?
|
|
1564
|
+
ORDER BY id ASC
|
|
1565
|
+
LIMIT 1
|
|
1566
|
+
`),listProjectWorkflows:t.prepare("SELECT * FROM project_workflow WHERE project_id = ? ORDER BY priority ASC, id ASC"),listEnabledProjectWorkflows:t.prepare("SELECT * FROM project_workflow WHERE project_id = ? AND enabled = 1 ORDER BY priority ASC, id ASC"),removeProjectWorkflow:t.prepare("DELETE FROM project_workflow WHERE id = ?"),setProjectWorkflowEnabled:t.prepare("UPDATE project_workflow SET enabled = ? WHERE id = ?"),createIssue:t.prepare(`
|
|
1567
|
+
INSERT INTO project_issue
|
|
1568
|
+
(project_id, title, body, severity, labels, ai_test_path, source_run_id, created_at, updated_at)
|
|
1569
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1570
|
+
`),getIssue:t.prepare("SELECT * FROM project_issue WHERE id = ?"),listIssuesForProject:t.prepare(`
|
|
1571
|
+
SELECT * FROM project_issue
|
|
1572
|
+
WHERE project_id = ?
|
|
1573
|
+
ORDER BY
|
|
1574
|
+
CASE severity
|
|
1575
|
+
WHEN 'critical' THEN 0
|
|
1576
|
+
WHEN 'high' THEN 1
|
|
1577
|
+
WHEN 'medium' THEN 2
|
|
1578
|
+
WHEN 'low' THEN 3
|
|
1579
|
+
ELSE 4
|
|
1580
|
+
END,
|
|
1581
|
+
created_at ASC,
|
|
1582
|
+
id ASC
|
|
1583
|
+
`),claimNextIssue:t.prepare(`
|
|
1584
|
+
UPDATE project_issue
|
|
1585
|
+
SET status = 'assigned',
|
|
1586
|
+
assigned_run_id = ?,
|
|
1587
|
+
updated_at = ?
|
|
1588
|
+
WHERE id = (
|
|
1589
|
+
SELECT id FROM project_issue
|
|
1590
|
+
WHERE project_id = ?
|
|
1591
|
+
AND status IN ('open', 'reopened')
|
|
1592
|
+
ORDER BY
|
|
1593
|
+
CASE severity
|
|
1594
|
+
WHEN 'critical' THEN 0
|
|
1595
|
+
WHEN 'high' THEN 1
|
|
1596
|
+
WHEN 'medium' THEN 2
|
|
1597
|
+
WHEN 'low' THEN 3
|
|
1598
|
+
ELSE 4
|
|
1599
|
+
END,
|
|
1600
|
+
created_at ASC,
|
|
1601
|
+
id ASC
|
|
1602
|
+
LIMIT 1
|
|
1603
|
+
)
|
|
1604
|
+
RETURNING *
|
|
1605
|
+
`),claimIssue:t.prepare(`
|
|
1606
|
+
UPDATE project_issue
|
|
1607
|
+
SET status = 'assigned',
|
|
1608
|
+
assigned_run_id = ?,
|
|
1609
|
+
updated_at = ?
|
|
1610
|
+
WHERE id = ?
|
|
1611
|
+
AND status IN ('open', 'reopened')
|
|
1612
|
+
RETURNING *
|
|
1613
|
+
`),closeIssue:t.prepare(`
|
|
1614
|
+
UPDATE project_issue
|
|
1615
|
+
SET status = 'closed',
|
|
1616
|
+
closed_run_id = ?,
|
|
1617
|
+
commit_hash = ?,
|
|
1618
|
+
closed_at = ?,
|
|
1619
|
+
updated_at = ?
|
|
1620
|
+
WHERE id = ?
|
|
1621
|
+
RETURNING *
|
|
1622
|
+
`),reopenIssue:t.prepare(`
|
|
1623
|
+
UPDATE project_issue
|
|
1624
|
+
SET status = 'reopened',
|
|
1625
|
+
source_run_id = ?,
|
|
1626
|
+
assigned_run_id = NULL,
|
|
1627
|
+
updated_at = ?,
|
|
1628
|
+
closed_at = NULL
|
|
1629
|
+
WHERE id = ?
|
|
1630
|
+
AND status = 'closed'
|
|
1631
|
+
RETURNING *
|
|
1632
|
+
`),updateIssue:t.prepare(`
|
|
1633
|
+
UPDATE project_issue
|
|
1634
|
+
SET title = ?,
|
|
1635
|
+
body = ?,
|
|
1636
|
+
severity = ?,
|
|
1637
|
+
labels = ?,
|
|
1638
|
+
ai_test_path = ?,
|
|
1639
|
+
updated_at = ?
|
|
1640
|
+
WHERE id = ?
|
|
1641
|
+
RETURNING *
|
|
1642
|
+
`),listWorkflows:t.prepare("SELECT * FROM workflow ORDER BY name ASC, version ASC"),upsertDurableMemory:t.prepare(`
|
|
1643
|
+
INSERT INTO durable_memory (project_id, type, name, description, body, created_at, updated_at)
|
|
1644
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
1645
|
+
ON CONFLICT(project_id, name) DO UPDATE SET
|
|
1646
|
+
type = excluded.type,
|
|
1647
|
+
description = excluded.description,
|
|
1648
|
+
body = excluded.body,
|
|
1649
|
+
updated_at = excluded.updated_at
|
|
1650
|
+
`),getDurableMemoryByName:t.prepare("SELECT * FROM durable_memory WHERE project_id = ? AND name = ?"),listDurableMemory:t.prepare("SELECT * FROM durable_memory WHERE project_id = ? ORDER BY name ASC"),listDurableMemoryByType:t.prepare("SELECT * FROM durable_memory WHERE project_id = ? AND type = ? ORDER BY name ASC"),deleteDurableMemory:t.prepare("DELETE FROM durable_memory WHERE project_id = ? AND name = ?"),insertSessionEvent:t.prepare(`
|
|
1651
|
+
INSERT INTO session_event (run_id, step_id, kind, timestamp_ms, payload, payload_truncated, overflow_artifact_id)
|
|
1652
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
1653
|
+
`),getSessionEvent:t.prepare("SELECT * FROM session_event WHERE id = ?"),listSessionEvents:t.prepare("SELECT * FROM session_event WHERE run_id = ? ORDER BY id ASC"),listSessionEventsSince:t.prepare("SELECT * FROM session_event WHERE run_id = ? AND id > ? ORDER BY id ASC"),listAllEventsSince:t.prepare("SELECT * FROM session_event WHERE id > ? ORDER BY id ASC LIMIT ?"),upsertRollupStat:t.prepare(`
|
|
1654
|
+
INSERT INTO rollup_stats (run_id, step_id, metric_kind, value, bucket_start_ms, bucket_end_ms, updated_at)
|
|
1655
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
1656
|
+
ON CONFLICT(run_id, step_id, metric_kind, bucket_start_ms)
|
|
1657
|
+
DO UPDATE SET value = value + excluded.value, updated_at = excluded.updated_at
|
|
1658
|
+
`),listRollupStats:t.prepare(`
|
|
1659
|
+
SELECT * FROM rollup_stats WHERE run_id = ? ORDER BY step_id ASC, metric_kind ASC, bucket_start_ms ASC
|
|
1660
|
+
`),getRollupCursor:t.prepare("SELECT value FROM rollup_cursor WHERE key = ?"),setRollupCursor:t.prepare(`
|
|
1661
|
+
INSERT INTO rollup_cursor (key, value) VALUES (?, ?)
|
|
1662
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value
|
|
1663
|
+
`),insertDriftSignal:t.prepare(`
|
|
1664
|
+
INSERT INTO drift_signal
|
|
1665
|
+
(team_member_id, project_id, signal_kind, severity, description, detected_at, expires_at, payload)
|
|
1666
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
1667
|
+
`),getDriftSignal:t.prepare("SELECT * FROM drift_signal WHERE id = ?"),listDriftByMember:t.prepare("SELECT * FROM drift_signal WHERE team_member_id = ? ORDER BY detected_at DESC"),listUnackedDriftByMember:t.prepare("SELECT * FROM drift_signal WHERE team_member_id = ? AND acknowledged_at IS NULL ORDER BY detected_at DESC"),listDriftByProject:t.prepare("SELECT * FROM drift_signal WHERE project_id = ? ORDER BY detected_at DESC"),listAllDrift:t.prepare("SELECT * FROM drift_signal ORDER BY detected_at DESC"),findUnackedDrift:t.prepare("SELECT id FROM drift_signal WHERE team_member_id = ? AND project_id IS ? AND signal_kind = ? AND acknowledged_at IS NULL LIMIT 1"),ackDriftSignal:t.prepare("UPDATE drift_signal SET acknowledged_at = COALESCE(acknowledged_at, ?) WHERE id = ?"),insertJob:t.prepare(`
|
|
1668
|
+
INSERT OR IGNORE INTO job
|
|
1669
|
+
(project_id, workflow_id_override, source, source_ref, payload, priority, available_at, dedupe_key, concurrency_key_resolved, enqueued_at)
|
|
1670
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1671
|
+
`),getJob:t.prepare("SELECT * FROM job WHERE id = ?"),findJobByDedupe:t.prepare("SELECT * FROM job WHERE source = ? AND dedupe_key = ? ORDER BY id LIMIT 1"),selectClaimableJob:t.prepare(`
|
|
1672
|
+
SELECT id FROM job
|
|
1673
|
+
WHERE ((status = 'queued' AND available_at <= ?) OR (status = 'running' AND locked_until < ?))
|
|
1674
|
+
AND (locked_until IS NULL OR locked_until < ?)
|
|
1675
|
+
ORDER BY priority DESC, available_at ASC, id ASC
|
|
1676
|
+
LIMIT 1
|
|
1677
|
+
`),selectClaimableJobs:t.prepare(`
|
|
1678
|
+
SELECT id FROM job
|
|
1679
|
+
WHERE ((status = 'queued' AND available_at <= ?) OR (status = 'running' AND locked_until < ?))
|
|
1680
|
+
AND (locked_until IS NULL OR locked_until < ?)
|
|
1681
|
+
ORDER BY priority DESC, available_at ASC, id ASC
|
|
1682
|
+
`),claimJob:t.prepare(`
|
|
1683
|
+
UPDATE job
|
|
1684
|
+
SET status = 'running',
|
|
1685
|
+
locked_by = ?,
|
|
1686
|
+
locked_until = ?,
|
|
1687
|
+
attempt_count = attempt_count + 1,
|
|
1688
|
+
started_at = COALESCE(started_at, ?)
|
|
1689
|
+
WHERE id = ?
|
|
1690
|
+
AND ((status = 'queued' AND available_at <= ?) OR (status = 'running' AND locked_until < ?))
|
|
1691
|
+
AND (locked_until IS NULL OR locked_until < ?)
|
|
1692
|
+
`),setJobConcurrencyKey:t.prepare("UPDATE job SET concurrency_key_resolved = ? WHERE id = ?"),countRunningByConcurrencyKey:t.prepare(`
|
|
1693
|
+
SELECT COUNT(*) AS count
|
|
1694
|
+
FROM job
|
|
1695
|
+
WHERE concurrency_key_resolved = ?
|
|
1696
|
+
AND status = 'running'
|
|
1697
|
+
AND locked_until > ?
|
|
1698
|
+
AND id != ?
|
|
1699
|
+
`),releaseJob:t.prepare(`
|
|
1700
|
+
UPDATE job
|
|
1701
|
+
SET status = ?, last_error = ?, ended_at = ?, locked_by = NULL, locked_until = NULL
|
|
1702
|
+
WHERE id = ?
|
|
1703
|
+
`),pauseJob:t.prepare(`
|
|
1704
|
+
UPDATE job
|
|
1705
|
+
SET status = 'paused',
|
|
1706
|
+
locked_by = NULL,
|
|
1707
|
+
locked_until = NULL,
|
|
1708
|
+
ended_at = NULL
|
|
1709
|
+
WHERE id = ?
|
|
1710
|
+
`),requeuePausedJob:t.prepare(`
|
|
1711
|
+
UPDATE job
|
|
1712
|
+
SET status = 'queued',
|
|
1713
|
+
locked_by = NULL,
|
|
1714
|
+
locked_until = NULL,
|
|
1715
|
+
available_at = ?,
|
|
1716
|
+
ended_at = NULL,
|
|
1717
|
+
last_error = NULL
|
|
1718
|
+
WHERE id = ?
|
|
1719
|
+
`),setJobRun:t.prepare("UPDATE job SET run_id = ? WHERE id = ?"),insertRun:t.prepare(`
|
|
1720
|
+
INSERT INTO run (job_id, workflow_id, team_id, current_state, workflow_version_id, parent_run_id, started_at)
|
|
1721
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
1722
|
+
`),getRun:t.prepare("SELECT * FROM run WHERE id = ?"),setRunCurrentState:t.prepare("UPDATE run SET current_state = ?, paused_at = NULL WHERE id = ?"),setRunPausedState:t.prepare("UPDATE run SET current_state = ?, paused_at = ? WHERE id = ?"),resumeRunState:t.prepare("UPDATE run SET current_state = ?, paused_at = NULL WHERE id = ?"),setRunPendingEscalationDecision:t.prepare("UPDATE run SET pending_escalation_decision = ? WHERE id = ?"),setRunTerminalState:t.prepare(`
|
|
1723
|
+
UPDATE run SET terminal_state = ?, ended_at = ?, current_state = NULL, paused_at = NULL WHERE id = ?
|
|
1724
|
+
`),insertStep:t.prepare(`
|
|
1725
|
+
INSERT INTO step (run_id, parent_step_id, state_name, outcome, status_detail, started_at)
|
|
1726
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
1727
|
+
`),getStep:t.prepare("SELECT * FROM step WHERE id = ?"),listStepsForRun:t.prepare("SELECT * FROM step WHERE run_id = ? ORDER BY id ASC"),insertSubmittedPr:t.prepare(`
|
|
1728
|
+
INSERT INTO submitted_pr
|
|
1729
|
+
(repo, pr_url, issue_url, local_path, branch, head_sha, status, submitted_at, last_known_state, created_by_run_id)
|
|
1730
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1731
|
+
`),getSubmittedPr:t.prepare("SELECT * FROM submitted_pr WHERE id = ?"),findSubmittedPrByUrl:t.prepare("SELECT * FROM submitted_pr WHERE pr_url = ?"),listSubmittedPrs:t.prepare("SELECT * FROM submitted_pr ORDER BY submitted_at DESC, id DESC"),listSubmittedPrsByStatus:t.prepare("SELECT * FROM submitted_pr WHERE status = ? ORDER BY submitted_at DESC, id DESC"),listLatestStepOutcomesByState:t.prepare(`
|
|
1732
|
+
SELECT state_name, outcome FROM step s1
|
|
1733
|
+
WHERE run_id = ?
|
|
1734
|
+
AND outcome IS NOT NULL
|
|
1735
|
+
AND id = (SELECT MAX(s2.id) FROM step s2 WHERE s2.run_id = s1.run_id AND s2.state_name = s1.state_name AND s2.outcome IS NOT NULL)
|
|
1736
|
+
ORDER BY id
|
|
1737
|
+
`),finishStep:t.prepare("UPDATE step SET outcome = ?, status_detail = ?, ended_at = ? WHERE id = ?"),finishLatestOpenStepForRunState:t.prepare(`
|
|
1738
|
+
UPDATE step
|
|
1739
|
+
SET outcome = ?, status_detail = ?, ended_at = ?
|
|
1740
|
+
WHERE id = (
|
|
1741
|
+
SELECT id FROM step
|
|
1742
|
+
WHERE run_id = ? AND state_name = ? AND ended_at IS NULL
|
|
1743
|
+
ORDER BY id DESC
|
|
1744
|
+
LIMIT 1
|
|
1745
|
+
)
|
|
1746
|
+
`),insertStepArtifact:t.prepare(`
|
|
1747
|
+
INSERT INTO step_artifact (step_id, kind, path, content, sha, provider_call_mode, created_at)
|
|
1748
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
1749
|
+
`),getStepArtifact:t.prepare("SELECT * FROM step_artifact WHERE id = ?"),insertExternalObject:t.prepare(`
|
|
1750
|
+
INSERT OR IGNORE INTO external_object
|
|
1751
|
+
(type, provider, project_id, run_id, external_id, url, status, metadata, last_seen_at, created_at)
|
|
1752
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1753
|
+
`),findExternalObjectByUnique:t.prepare(`
|
|
1754
|
+
SELECT * FROM external_object WHERE provider = ? AND type = ? AND external_id = ?
|
|
1755
|
+
`),insertExternalSignal:t.prepare(`
|
|
1756
|
+
INSERT OR IGNORE INTO external_signal
|
|
1757
|
+
(object_id, kind, source, occurred_at, payload, signal_hash, handled_at, created_at)
|
|
1758
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
1759
|
+
`),getExternalSignal:t.prepare("SELECT * FROM external_signal WHERE id = ?"),findExternalSignalByUnique:t.prepare(`
|
|
1760
|
+
SELECT * FROM external_signal WHERE object_id = ? AND kind = ? AND signal_hash = ?
|
|
1761
|
+
`),insertAttention:t.prepare(`
|
|
1762
|
+
INSERT INTO attention
|
|
1763
|
+
(kind, severity, project_id, run_id, external_object_id, requires_user, payload, created_at)
|
|
1764
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
1765
|
+
`),getAttention:t.prepare("SELECT * FROM attention WHERE id = ?"),ackAttention:t.prepare("UPDATE attention SET acknowledged_at = ? WHERE id = ?"),insertSessionSize:t.prepare(`
|
|
1766
|
+
INSERT INTO session_size
|
|
1767
|
+
(team_name, alias, sessionid, input_tokens, cache_tokens, output_tokens, total_tokens, observed_at)
|
|
1768
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
1769
|
+
`),getSessionSize:t.prepare("SELECT * FROM session_size WHERE id = ?"),latestSessionSizes:t.prepare(`
|
|
1770
|
+
SELECT s.*
|
|
1771
|
+
FROM session_size s
|
|
1772
|
+
JOIN (
|
|
1773
|
+
SELECT team_name, alias, MAX(id) AS id
|
|
1774
|
+
FROM session_size
|
|
1775
|
+
GROUP BY team_name, alias
|
|
1776
|
+
) latest ON latest.id = s.id
|
|
1777
|
+
ORDER BY s.team_name ASC, s.alias ASC
|
|
1778
|
+
`),sessionSizeHistory:t.prepare(`
|
|
1779
|
+
SELECT * FROM session_size
|
|
1780
|
+
WHERE team_name = ? AND alias = ?
|
|
1781
|
+
ORDER BY observed_at DESC, id DESC
|
|
1782
|
+
LIMIT ?
|
|
1783
|
+
`),insertWebuiSession:t.prepare(`
|
|
1784
|
+
INSERT INTO webui_session
|
|
1785
|
+
(session_id, user_id, current_node, node_params, prev_node_stack, pending_form, chatbot_session_id, auth_state, last_transition_at, created_at)
|
|
1786
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1787
|
+
`),getWebuiSession:t.prepare("SELECT * FROM webui_session WHERE session_id = ?"),updateWebuiSessionTransition:t.prepare(`
|
|
1788
|
+
UPDATE webui_session
|
|
1789
|
+
SET current_node = ?,
|
|
1790
|
+
node_params = ?,
|
|
1791
|
+
prev_node_stack = ?,
|
|
1792
|
+
pending_form = ?,
|
|
1793
|
+
last_transition_at = ?
|
|
1794
|
+
WHERE session_id = ?
|
|
1795
|
+
`),setWebuiSessionChatbot:t.prepare(`
|
|
1796
|
+
UPDATE webui_session
|
|
1797
|
+
SET chatbot_session_id = ?,
|
|
1798
|
+
last_transition_at = ?
|
|
1799
|
+
WHERE session_id = ?
|
|
1800
|
+
`),insertChatbotSession:t.prepare(`
|
|
1801
|
+
INSERT INTO chatbot_session
|
|
1802
|
+
(chatbot_session_id, user_id, title, created_at, last_active_at, status)
|
|
1803
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
1804
|
+
`),getChatbotSession:t.prepare("SELECT * FROM chatbot_session WHERE chatbot_session_id = ?"),listChatbotSessionsForUser:t.prepare(`
|
|
1805
|
+
SELECT * FROM chatbot_session
|
|
1806
|
+
WHERE user_id = ?
|
|
1807
|
+
ORDER BY last_active_at DESC, chatbot_session_id ASC
|
|
1808
|
+
`),touchChatbotSession:t.prepare("UPDATE chatbot_session SET last_active_at = ? WHERE chatbot_session_id = ?"),insertChatbotMessage:t.prepare(`
|
|
1809
|
+
INSERT INTO chatbot_message (chatbot_session_id, role, content, tool_calls, created_at)
|
|
1810
|
+
VALUES (?, ?, ?, ?, ?)
|
|
1811
|
+
`),getChatbotMessage:t.prepare("SELECT * FROM chatbot_message WHERE id = ?"),listChatbotMessages:t.prepare(`
|
|
1812
|
+
SELECT * FROM chatbot_message
|
|
1813
|
+
WHERE chatbot_session_id = ?
|
|
1814
|
+
ORDER BY id ASC
|
|
1815
|
+
`),getConfig:t.prepare("SELECT value FROM lmctl_config WHERE key = ?"),upsertConfig:t.prepare(`
|
|
1816
|
+
INSERT INTO lmctl_config (key, value, updated_at)
|
|
1817
|
+
VALUES (?, ?, ?)
|
|
1818
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at
|
|
1819
|
+
`),listConfig:t.prepare("SELECT key, value, updated_at FROM lmctl_config ORDER BY key ASC"),insertInteractiveSession:t.prepare(`
|
|
1820
|
+
INSERT INTO interactive_session (run_id, step_id, state_name, turn_count, status, started_at, last_activity_at)
|
|
1821
|
+
VALUES (?, ?, ?, 0, ?, ?, ?)
|
|
1822
|
+
`),getInteractiveSessionByStepId:t.prepare("SELECT * FROM interactive_session WHERE step_id = ?"),getInteractiveSessionByRunAndState:t.prepare("SELECT * FROM interactive_session WHERE run_id = ? AND state_name = ?"),updateInteractiveSession:t.prepare(`
|
|
1823
|
+
UPDATE interactive_session SET status = ?, last_operator_input = ?, last_activity_at = ? WHERE id = ?
|
|
1824
|
+
`),setInteractiveAgentOutput:t.prepare(`
|
|
1825
|
+
UPDATE interactive_session SET last_agent_output = ?, turn_count = turn_count + 1, status = ?, last_activity_at = ? WHERE id = ?
|
|
1826
|
+
`),insertPromptDispatch:t.prepare(`
|
|
1827
|
+
INSERT INTO prompt_dispatch (prompt_id, project_id, job_id, text, context_json, created_at)
|
|
1828
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
1829
|
+
`),getPromptDispatch:t.prepare("SELECT * FROM prompt_dispatch WHERE prompt_id = ?"),setPromptDispatchCompleted:t.prepare("UPDATE prompt_dispatch SET completed_at = ? WHERE prompt_id = ?"),getWorkspace:t.prepare("SELECT * FROM workspace WHERE id = ? AND deleted_at IS NULL"),ensureWorkspace:t.prepare(`
|
|
1830
|
+
INSERT INTO workspace (id, name, idle_threshold_ms, created_at)
|
|
1831
|
+
VALUES (?, ?, ?, ?)
|
|
1832
|
+
ON CONFLICT(id) DO NOTHING
|
|
1833
|
+
`),insertWebProject:t.prepare(`
|
|
1834
|
+
INSERT INTO web_project (workspace_id, name, repo_path, config_json, linked_v4_project_id, last_active_at, created_at)
|
|
1835
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
1836
|
+
`),getWebProject:t.prepare("SELECT * FROM web_project WHERE id = ?"),listWebProjectsActive:t.prepare("SELECT * FROM web_project WHERE workspace_id = ? AND deleted_at IS NULL ORDER BY name ASC, id ASC"),updateWebProject:t.prepare(`
|
|
1837
|
+
UPDATE web_project
|
|
1838
|
+
SET name = ?,
|
|
1839
|
+
config_json = ?,
|
|
1840
|
+
last_active_at = ?
|
|
1841
|
+
WHERE id = ?
|
|
1842
|
+
`),setWebProjectLastActive:t.prepare("UPDATE web_project SET last_active_at = ? WHERE id = ?"),softDeleteWebProject:t.prepare("UPDATE web_project SET deleted_at = ? WHERE id = ? AND deleted_at IS NULL"),loadMailboxCursor:t.prepare("SELECT * FROM mailbox_cursor WHERE user_id = ? AND mailbox_key = ?"),saveMailboxCursor:t.prepare(`
|
|
1843
|
+
INSERT INTO mailbox_cursor (user_id, mailbox_key, last_processed_version_id, last_processed_seq, last_processed_at)
|
|
1844
|
+
VALUES (?, ?, ?, ?, ?)
|
|
1845
|
+
ON CONFLICT(user_id, mailbox_key) DO UPDATE SET
|
|
1846
|
+
last_processed_version_id = excluded.last_processed_version_id,
|
|
1847
|
+
last_processed_seq = excluded.last_processed_seq,
|
|
1848
|
+
last_processed_at = excluded.last_processed_at
|
|
1849
|
+
`),addUsage:t.prepare(`
|
|
1850
|
+
INSERT INTO usage_meter (user_id, device_id, period, put_count, get_count, list_count, updated_at)
|
|
1851
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
1852
|
+
ON CONFLICT(user_id, device_id, period) DO UPDATE SET
|
|
1853
|
+
put_count = put_count + excluded.put_count,
|
|
1854
|
+
get_count = get_count + excluded.get_count,
|
|
1855
|
+
list_count = list_count + excluded.list_count,
|
|
1856
|
+
updated_at = excluded.updated_at
|
|
1857
|
+
`),loadUsage:t.prepare("SELECT * FROM usage_meter WHERE user_id = ? AND device_id = ? AND period = ?"),sumUsageForPeriod:t.prepare(`
|
|
1858
|
+
SELECT COALESCE(SUM(put_count), 0) AS put,
|
|
1859
|
+
COALESCE(SUM(get_count), 0) AS get,
|
|
1860
|
+
COALESCE(SUM(list_count), 0) AS list
|
|
1861
|
+
FROM usage_meter WHERE user_id = ? AND period = ?
|
|
1862
|
+
`),upsertRootTeam:t.prepare(`
|
|
1863
|
+
INSERT INTO root_team (teamfile_path, name, raw_text, raw_sha256, registered_at, last_seeded_at)
|
|
1864
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
1865
|
+
ON CONFLICT(teamfile_path) DO UPDATE SET
|
|
1866
|
+
name = excluded.name,
|
|
1867
|
+
raw_text = excluded.raw_text,
|
|
1868
|
+
raw_sha256 = excluded.raw_sha256,
|
|
1869
|
+
registered_at = excluded.registered_at,
|
|
1870
|
+
last_seeded_at = excluded.last_seeded_at
|
|
1871
|
+
`),getRootTeam:t.prepare("SELECT * FROM root_team WHERE teamfile_path = ?"),listRootTeams:t.prepare("SELECT * FROM root_team ORDER BY teamfile_path ASC"),insertTeamChatLog:t.prepare(`
|
|
1872
|
+
INSERT INTO team_chat_log (
|
|
1873
|
+
root_teamfile, sender_teamfile, sender_alias, receiver_teamfile, receiver_alias,
|
|
1874
|
+
message, response, origin, status, error_detail, truncated, message_type, created_at
|
|
1875
|
+
)
|
|
1876
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1877
|
+
`),listTeamChatLog:t.prepare("SELECT * FROM team_chat_log WHERE root_teamfile = ? ORDER BY created_at ASC, id ASC"),listTeamChatLogSinceId:t.prepare("SELECT * FROM team_chat_log WHERE id > ? ORDER BY id ASC LIMIT ?"),getMaxTeamChatLogId:t.prepare("SELECT COALESCE(MAX(id), 0) AS max_id FROM team_chat_log"),loadTeamChatLogCursor:t.prepare("SELECT * FROM team_chat_log_cursor WHERE cursor_key = ?"),saveTeamChatLogCursor:t.prepare(`
|
|
1878
|
+
INSERT INTO team_chat_log_cursor (cursor_key, last_pushed_id, updated_at)
|
|
1879
|
+
VALUES (?, ?, ?)
|
|
1880
|
+
ON CONFLICT(cursor_key) DO UPDATE SET
|
|
1881
|
+
last_pushed_id = excluded.last_pushed_id,
|
|
1882
|
+
updated_at = excluded.updated_at
|
|
1883
|
+
`),updateTeamChatLogResponse:t.prepare(`
|
|
1884
|
+
UPDATE team_chat_log
|
|
1885
|
+
SET response = ?,
|
|
1886
|
+
status = ?,
|
|
1887
|
+
error_detail = ?,
|
|
1888
|
+
truncated = ?
|
|
1889
|
+
WHERE id = ?
|
|
1890
|
+
`),getTeamChatLogById:t.prepare("SELECT * FROM team_chat_log WHERE id = ?"),terminalizeTeamChatLogIfRunning:t.prepare(`
|
|
1891
|
+
UPDATE team_chat_log
|
|
1892
|
+
SET status = ?,
|
|
1893
|
+
error_detail = ?,
|
|
1894
|
+
response = NULL
|
|
1895
|
+
WHERE id = ?
|
|
1896
|
+
AND status = 'running'
|
|
1897
|
+
`),...la(t),...oa(t)}}function Nf(t,e){return e===void 0?{resumed:!1,reason:t}:{resumed:!1,reason:t,valid:e}}var Ga=eo(As(),1);import{homedir as qf}from"node:os";import{join as Xa}from"node:path";var Gf=".lmctl",Jf="state.db";function Vf(){let t=process.env.LMCTL_HOME;return t!==void 0&&t.length>0?t:Xa(qf(),Gf)}function Kf(){return Xa(Vf(),Jf)}function Pe(t){return t!==void 0&&t.length>0?t:process.env.LMCTL_DB!==void 0&&process.env.LMCTL_DB.length>0?process.env.LMCTL_DB:Kf()}function qa(t){return process.env.LMCTL_DB!==void 0&&process.env.LMCTL_DB.length>0?`db: ${t} (overridden by --db/LMCTL_DB)`:`db: ${t}`}async function $(t,e){if(t.dal!==void 0)return e(t.dal);let r=lt({path:Pe()});try{return await e(r)}finally{r.close()}}function ct(t,e){return t.stderr.write(`error: ${e}
|
|
1898
|
+
`),1}function Je(){return(0,Ga.formatClock)()}function zr(t,e,r=5e3){let n=Date.now(),s=n,i=setInterval(()=>{let o=Date.now();o-s<r||t.stderr.write(e(Math.round((o-n)/1e3)))},r);return i.unref(),{poke:()=>{s=Date.now()},stop:()=>clearInterval(i)}}function Qr(t){if(t===void 0)return null;let e=Number.parseInt(t,10);return Number.isInteger(e)&&e>0?e:null}function Yf(t,e){if(ma(e)!=="dead")return null;let r=`holder process verified not alive; reconciled to aborted (invocation #${e.id}, holder pid ${e.holder_pid??"unknown"} on ${e.holder_host??"unknown"})`;return t.abortTrackedInvocationAndTerminalizeMessage(e.id,{holder_pid:e.holder_pid,holder_host:e.holder_host,started_at:e.started_at,last_heartbeat_at:e.last_heartbeat_at},r)}function Zr(t,e,r){let n=t.query(`SELECT id, status, holder_pid, holder_host, started_at, last_heartbeat_at
|
|
1899
|
+
FROM tracked_invocation
|
|
1900
|
+
WHERE target_teamfile = ?
|
|
1901
|
+
AND target_alias = ?
|
|
1902
|
+
AND status = 'running'`,e,r),s=0;for(let i of n)Yf(t,i)!==null&&(s+=1);return s}import{platform as Ja}from"node:os";import{realpathSync as zf}from"node:fs";import{resolve as Qf}from"node:path";function xs(t){let e=Qf(t);try{return zf(e)}catch{return e}}var en=class{providers=[];adapters=new Map;register(e){this.providers.push(e)}async listAll(e){let r=[],n=e?.provider?this.providers.filter(o=>o.name===e.provider):this.providers,s=await Promise.all(n.map(o=>o.discoverSessions()));for(let o of s)r.push(...o);let i=r;if(e?.workspace){let o=xs(e.workspace);i=i.filter(a=>xs(a.cwd)===o)}if(e?.from){let o=e.from.getTime();i=i.filter(a=>a.modifiedAt.getTime()>=o)}if(e?.to){let o=e.to.getTime();i=i.filter(a=>a.modifiedAt.getTime()<=o)}return i.sort((o,a)=>a.modifiedAt.getTime()-o.modifiedAt.getTime()),e?.limit&&(i=i.slice(0,e.limit)),i}async getSession(e,r){let n=r?this.providers.filter(s=>s.name===r):this.providers;for(let s of n){let i=await s.loadSession(e);if(i)return i}return null}async resolveSession(e,r){let n=await this.resolveSessions(e,r);return n.length===1?n[0]:null}async resolveSessions(e,r){let n=r?this.providers.filter(i=>i.name===r):this.providers,s=[];for(let i of n){let o=await i.resolveSessionPath(e);o&&s.push({provider:i,filePath:o})}return s}getWatchTargets(){let e=Ja()==="darwin"||Ja()==="win32",r=[];for(let n of this.providers)if(typeof n.getWatchPaths=="function")for(let s of n.getWatchPaths())r.push({provider:n.name,directory:s.directory,recursive:e,filePattern:s.filePattern});return r}async deleteSession(e,r){let n=await this.resolveSession(e,r);return n?n.provider.deleteSession(e):!1}registerAdapter(e){this.adapters.set(e.name,e),this.providers.push({name:e.name,discoverSessions:()=>e.discover(),loadSession:r=>e.load(r),resolveSessionPath:r=>e.resolvePath(r),deleteSession:r=>e.delete(r),getWatchPaths:()=>e.getWatchPaths?.()??[]})}getAdapter(e){return this.adapters.get(e)}getAllAdapters(){return[...this.adapters.values()]}};function dt(t){let e=new en;for(let r of t)e.registerAdapter(r);return e}import{join as ic}from"node:path";import{readdir as tn,stat as za,unlink as tp}from"node:fs/promises";import{join as bt,basename as Qa}from"node:path";import{createReadStream as Va}from"node:fs";import{createInterface as Ka}from"node:readline";import{stat as Zf}from"node:fs/promises";import{homedir as ep}from"node:os";var U=ep();function Ya(t){try{let e=JSON.parse(t);return e===null||typeof e!="object"||Array.isArray(e)?void 0:e}catch{return}}async function*Q(t){let e=Va(t,{encoding:"utf-8"}),r=Ka({input:e,crlfDelay:1/0});try{for await(let n of r){let s=n.trim();if(!s)continue;let i=Ya(s);i!==void 0&&(yield i)}}finally{e.destroy()}}async function Ee(t,e){let r=[],n=Va(t,{encoding:"utf-8"}),s=Ka({input:n,crlfDelay:1/0});try{for await(let i of s){let o=i.trim();if(!o)continue;let a=Ya(o);if(a!==void 0&&r.push(a),r.length>=e)break}}finally{s.close(),n.destroy()}return r}async function Z(t){let e=await Zf(t);return{createdAt:e.birthtime,modifiedAt:e.mtime}}function q(t){return t.replace(/\\n/g,`
|
|
1903
|
+
`).replace(/\\t/g," ").replace(/\\r/g,"\r")}function D(t,e){return t.length<=e?t:t.slice(0,e-3)+"..."}function ve(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function rp(t){return t==="file-history-snapshot"||t==="progress"||t==="system"||t==="queue-operation"}function np(t){if(t.type==="system"){let e=t.message?.content;if(typeof e=="string"&&e.trim())return q(e.trim());if(e!==void 0)return JSON.stringify(e,null,2)}return t.type==="progress"&&t.data!==void 0?JSON.stringify(t.data,null,2):JSON.stringify(t,null,2)}async function Za(t){let e=0,r=0,n=0,s=0,i=0,o=0,a,l;for await(let c of Q(t))if(!c.isSidechain){if(c.type==="user"&&!c.isMeta&&c.message){let u=c.message.content;if(typeof u=="string"){if(u.includes("<command-name>")||u.includes("<local-command-"))continue;e++,l=D(u.trim(),80)}}else if(c.type==="assistant"&&c.message){let u=c.message.content;if(Array.isArray(u))for(let p of u)p.type==="text"&&e++;let d=c.message.usage;if(d){let p=d.input_tokens||0,m=d.cache_creation_input_tokens||0,h=d.cache_read_input_tokens||0,g=d.output_tokens||0;r+=p+m+h,n+=h,s+=m,i+=g;let y=p+m+h;y&&(o=y),a={inputTokens:p,cacheWriteInputTokens:m,cachedInputTokens:h,outputTokens:g}}}}return{messageCount:e,totalInputTokens:r,totalCacheReadInputTokens:n,totalCacheWriteInputTokens:s,totalOutputTokens:i,lastInputTokens:o,lastTokenUsage:a,lastUserMessage:l}}var rn=class{name="claude";claudeDir;projectsDir;constructor(e={}){this.claudeDir=e.claudeDir||bt(U,".claude"),this.projectsDir=bt(this.claudeDir,"projects")}getWatchPaths(){return[{directory:this.projectsDir,filePattern:/\.jsonl$/}]}async discoverSessions(){let e=[],r;try{r=await tn(this.projectsDir)}catch{return e}for(let n of r){let s=bt(this.projectsDir,n);if(!(await za(s).catch(()=>null))?.isDirectory())continue;let o;try{o=await tn(s)}catch{continue}for(let a of o){if(!a.endsWith(".jsonl"))continue;let l=Qa(a,".jsonl");if(!/^[0-9a-f]{8}-/.test(l))continue;let c=bt(s,a);try{let u=await this.extractSummary(c,l);u&&e.push(u)}catch{}}}return e}async extractSummary(e,r){let n=await Ee(e,50),s=await Z(e),i="",o,a,l,c,u,d;for(let m of n)if(!rp(m.type)&&(!i&&m.cwd&&(i=m.cwd),!o&&m.slug&&(o=m.slug),!a&&m.version&&(a=m.version),!d&&m.timestamp&&(d=new Date(m.timestamp)),m.type==="assistant"&&m.message?.model&&(l=m.message.model),m.type==="user"&&!m.isMeta&&m.message)){let h=m.message.content;if(typeof h=="string"){if(h.includes("<command-name>")||h.includes("<local-command-"))continue;c||(c=D(h.trim(),80)),u=D(h.trim(),80)}}if(!i)return null;let p=await Za(e);return{provider:"claude",sessionId:r,slug:o,cwd:i,createdAt:d||s.createdAt,modifiedAt:s.modifiedAt,model:l,cliVersion:a,startCommand:"claude",firstUserMessage:c,lastUserMessage:p.lastUserMessage??u,messageCount:p.messageCount,filePath:e,totalInputTokens:p.totalInputTokens||void 0,totalCachedInputTokens:p.totalCacheReadInputTokens||void 0,totalCacheWriteInputTokens:p.totalCacheWriteInputTokens||void 0,totalOutputTokens:p.totalOutputTokens||void 0,lastInputTokens:p.lastInputTokens||void 0,lastTokenUsage:p.lastTokenUsage}}async loadSession(e){let r=await this.resolveSessionFile(e);if(!r)return null;let n=await Z(r),s=[],i="",o,a,l,c,u,d,p,m=e,h,g=[];for await(let f of Q(r))if(f.type!=="file-history-snapshot"&&!f.isSidechain){if(!i&&f.cwd&&(i=f.cwd),!o&&f.slug&&(o=f.slug),!a&&f.version&&(a=f.version),!c&&f.gitBranch&&(c=f.gitBranch),!p&&f.timestamp&&(p=new Date(f.timestamp)),f.sessionId&&(m=f.sessionId),f.type==="system"||f.type==="progress"||f.type==="queue-operation"){s.push({role:"system",timestamp:new Date(f.timestamp||0),content:np(f)});continue}if(f.type==="user"&&f.message){if(f.isMeta)continue;let T=new Date(f.timestamp||0),E=f.message.content;if(f.isCompactSummary!==!0&&f.isVisibleInTranscriptOnly!==!0&&f.promptSource!=="system"&&f.toolUseResult===void 0&&f.origin?.kind!=="task-notification"&&f.interruptedMessageId===void 0&&f.interruptedByShutdown!==!0&&f.scheduledTaskId===void 0&&f.scheduledFireId===void 0&&!(Array.isArray(E)&&E.some(I=>I.type==="tool_result"))){let I=typeof E=="string"?E:Array.isArray(E)?E.filter(w=>w.type==="text"&&typeof w.text=="string").map(w=>w.text).join(`
|
|
1904
|
+
`):"";I&&!/^<(?:command-name>|local-command-)/u.test(I.trimStart())&&g.push(I)}if(typeof E=="string"){if(E.includes("<command-name>")||E.includes("<local-command-"))continue;u||(u=D(E.trim(),80)),d=D(E.trim(),80),h=void 0,s.push({role:"user",timestamp:T,content:q(E.trim())})}else if(Array.isArray(E)){for(let I of E)if(I.type==="tool_result"){let w=typeof I.content=="string"?q(I.content):JSON.stringify(I.content);s.push({role:"tool_result",timestamp:T,content:w,toolCallId:I.tool_use_id})}}}if(f.type==="assistant"&&f.message){f.message.stop_reason===null||f.message.stop_reason==="tool_use"?h="in_progress":typeof f.message.stop_reason=="string"&&(h="complete"),f.message.model&&(l=f.message.model);let T=new Date(f.timestamp||0),E=f.message.content;if(Array.isArray(E))for(let I of E)I.type==="text"&&I.text?s.push({role:"assistant",timestamp:T,content:q(I.text),model:f.message.model,...typeof f.message.stop_reason=="string"?{stopReason:f.message.stop_reason}:{}}):I.type==="tool_use"?s.push({role:"tool_use",timestamp:T,content:I.name||"unknown tool",toolName:I.name,toolInput:JSON.stringify(I.input,null,2),toolInputData:I.input,toolCallId:I.id,model:f.message.model,...typeof f.message.stop_reason=="string"?{stopReason:f.message.stop_reason}:{}}):I.type==="thinking"&&I.thinking&&s.push({role:"thinking",timestamp:T,content:I.thinking})}}if(!i)return null;sp(s);let y=await Za(r);return{provider:"claude",sessionId:m,slug:o,cwd:i,createdAt:p||n.createdAt,modifiedAt:n.modifiedAt,model:l,cliVersion:a,startCommand:"claude",gitBranch:c,turnStatus:h,firstUserMessage:u,lastUserMessage:d,messageCount:y.messageCount,filePath:r,totalInputTokens:y.totalInputTokens||void 0,totalCachedInputTokens:y.totalCacheReadInputTokens||void 0,totalCacheWriteInputTokens:y.totalCacheWriteInputTokens||void 0,totalOutputTokens:y.totalOutputTokens||void 0,lastInputTokens:y.lastInputTokens||void 0,lastTokenUsage:y.lastTokenUsage,messages:s,userPrompts:g}}async resolveSessionPath(e){return this.resolveSessionFile(e)}async deleteSession(e){let r=await this.resolveSessionFile(e);return r?(await tp(r),!0):!1}async resolveSessionFile(e){let r;try{r=await tn(this.projectsDir)}catch{return null}let n=[];for(let o of r){let a=bt(this.projectsDir,o);if(!(await za(a).catch(()=>null))?.isDirectory())continue;let c;try{c=await tn(a)}catch{continue}for(let u of c){if(!u.endsWith(".jsonl"))continue;let d=Qa(u,".jsonl");/^[0-9a-f]{8}-/.test(d)&&n.push({filePath:bt(a,u),fileSessionId:d})}}let s=n.find(o=>o.fileSessionId===e);if(s)return s.filePath;let i=n.filter(o=>o.fileSessionId.startsWith(e));if(i.length===1)return i[0].filePath;for(let o of n){let a=await Ee(o.filePath,20);for(let l of a)if(l.slug&&l.slug===e)return o.filePath}return null}};function sp(t){let e=ip(t),r=new Set;for(let n of t){if(n.role!=="tool_use"||n.toolName!=="Bash"||n.toolInputData?.run_in_background!==!0||n.toolCallId===void 0)continue;let s=e.get(n.toolCallId);if(s===void 0)continue;let i=s.content.match(/Command running in background with ID:\s*([A-Za-z0-9_-]+)/)?.[1];i!==void 0&&(r.add(i),n.backgroundTaskId=i,s.backgroundTaskId=i)}for(let n of t){if(n.role!=="tool_use"||n.toolName!=="TaskOutput"&&n.toolName!=="TaskStop"||n.toolCallId===void 0)continue;let s=n.toolInputData?.task_id;if(typeof s!="string"||!r.has(s))continue;n.backgroundTaskId=s;let i=e.get(n.toolCallId);i!==void 0&&(i.backgroundTaskId=s)}}function ip(t){let e=new Map;for(let r of t)r.role==="tool_result"&&r.toolCallId!==void 0&&e.set(r.toolCallId,r);return e}import{spawn as ol}from"node:child_process";import{mkdirSync as Tp}from"node:fs";import{readFileSync as op,writeFileSync as oS,mkdirSync as aS}from"node:fs";import{join as ap,dirname as cS}from"node:path";import{homedir as lp}from"node:os";var Rs={claude:{start:"claude",resume:"claude --resume {{session_id}} --dangerously-skip-permissions",profiles:{default:{description:"Default profile",flags:""}}},codex:{start:"codex",resume:"codex resume {{session_id}} --dangerously-bypass-approvals-and-sandbox",profiles:{default:{description:"Default profile",flags:""}}},opencode:{start:"opencode",resume:"opencode --session {{session_id}}",profiles:{default:{description:"Default profile",flags:""}}},gemini:{start:"gemini",resume:"gemini --resume {{session_id}} -y",profiles:{default:{description:"Default profile",flags:""}}},copilot:{start:"copilot",resume:"copilot --resume={{session_id}} --yolo",profiles:{default:{description:"Default profile",flags:""}}},qwen:{start:"qwen",resume:"qwen --resume {{session_id}} --approval-mode yolo",profiles:{default:{description:"Default profile",flags:""}}},agy:{start:"agy",resume:"agy --conversation {{session_id}} --dangerously-skip-permissions",profiles:{default:{description:"Default profile",flags:""}}},kimi:{start:"kimi --auto",resume:"kimi --session {{session_id}} --auto",profiles:{default:{description:"Default profile",flags:""}}},hermes:{start:"hermes",resume:"hermes --yolo --resume {{session_id}}",profiles:{default:{description:"Default profile",flags:""}}}},cp={claude:{mode:"argv",argv:["claude","-p","{{prompt}}","--resume","{{session_id}}"]},codex:{mode:"argv",argv:["codex","exec","--dangerously-bypass-approvals-and-sandbox","--skip-git-repo-check","resume","{{session_id}}","{{prompt}}"]},opencode:{mode:"argv",argv:["opencode","run","--session","{{session_id}}","{{prompt}}"]},gemini:{mode:"argv",argv:["gemini","-p","{{prompt}}","--resume","{{session_id}}"]},copilot:{mode:"argv",argv:["gh","copilot","--","--resume={{session_id}}","-p","{{prompt}}","-s","--allow-all-tools"]},qwen:{mode:"argv",argv:["qwen","-p","{{prompt}}","--resume","{{session_id}}","--approval-mode","yolo"]},agy:{mode:"argv",argv:["agy","--conversation","{{session_id}}","-p","{{prompt}}","--dangerously-skip-permissions","--print-timeout","8h"]},kimi:{mode:"argv",argv:["kimi","-p","{{prompt}}","--session","{{session_id}}","--output-format","stream-json"]},hermes:{mode:"argv",argv:["hermes","--yolo","-z","{{prompt}}","--resume","{{session_id}}"]}};function dp(t){return t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):t}function up(t){let e=t.indexOf("=");if(e===-1)return null;let r=t.slice(0,e).trim(),n=dp(t.slice(e+1).trim());return r?{key:r,value:n}:null}function mp(t){let e=t.trim();return e.startsWith("[")&&e.endsWith("]")?e.slice(1,-1).trim():null}function nn(t){return"'"+t.replace(/'/g,"'\\''")+"'"}function fp(){return ap(lp(),".lmctl","config.toml")}function tl(t){let e=t??fp(),r;try{r=op(e,"utf-8")}catch{return{tools:{}}}return pp(r)}function el(t){if(typeof t=="number")return Number.isFinite(t)?t:null;let e=String(t).trim();if(!e)return null;let r=e.match(/^(\d+(?:\.\d+)?)\s*([KkMm]?)$/);if(!r)return null;let n=parseFloat(r[1]);if(!Number.isFinite(n))return null;switch(r[2]){case"K":case"k":return Math.round(n*1e3);case"M":case"m":return Math.round(n*1e6);default:return Math.round(n)}}function pp(t){let e={},r={},n=t.split(`
|
|
1905
|
+
`),s={kind:"none"},i={},o=!1,a={};function l(){if(s.kind==="tool"){let d=e[s.tool]??{};if(s.profile){let p=d.profiles?.[s.profile]??{};i.description&&(p.description=i.description),i.flags!==void 0&&(p.flags=i.flags),d.profiles||(d.profiles={}),d.profiles[s.profile]=p}else i.start&&(d.start=i.start),i.resume&&(d.resume=i.resume),i.agent&&(d.agent=i.agent),i.profile_flag!==void 0&&(d.profile_flag=i.profile_flag);e[s.tool]=d}else if(s.kind==="compact"){let d=s.provider?r.providers?.[s.provider]??{}:r.global??{};if(i.min!==void 0){let p=el(i.min);p!==null&&(d.min=p)}if(i.max!==void 0){let p=el(i.max);p!==null&&(d.max=p)}s.provider?(r.providers||(r.providers={}),r.providers[s.provider]=d):r.global=d}i={}}for(let d of n){let p=d.trim();if(!p||p.startsWith("#"))continue;let m=mp(p);if(m!==null){if(o=!0,l(),m.startsWith("tool.")){let g=".profile.",y=m.indexOf(g);y!==-1?s={kind:"tool",tool:m.slice(5,y),profile:m.slice(y+g.length)}:s={kind:"tool",tool:m.slice(5),profile:null}}else m==="compact"?s={kind:"compact",provider:null}:m.startsWith("compact.")?s={kind:"compact",provider:m.slice(8)}:s={kind:"none"};continue}let h=up(p);h&&s.kind!=="none"?i[h.key]=h.value:h&&!o&&(a[h.key]=h.value)}l();let c={tools:e};(r.global||r.providers)&&(c.compact=r);let u=a.site_name;return u!==void 0&&u.length>0&&(c.site_name=u),c}function hp(t,e,r){if(!r)return"";let n=t.tools[e]??Rs[e],s=n?.profiles?.[r]?.flags??Rs[e]?.profiles?.[r]?.flags;if(s!==void 0)return s.trim();if(n?.profile_flag)return n.profile_flag.replace(/\{\{profile\}\}/g,r).trim();throw new Error(`Profile "${r}" is not configured for tool "${e}"`)}function rl(t,e){return!!t.tools[e]}function nl(t,e,r,n,s){let i=t.tools[e]??Rs[e],o;if(i?.agent){let l=nn(n);o=i.agent.replace(/\{\{session_id\}\}/g,r).replace(/\{\{prompt\}\}/g,l)}else{let l=cp[e];if(!l)throw new Error(`No agent command configured for tool "${e}"`);let c=l.argv.map(u=>u.replace(/\{\{session_id\}\}/g,r).replace(/\{\{prompt\}\}/g,n));if(l.mode==="stdin"){let u=c.map(nn).join(" ");o=`printf '%s\\n' ${nn(n)} | ${u}`}else o=c.map(nn).join(" ")}let a=hp(t,e,s);return a&&(o+=" "+a),o}function sl(t=process.env){let e=t.LMCTL_ONE_SHOT_TIMEOUT_MS;if(!e)return 6e5;let r=Number(e);return!Number.isFinite(r)||r<=0?6e5:r}var gp="ACK: waiting for explicit lmctl task.",W=`lmctl seed initial connection only. Create or pin this provider session, then stop. Do not inspect files, run commands, infer a task, delegate, or edit. A dispatch that dies mid-turn is usually a timeout you set -- use --idle-timeout, not a shell timeout. Reply exactly: ${gp}`,sn=`send this exact lmctl seed instruction: "${W}"`;import{existsSync as _p}from"node:fs";var bs="LMCTL_SELF_SESSIONID",Ep="LMCTL_LAUNCH_SOURCE";function il(t){let e=t.CLAUDE_CODE_EXECPATH;if(e===void 0||e.length===0)return t;let r=process.platform!=="win32"&&e.toLowerCase().endsWith(".exe"),n=!r&&!_p(e);if(!r&&!n)return t;R({event:"claude_execpath_sanitized",reason:r?"wrong_platform_exe":"missing_file",value:e,platform:process.platform});let s={...t};return delete s.CLAUDE_CODE_EXECPATH,s}function Nt(t,e){let r={...t??process.env,PWD:e};return delete r.OLDPWD,r}function yp(t,e){return e===void 0||e.length===0?t:{...t??process.env,[bs]:e}}function oe(t,e,r,n="chat"){return{...yp(Nt(t,e),r),[Ep]:n}}function Qt(t){return t.replace(/\x1b\[[0-9;]*[a-zA-Z]/g,"")}var Ns=class t extends Error{cancelReason;constructor(e,r){super(e),this.name="TurnAbortError",this.cancelReason=r,Object.setPrototypeOf(this,t.prototype)}},G=class t{name;capabilities;injection;provider;binary;seedArgs;seedStdin;resumeTemplate;startTemplate;transportFn;constructor(e){this.name=e.provider.name,this.provider=e.provider,this.capabilities=e.capabilities,this.injection=e.injection,this.binary=e.binary,this.seedArgs=e.seedArgs,this.seedStdin=e.seedStdin,this.resumeTemplate=e.resumeTemplate,this.startTemplate=e.startTemplate,this.transportFn=e.transport}discover(){return this.provider.discoverSessions()}load(e){return this.provider.loadSession(e)}resolvePath(e){return this.provider.resolveSessionPath(e)}delete(e){return this.provider.deleteSession(e)}getWatchPaths(){return this.provider.getWatchPaths?.()??[]}seedArgsFor(e){let r=e?.prompt;return r===void 0?this.seedArgs:this.seedArgs.map(n=>n===W?r:n)}turnOptsFor(e){return e}seed(e,r){return Tp(e,{recursive:!0}),new Promise(n=>{let s;try{s=ol(this.binary,this.seedArgsFor(r),{cwd:e,env:Nt(void 0,e),stdio:["pipe","pipe","pipe"],timeout:6e4})}catch(l){return n({success:!1,error:l instanceof Error?l.message:String(l)})}let i="",o="";s.stdout?.on("data",l=>{i+=l.toString()}),s.stderr?.on("data",l=>{o+=l.toString()});let a=r?.prompt!==void 0&&this.seedStdin!==void 0?`${r.prompt}
|
|
1906
|
+
`:this.seedStdin;a&&s.stdin?.write(a),s.stdin?.end(),s.on("exit",l=>{if(l===0||l===null)n({success:!0});else{let c=Qt(o).trim(),u=Qt(i).trim();n({success:!1,error:(c||u).slice(0,500)||`exit code ${l}`})}}),s.on("error",l=>{n({success:!1,error:l.message})})})}resumeCommand(e,r){return this.resumeTemplate.replace(/\{\{session_id\}\}/g,e)}startCommand(e){return this.startTemplate}manualSeedHint(e){return{launchCommand:`cd ${e} && ${this.binary}`,postLaunchNote:sn,lsCommand:`lmctl ls --provider ${this.name} --sessiondir ${e}`}}static DEFAULT_IDLE_TIMEOUT_MS=8*60*60*1e3;sendTurn(e,r){let n=this.turnOptsFor(r);if(n.userConfig&&rl(n.userConfig,this.name)){let i=n.userConfig.tools[this.name];if(i?.agent)return this.runOneShotAgent(e,n,i.agent)}let s=n.timeoutMs??t.DEFAULT_IDLE_TIMEOUT_MS;return s<=0&&!n.signal?this.transportFn(e,{...n,binary:this.binary}):this.withTimeouts(s,e,n)}withTimeouts(e,r,n){let s=new AbortController,i,o,a="",l,c=()=>{e<=0||(clearTimeout(i),i=setTimeout(()=>{n.onIdleWarning?.(e),u(),s.abort(),l&&l({text:a,sessionId:n.sessionId,durationMs:e,status:"stalled",stalledAfterMs:e})},e))},u=()=>{clearTimeout(i)};n.signal&&(n.signal.aborted?(o="external",s.abort()):n.signal.addEventListener("abort",()=>{o="external",s.abort()},{once:!0})),c();let d={...n,binary:this.binary,signal:s.signal,onDelta:h=>{a+=h,c(),n.onDelta?.(h)},onProgress:h=>{h.kind!=="api_retry"&&c(),n.onProgress?.(h)}},p=this.transportFn(r,d).then(h=>(u(),{...h,status:"ok"})).catch(h=>{throw u(),o==="external"?new Ns("Turn cancelled","external"):h}),m=new Promise(h=>{l=h});return Promise.race([p,m])}runOneShotAgent(e,r,n){let s=nl(r.userConfig,this.name,r.sessionId,e,r.profile),i=Date.now();return new Promise((o,a)=>{let l=sl(r.env),c=ol(s,{shell:!0,cwd:r.cwd,env:oe(r.env,r.cwd,r.sessionId),stdio:["pipe","pipe","pipe"]}),u=!1,d=!1,p=setTimeout(()=>{d=!0,c.kill()},l),m="",h="";if(c.stdout?.on("data",g=>{let y=g.toString();m+=y,r.onDelta?.(y)}),c.stderr?.on("data",g=>{h+=g.toString()}),r.signal){if(r.signal.aborted)return clearTimeout(p),c.kill(),a(new Error("Aborted"));r.signal.addEventListener("abort",()=>c.kill(),{once:!0})}c.on("exit",g=>{if(u)return;u=!0,clearTimeout(p);let y=Date.now()-i;d?a(new Error(`Agent command timed out after ${l}ms`)):g===0||g===null?o({text:m.trim(),sessionId:r.sessionId,durationMs:y}):a(new Error(h.trim().slice(0,200)||`Agent command exited with code ${g}`))}),c.on("error",g=>{u||(u=!0,clearTimeout(p),a(g))})})}};import{spawn as ml}from"node:child_process";import{existsSync as fl}from"node:fs";var Zt=class extends Error{constructor(e,r){super(e,r),this.name=this.constructor.name}},J=class extends Zt{};var on=class extends Zt{rpcCode;rpcData;constructor(e,r,n){super(e),r!==void 0&&(this.rpcCode=r),n!==void 0&&(this.rpcData=n)}};function er(t,e){let r;if(e&&typeof e=="object"){let n=e.code;typeof n=="number"&&(r=n)}return new on(t,r,e)}import*as Ls from"node:child_process";var Sp=1e3;function wp(t){if(typeof Ls.spawnSync=="function")try{Ls.spawnSync("taskkill",["/T","/F","/PID",String(t)],{windowsHide:!0})}catch{}}function al(t){return t.exitCode!==null||t.signalCode!==null}function ks(t,e){return al(t)?Promise.resolve(!0):new Promise(r=>{let n=!1,s=()=>{n||(n=!0,clearTimeout(i),r(!0))},i=setTimeout(()=>{n||(n=!0,t.removeListener("exit",s),r(!1))},e);t.once("exit",s)})}async function V(t,e={}){let r=Date.now(),n=e.stdinEnd!==!1,s=e.softDelayMs??5e3,i=e.killDelayMs??5e3,o=e.platform??process.platform,a=e.runTaskkill??wp;if(al(t))return{signal:"natural",elapsedMs:Date.now()-r};if(n&&t.stdin&&!t.stdin.destroyed)try{t.stdin.end()}catch{}if(await ks(t,s))return{signal:"stdin",elapsedMs:Date.now()-r};if(o==="win32"&&typeof t.pid=="number")a(t.pid);else try{t.kill("SIGTERM")}catch{}if(await ks(t,i))return{signal:"SIGTERM",elapsedMs:Date.now()-r};if(o!=="win32")try{t.kill("SIGKILL")}catch{}return await ks(t,Sp)?{signal:"SIGKILL",elapsedMs:Date.now()-r}:{signal:"abandoned",elapsedMs:Date.now()-r}}function ll(t){K()&&he({event:"legacy",msg:`[debug] ${t}`},{always:!0})}var vp={claude:["--dangerously-skip-permissions"],qwen:["--approval-mode","yolo"],gemini:["-y"],copilot:["--yolo"],agy:["--dangerously-skip-permissions"],lmplayer:["--dangerously-skip-permissions"]},Ip={claude:{yolo:["--dangerously-skip-permissions"],plan:["--permission-mode","plan"]},qwen:{yolo:["--approval-mode","yolo"],plan:["--approval-mode","plan"]},gemini:{yolo:["-y"],plan:["--approval-mode","plan"]},copilot:{yolo:["--yolo"],plan:["--yolo"]},agy:{yolo:["--dangerously-skip-permissions"],plan:["--dangerously-skip-permissions"]},lmplayer:{yolo:["--dangerously-skip-permissions"],plan:["--dangerously-skip-permissions"]}};function Ve(t,e){let r=Ip[t];if(r)return r[e]??r.yolo}var Ap=new Set(["codex","opencode","kimi","dsh","hermes","pi"]);function xp(t,e){if(e.length===0)return!0;for(let r=0;r+e.length<=t.length;r++){let n=!0;for(let s=0;s<e.length;s++)if(t[r+s]!==e[s]){n=!1;break}if(n)return!0}return!1}function se(t,e,r="yolo"){if(Ap.has(t)){ll(`YOLO ${t} [mode=${r}]: ${t==="codex"?`JSON-RPC params (approvalPolicy=never, sandbox=${r==="plan"?"read-only":"danger-full-access"})`:t==="opencode"?".opencode/opencode.json (permission=allow)":t==="kimi"?`ACP session/set_config_option (configId=mode, value=${r==="plan"?"plan":"auto"})`:t==="dsh"?"DSH_PERMISSION_MODE=danger-full-access env var on the sidecar spawn \u2014 no argv flag":t==="hermes"?"HERMES_YOLO_MODE=1 shell gate + ACP session/set_mode (modeId=dont_ask) edit gate":t==="pi"?"no tool-permission prompts exist in pi by design \u2014 nothing to bypass":"protocol/config (out-of-band)"} \u2014 no argv flag`);return}let n=r==="plan"?Ve(t,"plan"):vp[t];if(!n){let s=`unknown provider "${t}" \u2014 YOLO contract not configured. Add an entry to YOLO_FLAGS in src/providers/yolo-contract.ts before spawning this provider.`;throw R({event:"yolo_assert_failed",provider:t,reason:"unconfigured_provider",args:e.join(" "),message:s}),new J(s)}if(!xp(e,n)){let s=n.join(" "),i=`${t} spawn missing YOLO flag '${s}' \u2014 YOLO is mandatory for every provider; see src/providers/yolo-contract.ts. Got argv: [${e.map(o=>JSON.stringify(o)).join(", ")}]`;throw R({event:"yolo_assert_failed",provider:t,reason:"flag_missing",required_flag:s,mode:r,args:e.join(" "),message:i}),new J(i)}ll(`YOLO ${t} [mode=${r}]: argv flag '${n.join(" ")}'`)}var Rp=2e3,an=8*60*60*1e3,bp=5e3,Np=1e3,kp=50,Cs=Symbol("check-timed-out");async function ln(t,e,r){if(typeof t=="boolean")return t;let n,s;try{return await Promise.race([t,new Promise(i=>{n=setTimeout(()=>i(Cs),e),n.unref?.(),r!==void 0&&(s=()=>i(Cs),r.addEventListener("abort",s,{once:!0}))})])}finally{n!==void 0&&clearTimeout(n),s!==void 0&&r?.removeEventListener("abort",s)}}function Ke(t,e){if(t===void 0){e.closeStdin();return}let r=!1,n=i=>{if(!r){r=!0;try{t.onRelease?.({elapsedMs:Date.now()-i.startedMs,held:i.held,reason:i.reason})}catch{}}e.closeStdin()},s=Date.now();Lp(t,e,s,n).catch(()=>{n({startedMs:s,held:!1,reason:"check-error"})})}async function Lp(t,e,r,n){let s=t.pollMs??Rp,i=t.maxHoldMs??an,o=t.settleMs??bp,a=t.backgroundGraceMs??Np,l=!1,c=null,u=d=>n({startedMs:r,held:l,reason:d});for(;;){if(e.isAborted())return u("aborted");if(e.hasChildExited())return u("child-exited");let d=i-(Date.now()-r);if(d<=0)return u("max-hold");let p;try{p=await ln(t.hasOutstandingWork(),d,e.signal)}catch{return u("check-error")}if(p===Cs)return u(e.isAborted()||e.signal?.aborted===!0?"aborted":"max-hold");if(p)c=null;else{if(!l&&e.wasBackgroundJobLaunched?.()===!0&&Date.now()-r<a){let g=a-(Date.now()-r);await new Promise(y=>setTimeout(y,Math.max(0,Math.min(s,kp,g))).unref?.());continue}if(!l||o<=0)return u("cleared");c===null&&(c=Date.now(),ne(`${e.label}: dispatched work cleared \u2014 settling ${o}ms before closing stdin`));let h=Math.max(c,e.lastEventAtMs());if(!e.isTurnInFlight()&&Date.now()-h>=o)return u("cleared")}if(l||(l=!0,t.onHold?.(),ne(`${e.label}: deferring stdin close \u2014 outstanding dispatched work (poll ${s}ms)`)),Date.now()-r>=i)return R({event:"transport_hold_open_max_wait",provider:e.label,elapsed_ms:Date.now()-r}),u("max-hold");let m=Math.max(0,Math.min(s,i-(Date.now()-r)));await new Promise(h=>setTimeout(h,m).unref?.())}}function cl(t){if(t.length===0)return"";if(t.length===1)return t[0];let e=[];for(let r=0;r<t.length;r++)r===0?e.push(t[r]):e.push(`
|
|
1907
|
+
|
|
1908
|
+
--- additional response (turn ${r+1} of ${t.length}; likely an injected mid-call notification) ---
|
|
1909
|
+
|
|
1910
|
+
`+t[r]);return e.join("")}function cn(t={}){let e=[],r="",n=!1;return{processLine(s){if(!s.trim())return;let i;try{i=JSON.parse(s)}catch{return}t.onEvent?.(i);let o=i.type;if(o==="system"&&i.subtype==="init"&&(r=i.session_id||r),o==="assistant"){let l=i.message?.content;if(Array.isArray(l))for(let c of l)c.type==="text"&&c.text&&t.onText?.(c.text)}o==="result"&&(n=!0,e.push(i))},sawResult(){return n},finalize(){if(!n)return null;let s=dl(e),i=cl(s.resultTexts);return{result:i,sessionId:s.sessionId||r,durationMs:s.durationMs,numTurns:s.numTurns,isError:s.isError&&i.trim().length===0,errorMessage:s.errorMessage}}}}function dl(t){let e=[],r=0,n=0,s="",i=!1,o;for(let a of t){e.push(a.result||"");let l=a.duration_ms;typeof l=="number"&&Number.isFinite(l)&&(r+=l);let c=a.num_turns;typeof c=="number"&&Number.isFinite(c)&&(n=c);let u=a.session_id;if(typeof u=="string"&&u&&(s=u),a.is_error===!0){i=!0;let d=a.errors,p=Array.isArray(d)?d.filter(h=>typeof h=="string").join("; "):void 0,m=typeof a.subtype=="string"?a.subtype:"unknown";o=p&&p.length>0?p:`result subtype=${m} (no error detail provided)`}}return{resultTexts:e,durationMs:r,numTurns:n,sessionId:s,isError:i,errorMessage:o}}import{join as dn}from"node:path";import{readdir as Cp}from"node:fs/promises";var Op={claude:"claude",qwen:"qwen"};function pl(){let t=process.env.LMCTL_RESULT_GRACE_TIMEOUT_MS;if(t===void 0||t.trim().length===0)return 12e4;let e=Number(t);return Number.isFinite(e)&&e>0?e:12e4}function hl(){let t=process.env.LMCTL_TOOL_USE_GRACE_TIMEOUT_MS;if(t===void 0||t.trim().length===0)return 27e5;let e=Number(t);return Number.isFinite(e)&&e>0?e:27e5}function gl(t){let r=t.message?.content;return Array.isArray(r)?r.some(n=>n?.type==="tool_use"):!1}function Dp(t){let e=t.stderr.trim().slice(0,500),r=`lmctl: ${t.tool} exited with code ${t.exitCode} before returning a final result event.
|
|
1911
|
+
One possible cause: the provider stream ended before a complete response was delivered; for Claude Code this can appear as "API Error: Stream idle timeout - partial response received".`;return e?`Original provider error:
|
|
1912
|
+
${e}
|
|
1913
|
+
|
|
1914
|
+
${r}`:r}var Mp={claude:["--dangerously-skip-permissions"],qwen:["--approval-mode","yolo"]};function _l(t){let e=t.tool||"claude",r=t.binaryPath||Op[e]||"claude",n=["-p","","--output-format","stream-json","--input-format","stream-json"];e==="claude"&&n.push("--verbose"),t.sessionId&&n.push("--resume",t.sessionId),t.model&&n.push("--model",t.model);let s=t.permissionMode??"yolo",i=Ve(e,s)??Mp[e]??["--dangerously-skip-permissions"];if(n.push(...i),se(e,n,s),t.cwd&&!fl(t.cwd))throw R({event:"transport_error",provider:e,error_class:"TransportConnectionError",error_message:`sessiondir missing: ${t.cwd}`,elapsed_ms:0}),new J(`sessiondir missing: ${t.cwd}`,{cause:Object.assign(new Error("cwd missing"),{code:"ENOENT_CWD"})});let o=oe(t.env,t.cwd,t.sessionId);return{tool:e,binary:r,args:n,spawnEnv:e==="claude"?il(o):o}}function El(t,e){return new Promise((r,n)=>{let s=Date.now(),i,o,a,l;try{({tool:i,binary:o,args:a,spawnEnv:l}=_l(e))}catch(O){return n(O instanceof Error?O:new Error(String(O)))}let c=ml(o,a,{cwd:e.cwd,stdio:["pipe","pipe","pipe"],env:l});c.stdin?.on("error",O=>{ne(`stream-json: stdin pipe error, ignored (exit handler reports): ${O.message}`)});let u=!1;if(e.signal){if(e.signal.aborted)return u=!0,R({event:"transport_abort",provider:i,phase:"pre_spawn"}),V(c).catch(()=>{}),n(new Error("Aborted"));e.signal.addEventListener("abort",()=>{u=!0,R({event:"transport_abort",provider:i}),V(c).catch(()=>{}),n(new Error("Aborted"))},{once:!0})}let d="",p=!1,m=!1,h=0,g=!1,y="",f="",T,E,I=null,w=null,_=!1,v=!1,S=pl(),A=hl();function x(){T!==void 0&&(clearTimeout(T),T=void 0)}function b(){E!==void 0&&(clearTimeout(E),E=void 0)}let k=null;function P(){return p||u||ie.sawResult()}function re(O){return O==="text_done"?S:A}async function z(O){if(O==="text_done"?T=void 0:E=void 0,P()||I!==null)return;k??=Date.now();let X=re(O);if(e.holdOpen){let $t=(e.holdOpen.maxHoldMs??an)-(Date.now()-k),Jn=$t>0?await ln(Promise.resolve(e.holdOpen.hasOutstandingWork()).catch(()=>!1),$t,e.signal):!1;if(P()||(O==="text_done"?T!==void 0:E!==void 0))return;if(Jn===!0){R({event:"transport_stall_grace_deferred",provider:i,grace_kind:O,grace_ms:X,reason:"outstanding_dispatched_work"}),ae(O);return}}w=O,I=O==="text_done"?`${i} finished responding but never emitted its closing result event (${X}ms of silence after its last message)`:`${i} went silent mid-turn and never emitted its closing result event (${X}ms of silence)`,R({event:"transport_stall_grace_fired",provider:i,grace_kind:O,grace_ms:X}),V(c).catch(()=>{})}function ae(O){let X=setTimeout(()=>{z(O)},re(O));X.unref?.(),O==="text_done"?(x(),T=X):(b(),E=X)}let ie=cn({onEvent:O=>{h=Date.now(),g=O.type!=="result",O.type==="system"&&O.subtype==="init"&&(f=O.session_id||f),O.type==="assistant"?(_=!gl(O),v=_&&O.message?.stop_reason==="pause_turn"):(O.type==="result"||O.type==="user")&&(_=!1,v=!1),x(),i==="claude"&&_&&!v&&!ie.sawResult()&&ae("text_done"),b(),i==="claude"&&!ie.sawResult()&&ae("tool_use_silence"),e.onEvent?.(O)},onText:O=>{y+=O,e.onText?.(O)}});function B(){m||(m=!0,Ke(e.holdOpen,{isAborted:()=>u,hasChildExited:()=>p,isTurnInFlight:()=>g,lastEventAtMs:()=>h,closeStdin:()=>{c.stdin?.end()},signal:e.signal,label:e.tool||"claude"}))}function ce(O){let X=ie.sawResult();ie.processLine(O),!X&&ie.sawResult()&&B()}c.stdout?.on("data",O=>{d+=O.toString();let X=d.split(`
|
|
1915
|
+
`);d=X.pop()||"";for(let wr of X)ce(wr)});let De="";c.stderr?.on("data",O=>{De+=O.toString()}),c.on("error",O=>{R({event:"transport_error",provider:i,error_class:"TransportConnectionError",error_message:O.message}),n(new J(`Failed to spawn ${o}: ${O.message}`,{cause:O}))}),c.on("exit",O=>{if(p=!0,x(),b(),u)return;d.trim()&&ce(d);let X=ie.finalize();X?.isError?(R({event:"transport_error",provider:i,error_class:"Error",reason:"provider_result_error",error_message:X.errorMessage}),n(new Error(`${i} reported an error for this turn (no assistant output)`+(e.sessionId?` \u2014 session=${e.sessionId}`:"")+`: ${X.errorMessage??"unknown error"}`))):X?(ne(`stream-json: result ${X.result.slice(0,80)}${X.result.length>80?"...":""} (${X.durationMs}ms)`),r({result:X.result,sessionId:X.sessionId,durationMs:X.durationMs,numTurns:X.numTurns,exitCode:O})):I!==null&&w==="text_done"&&y.trim().length>0?(R({event:"transport_stall_finalized",provider:i,reason:I,text_len:y.length}),r({result:y,sessionId:f||e.sessionId||"",durationMs:Date.now()-s,numTurns:1,exitCode:O,warnings:[I]})):I!==null&&w==="tool_use_silence"?(R({event:"transport_error",provider:i,error_class:"Error",reason:"provider_stalled_mid_turn",exit_code:O,stderr_tail:De.slice(0,500)}),n(new Error(`${I} \u2014 a tool call was still in flight, so any streamed text is incomplete mid-turn narration, not a real answer`+(e.sessionId?` (session=${e.sessionId})`:"")))):(R({event:"transport_error",provider:i,error_class:"Error",reason:I!==null?"provider_stalled_no_content":"provider_no_result",exit_code:O,stderr_tail:De.slice(0,500)}),n(new Error(I!==null?`${I} \u2014 and produced no usable content to fall back on`+(e.sessionId?` (session=${e.sessionId})`:""):Dp({tool:i,exitCode:O,stderr:De}))))});let _t=JSON.stringify({type:"user",message:{role:"user",content:t}});c.stdin?.write(_t+`
|
|
1916
|
+
`),ne(`stream-json: prompt sent (${t.length} chars)`)})}function Fp(t){return t==="qwen"?[dn(U,".qwen","projects")]:[dn(U,".claude","projects")]}async function ul(t,e,r){let n=r??Fp(t),s=null;for(let a of n){let l;try{l=await Cp(a)}catch{continue}for(let c of l){for(let u of[dn(a,c,`${e}.jsonl`),dn(a,c,"chats",`${e}.jsonl`)])if(fl(u)){s=u;break}if(s!==null)break}if(s!==null)break}if(s===null)throw new Error(`stream-json bundle: no session file for session "${e}" under ${n.join(", ")} \u2014 the session must exist on disk before a bundle can resume it`);let o=(await Ee(s,5).catch(()=>[])).map(a=>a?.sessionId).find(a=>typeof a=="string"&&a.length>0);if(o!==e)throw new Error(`stream-json bundle: session file ${s} header does not match the requested session (expected "${e}", header carries ${o??"no sessionId"}) \u2014 the session was likely re-seeded externally; aborting instead of writing into the wrong session`)}async function yl(t){let{tool:e,binary:r,args:n,spawnEnv:s}=_l(t),i=ml(r,n,{cwd:t.cwd,stdio:["pipe","pipe","pipe"],env:s}),o=Date.now();i.stdin?.on("error",N=>{ne(`stream-json bundle: stdin pipe error, ignored (exit handler reports): ${N.message}`)});let a={exited:!1,exitCode:null,lastEventAtMs:0,turnActive:!1,completedTurns:0,closed:!1,closing:null},l=t.sessionId||"",c=null,u="";i.stderr?.on("data",N=>{u+=N.toString()});let d="",p="",m=!1,h=!1,g=null,y=null,f=null,T,E,I=pl(),w=hl(),_=null,v=[],S=()=>a.exited?Promise.resolve():new Promise(N=>{v.push(N)}),A=()=>new Error(`stream-json bundle process (${e}) exited${a.exitCode!==null?` with code ${a.exitCode}`:""} after ${a.completedTurns} completed prompt(s); the bundle cannot continue`);function x(){T!==void 0&&(clearTimeout(T),T=void 0)}function b(){E!==void 0&&(clearTimeout(E),E=void 0)}function k(){return a.exited||_===null||_.aborted||_.processor.sawResult()}function P(N){return N==="text_done"?I:w}async function re(N){if(N==="text_done"?T=void 0:E=void 0,k()||g!==null)return;f??=Date.now();let M=P(N);if(t.holdOpen){let Et=(t.holdOpen.maxHoldMs??an)-(Date.now()-f),vr=Et>0?await ln(Promise.resolve(t.holdOpen.hasOutstandingWork()).catch(()=>!1),Et,void 0):!1;if(k()||(N==="text_done"?T!==void 0:E!==void 0))return;if(vr===!0){R({event:"transport_stall_grace_deferred",provider:e,grace_kind:N,grace_ms:M,reason:"outstanding_dispatched_work"}),z(N);return}}y=N,g=N==="text_done"?`${e} finished responding but never emitted its closing result event (${M}ms of silence after its last message)`:`${e} went silent mid-turn and never emitted its closing result event (${M}ms of silence)`,R({event:"transport_stall_grace_fired",provider:e,grace_kind:N,grace_ms:M}),V(i).catch(()=>{})}function z(N){let M=setTimeout(()=>{re(N)},P(N));M.unref?.(),N==="text_done"?(x(),T=M):(b(),E=M)}let ae=!1,ie,B,ce=new Promise((N,M)=>{ie=N,B=M});ce.catch(()=>{});let De=setTimeout(()=>{ae||(ae=!0,B(new Error(`stream-json bundle: ${e} emitted no init event within the open timeout \u2014 cannot verify the resumed session identity`)))},t.closeTimeoutMs!==void 0?Math.max(t.closeTimeoutMs,5e3):3e4);De.unref?.();function _t(N){ae||(ae=!0,clearTimeout(De),N?B(N):ie())}let O="";function X(N){if(a.lastEventAtMs=Date.now(),N.type==="system"&&N.subtype==="init"){if(p=N.session_id||p,t.sessionId&&typeof N.session_id=="string"&&N.session_id.length>0&&N.session_id!==t.sessionId){let te=new Error(`stream-json bundle: provider resumed a different session (init reported "${N.session_id}", expected "${t.sessionId}")`);_t(te),V(i).catch(()=>{});return}_t()}let M=_?.processor.sawResult()??!0;N.type==="assistant"?(m=!gl(N),h=m&&N.message?.stop_reason==="pause_turn"):(N.type==="result"||N.type==="user")&&(m=!1,h=!1),x(),e==="claude"&&a.turnActive&&m&&!h&&!M&&z("text_done"),b(),e==="claude"&&a.turnActive&&!M&&z("tool_use_silence")}function wr(){let N=_;if(N===null)return;let M=N.processor.finalize();if(M!==null){if(_=null,a.turnActive=!1,x(),b(),M.isError){R({event:"transport_error",provider:e,error_class:"Error",reason:"provider_result_error",error_message:M.errorMessage}),N.reject(new Error(`${e} reported an error for this turn (no assistant output)`+(t.sessionId?` \u2014 session=${t.sessionId}`:"")+`: ${M.errorMessage??"unknown error"}`));return}a.completedTurns+=1,l=M.sessionId||l,ne(`stream-json bundle: result ${M.result.slice(0,80)}${M.result.length>80?"...":""} (${M.durationMs}ms)`),N.resolve({result:M.result,sessionId:M.sessionId||l,durationMs:M.durationMs,numTurns:M.numTurns})}}function $t(N){if(!N.trim())return;let M;try{M=JSON.parse(N)}catch{return}X(M);let te=_;if(te!==null){let Et=te.processor.sawResult();te.processor.processLine(N),te.onEventForward?.(M),!Et&&te.processor.sawResult()&&wr()}}i.stdout?.on("data",N=>{O+=N.toString();let M=O.split(`
|
|
1917
|
+
`);O=M.pop()||"";for(let te of M)$t(te)}),i.on("error",N=>{if(c=new J(`Failed to spawn ${r}: ${N.message}`,{cause:N}),R({event:"transport_error",provider:e,error_class:"TransportConnectionError",error_message:N.message}),_t(c),_!==null){let M=_;_=null,a.turnActive=!1,M.reject(c)}}),i.on("exit",N=>{a.exited=!0,a.exitCode=N,x(),b(),O.trim()&&$t(O),_t(a.exited&&!ae?new Error(`stream-json bundle: ${e} exited (code ${String(N)}) before its init event`):void 0);let M=_;M!==null&&(_=null,a.turnActive=!1,M.aborted||(g!==null&&y==="text_done"&&d.trim().length>0?(R({event:"transport_stall_finalized",provider:e,reason:g,text_len:d.length}),M.resolve({result:d,sessionId:p||t.sessionId||"",durationMs:Date.now()-M.startMs,numTurns:1,warnings:[g]})):g!==null&&y==="tool_use_silence"?(R({event:"transport_error",provider:e,error_class:"Error",reason:"provider_stalled_mid_turn",exit_code:N,stderr_tail:u.slice(0,500)}),M.reject(new Error(`${g} \u2014 a tool call was still in flight, so any streamed text is incomplete mid-turn narration, not a real answer`+(t.sessionId?` (session=${t.sessionId})`:"")))):(R({event:"transport_error",provider:e,error_class:"Error",reason:g!==null?"provider_stalled_no_content":"provider_no_result",exit_code:N,stderr_tail:u.slice(0,500)}),M.reject(A()))));for(let te of v.splice(0))te()});try{t.sessionId&&await ul(e,t.sessionId,t.sessionFileRoots),await ce}catch(N){let M=c??(N instanceof Error?N:new Error(String(N))),te=t.closeTimeoutMs??2e3;throw await V(i,{softDelayMs:Math.min(1e3,te),killDelayMs:Math.min(1e3,te)}).catch(()=>{}),M}let Jn=N=>new Promise(M=>{setTimeout(M,N).unref?.()});return{tool:e,get sessionId(){return l},get completedTurns(){return a.completedTurns},async sendTurn(N,M={}){if(a.closed||a.closing!==null)throw new Error(`stream-json bundle session (${e}) is closed`);if(a.exited)throw A();if(_!==null)throw new Error(`stream-json bundle session (${e}) has a turn still in flight \u2014 a stalled turn poisons the bundle; close it instead of sending`);let te=()=>(a.closed=!0,V(i).catch(()=>{}),new Error("Aborted"));if(M.signal?.aborted)throw te();if(t.sessionId&&(await ul(e,t.sessionId,t.sessionFileRoots),a.exited))throw A();if(M.signal?.aborted)throw te();return d="",m=!1,h=!1,g=null,y=null,f=null,new Promise((Et,vr)=>{let Vn={processor:cn({onText:Qi=>{d+=Qi,M.onText?.(Qi)}}),resolve:Et,reject:vr,startMs:Date.now(),aborted:!1,onEventForward:M.onEvent};_=Vn,a.turnActive=!0;let qd=()=>{Vn.aborted=!0,R({event:"transport_abort",provider:e}),a.closed=!0,V(i).catch(()=>{}),_===Vn&&(_=null,a.turnActive=!1),vr(new Error("Aborted"))};M.signal?.addEventListener("abort",qd,{once:!0});let Gd=JSON.stringify({type:"user",message:{role:"user",content:N}});i.stdin?.write(`${Gd}
|
|
1918
|
+
`),ne(`stream-json bundle: prompt sent (${N.length} chars)`)})},close(){return a.closing!==null||(a.closing=(async()=>{if(a.closed=!0,!a.exited&&(t.holdOpen!==void 0?await new Promise(N=>{Ke(t.holdOpen,{isAborted:()=>!1,hasChildExited:()=>a.exited,isTurnInFlight:()=>a.turnActive,lastEventAtMs:()=>a.lastEventAtMs,closeStdin:()=>{i.stdin?.end(),N()},label:e})}):i.stdin?.end(),!a.exited)){let N=t.closeTimeoutMs??2e3;await Promise.race([S(),Jn(N)]),a.exited||await V(i,{stdinEnd:!1,softDelayMs:Math.min(1e3,N),killDelayMs:Math.min(1e3,N)}).catch(()=>{})}})()),a.closing}}}import{spawn as wl}from"node:child_process";import{createInterface as vl}from"node:readline";import{existsSync as Up,readFileSync as $p}from"node:fs";import{fileURLToPath as jp}from"node:url";function Os(t={}){return[]}function Ds(t){return t==="plan"?"read-only":"danger-full-access"}function Tl(t="0.0.0"){return{clientInfo:{name:"lmctl",title:"lmctl",version:t},capabilities:{experimentalApi:!1}}}function un(){return{agentItems:new Map,resultText:""}}function kt(t,e,r,n){let s=t.method;if(!s)return!1;let i=t.params;if(s==="turn/started")return e.agentItems.clear(),e.resultText="",!1;if(s==="item/started"){let o=i?.item;if(o?.type==="agentMessage"&&typeof o.id=="string"){let a=typeof o.phase=="string"?o.phase:void 0,l=a==="commentary"||a==="final_answer"?a:void 0;return e.agentItems.set(o.id,{phase:l,buffer:""}),!0}return!1}if(s==="item/agentMessage/delta"){let o=i?.delta||"",a=typeof i?.itemId=="string"?i.itemId:void 0;if(!o)return!0;let l=a?e.agentItems.get(a):void 0;return l?(l.phase==="commentary"||(l.buffer+=o),r?.(o),l.phase&&i&&(i._lmctlItemPhase=l.phase)):(e.resultText+=o,r?.(o)),!0}if(s==="item/completed"){let o=i?.item;if(o?.type==="agentMessage"&&typeof o.id=="string"){let a=e.agentItems.get(o.id);if(a){if(a.phase!=="commentary"){let l=typeof o.text=="string"?o.text:a.buffer;if(n&&typeof o.text=="string"&&o.text!==a.buffer){let c=typeof i?.threadId=="string"?i.threadId:void 0,u=typeof i?.turnId=="string"?i.turnId:void 0;n({itemId:o.id,threadId:c,turnId:u,expectedFromItemText:o.text,gotFromBuffer:a.buffer})}e.resultText+=l}e.agentItems.delete(o.id)}return!0}return!1}return!1}function mn(t){for(let[,e]of t.agentItems.entries())e.phase!=="commentary"&&e.buffer&&(t.resultText+=e.buffer);t.agentItems.clear()}function Sl(t){let e=t.params,r=e?.error,n=typeof r?.message=="string"?r.message:void 0,s=n&&n.length>0?n:"(no message)";return e?.willRetry===!0?{willRetry:!0}:{willRetry:!1,turnError:new Error(`Turn errored: ${s}`)}}function fn(){return{pendingCodexError:null}}function pn(t,e){let r=Sl(t);return r.willRetry||(e.pendingCodexError=r.turnError),r}function hn(t,e){if(e.pendingCodexError){let i=e.pendingCodexError;return e.pendingCodexError=null,{shouldReject:!0,turnError:i}}let n=t.params?.turn;if((typeof n?.status=="string"?n.status:void 0)==="failed"){let i=n?.error,o=typeof i?.message=="string"?i.message:void 0,a=o&&o.length>0?o:"(no message)";return{shouldReject:!0,turnError:new Error(`Turn errored: ${a}`)}}return{shouldReject:!1}}var Bp=(()=>{try{let t=new URL("../../../package.json",import.meta.url),e=JSON.parse($p(jp(t),"utf8"));return typeof e.version=="string"?e.version:"0.0.0"}catch{return"0.0.0"}})();function Il(){return Tl(Bp)}function Ye(t,e){ne(`[codex:${t}] ${JSON.stringify(e)}`)}function Wp(t){let e=t.stderr.trim().slice(0,500),r=`lmctl: codex app-server exited with code ${t.exitCode} before completing the turn.
|
|
1919
|
+
One possible cause: Codex stopped before delivering a terminal turn/completed event.`;return e?`Original provider error:
|
|
1920
|
+
${e}
|
|
1921
|
+
|
|
1922
|
+
${r}`:r}function Al(t){let e=t.binaryPath||"codex",r=["app-server","--listen","stdio://"];t.model&&r.push("-c",`model=${JSON.stringify(t.model)}`);let n=t.isLead??t.alias?.toLowerCase()==="lead",s=n?Os():[];r.push(...s),K()&&ge(JSON.stringify({event:"codex_mcp_inject",alias:t.alias??null,isLead:n,injected:s.length>0}));let i=t.permissionMode??"yolo",o=Ds(i);if(se("codex",r,i),t.cwd&&!Up(t.cwd))throw R({event:"transport_error",provider:"codex",error_class:"TransportConnectionError",error_message:`sessiondir missing: ${t.cwd}`}),new J(`sessiondir missing: ${t.cwd}`,{cause:Object.assign(new Error("cwd missing"),{code:"ENOENT_CWD"})});return{binary:e,codexArgs:r,sandbox:o,permissionMode:i,spawnEnv:oe(t.env,t.cwd,t.threadId)}}function xl(t,e){return new Promise((r,n)=>{let s,i,o;try{({binary:s,codexArgs:i,sandbox:o}=Al(e))}catch(_){return n(_ instanceof Error?_:new Error(String(_)))}let a=wl(s,i,{cwd:e.cwd,stdio:["pipe","pipe","pipe"],env:oe(e.env,e.cwd,e.threadId)}),l=!1;if(e.signal){if(e.signal.aborted)return l=!0,R({event:"transport_abort",provider:"codex",phase:"pre_spawn"}),V(a).catch(()=>{}),n(new Error("Aborted"));e.signal.addEventListener("abort",()=>{l=!0,R({event:"transport_abort",provider:"codex"}),V(a).catch(()=>{}),n(new Error("Aborted"))},{once:!0})}let c=vl({input:a.stdout}),u=new Map,d=1,p=e.threadId||"",m="",h=!1,g=!1,y=Date.now(),f=un(),T=fn();function E(_,v={}){return new Promise((S,A)=>{let x=d++;u.set(x,{resolve:S,reject:A});let b=JSON.stringify({jsonrpc:"2.0",id:x,method:_,params:v});a.stdin?.write(b+`
|
|
1923
|
+
`)})}function I(_,v={}){let S=JSON.stringify({jsonrpc:"2.0",method:_,params:v});a.stdin?.write(S+`
|
|
1924
|
+
`)}c.on("line",_=>{let v;try{v=JSON.parse(_)}catch{return}if(typeof v.id=="number"&&u.has(v.id)){let x=u.get(v.id);if(u.delete(v.id),v.error){let b=v.error,k=typeof b?.message=="string"&&b.message.length>0?b.message:JSON.stringify(v.error);x.reject(er(`codex app-server error: ${k}`,b))}else x.resolve(v);e.onEvent?.(v);return}let S=v.method;if(!S){e.onEvent?.(v);return}if(S==="thread/started"){let b=v.params?.thread;b?.id&&(p=b.id)}let A=K()?x=>{Ye("item.text/buffer-mismatch",{itemId:x.itemId,threadId:x.threadId??null,turnId:x.turnId??null,expectedFromItemText:x.expectedFromItemText,gotFromBuffer:x.gotFromBuffer,expectedLen:x.expectedFromItemText.length,gotLen:x.gotFromBuffer.length})}:void 0;if(S==="turn/started"){let x=v.params,b=x?.turn;b?.id&&(m=b.id),kt(v,f,e.onDelta,A),K()&&Ye("turn/started",{params:x??null})}if(K()&&(S==="item/started"||S==="item/completed")){let x=v.params;x?.item?.type==="agentMessage"&&Ye(S,{params:x??null})}if(S==="item/started"||S==="item/agentMessage/delta"||S==="item/completed"){if(S==="item/agentMessage/delta"){let x=v.params;K()&&Ye("agentMessage/delta",{params:x??null})}kt(v,f,e.onDelta,A)}if(S==="turn/completed"){let x=v.params;if(K())for(let[k,P]of f.agentItems.entries())P.buffer&&Ye("turn/completed/unflushed-item",{itemId:k,phase:P.phase,bufferLen:P.buffer.length});mn(f),K()&&Ye("turn/completed",{params:x??null});let b=hn(v,T);b.shouldReject?(K()&&Ye("turn/completed/terminal-reject",{message:b.turnError.message}),g=!0,h=!0,a.stdin?.end(),n(b.turnError)):(h=!0,a.stdin?.end())}if(S==="error"){let x=pn(v,T);if(K()){let b=v.params,k=b?.error,P=typeof k?.message=="string"?k.message:"(no message)";Ye(x.willRetry?"error/retry":"error/terminal-deferred",{message:P,willRetry:x.willRetry,params:b??null})}}e.onEvent?.(v)});let w="";a.stderr?.on("data",_=>{w+=_.toString()}),a.on("error",_=>{R({event:"transport_error",provider:"codex",error_class:"TransportConnectionError",error_message:_.message}),n(new J(`Failed to spawn codex app-server: ${_.message}`,{cause:_}))}),a.on("exit",_=>{if(!l&&!g){if(h){r({result:f.resultText,threadId:p,turnId:m,durationMs:Date.now()-y,exitCode:_});return}if(T.pendingCodexError){n(T.pendingCodexError);return}R({event:"transport_error",provider:"codex",error_class:"Error",reason:"provider_no_result",exit_code:_,stderr_tail:w.slice(0,500)}),n(new Error(Wp({exitCode:_,stderr:w})))}}),(async()=>{try{if(await E("initialize",Il()),I("initialized",{}),e.threadId)try{let _=E("thread/resume",{threadId:e.threadId,sandbox:o,approvalPolicy:"never",...e.model?{model:e.model}:{}}),v=new Promise((S,A)=>setTimeout(()=>A(new Error("resume timeout")),3e4));await Promise.race([_,v]),p=e.threadId}catch(_){process.stderr.write(`[codex] thread/resume failed, creating new thread
|
|
1925
|
+
`),R({event:"codex_thread_resume_fallback",provider:"codex",thread_id:e.threadId,error_message:_ instanceof Error?_.message:String(_)});let S=(await E("thread/start",{cwd:e.cwd,approvalPolicy:"never",sandbox:o,...e.model?{model:e.model}:{}})).result?.thread;S?.id&&(p=S.id)}else{let v=(await E("thread/start",{cwd:e.cwd,approvalPolicy:"never",sandbox:o,...e.model?{model:e.model}:{}})).result?.thread;v?.id&&(p=v.id)}await E("turn/start",{threadId:p,input:[{type:"text",text:t}],...e.model?{model:e.model}:{}})}catch(_){V(a).catch(()=>{}),n(_ instanceof Error?_:new Error(String(_)))}})()})}async function Rl(t){let{binary:e,codexArgs:r,sandbox:n}=Al(t),s=wl(e,r,{cwd:t.cwd,stdio:["pipe","pipe","pipe"],env:oe(t.env,t.cwd,t.threadId)}),i=Date.now(),o={exited:!1,exitCode:null,completedTurns:0,closed:!1,closing:null},a=t.threadId||"",l=null,c="";s.stderr?.on("data",w=>{c+=w.toString()});let u=vl({input:s.stdout}),d=new Map,p=1;function m(w,_={}){return new Promise((v,S)=>{let A=p++;d.set(A,{resolve:v,reject:S});let x=JSON.stringify({jsonrpc:"2.0",id:A,method:w,params:_});s.stdin?.write(x+`
|
|
1926
|
+
`)})}function h(w,_={}){let v=JSON.stringify({jsonrpc:"2.0",method:w,params:_});s.stdin?.write(v+`
|
|
1927
|
+
`)}let g=[],y=()=>o.exited?Promise.resolve():new Promise(w=>{g.push(w)}),f=()=>new Error(`codex bundle process exited${o.exitCode!==null?` with code ${o.exitCode}`:""} after ${o.completedTurns} completed prompt(s); the bundle cannot continue`),T=null;function E(w){let _=T;_===null||_.settled||(_.settled=!0,T=null,w&&_.reject(w))}u.on("line",w=>{let _;try{_=JSON.parse(w)}catch{return}if(typeof _.id=="number"&&d.has(_.id)){let A=d.get(_.id);if(d.delete(_.id),_.error){let x=_.error,b=typeof x?.message=="string"&&x.message.length>0?x.message:JSON.stringify(_.error);A.reject(er(`codex app-server error: ${b}`,x))}else A.resolve(_);T?.onEvent?.(_);return}let v=_.method;if(!v){T?.onEvent?.(_);return}if(v==="thread/started"){let x=_.params?.thread;x?.id&&(a=x.id)}let S=T;if(v==="turn/started"&&S!==null){let x=_.params?.turn;x?.id&&(S.turnId=x.id),kt(_,S.agentState,S.onDelta,void 0)}if(S!==null&&(v==="item/started"||v==="item/agentMessage/delta"||v==="item/completed")&&kt(_,S.agentState,S.onDelta,void 0),v==="turn/completed"&&S!==null&&!S.settled){mn(S.agentState);let A=hn(_,S.turnState);S.settled=!0,T=null,A.shouldReject?S.reject(A.turnError):(o.completedTurns+=1,S.resolve({text:S.agentState.resultText,sessionId:a,turnId:S.turnId,durationMs:Date.now()-S.startMs}))}v==="error"&&S!==null&&pn(_,S.turnState),S?.onEvent?.(_)}),s.on("error",w=>{l=new J(`Failed to spawn codex app-server: ${w.message}`,{cause:w}),R({event:"transport_error",provider:"codex",error_class:"TransportConnectionError",error_message:w.message});for(let _ of d.values())_.reject(l);d.clear(),E(l)}),s.on("exit",w=>{o.exited=!0,o.exitCode=w;let _=f();for(let S of d.values())S.reject(_);d.clear();let v=T;v!==null&&!v.settled&&(v.settled=!0,T=null,v.turnState.pendingCodexError?v.reject(v.turnState.pendingCodexError):(R({event:"transport_error",provider:"codex",error_class:"Error",reason:"provider_no_result",exit_code:w,stderr_tail:c.slice(0,500)}),v.reject(_)));for(let S of g.splice(0))S()});try{if(await m("initialize",Il()),h("initialized",{}),t.threadId){let w;try{w=await m("thread/resume",{threadId:t.threadId,sandbox:n,approvalPolicy:"never",...t.model?{model:t.model}:{}})}catch(v){throw new Error(`Cannot resume codex thread ${t.threadId} for a bundle: ${v instanceof Error?v.message:String(v)} (the thread/start fallback is disabled in bundle mode)`)}let _=w.result?.thread;if(typeof _?.id=="string"&&_.id.length>0){if(_.id!==t.threadId)throw new Error(`codex thread/resume did not return the requested thread id: expected "${t.threadId}", received "${_.id}"`);a=_.id}}else{let _=(await m("thread/start",{cwd:t.cwd,approvalPolicy:"never",sandbox:n,...t.model?{model:t.model}:{}})).result?.thread;_?.id&&(a=_.id)}}catch(w){let _=l??(w instanceof Error?w:new Error(String(w))),v=t.closeTimeoutMs??2e3;throw await V(s,{softDelayMs:Math.min(1e3,v),killDelayMs:Math.min(1e3,v)}).catch(()=>{}),_}let I=w=>new Promise(_=>{setTimeout(_,w).unref?.()});return{provider:"codex",get sessionId(){return a},get completedTurns(){return o.completedTurns},async sendTurn(w,_={}){if(o.closed||o.closing!==null)throw new Error("codex bundle session is closed");if(o.exited)throw f();if(T!==null)throw new Error("codex bundle session has a turn still in flight \u2014 a stalled turn poisons the bundle; close it instead of sending");if(_.signal?.aborted)throw new Error("Aborted");return new Promise((v,S)=>{let A={agentState:un(),turnState:fn(),resolve:v,reject:S,startMs:Date.now(),turnId:"",onDelta:_.onDelta,onEvent:_.onEvent,settled:!1};T=A;let x=()=>{A.settled||(A.settled=!0,T=null,A.turnId&&m("turn/interrupt",{threadId:a,turnId:A.turnId}).catch(()=>{}),S(new Error("Aborted")))};_.signal?.addEventListener("abort",x,{once:!0}),m("turn/start",{threadId:a,input:[{type:"text",text:w}],...t.model?{model:t.model}:{}}).catch(b=>{A.settled||(A.settled=!0,T=null,_.signal?.removeEventListener("abort",x),S(o.exited?f():b instanceof Error?b:new Error(String(b))))})})},close(){return o.closing!==null||(o.closing=(async()=>{if(o.closed=!0,!o.exited&&(t.holdOpen!==void 0?await new Promise(w=>{Ke(t.holdOpen,{isAborted:()=>!1,hasChildExited:()=>o.exited,isTurnInFlight:()=>T!==null,lastEventAtMs:()=>i,closeStdin:()=>{s.stdin?.end(),w()},label:"codex"})}):s.stdin?.end(),!o.exited)){let w=t.closeTimeoutMs??2e3;await Promise.race([y(),I(w)]),o.exited||await V(s,{stdinEnd:!1,softDelayMs:Math.min(1e3,w),killDelayMs:Math.min(1e3,w)}).catch(()=>{})}})()),o.closing}}}import{spawn as Jl}from"node:child_process";import{existsSync as gh}from"node:fs";var Nl="(?:png|jpe?g|webp|heic|pdf)",Hp=new RegExp(`\\bSTANCE:\\s*\\S+_\\d{6,}\\.${Nl}\\s*`,"gi"),Xp=new RegExp(`^ACK:\\s*waiting for explicit lmctl task\\.\\d{6,}\\.${Nl}\\s*`,"i"),qp=/^ACK:\s*waiting for explicit lmctl task[._]?\s*/i,Gp=/^STANCE:\s+\S+\s*$/gim,Jp=/\[Thought:\s*true\]\s*/gi;function gn(t){let e=[...t.matchAll(Hp)];if(e.length>0){let r=e[e.length-1],n=(r.index??0)+r[0].length;return bl(t.slice(n).trimStart())}return bl(Vp(t.replace(Xp,"")))}function Vp(t){let e=qp.exec(t);if(e===null)return t;let r=t.slice(e[0].length),n=[...r.matchAll(Gp)];if(n.length<2)return t;let s=n[0],i=(s.index??0)+s[0].length;return r.slice(i).trimStart()}function bl(t){let e=[...t.matchAll(Jp)];if(e.length===0)return t;let r=e[e.length-1],n=(r.index??0)+r[0].length;return t.slice(n).trimStart()}function ze(t,e=""){let r=t.result;return typeof r?.sessionId=="string"&&r.sessionId.length>0?r.sessionId:e}function kl(t){let e=t.result;return typeof e?.stopReason=="string"?e.stopReason:""}function _n(t={}){let e="",r="",n="",s=!1,i=!1,o=t.isolateResult??(t.tool==="gemini"?gn:void 0),a=()=>({result:o?o(r):r,sessionId:e,stopReason:n});return{setSessionId(l){e=l},beginTurn(){r="",n="",s=!1,i=!0},completeTurn(l){return n=kl(l),s=!0,i=!1,a()},cancelTurn(){r="",n="",i=!1},processMessage(l){if(l.method!=="session/update")return!1;let u=l.params?.update;if(u?.sessionUpdate!=="agent_message_chunk")return!1;let d=u.content,p=typeof d?.text=="string"?d.text:"";return p&&i&&(r+=p,t.onDelta?.(p)),!0},finalize(){return s?a():null}}}import{createInterface as Kp}from"node:readline";var Yp=1;function tr(t,e){let r=Kp({input:t.stdout}),n=new Map,s=(o,a={})=>new Promise((l,c)=>{let u=Yp++;n.set(u,{resolve:l,reject:c});let d=JSON.stringify({jsonrpc:"2.0",id:u,method:o,params:a});he({event:"acp_send",direction:"SEND",provider:e.provider,method:o,id:u,params:a}),t.stdin?.write(`${d}
|
|
1928
|
+
`)}),i=(o,a={})=>{t.stdin?.write(`${JSON.stringify({jsonrpc:"2.0",method:o,params:a})}
|
|
1929
|
+
`)};return r.on("line",o=>{let a;try{a=JSON.parse(o)}catch{return}if(he({event:"acp_recv",direction:"RECV",provider:e.provider,id:typeof a.id=="number"?a.id:void 0,method:typeof a.method=="string"?a.method:void 0,preview:JSON.stringify(a).slice(0,300)}),e.onEvent?.(a),typeof a.id=="number"&&n.has(a.id)){let c=n.get(a.id);if(n.delete(a.id),a.error){let u=a.error,d=typeof u?.message=="string"&&u.message.length>0?u.message:JSON.stringify(a.error);c.reject(er(`ACP RPC error: ${d}`,u))}else c.resolve(a);return}let l=a.method;if(l){if(typeof a.id=="number"){R({event:"acp_unhandled_request",provider:e.provider,method:l,id:a.id,params:a.params});let c=JSON.stringify({jsonrpc:"2.0",id:a.id,error:{code:-32601,message:`Method not found: ${l} (lmctl does not implement server-side ACP methods)`}});he({event:"acp_send",direction:"SEND",provider:e.provider,replyTo:a.id,error:"method not found"}),t.stdin?.write(`${c}
|
|
1930
|
+
`);return}e.onNotification?.(a)}}),{sendRpc:s,sendNotification:i,close(o=new J("ACP RPC channel closed")){r.close();for(let a of n.values())a.reject(o);n.clear()}}}import{readFileSync as zp,readdirSync as Ll}from"node:fs";import{join as En}from"node:path";function Cl(t,e){let r=e.GEMINI_DIR??process.env.GEMINI_DIR??En(U,".gemini"),n=En(r,"tmp"),s;try{s=Ll(n)}catch{throw new Error(`gemini bundle: cannot read the gemini session store at ${n} \u2014 cannot verify session "${t}"`)}let i=`"sessionId": "${t}"`,o=`"sessionId":"${t}"`;for(let a of s){let l=En(n,a,"chats"),c;try{c=Ll(l)}catch{continue}for(let u of c){if(!u.endsWith(".json"))continue;let d;try{d=zp(En(l,u),"utf8").slice(0,8192)}catch{continue}if(d.includes(i)||d.includes(o))return}}throw new Error(`gemini bundle: no session "${t}" in the gemini chats store (${n}) \u2014 the session must exist on disk before a bundle can resume it`)}var rr={name:"gemini",binary:"gemini",baseArgs:["--acp","-y","--skip-trust"],argv(t){let e=[...rr.baseArgs];if(t.permissionMode==="plan"){let r=Ve("gemini","plan"),n=Ve("gemini","yolo");e=e.filter(s=>!(n??[]).includes(s)),r&&e.push(...r)}return t.model&&e.push("--model",t.model),e},isolateResult:gn,sessionIdentity:{verifyLoadedSession:t=>{Cl(t.requestedSessionId,t.env)},recheckSession:t=>{Cl(t.requestedSessionId,t.env)}}};import{existsSync as Qp,readFileSync as Zp}from"node:fs";import{join as Ms}from"node:path";function Ol(t,e){let r=e.COPILOT_HOME??process.env.COPILOT_HOME??Ms(U,".copilot"),n=Ms(r,"session-state",t),s=Ms(n,"workspace.yaml");if(!Qp(s))throw new Error(`copilot bundle: no session "${t}" in the copilot session store (${n}) \u2014 the session must exist on disk before a bundle can resume it`);let i;try{i=Zp(s,"utf8").slice(0,4096)}catch(a){throw new Error(`copilot bundle: cannot read ${s} \u2014 cannot verify session "${t}": `+(a instanceof Error?a.message:String(a)))}let o=/^id:\s*(\S+)\s*$/m.exec(i);if(o===null||o[1]!==t)throw new Error(`copilot bundle: session store entry ${s} belongs to ${o?.[1]??"no recorded id"}, not "${t}"`)}var nr={name:"copilot",binary:"copilot",baseArgs:["--acp","--yolo"],argv(t){return t.permissionMode==="plan"&&(process.stderr.write(`[acp] copilot has no plan-mode flag in --acp mode; --permission-mode plan is not honored (running yolo). See src/providers/yolo-contract.ts.
|
|
1931
|
+
`),R({event:"acp_plan_mode_unsupported",provider:"copilot",requested_mode:"plan",effective_mode:"yolo"})),t.model&&(process.stderr.write(`[acp] copilot does not support per-session model selection in --acp mode (model="${t.model}" ignored). Set the default via copilot's /model slash command in an interactive \`lmctl terminal\` session.
|
|
1932
|
+
`),R({event:"acp_model_unsupported",provider:"copilot",model:t.model})),[...nr.baseArgs]},yoloAssertion:"always-yolo",sessionIdentity:{verifyLoadedSession:t=>{Ol(t.requestedSessionId,t.env)},recheckSession:t=>{Ol(t.requestedSessionId,t.env)}}};import{spawn as lh}from"node:child_process";import{resolve as Hl}from"node:path";import{existsSync as eh,mkdirSync as th,readFileSync as rh,writeFileSync as Dl}from"node:fs";import{join as Ml,resolve as Ow}from"node:path";var Fl={yellow:t=>t};function nh(t){if(t==="allow")return!0;if(t&&typeof t=="object"&&!Array.isArray(t)){let e=Object.entries(t);if(e.length===1&&e[0][0]==="*"&&e[0][1]==="allow")return!0}return!1}function Pl(t,e={}){let r=Ml(t,".opencode"),n=Ml(r,"opencode.json");if(!eh(n)){th(r,{recursive:!0});let o=JSON.stringify({permission:"allow"},null,2);return Dl(n,o+`
|
|
1933
|
+
`,"utf-8"),!0}let s;try{s=JSON.parse(rh(n,"utf-8"))}catch{return console.log(Fl.yellow(` .opencode/opencode.json at ${n} is malformed \u2014 skipping opencode config install.`)),!1}if(typeof s!="object"||s===null)return console.log(Fl.yellow(` .opencode/opencode.json at ${n} is not an object \u2014 skipping opencode config install.`)),!1;let i=!1;return s.permission===void 0&&(s.permission="allow",i=!0),nh(s.permission)||R({event:"opencode_yolo_override",provider:"opencode",config_path:n,user_permission:s.permission,message:`opencode.json has a user-set 'permission' value other than 'allow' \u2014 lmctl's YOLO contract is NOT in effect; turns may hang waiting on permission prompts. Set permission: "allow" or remove the key to restore YOLO.`}),i&&Dl(n,JSON.stringify(s,null,2)+`
|
|
1934
|
+
`,"utf-8"),i}import{existsSync as Ps,readdirSync as sh,statSync as Ul}from"node:fs";import{join as Qe}from"node:path";import{createRequire as ih}from"node:module";var Fs=null;function Us(){return Fs===null&&(Fs=ih(import.meta.url)("node:sqlite").DatabaseSync),Fs}function $l(){return{observed:!1,totalInputTokens:0,totalCachedInputTokens:0,totalCacheWriteInputTokens:0,totalOutputTokens:0,totalReasoningOutputTokens:0}}function jl(t,e){if(!e)return;t.observed=!0;let r=e.input??0,n=e.output??0,s=e.reasoning??0,i=e.cache?.read??0,o=e.cache?.write??0;if(t.totalInputTokens+=r,t.totalCachedInputTokens+=i,t.totalCacheWriteInputTokens+=o,t.totalOutputTokens+=n,t.totalReasoningOutputTokens+=s,r+n+s+i+o>0){let a=r+i+o;t.lastInputTokens=a,t.lastTokenUsage={inputTokens:r,cachedInputTokens:i,cacheWriteInputTokens:o,outputTokens:n,reasoningOutputTokens:s,totalTokens:a+n+s}}}function Bl(t){return t.observed?{totalInputTokens:t.totalInputTokens,totalCachedInputTokens:t.totalCachedInputTokens,totalCacheWriteInputTokens:t.totalCacheWriteInputTokens,totalOutputTokens:t.totalOutputTokens,totalReasoningOutputTokens:t.totalReasoningOutputTokens,lastInputTokens:t.lastInputTokens,lastTokenUsage:t.lastTokenUsage}:{}}function Wl(){let t=process.env.XDG_DATA_HOME||Qe(U,".local","share"),e=process.env.XDG_CONFIG_HOME||Qe(U,".config");return[Qe(t,"opencode","opencode.db"),Qe(e,"opencode","opencode.db")]}function oh(){if(process.env.OPENCODE_DB)return[process.env.OPENCODE_DB];let t=process.env.XDG_DATA_HOME||Qe(U,".local","share"),e=Qe(t,"lmplayer"),r=Qe(e,"opencode-local.db"),n=[r];try{let s=sh(e).filter(i=>/^opencode.*\.db$/u.test(i)).map(i=>Qe(e,i)).filter(i=>i!==r).sort((i,o)=>{try{return Ul(o).mtimeMs-Ul(i).mtimeMs}catch{return 0}});n.push(...s)}catch{}return n}function ah(t){return t==="lmplayer"?oh():Wl()}var Lt=class{name;startCommand;dbPaths;busyTimeoutMs;constructor(e){this.name=e?.providerName??"opencode",this.startCommand=e?.startCommand??this.name,this.busyTimeoutMs=e?.busyTimeoutMs??5e3,e?.dbPath?this.dbPaths=[e.dbPath]:this.dbPaths=ah(this.name)}existingDbPaths(){return this.dbPaths.filter(e=>Ps(e))}openDb(e){if(!Ps(e))return null;let r=new(Us())(e,{open:!0,readOnly:!0});return r.exec(`PRAGMA busy_timeout = ${this.busyTimeoutMs}`),r}async discoverSessions(){let e=[];for(let r of this.existingDbPaths()){let n=this.openDb(r);if(n)try{let s=new Map,i=n.prepare("SELECT id, worktree, name FROM project").all();for(let a of i)s.set(a.id,a);let o=n.prepare(`SELECT s.id, s.project_id, s.slug, s.directory, s.title, s.version,
|
|
1935
|
+
s.time_created, s.time_updated
|
|
1936
|
+
FROM session s
|
|
1937
|
+
ORDER BY s.time_updated DESC`).all();for(let a of o){let l=s.get(a.project_id),c=a.directory||l?.worktree||"(unknown)",u=n.prepare(`SELECT m.id, m.data, m.time_created FROM message m
|
|
1938
|
+
WHERE m.session_id = ? ORDER BY m.time_created ASC`).all(a.id),d=0,p,m,h,g=$l(),y=[];for(let T of u){let E;try{E=JSON.parse(T.data)}catch{continue}h||(h=E.model?.modelID||E.modelID),(E.role==="user"||E.role==="assistant")&&d++,E.role==="user"&&y.push(T.id),E.role==="assistant"&&jl(g,E.tokens)}let f=[...y.length>0?[y[0]]:[],...y.length>1?[y[y.length-1]]:[]];for(let T of f){let E=n.prepare("SELECT id, data FROM part WHERE message_id = ? ORDER BY time_created ASC").all(T),I=this.extractText(E);I&&(p||(p=D(I,80)),m=D(I,80))}e.push({provider:this.name,sessionId:a.id,slug:a.slug,cwd:c,createdAt:new Date(a.time_created),modifiedAt:new Date(a.time_updated),model:h,startCommand:this.startCommand,firstUserMessage:p,lastUserMessage:m,messageCount:d,filePath:r,...Bl(g)})}}catch(s){R({event:"opencode_discover_sessions_failed",provider:this.name,db_path:r,error_message:s instanceof Error?s.message:String(s)})}finally{n.close()}}return e.sort((r,n)=>n.modifiedAt.getTime()-r.modifiedAt.getTime())}async loadSession(e){for(let r of this.existingDbPaths()){let n=this.openDb(r);if(n)try{let s=this.findSessionRow(n,e);if(!s)continue;return this.buildSessionDetail(n,s,r)}catch{}finally{n.close()}}return null}buildSessionDetail(e,r,n){let s=e.prepare("SELECT id, worktree, name FROM project WHERE id = ?").get(r.project_id),i=r.directory||s?.worktree||"(unknown)",o=e.prepare(`SELECT id, session_id, time_created, time_updated, data
|
|
1939
|
+
FROM message WHERE session_id = ? ORDER BY time_created ASC`).all(r.id),a=[],l=[],c=0,u,d,p,m=$l();for(let h of o){let g;try{g=JSON.parse(h.data)}catch{continue}u||(u=g.model?.modelID||g.modelID);let y=g.model?.modelID||g.modelID,f=new Date(g.time?.created||h.time_created),T=e.prepare("SELECT id, data FROM part WHERE message_id = ? ORDER BY time_created ASC").all(h.id);if(g.role==="user"){let E=this.extractText(T),I=this.extractText(T,!0);I&&l.push(I),E&&(d||(d=D(E,80)),p=D(E,80)),a.push({role:"user",timestamp:f,content:E||"(empty)"}),c++}else if(g.role==="assistant"){jl(m,g.tokens);for(let E of T){let I;try{I=JSON.parse(E.data)}catch{continue}I.type==="text"&&I.text?a.push({role:"assistant",timestamp:f,content:I.text,model:y}):I.type==="reasoning"&&I.text?a.push({role:"thinking",timestamp:f,content:I.text}):I.type==="tool"&&I.tool&&(a.push({role:"tool_use",timestamp:f,content:`${I.tool}`,toolName:I.tool,toolCallId:I.callID,toolInput:I.state?.input?JSON.stringify(I.state.input):void 0,toolInputData:ve(I.state?.input)}),I.state&&(I.state.status==="completed"||I.state.status==="error"||I.state.output!==void 0||I.state.error!==void 0)&&a.push({role:"tool_result",timestamp:f,content:I.state.error??I.state.output??"",toolCallId:I.callID}))}c++}}return{provider:this.name,sessionId:r.id,slug:r.slug,cwd:i,createdAt:new Date(r.time_created),modifiedAt:new Date(r.time_updated),model:u,startCommand:this.startCommand,firstUserMessage:d,lastUserMessage:p,messageCount:c,filePath:n,...Bl(m),messages:a,userPrompts:l}}extractText(e,r=!1){let n=[];for(let s of e){let i;try{i=JSON.parse(s.data)}catch{continue}r&&(i.synthetic===!0||i.ignored===!0)||i.type==="text"&&i.text&&n.push(i.text)}return n.join(`
|
|
1940
|
+
`).trim()}async resolveSessionPath(e){for(let r of this.existingDbPaths()){let n=this.openDb(r);if(n)try{if(this.findSessionRow(n,e))return r}catch{}finally{n.close()}}return null}async deleteSession(e){for(let r of this.existingDbPaths()){let n=new(Us())(r,{open:!0});try{let s=this.findSessionRow(n,e);if(!s)continue;return n.prepare("DELETE FROM session WHERE id = ?").run(s.id).changes>0}catch{}finally{n.close()}}return!1}findSessionRow(e,r){let n=e.prepare(`SELECT s.id, s.project_id, s.slug, s.directory, s.title, s.version,
|
|
1941
|
+
s.time_created, s.time_updated
|
|
1942
|
+
FROM session s WHERE s.id = ?`).get(r);if(n)return n;let s=e.prepare(`SELECT s.id, s.project_id, s.slug, s.directory, s.title, s.version,
|
|
1943
|
+
s.time_created, s.time_updated
|
|
1944
|
+
FROM session s
|
|
1945
|
+
WHERE s.id LIKE ?
|
|
1946
|
+
ORDER BY s.time_updated DESC
|
|
1947
|
+
LIMIT 2`).all(`${r}%`);return s.length!==1?null:s[0]}};function $s(t,e){let r=e?.dbPath!==void 0?[e.dbPath]:Wl();for(let n of r){if(!Ps(n))continue;let s=new(Us())(n,{open:!0,readOnly:!0});try{s.exec("PRAGMA busy_timeout = 5000");let i=s.prepare("SELECT directory FROM session WHERE id = ?").get(t);if(i!==void 0)return{directory:typeof i.directory=="string"?i.directory:""}}finally{s.close()}}return null}function sr(t){return{id:t.id,onFailure:"non-fatal",applies:e=>t.value(e)!==void 0,run:async e=>{await e.sendRpc("session/set_config_option",{sessionId:e.sessionId,configId:t.configId,value:t.value(e)})},describeFailure:(e,r)=>{let n=t.value(e),s=r instanceof Error?r.message:String(r);return{event:"acp_config_option_failed",fields:{config_id:t.configId,value:n,error_message:s},stderrLine:`[acp] set_config_option(${t.configId}=${n}) failed: ${s}
|
|
1948
|
+
`,warning:`${t.provider} ignored ${t.configId}=${n}: ${s}`,message:s}},successLog:e=>`acp: set_config_option(${t.configId}=${t.value(e)}) ok`}}var ut={name:"opencode",binary:"opencode",baseArgs:["acp"],argv:()=>[...ut.baseArgs],preSpawn(t){try{Pl(t.cwd)}catch(e){R({event:"opencode_config_install_failed",cwd:t.cwd,error_message:e instanceof Error?e.message:String(e)})}},sessionSetup:[sr({id:"model",provider:"opencode",configId:"model",value:t=>t.model}),sr({id:"effort",provider:"opencode",configId:"effort",value:t=>t.effort})],probe:Xl,sessionIdentity:{verifyLoadedSession:t=>{let e=$s(t.requestedSessionId,{...t.env.OPENCODE_DB!==void 0?{dbPath:t.env.OPENCODE_DB}:{}});if(e===null)throw new Error(`opencode bundle: no session "${t.requestedSessionId}" in the opencode session store \u2014 the session must exist on disk before a bundle can resume it`);if(Hl(e.directory)!==Hl(t.cwd))throw new Error(`opencode bundle: session "${t.requestedSessionId}" belongs to ${e.directory}, not ${t.cwd} \u2014 refusing to resume another workspace's session`)},recheckSession:t=>{if($s(t.requestedSessionId,{...t.env.OPENCODE_DB!==void 0?{dbPath:t.env.OPENCODE_DB}:{}})===null)throw new Error(`opencode bundle: session "${t.requestedSessionId}" disappeared from the session store mid-bundle`)}}};function Xl(t){let e;try{e=lh(t.binaryPath??ut.binary,[...ut.baseArgs],{cwd:t.cwd,stdio:["pipe","pipe","pipe"],env:oe(t.env,t.cwd,void 0,"unknown")})}catch(s){return Promise.resolve({status:"unavailable",reason:"spawn",error:s instanceof Error?s.message:String(s)})}let r=tr(e,{provider:"opencode"}),n=t.timeoutMs??5e3;return new Promise(s=>{let i=!1,o=(u,d=!0)=>{if(!i){if(i=!0,clearTimeout(c),e.removeListener("error",a),e.removeListener("exit",l),r.close(),!d){s(u);return}V(e,{softDelayMs:100,killDelayMs:100}).finally(()=>s(u))}},a=u=>{o({status:"unavailable",reason:"spawn",error:u.message},!1)},l=(u,d)=>{o({status:"unavailable",reason:"handshake",error:`opencode ACP exited before verification (code=${String(u)}, signal=${String(d)})`},!1)};e.once("error",a),e.once("exit",l);let c=setTimeout(()=>{o({status:"unavailable",reason:"timeout"})},n);(async()=>{try{await r.sendRpc("initialize",{protocolVersion:1,clientInfo:{name:"lmctl",version:"0.1.0"},clientCapabilities:{}}),r.sendNotification("notifications/initialized");let u=await r.sendRpc("session/new",{cwd:t.cwd,mcpServers:[]}),d=ze(u);try{await r.sendRpc("session/set_config_option",{sessionId:d,configId:"model",value:t.model})}catch(p){o({status:"rejected",option:"model",value:t.model,error:p instanceof Error?p.message:String(p)});return}if(t.effort!==void 0)try{await r.sendRpc("session/set_config_option",{sessionId:d,configId:"effort",value:t.effort})}catch(p){o({status:"rejected",option:"effort",value:t.effort,error:p instanceof Error?p.message:String(p)});return}o({status:"verified"})}catch(u){o({status:"unavailable",reason:"handshake",error:u instanceof Error?u.message:String(u)})}})()})}import{existsSync as ch}from"node:fs";import{readdir as dh}from"node:fs/promises";import{join as js,resolve as uh}from"node:path";var mh=/runtime\s+\S+\s+does not exist in workspace\s+\S+/;function Gl(t){let e=mh.exec(t);return e?e[0]:null}function fh(t){if(!t.includes("notifications/initialized"))return t;let e=t.split(/\r?\n/),r=[];for(let n=0;n<e.length;n++){let s=e[n];if(s.includes("Error handling notification")&&s.includes("notifications/initialized")){let i=[s],o=n;for(;o+1<e.length&&i.length<8&&(o++,i.push(e[o]),e[o].trim()!=="}"););let a=i.join(`
|
|
1949
|
+
`);if(/\bcode:\s*-32601\b/.test(a)&&/Method not found[^]*notifications\/initialized/.test(a)){n=o;continue}}r.push(s)}return r.join(`
|
|
1950
|
+
`)}var Bs=t=>t.permissionMode==="plan"?"plan":"auto";async function ql(t,e){let r=uh(e.KIMI_CODE_HOME??process.env.KIMI_CODE_HOME??js(U,".kimi-code")),n=js(r,"sessions"),s;try{s=await dh(n,{withFileTypes:!0})}catch{throw new Error(`kimi bundle: cannot read the kimi session store at ${n} \u2014 cannot verify session "${t}"`)}for(let i of s)if(i.isDirectory()&&ch(js(n,i.name,t,"agents","main","wire.jsonl")))return;throw new Error(`kimi bundle: no session "${t}" in the kimi session store (${n}) \u2014 the session must exist on disk before a bundle can resume it`)}var ir={name:"kimi",binary:"kimi",baseArgs:["acp"],argv:()=>[...ir.baseArgs],sessionSetup:[{id:"permission-mode",onFailure:"fail-closed",applies:()=>!0,run:async t=>{await t.sendRpc("session/set_config_option",{sessionId:t.sessionId,configId:"mode",value:Bs(t)})},describeFailure:(t,e)=>{let r=Bs(t),n=e instanceof Error?e.message:String(e);return{event:"acp_permission_mode_failed",fields:{config_id:"mode",value:r,error_message:n},message:`Cannot set Kimi ACP permission mode to ${r}: ${n}`}},successLog:t=>`acp: set_config_option(mode=${Bs(t)}) ok`},sr({id:"model",provider:"kimi",configId:"model",value:t=>t.model})],onExitFinalization(t){let e=Gl(t.result);e!==null&&R({event:"kimi_runtime_dead",provider:"kimi",session_id:t.sessionId,matched_text:e})},filterExpectedStderr:fh,sessionIdentity:{verifyLoadedSession:async t=>{await ql(t.requestedSessionId,t.env)},recheckSession:async t=>{await ql(t.requestedSessionId,t.env)}}};var or={name:"hermes",binary:"hermes",baseArgs:["acp"],argv(t){if(t.permissionMode==="plan")throw new Error('provider "hermes" does not support --permission-mode plan');return[...or.baseArgs]},preSpawn(t){t.permissionMode==="yolo"&&(t.env.HERMES_YOLO_MODE="1")},modeVocabulary:{known:["default","accept_edits","dont_ask"],selectable:["accept_edits","dont_ask"]},sessionSetup:[{id:"session-mode",onFailure:"fail-closed",applies:t=>t.acpMode!==void 0,run:async t=>{await t.sendRpc("session/set_mode",{sessionId:t.sessionId,modeId:t.acpMode})},describeFailure:(t,e)=>{let r=e instanceof Error?e.message:String(e);return{event:"acp_session_mode_failed",fields:{mode_id:t.acpMode,error_message:r},message:`Cannot set hermes ACP session mode to ${String(t.acpMode)}: ${r}`}},successLog:t=>`acp: set_mode(modeId=${String(t.acpMode)}) ok`},{id:"model",onFailure:"fail-closed",applies:t=>{if(t.model===void 0)return!1;let e=t.response.result?.models?.currentModelId;return t.model!==e},run:async t=>{await t.sendRpc("session/set_model",{sessionId:t.sessionId,modelId:t.model})},describeFailure:(t,e)=>{let r=e instanceof Error?e.message:String(e);return{event:"acp_config_option_failed",fields:{config_id:"model",value:t.model,error_message:r},stderrLine:`[acp] set_model(modelId=${String(t.model)}) failed: ${r}
|
|
1951
|
+
`,message:`Cannot set Hermes ACP model to ${String(t.model)}: ${r}`}},successLog:t=>`acp: set_model(modelId=${String(t.model)}) ok`}],sessionIdentity:{verifyLoadedSession:()=>{}}};var ph={gemini:rr,copilot:nr,opencode:ut,kimi:ir,hermes:or};function ar(t){return ph[t]}var hh={gemini:{binary:rr.binary,args:rr.baseArgs},copilot:{binary:nr.binary,args:nr.baseArgs},opencode:{binary:ut.binary,args:ut.baseArgs},kimi:{binary:ir.binary,args:ir.baseArgs},hermes:{binary:or.binary,args:or.baseArgs}};function Vl(t,e){let r=ar(t)?.modeVocabulary;if(!r)throw new J(`ACP mode "${e}" requested for provider "${t}", which declares no ACP mode vocabulary. Add the provider's mode ids to its AcpProviderProfile modeVocabulary before setting a mode.`);if(!r.known.includes(e))throw new J(`provider "${t}" has no ACP mode "${e}" (known: ${r.known.join(", ")}).`);if(!r.selectable.includes(e))throw new J(`provider "${t}" ACP mode "${e}" is not selectable by lmctl (selectable: ${r.selectable.join(", ")}).`)}function _h(t){let e=t.stderr.trim().slice(0,500),r=`lmctl: ${t.tool} ACP process exited with code ${t.exitCode} before completing the prompt.
|
|
1952
|
+
One possible cause: the provider process failed before a complete ACP response was delivered.`;return e?`Original provider error:
|
|
1953
|
+
${e}
|
|
1954
|
+
|
|
1955
|
+
${r}`:r}function Eh(t,e){return ar(t)?.filterExpectedStderr?.(e)??e}function Kl(t){if(t.method!=="session/update")return!1;let r=t.params?.update;if(r===void 0)return!1;let n=r.sessionUpdate;if(n!=="tool_call"&&n!=="tool_call_update")return!1;let s=r.status;return s!==void 0&&s!=="pending"&&s!=="in_progress"?!1:r.rawInput?.background===!0}async function Yl(t,e,r,n){for(let s of t.sessionSetup??[]){let i={...e,sessionId:r.sessionId,response:r.response,sendRpc:n};if(s.applies(i))try{await s.run(i),s.successLog&&ne(s.successLog(i))}catch(o){let a=s.describeFailure(i,o);if(R({event:a.event,provider:t.name,...a.fields}),a.stderrLine&&process.stderr.write(a.stderrLine),a.warning&&e.warnings.push(a.warning),s.onFailure==="fail-closed")throw new Error(a.message)}}}function zl(t,e,r){let n=oe(e.env,e.cwd,e.sessionId);t.preSpawn?.({...r,cwd:e.cwd,env:n});let s=e.binaryPath||t.binary,i=t.argv(r),o=t.yoloAssertion==="always-yolo"?"yolo":r.permissionMode;if(se(e.tool,i,o),e.cwd&&!gh(e.cwd))throw R({event:"transport_error",provider:e.tool,error_class:"TransportConnectionError",error_message:`sessiondir missing: ${e.cwd}`,elapsed_ms:0}),new J(`sessiondir missing: ${e.cwd}`,{cause:Object.assign(new Error("cwd missing"),{code:"ENOENT_CWD"})});return{binary:s,spawnArgs:i,spawnEnv:n}}async function Ql(t){let{sendRpc:e,sendNotification:r,opts:n,outputProcessor:s}=t,i=t.strictSessionIdentity===!0;await e("initialize",{protocolVersion:1,clientInfo:{name:"lmctl",version:"0.1.0"},clientCapabilities:{}}),r("notifications/initialized");let o=n.sessionId||"",a;if(n.sessionId){let l;try{l=await e("session/load",{sessionId:n.sessionId,cwd:n.cwd,mcpServers:[]})}catch(c){if(i||n.requireResume)throw new Error(`Cannot resume session ${n.sessionId} via ACP: ${c instanceof Error?c.message:String(c)}`);process.stderr.write(`[acp] session/load failed for ${n.sessionId}, creating new session
|
|
1956
|
+
`),R({event:"acp_session_resume_fallback",provider:n.tool,session_id:n.sessionId,error_message:c instanceof Error?c.message:String(c)});let u=await e("session/new",{cwd:n.cwd,mcpServers:[]});return o=ze(u),s.setSessionId(o),{sessionId:o,sessionResponse:u}}if(i){let c=ze(l);if(c!==""&&c!==n.sessionId)throw new Error(`ACP session/load did not return the requested session id: expected "${n.sessionId}", received "${c}"`);if(c===""){if(t.verifyLoadResponse===void 0)throw new Error(`ACP session/load did not return the requested session id: expected "${n.sessionId}", received none`);await t.verifyLoadResponse(l)}o=n.sessionId}else o=ze(l,n.sessionId);a=l,s.setSessionId(o)}else{let l=await e("session/new",{cwd:n.cwd,mcpServers:[]});o=ze(l),a=l,s.setSessionId(o)}return{sessionId:o,sessionResponse:a}}function Zl(t,e){let r=ar(e.tool);if(!r)return Promise.reject(new Error(`No ACP config for tool "${e.tool}"`));if(e.acpMode!==void 0)try{Vl(e.tool,e.acpMode)}catch(n){return Promise.reject(n)}return new Promise((n,s)=>{let i=e.permissionMode??"yolo",o=[],a={permissionMode:i,...e.model!==void 0?{model:e.model}:{},...e.effort!==void 0?{effort:e.effort}:{},...e.acpMode!==void 0?{acpMode:e.acpMode}:{},purpose:"chat",warnings:{push:S=>{o.push(S)}}},l,c,u;try{({binary:l,spawnArgs:c,spawnEnv:u}=zl(r,e,a))}catch(S){return s(S instanceof Error?S:new Error(String(S)))}let d=Jl(l,c,{cwd:e.cwd,stdio:["pipe","pipe","pipe"],env:u}),p=Date.now(),m=!1,h=!1,g=0,y=!1,f=!1;if(e.signal){if(e.signal.aborted)return m=!0,R({event:"transport_abort",provider:e.tool,phase:"pre_spawn"}),V(d).catch(()=>{}),s(new Error("Aborted"));e.signal.addEventListener("abort",()=>{m=!0,R({event:"transport_abort",provider:e.tool,elapsed_ms:Date.now()-p}),V(d).catch(()=>{}),s(new Error("Aborted"))},{once:!0})}let T=e.sessionId||"",E=_n({tool:e.tool,onDelta:e.onDelta,...r.isolateResult?{isolateResult:r.isolateResult}:{}});E.setSessionId(T);let I=tr(d,{provider:e.tool,onEvent:S=>{g=Date.now(),Kl(S)&&(f=!0),e.onEvent?.(S)},onNotification:S=>{g=Date.now(),E.processMessage(S)}}),{sendRpc:w,sendNotification:_}=I,v="";d.stderr?.on("data",S=>{v+=S.toString()}),d.on("error",S=>{I.close(S),R({event:"transport_error",provider:e.tool,error_class:"TransportConnectionError",error_message:S.message,elapsed_ms:Date.now()-p}),s(new J(`Failed to spawn ${r.binary} ${r.baseArgs.join(" ")}: ${S.message}`,{cause:S}))}),d.on("exit",S=>{if(h=!0,I.close(new J(`ACP process exited with code ${String(S)}`)),m)return;let A=E.finalize();if(A!==null)r.onExitFinalization?.({...a,sessionId:A.sessionId,result:A.result,stopReason:A.stopReason,exitCode:S}),n({result:A.result,sessionId:A.sessionId,durationMs:Date.now()-p,stopReason:A.stopReason,exitCode:S,...o.length>0?{warnings:o}:{}});else{let x=Eh(e.tool,v);R({event:"transport_error",provider:e.tool,error_class:"Error",reason:"provider_no_result",exit_code:S,stderr_tail:x.slice(0,500),elapsed_ms:Date.now()-p}),s(new Error(_h({tool:e.tool,exitCode:S,stderr:x})))}}),(async()=>{try{let S=await Ql({sendRpc:w,sendNotification:_,opts:e,outputProcessor:E});T=S.sessionId;let A=S.sessionResponse;await Yl(r,a,{sessionId:T,response:A},w),E.beginTurn(),y=!0,ne(`acp: prompt sent (${t.length} chars)`);let x=await w("session/prompt",{sessionId:T,prompt:[{type:"text",text:t}]}),b=E.completeTurn(x);y=!1,ne(`acp: result received (${b.result.length} chars, stopReason=${b.stopReason})`),Ke(e.holdOpen,{isAborted:()=>m,hasChildExited:()=>h,isTurnInFlight:()=>y,lastEventAtMs:()=>g,closeStdin:()=>{d.stdin?.end()},signal:e.signal,label:e.tool,wasBackgroundJobLaunched:()=>f})}catch(S){V(d).catch(()=>{}),s(S instanceof Error?S:new Error(String(S)))}})()})}async function ec(t){let e=ar(t.tool);if(!e)throw new Error(`No ACP config for tool "${t.tool}"`);t.acpMode!==void 0&&Vl(t.tool,t.acpMode);let r=t.permissionMode??"yolo",n=[],s=!0,i={permissionMode:r,...t.model!==void 0?{model:t.model}:{},...t.effort!==void 0?{effort:t.effort}:{},...t.acpMode!==void 0?{acpMode:t.acpMode}:{},purpose:"chat",warnings:{push:S=>{n.push(S)}}},{binary:o,spawnArgs:a,spawnEnv:l}=zl(e,t,i),c=Jl(o,a,{cwd:t.cwd,stdio:["pipe","pipe","pipe"],env:l}),u=Date.now(),d={exited:!1,exitCode:null,lastEventAtMs:0,turnInFlight:!1,backgroundJobLaunched:!1,completedTurns:0,closed:!1,closing:null,telemetryFired:!1},p=t.sessionId||"",m=null,h="";c.stderr?.on("data",S=>{h+=S.toString()});let g,y,f=_n({tool:t.tool,onDelta:S=>g?.(S),...e.isolateResult?{isolateResult:e.isolateResult}:{}});f.setSessionId(p);let T=tr(c,{provider:t.tool,onEvent:S=>{d.lastEventAtMs=Date.now(),Kl(S)&&(d.backgroundJobLaunched=!0),y?.(S)},onNotification:S=>{d.lastEventAtMs=Date.now(),f.processMessage(S)}}),E=()=>new Error(`ACP bundle process (${t.tool}) exited${d.exitCode!==null?` with code ${d.exitCode}`:""} after ${d.completedTurns} completed prompt(s); the bundle cannot continue`),I=[],w=()=>d.exited?Promise.resolve():new Promise(S=>{I.push(S)}),_=null;c.on("error",S=>{m=new J(`Failed to spawn ${e.binary} ${e.baseArgs.join(" ")}: ${S.message}`,{cause:S}),R({event:"transport_error",provider:t.tool,error_class:"TransportConnectionError",error_message:S.message,elapsed_ms:Date.now()-u}),T.close(S)}),c.on("exit",S=>{if(d.exited=!0,d.exitCode=S,T.close(new J(`ACP process exited with code ${String(S)}`)),!d.telemetryFired){d.telemetryFired=!0;let A=f.finalize();A!==null&&e.onExitFinalization?.({...i,sessionId:A.sessionId,result:A.result,stopReason:A.stopReason,exitCode:S})}if(_!==null){let A=_;_=null,A(E())}for(let A of I.splice(0))A()});try{let S=await Ql({sendRpc:T.sendRpc,sendNotification:T.sendNotification,opts:t,outputProcessor:f,strictSessionIdentity:!0,verifyLoadResponse:e.sessionIdentity===void 0?void 0:async A=>e.sessionIdentity.verifyLoadedSession({...i,requestedSessionId:t.sessionId,loadResponse:A,cwd:t.cwd,env:l})});p=S.sessionId,await Yl(e,i,{sessionId:S.sessionId,response:S.sessionResponse},T.sendRpc)}catch(S){let A=m??(S instanceof Error?S:new Error(String(S)));throw V(c).catch(()=>{}),A}let v=S=>new Promise(A=>{setTimeout(A,S).unref?.()});return{tool:t.tool,get sessionId(){return p},get completedTurns(){return d.completedTurns},async sendTurn(S,A={}){if(d.closed||d.closing!==null)throw new Error(`ACP bundle session (${t.tool}) is closed`);if(d.exited)throw E();if(d.turnInFlight)throw new Error(`ACP bundle session (${t.tool}) has a turn still in flight \u2014 a stalled turn poisons the bundle; close it instead of sending`);if(A.signal?.aborted)throw new Error("Aborted");if(e.sessionIdentity?.recheckSession!==void 0){if(await e.sessionIdentity.recheckSession({requestedSessionId:p,cwd:t.cwd,env:l}),d.exited)throw E();if(A.signal?.aborted)throw new Error("Aborted")}d.turnInFlight=!0,g=A.onDelta,y=A.onEvent;let x=Date.now();try{f.beginTurn(),ne(`acp: bundle prompt sent (${S.length} chars)`);let b=await new Promise((re,z)=>{_=z;let ae=()=>{f.cancelTurn(),T.sendNotification("session/cancel",{sessionId:p}),z(new Error("Aborted"))},ie=A.signal;ie?.addEventListener("abort",ae,{once:!0}),T.sendRpc("session/prompt",{sessionId:p,prompt:[{type:"text",text:S}]}).then(B=>{ie?.removeEventListener("abort",ae),re(B)},B=>{ie?.removeEventListener("abort",ae),z(B instanceof Error?B:new Error(String(B)))})});_=null;let k=f.completeTurn(b);d.turnInFlight=!1,d.completedTurns+=1,ne(`acp: bundle result received (${k.result.length} chars, stopReason=${k.stopReason})`);let P=s&&n.length>0?[...n]:void 0;return s=!1,{result:k.result,sessionId:k.sessionId,stopReason:k.stopReason,durationMs:Date.now()-x,...P!==void 0?{warnings:P}:{}}}catch(b){throw _=null,f.cancelTurn(),d.turnInFlight=!1,d.exited?E():b}finally{g=void 0,y=void 0}},close(){return d.closing!==null||(d.closing=(async()=>{if(d.closed=!0,d.exited||(t.holdOpen!==void 0?await new Promise(A=>{Ke(t.holdOpen,{isAborted:()=>!1,hasChildExited:()=>d.exited,isTurnInFlight:()=>d.turnInFlight,lastEventAtMs:()=>d.lastEventAtMs,closeStdin:()=>{c.stdin?.end(),A()},label:t.tool,wasBackgroundJobLaunched:()=>d.backgroundJobLaunched})}):c.stdin?.end(),d.exited))return;let S=t.closeTimeoutMs??2e3;await Promise.race([w(),v(S)]),d.exited||await V(c,{stdinEnd:!1,softDelayMs:Math.min(1e3,S),killDelayMs:Math.min(1e3,S)}).catch(()=>{})})()),d.closing}}}function Y(t,e=120){let r=t.replace(/\s+/g," ").trim();return r.length>e?r.slice(0,e-1)+"\u2026":r}var yh=256;function rc(t,e){return r=>{if(r.kind==="tool_use"&&typeof r.id=="string"){if(t.size>=yh){let n=t.keys().next().value;n!==void 0&&t.delete(n)}t.set(r.id,Date.now()),e(r);return}if(r.kind==="tool_result"&&typeof r.id=="string"&&r.elapsedMs===void 0){let n=t.get(r.id);if(n!==void 0){e({...r,elapsedMs:Date.now()-n}),t.delete(r.id);return}}e(r)}}function Th(){let t=new Map;return(e,r)=>{Sh(e,rc(t,r))}}function Sh(t,e){let r=t.type;if(r==="system"){let n=t.subtype;if(n==="api_retry"){let s=typeof t.attempt=="number"?t.attempt:void 0,i=typeof t.max_retries=="number"?t.max_retries:void 0,o=typeof t.error_status=="number"?t.error_status:void 0,a=typeof t.error=="string"?t.error:void 0,l=typeof t.retry_delay_ms=="number"?t.retry_delay_ms:void 0,c=[];s!==void 0&&c.push(i!==void 0?`attempt ${s}/${i}`:`attempt ${s}`),o!==void 0&&c.push(`HTTP ${o}`),l!==void 0&&c.push(`retry in ${Math.round(l/1e3)}s`),a&&c.push(Y(a,60));let u=c.length>0?c.join(", "):n;e({kind:"api_retry",summary:u});return}if(n==="api_error"){let s=typeof t.error_status=="number"?t.error_status:void 0,i=typeof t.error=="string"?t.error:void 0,o=["api_error"];s!==void 0&&o.push(`HTTP ${s}`),i&&o.push(Y(i,80)),e({kind:"other",summary:o.join(": "),raw:t});return}e({kind:"system",summary:n||"system",raw:t});return}if(r==="assistant"||r==="user"){let s=t.message?.content;if(!Array.isArray(s))return;for(let i of s){let o=i.type;if(o==="text"){let a=i.text||"";a&&e({kind:"text",summary:Y(a),raw:i})}else if(o==="tool_use"){let a=i.name||"tool",l=typeof i.id=="string"?i.id:void 0,c=i.input,u="";c&&(typeof c.command=="string"?u=c.command:typeof c.file_path=="string"?u=c.file_path:typeof c.path=="string"?u=c.path:typeof c.pattern=="string"?u=c.pattern:typeof c.url=="string"?u=c.url:u=Y(JSON.stringify(c))),e({kind:"tool_use",tool:a,summary:Y(u),id:l,raw:i})}else if(o==="thinking"){let a=i.thinking||"";e({kind:"thinking",summary:Y(a),raw:i})}else if(o==="tool_result"){let l=i.is_error===!0?"error":"ok",c=typeof i.tool_use_id=="string"?i.tool_use_id:void 0,u,d=i.content;if(typeof d=="string")u=`${d.split(`
|
|
1957
|
+
`).length} lines, ${d.length} chars`;else if(Array.isArray(d)){let p=d.map(m=>typeof m=="object"&&m&&"text"in m?m.text:"").filter(Boolean).join("");p&&(u=`${p.split(`
|
|
1958
|
+
`).length} lines, ${p.length} chars`)}e({kind:"tool_result",status:l,summary:u,id:c,raw:i})}else o&&e({kind:"other",summary:o,raw:i})}return}if(r==="result"){e({kind:"system",summary:"result",raw:t});return}}async function yn(t,e){let r=e.binary==="qwen"?"qwen":"claude",n=e.onProgress?Th():void 0;if(e.bundleSession!==void 0){let i=e.bundleSession;if(i.provider!==r)throw new Error(`bundle session provider mismatch: session serves "${i.provider}", turn targets "${r}"`);let o=await i.sendTurn(t,{onDelta:e.onDelta,onEvent:n?a=>n(a,e.onProgress):void 0,signal:e.signal});return{text:o.text,sessionId:o.sessionId,durationMs:o.durationMs,...o.warnings!==void 0&&o.warnings.length>0?{warnings:o.warnings}:{}}}let s=await El(t,{sessionId:e.sessionId,cwd:e.cwd,env:e.env,tool:r,binaryPath:e.progPath,model:e.model,permissionMode:e.permissionMode,onText:e.onDelta,onEvent:n?i=>n(i,e.onProgress):void 0,signal:e.signal,holdOpen:e.holdOpen});return{text:s.result,sessionId:s.sessionId,durationMs:s.durationMs,numTurns:s.numTurns,...s.warnings!==void 0&&s.warnings.length>0?{warnings:s.warnings}:{}}}async function Tn(t){let e=t.binary==="qwen"?"qwen":"claude",r=await yl({tool:e,sessionId:t.sessionId,cwd:t.cwd,env:t.env,binaryPath:t.progPath,model:t.model,permissionMode:t.permissionMode,holdOpen:t.holdOpen,closeTimeoutMs:t.closeTimeoutMs,sessionFileRoots:t.sessionFileRoots});return{provider:e,get sessionId(){return r.sessionId},get completedTurns(){return r.completedTurns},async sendTurn(n,s={}){let i=await r.sendTurn(n,{onText:s.onDelta,onEvent:s.onEvent,signal:s.signal});return{text:i.result,sessionId:i.sessionId,durationMs:i.durationMs,...i.warnings!==void 0?{warnings:i.warnings}:{}}},close:()=>r.close()}}function wh(){let t=new Map;return(e,r)=>{vh(e,rc(t,r))}}function vh(t,e){if(t.method!=="session/update")return;let s=t.params?.update;if(!s)return;let i=s.sessionUpdate;if(i){if(i==="agent_message_chunk"){let a=s.content?.text||"";a&&e({kind:"text",summary:Y(a)});return}if(i==="agent_thought_chunk"){let a=s.content?.text||"";e({kind:"thinking",summary:Y(a)});return}if(i==="tool_call"){let o=s.title||s.kind||"tool",a=typeof s.toolCallId=="string"?s.toolCallId:void 0,l="",c=s.rawInput;c&&(typeof c.command=="string"?l=c.command:typeof c.file_path=="string"?l=c.file_path:typeof c.path=="string"?l=c.path:l=Y(JSON.stringify(c))),e({kind:"tool_use",tool:o,summary:Y(l),id:a});return}if(i==="tool_call_update"){let o=s.status||"",a=typeof s.toolCallId=="string"?s.toolCallId:void 0;if(o==="completed"||o==="failed")e({kind:"tool_result",summary:o,status:o==="failed"?"error":"ok",id:a});else if(o==="in_progress"){let l=s.content,c=typeof l=="string"?l:typeof l?.text=="string"?l.text:"",u=c?`running\u2026 ${Y(c,80)}`:"running\u2026";e({kind:"other",summary:u,id:a})}return}e({kind:"other",summary:i})}}async function Le(t,e){let r=e.acpTool||e.binary,n=e.onProgress?wh():void 0;if(e.bundleSession!==void 0){let a=e.bundleSession;if(a.provider!==r)throw new Error(`bundle session provider mismatch: session serves "${a.provider}", turn targets "${r}"`);let l=await a.sendTurn(t,{onDelta:e.onDelta,onEvent:n?c=>n(c,e.onProgress):void 0,signal:e.signal});return{text:l.text,sessionId:l.sessionId,durationMs:l.durationMs,stopReason:l.stopReason,...l.warnings!==void 0?{warnings:l.warnings}:{}}}let s=[];if(e.model&&r==="copilot"){let a="copilot --acp does not implement per-session model selection";he({event:"model_ignored",provider:r,model:e.model,reason:a}),s.push(`copilot ignored model=${e.model}: ${a}`)}let i=await Zl(t,{tool:r,sessionId:e.sessionId,cwd:e.cwd,env:e.env,binaryPath:e.progPath,model:e.model,effort:e.effort,alias:e.alias,permissionMode:e.permissionMode,acpMode:e.acpMode,requireResume:e.requireResume,onDelta:e.onDelta,onEvent:n?a=>n(a,e.onProgress):void 0,signal:e.signal,holdOpen:e.holdOpen}),o=[...s,...i.warnings??[]];return{text:i.result,sessionId:i.sessionId,durationMs:i.durationMs,stopReason:i.stopReason,...o.length>0?{warnings:o}:{}}}async function Ce(t){let e=t.acpTool||t.binary,r=await ec({tool:e,sessionId:t.sessionId,cwd:t.cwd,env:t.env,binaryPath:t.progPath,model:t.model,effort:t.effort,alias:t.alias,permissionMode:t.permissionMode,acpMode:t.acpMode,requireResume:!0,holdOpen:t.holdOpen,closeTimeoutMs:t.closeTimeoutMs});return{provider:e,get sessionId(){return r.sessionId},get completedTurns(){return r.completedTurns},async sendTurn(n,s){let i=await r.sendTurn(n,s);return{text:i.result,sessionId:i.sessionId,durationMs:i.durationMs,stopReason:i.stopReason,...i.warnings!==void 0?{warnings:i.warnings}:{}}},close:()=>r.close()}}function tc(t,e){let r=t.method;if(!r)return;let n=t.params;if(r==="turn/started"){e({kind:"system",summary:"turn started"});return}if(r==="turn/completed"){e({kind:"system",summary:"turn completed"});return}if(r==="error"){let s=n?.error,i=typeof s?.message=="string"?s.message:void 0,o=i&&i.length>0?i:"(no message)",a=n?.willRetry===!0;e(a?{kind:"api_retry",summary:`codex retry: ${Y(o,120)}`}:{kind:"other",summary:`codex error: ${Y(o,120)}`});return}if(r==="item/started"||r==="item/completed"){let s=n?.item;if(!s)return;let i=s.type,o=r==="item/started";switch(i){case"commandExecution":{let a=typeof s.id=="string"?s.id:void 0,l=s.command,c=Array.isArray(l)?l.join(" "):typeof l=="string"?l:"";if(o)e({kind:"tool_use",tool:"Bash",summary:Y(c||"(command)"),id:a});else{let u=s.exitCode,d=s.status||"",p=typeof s.durationMs=="number"?s.durationMs:void 0,m=typeof u=="number"?`exit ${u}`:d||"done",h=[];typeof u=="number"?h.push(`exit ${u}`):d&&h.push(d),typeof p=="number"&&h.push(`${Math.round(p/1e3)}s`),e({kind:"tool_result",summary:h.join(", ")||"done",status:m,elapsedMs:p,id:a})}return}case"fileChange":{let a=typeof s.id=="string"?s.id:void 0;if(o){let l=s.changes,c=Array.isArray(l)?l.map(u=>u.path||"").filter(Boolean).join(", "):"";e({kind:"tool_use",tool:"FileChange",summary:Y(c||"(edit)"),id:a})}else{let l=s.status||"done";e({kind:"tool_result",summary:l,status:l,id:a})}return}case"mcpToolCall":{let a=typeof s.id=="string"?s.id:void 0,l=s.server||"mcp",c=s.tool||"tool";if(o)e({kind:"tool_use",tool:`${l}/${c}`,summary:"",id:a});else{let u=s.status||"done";e({kind:"tool_result",summary:u,status:u,id:a})}return}case"webSearch":{let a=typeof s.id=="string"?s.id:void 0;e(o?{kind:"tool_use",tool:"WebSearch",summary:Y(s.query||""),id:a}:{kind:"tool_result",summary:"done",status:"done",id:a});return}case"reasoning":{o&&e({kind:"thinking",summary:""});return}case"agentMessage":case"userMessage":return;default:{i&&e({kind:o?"tool_use":"tool_result",tool:i,summary:""});return}}}if(r==="item/agentMessage/delta"){let s=n?.delta||"";if(s){let i=typeof n?._lmctlItemPhase=="string"?n._lmctlItemPhase:void 0;e(i==="commentary"?{kind:"thinking",summary:Y(s)}:{kind:"text",summary:Y(s)})}return}if(r==="item/reasoning/summaryTextDelta"||r==="item/reasoning/textDelta"){let s=n?.delta||"";s&&e({kind:"thinking",summary:Y(s)});return}if(r==="item/commandExecution/outputDelta"){let s=(typeof n?.delta=="string"?n.delta:"")||"";if(s){let i=s.split(`
|
|
1959
|
+
`).filter(l=>l.length>0),o=i[i.length-1]||"",a=i.length>1?`${i.length} lines: ${Y(o,60)}`:Y(s,80);e({kind:"other",summary:`running\u2026 ${a}`})}else e({kind:"other",summary:"running\u2026"});return}if(r==="item/commandExecution/terminalInteraction"||r==="item/commandExecution/outputChunk"||r==="item/commandExecution/output"){let s=(typeof n?.stdin=="string"?n.stdin:"")||(typeof n?.delta=="string"?n.delta:"")||(typeof n?.output=="string"?n.output:"")||(typeof n?.text=="string"?n.text:"")||(typeof n?.content=="string"?n.content:"")||(typeof n?.chunk=="string"?n.chunk:"")||"";if(s){let i=s.split(`
|
|
1960
|
+
`).filter(l=>l.length>0),o=i[i.length-1]||"",a=i.length>1?`${i.length} lines: ${Y(o,60)}`:Y(s,80);e({kind:"other",summary:`running\u2026 ${a}`})}else e({kind:"other",summary:"running\u2026"});return}if(r.startsWith("item/")){e({kind:"other",summary:r.slice(5)});return}}async function nc(t,e){if(e.bundleSession!==void 0){let n=e.bundleSession;if(n.provider!=="codex")throw new Error(`bundle session provider mismatch: session serves "${n.provider}", turn targets "codex"`);let s=await n.sendTurn(t,{onDelta:e.onDelta,onEvent:e.onProgress?i=>tc(i,e.onProgress):void 0,signal:e.signal});return{text:s.text,sessionId:s.sessionId,durationMs:s.durationMs}}let r=await xl(t,{threadId:e.sessionId,cwd:e.cwd,env:e.env,binaryPath:e.progPath,model:e.model,alias:e.alias,isLead:e.isLead,permissionMode:e.permissionMode,onDelta:e.onDelta,onEvent:e.onProgress?n=>tc(n,e.onProgress):void 0,signal:e.signal});return{text:r.result,sessionId:r.threadId,durationMs:r.durationMs}}async function sc(t){let e=await Rl({threadId:t.sessionId,cwd:t.cwd,env:t.env,binaryPath:t.progPath,model:t.model,alias:t.alias,isLead:t.isLead,permissionMode:t.permissionMode,holdOpen:t.holdOpen,closeTimeoutMs:t.closeTimeoutMs});return{provider:"codex",get sessionId(){return e.sessionId},get completedTurns(){return e.completedTurns},async sendTurn(r,n){let s=await e.sendTurn(r,n);return{text:s.text,sessionId:s.sessionId,durationMs:s.durationMs}},close:()=>e.close()}}function Hs(t){return new Ws(t)}var Ws=class extends G{claudeDir;constructor(e){super({provider:new rn(e),capabilities:{canCreate:!0,canResumeInteractive:!0,canFork:!1,forkSupport:"manual",canStructuredTurn:!0,canStreamDeltas:!0,canCancel:!0},injection:{leaderMode:"prompt-append"},binary:"claude",seedArgs:["-p",W,"--dangerously-skip-permissions"],resumeTemplate:"claude --resume {{session_id}}",startTemplate:"claude",transport:yn}),this.claudeDir=e?.claudeDir??ic(U,".claude")}openSession(e){return Tn({...e,binary:"claude",sessionFileRoots:e.sessionFileRoots??[ic(this.claudeDir,"projects")]})}seedArgsFor(e){let r=super.seedArgsFor(e);return e?.model?[...r,"--model",e.model]:r}};import{readdir as Ih,stat as oc,unlink as Ah}from"node:fs/promises";import{join as lr,basename as xh}from"node:path";function Rh(t,e,r){return`${t}|${e.toISOString()}|${r}`}function cr(t,e,r){let n=Rh(r.role,r.timestamp,r.content);e.has(n)||(e.add(n),t.push(r))}function ac(t,e){return e==="exec"||t==="codex_exec"?"codex exec":"codex"}function bh(t){if(!t)return;let e=t.cached_input_tokens??t.cache_read_input_tokens;return{inputTokens:t.input_tokens,cachedInputTokens:e,outputTokens:t.output_tokens,reasoningOutputTokens:t.reasoning_output_tokens,totalTokens:t.total_tokens}}function Ct(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return String(t);if(Array.isArray(t))return t.map(r=>{if(typeof r=="string")return r;if(r&&typeof r=="object"){let n=r;if(typeof n.text=="string")return n.text;if(typeof n.image_url=="string")return"[input_image]";if(typeof n.type=="string")return`[${n.type}]`}return Ct(r)}).filter(r=>r.length>0).join(`
|
|
1961
|
+
`);try{return JSON.stringify(t)}catch{return String(t)}}function Nh(t){let e=t;if(typeof t=="string")try{e=JSON.parse(t)}catch{return}return e!==null&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function kh(t,e){if(e===void 0)return;let r={input:e};if(t!=="apply_patch"||typeof e!="string")return r;let n=[...e.matchAll(/^\*\*\* (?:(Add|Update|Delete) File|(Move) to): (.+)\r?$/gm)].map(s=>({kind:s[1]??s[2],path:s[3]?.trim()})).filter(s=>!!(s.kind&&s.path));return n.length>0&&(r.path=n[0].path,r.paths=n.map(s=>s.path),r.kinds=n.map(s=>s.kind)),r}async function lc(t){let e=0,r=0,n=0,s=0,i=0,o,a,l;for await(let c of Q(t)){if(c.type==="event_msg"&&c.payload?.type==="user_message"){let u=c.payload.message||c.payload.text;u&&(l=D(u.trim(),80))}if(c.type==="response_item"&&c.payload){let u=c.payload;if(u.type==="message"&&u.role==="user"&&u.content)for(let d of u.content)d.type==="input_text"&&typeof d.text=="string"&&d.text&&(e++,l=D(d.text.trim(),80));else if(u.type==="message"&&u.role==="assistant"&&u.content)for(let d of u.content)d.type==="output_text"&&typeof d.text=="string"&&d.text&&e++}if(c.payload&&typeof c.payload.model_context_window=="number"&&(a=c.payload.model_context_window),c.type==="event_msg"&&c.payload?.type==="token_count"&&c.payload.info?.total_token_usage){let u=c.payload.info.total_token_usage;r=u.input_tokens??r,n=u.cached_input_tokens??u.cache_read_input_tokens??n,s=u.output_tokens??s,i=u.reasoning_output_tokens??i;let d=bh(c.payload.info.last_token_usage);d&&(o=d),typeof c.payload.info.model_context_window=="number"&&(a=c.payload.info.model_context_window)}}return{messageCount:e,totalInputTokens:r,totalCachedInputTokens:n,totalOutputTokens:s,totalReasoningOutputTokens:i,lastTokenUsage:o,modelContextWindow:a,lastUserMessage:l}}var Sn=class{name="codex";codexDirs;constructor(e={}){let r=[lr(U,".codex"),lr(U,".code")];if(e.codexDirs&&e.codexDirs.length>0){this.codexDirs=[...new Set(e.codexDirs)];return}let n=[e.codexDir||r[0],e.codeDir||r[1]];this.codexDirs=[...new Set(n)]}getWatchPaths(){return this.codexDirs.map(e=>({directory:lr(e,"sessions"),filePattern:/\.jsonl$/}))}async getSessionsDirs(){let e=[];for(let r of this.codexDirs){let n=lr(r,"sessions");try{await oc(n),e.push(n)}catch{}}return e}async discoverSessions(){let e=[],r=await this.getSessionsDirs();for(let n of r){let s=await this.findSessionFiles(n);for(let i of s)try{let o=await this.extractSummary(i);o&&e.push(o)}catch{}}return e}async findSessionFiles(e){let r=[],n;try{n=await Ih(e)}catch{return r}for(let s of n){let i=lr(e,s),o=await oc(i).catch(()=>null);if(o)if(o.isDirectory()){let a=await this.findSessionFiles(i);r.push(...a)}else s.endsWith(".jsonl")&&r.push(i)}return r}extractSessionIdFromFilename(e){let r=xh(e,".jsonl"),n=r.match(/rollout-\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-(.+)$/);return n?n[1]:r}async extractSummary(e){let r=await Ee(e,30),n=await Z(e),s=this.extractSessionIdFromFilename(e),i="",o,a,l,c,u,d,p;for(let h of r){if(h.type==="session_meta"&&h.payload&&(h.payload.id&&(s=h.payload.id),h.payload.cwd&&(i=h.payload.cwd),h.payload.cli_version&&(o=h.payload.cli_version),h.payload.timestamp&&(l=new Date(h.payload.timestamp)),h.payload.originator&&(d=h.payload.originator),h.payload.source&&(p=h.payload.source)),h.type==="turn_context"&&h.payload&&(h.payload.model&&(a=h.payload.model),!i&&h.payload.cwd&&(i=h.payload.cwd)),h.type==="event_msg"&&h.payload?.type==="user_message"){let g=h.payload.message||h.payload.text;g&&(c||(c=D(g.trim(),80)),u=D(g.trim(),80))}if(h.type==="response_item"&&h.payload?.type==="message"&&h.payload.role==="user"&&h.payload.content){let g=h.payload.content.find(y=>y.type==="input_text"&&typeof y.text=="string"&&y.text);typeof g?.text=="string"&&(c||(c=D(g.text.trim(),80)),u=D(g.text.trim(),80))}}if(!i)return null;let m=await lc(e);return{provider:"codex",sessionId:s,cwd:i,createdAt:l||n.createdAt,modifiedAt:n.modifiedAt,model:a,cliVersion:o,startCommand:ac(d,p),firstUserMessage:c,lastUserMessage:m.lastUserMessage??u,messageCount:m.messageCount,filePath:e,totalInputTokens:m.totalInputTokens||void 0,totalCachedInputTokens:m.totalCachedInputTokens||void 0,totalOutputTokens:m.totalOutputTokens||void 0,totalReasoningOutputTokens:m.totalReasoningOutputTokens||void 0,lastInputTokens:m.lastTokenUsage?.inputTokens||void 0,lastTokenUsage:m.lastTokenUsage,modelContextWindow:m.modelContextWindow}}async loadSession(e){let r=await this.resolveSessionFile(e);if(!r)return null;let n=await Z(r),s=[],i="",o,a,l,c,u,d=e,p,m,h=new Set,g=[],y=new Set,f=[],T=(w,_)=>{let v=f.find(S=>!S.mirrored&&S.source!==_&&S.text===w);v?v.mirrored=!0:f.push({text:w,source:_,mirrored:!1})},E=()=>{g.push(...f.map(w=>w.text)),f=[]};for await(let w of Q(r)){let _=w.timestamp?new Date(w.timestamp):new Date;if(w.type==="session_meta"&&w.payload){w.payload.id&&(d=w.payload.id),w.payload.cwd&&(i=w.payload.cwd),w.payload.cli_version&&(o=w.payload.cli_version),w.payload.timestamp&&(l=new Date(w.payload.timestamp)),p=ac(w.payload.originator,w.payload.source);continue}if(w.type==="turn_context"&&w.payload){w.payload.model&&(a=w.payload.model),!i&&w.payload.cwd&&(i=w.payload.cwd);continue}if(w.type==="response_item"&&w.payload){let v=w.payload;if(v.type==="message"){if(v.role==="user"&&v.content){let S=v.internal_chat_message_metadata_passthrough?.content_item_kinds;if(Array.isArray(S)){let A=v.content.filter((x,b)=>S[b]==="user.text"&&typeof x.text=="string").map(x=>x.text).join(`
|
|
1962
|
+
`);S.includes("user.text")&&A&&(!v.id||!y.has(v.id))&&(T(A,"metadata"),v.id&&y.add(v.id))}for(let A of v.content)if(A.type==="input_text"&&typeof A.text=="string"&&A.text){let x=A.text.trim();c||(c=D(x,80)),u=D(x,80),cr(s,h,{role:"user",timestamp:_,content:q(x)})}continue}if(v.role==="assistant"&&v.content){for(let S of v.content)S.type==="output_text"&&typeof S.text=="string"&&S.text&&cr(s,h,{role:"assistant",timestamp:_,content:q(S.text),model:a});continue}if(v.role!=="user"&&v.role!=="assistant"&&v.content){for(let S of v.content)(S.type==="input_text"||S.type==="output_text")&&typeof S.text=="string"&&S.text&&cr(s,h,{role:"system",timestamp:_,content:q(S.text.trim())});continue}}if(v.type==="function_call"){s.push({role:"tool_use",timestamp:_,content:v.name||"unknown tool",toolName:v.name,toolInput:v.arguments!==void 0?q(Ct(v.arguments)):void 0,toolInputData:Nh(v.arguments),toolCallId:v.call_id});continue}if(v.type==="function_call_output"){s.push({role:"tool_result",timestamp:_,content:q(Ct(v.output)),toolCallId:v.call_id});continue}if(v.type==="custom_tool_call"){s.push({role:"tool_use",timestamp:_,content:v.name||"unknown tool",toolName:v.name,toolInput:v.input!==void 0?q(Ct(v.input)):void 0,toolInputData:kh(v.name,v.input),toolCallId:v.call_id});continue}if(v.type==="custom_tool_call_output"){s.push({role:"tool_result",timestamp:_,content:q(Ct(v.output)),toolCallId:v.call_id});continue}if(v.type==="reasoning"&&v.summary){let S=v.summary.map(A=>Ct(A.text)).join(`
|
|
1963
|
+
`);S.trim()&&cr(s,h,{role:"thinking",timestamp:_,content:q(S)});continue}}if(w.type==="event_msg"&&w.payload&&(w.payload.type==="task_started"?(E(),m="in_progress"):w.payload.type==="task_complete"?m="complete":w.payload.type==="turn_aborted"&&(m="aborted"),w.payload.type==="user_message"&&typeof w.payload.message=="string"&&T(w.payload.message,"event"),w.payload.type==="agent_reasoning")){let v=w.payload.message||w.payload.text;v&&cr(s,h,{role:"thinking",timestamp:_,content:q(v)})}}if(!i)return null;E();let I=await lc(r);return{provider:"codex",sessionId:d,cwd:i,createdAt:l||n.createdAt,modifiedAt:n.modifiedAt,model:a,cliVersion:o,startCommand:p,turnStatus:m,firstUserMessage:c,lastUserMessage:u,messageCount:I.messageCount,filePath:r,totalInputTokens:I.totalInputTokens||void 0,totalCachedInputTokens:I.totalCachedInputTokens||void 0,totalOutputTokens:I.totalOutputTokens||void 0,totalReasoningOutputTokens:I.totalReasoningOutputTokens||void 0,lastInputTokens:I.lastTokenUsage?.inputTokens||void 0,lastTokenUsage:I.lastTokenUsage,modelContextWindow:I.modelContextWindow,messages:s,userPrompts:g}}async resolveSessionPath(e){return this.resolveSessionFile(e)}async deleteSession(e){let r=await this.resolveSessionFile(e);return r?(await Ah(r),!0):!1}async resolveSessionFile(e){let r=await this.getSessionsDirs(),n=[];for(let i of r){let o=await this.findSessionFiles(i);n.push(...o)}for(let i of n)if(this.extractSessionIdFromFilename(i)===e)return i;let s=[];for(let i of n)this.extractSessionIdFromFilename(i).startsWith(e)&&s.push(i);if(s.length===1)return s[0];for(let i of n){let o=await Ee(i,1);if(o.length>0&&o[0].type==="session_meta"){let a=o[0].payload?.id;if(a===e||a&&a.startsWith(e))return i}}return null}};function Gs(t){return new qs(t)}var Xs="gpt-5.6-sol",qs=class extends G{constructor(e){super({provider:new Sn(e),capabilities:{canCreate:!0,canResumeInteractive:!0,canFork:!1,forkSupport:"manual",canStructuredTurn:!0,canStreamDeltas:!1,canCancel:!1},injection:{leaderMode:"prompt-append"},binary:"codex",seedArgs:["exec","--dangerously-bypass-approvals-and-sandbox","--skip-git-repo-check","-"],seedStdin:`${W}
|
|
1964
|
+
`,resumeTemplate:"codex resume {{session_id}}",startTemplate:"codex",transport:nc})}openSession(e){return sc({...e,model:e.model??Xs})}seedArgsFor(e){let r=super.seedArgsFor(e),n=e?.model??Xs;return[...r.slice(0,-1),"--model",n,r[r.length-1]]}turnOptsFor(e){return e.model?e:{...e,model:Xs}}};import{readFileSync as jh,writeFileSync as Bh,mkdirSync as Wh}from"node:fs";import{join as Hh,dirname as Xh}from"node:path";import{randomUUID as qh}from"node:crypto";import{createHash as Ch}from"node:crypto";import{readdir as ur,readFile as uc,stat as vn,unlink as Oh}from"node:fs/promises";import{join as ye,basename as Dh,dirname as Mh}from"node:path";import{cwd as Fh}from"node:process";function dr(t){if(!t.trim())return"unknown";let e=t.split(/\r?\n/).filter(n=>n.trim().length>0);if(e.length>1)try{let n=JSON.parse(e[0]);if(n!==null&&typeof n=="object"&&!Array.isArray(n)&&"kind"in n)return"jsonl"}catch{}let r;try{r=JSON.parse(t)}catch{return"unknown"}if(r!==null&&typeof r=="object"&&!Array.isArray(r)){let n=r;if(Array.isArray(n.messages))return"json";if("kind"in n)return"jsonl"}return"unknown"}function wn(t){let e=dr(t);if(e==="unknown")throw new Error("gemini session content matches neither known format (old .json with messages[] or new .jsonl with kind metadata)");if(e==="json"){let a=JSON.parse(t);return{sessionId:a.sessionId,projectHash:a.projectHash,startTime:a.startTime,lastUpdated:a.lastUpdated,kind:a.kind,messages:Array.isArray(a.messages)?a.messages:[]}}let r=t.split(`
|
|
1965
|
+
`).map(a=>a).filter(a=>a.trim().length>0);if(r.length===0)throw new Error("gemini session file is empty");let n=r[0],s;try{s=JSON.parse(n)}catch(a){throw new Error(`gemini JSONL session: metadata line failed to parse: ${a instanceof Error?a.message:String(a)}`)}if(s===null||typeof s!="object")throw new Error("gemini JSONL session: metadata line is not an object");let i=[],o=new Map;for(let a=1;a<r.length;a++){let l;try{l=JSON.parse(r[a])}catch{continue}if(l===null||typeof l!="object")continue;let c=l;if("$set"in c&&c.$set&&typeof c.$set=="object"){Object.assign(s,c.$set);continue}if(typeof c.id=="string"||typeof c.type=="string"){let u=c;if(typeof u.id=="string"){let d=o.get(u.id);d?Lh(d,u):(i.push(u),o.set(u.id,u))}else i.push(u)}}return{sessionId:typeof s.sessionId=="string"?s.sessionId:void 0,projectHash:typeof s.projectHash=="string"?s.projectHash:void 0,startTime:typeof s.startTime=="string"?s.startTime:void 0,lastUpdated:typeof s.lastUpdated=="string"?s.lastUpdated:void 0,kind:typeof s.kind=="string"?s.kind:void 0,messages:i}}function Lh(t,e){for(let[r,n]of Object.entries(e))if(n!==void 0){if(r==="tokens"&&cc(t.tokens)&&cc(n)){t.tokens={...t.tokens,...n};continue}t[r]=n}}function cc(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}function dc(t,e){if(e==="json")return JSON.stringify(t,null,2);let{messages:r,...n}=t,s=[JSON.stringify(n)];for(let i of r)s.push(JSON.stringify(i));return s.join(`
|
|
1966
|
+
`)+`
|
|
1967
|
+
`}function Js(t){return t?typeof t=="string"?t:Array.isArray(t)?t.map(e=>e.text||"").join(""):"":""}function mc(t){return t==="user"}function Vs(t){return t==="gemini"||t==="assistant"}function mt(t,e=new Date(0)){if(!t)return e;let r=new Date(t);return Number.isNaN(r.getTime())?e:r}function Ph(t){return`${t.sessionId}\0${t.cwd}`}function Uh(t,e){let r=t.filePaths??[t.filePath],n=e.filePaths??[e.filePath],s=[...new Set([...r,...n])],i=e.modifiedAt.getTime()>=t.modifiedAt.getTime()?e:t;return{...i,createdAt:t.createdAt.getTime()<=e.createdAt.getTime()?t.createdAt:e.createdAt,modifiedAt:i.modifiedAt,filePath:i.filePath,filePaths:s}}function In(t){let e=Number(t??0);return Number.isFinite(e)?Math.max(0,Math.round(e)):0}function fc(t){let e=0,r=0,n=0,s=0,i=0,o;for(let a of t){if(!Vs(a.type)||!a.tokens)continue;let l=In(a.tokens.input),c=In(a.tokens.cached),u=Math.max(l-c,0),d=In(a.tokens.output),p=In(a.tokens.thoughts);e+=l,r+=c,n+=d,s+=p,i=l,o={inputTokens:u,cachedInputTokens:c,cacheWriteInputTokens:0,outputTokens:d,reasoningOutputTokens:p,totalTokens:l+d+p}}return{totalInputTokens:e,totalCachedInputTokens:r,totalOutputTokens:n,totalReasoningOutputTokens:s,lastInputTokens:i,lastTokenUsage:o}}function $h(t){return Ch("sha256").update(t).digest("hex")}function mr(t,e){let r=e;for(;r&&!t.has(r);){t.add(r);let n=Mh(r);if(n===r)break;r=n}}var An=class{name="gemini";workspaceHashMap;geminiProjectsFile;geminiTmpDir;claudeProjectsDir;codexSessionDirs;extraWorkspacePaths;constructor(e={}){let r=e.geminiDir||ye(U,".gemini");this.geminiProjectsFile=ye(r,"projects.json"),this.geminiTmpDir=ye(r,"tmp");let n=e.claudeDir||ye(U,".claude");this.claudeProjectsDir=ye(n,"projects");let s=[ye(U,".codex"),ye(U,".code")],i=e.codexDirs&&e.codexDirs.length>0?e.codexDirs:[e.codexDir||s[0],e.codeDir||s[1]];this.codexSessionDirs=[...new Set(i)].map(o=>ye(o,"sessions")),this.extraWorkspacePaths=e.extraWorkspacePaths||[]}getWatchPaths(){return[{directory:this.geminiTmpDir,filePattern:/\.jsonl?$/}]}async discoverSessions(){let e=await this.findSessionFiles(),r=new Map;for(let n of e)try{let s=await this.extractSummary(n);if(!s)continue;let i=Ph(s),o=r.get(i);r.set(i,o?Uh(o,s):s)}catch{}return[...r.values()]}async loadSession(e){let r=await this.resolveSessionFile(e);if(!r)return null;let n;try{n=await this.readSessionFile(r)}catch{return null}if(!n)return null;let s=await Z(r),i=[],o=[],a=n.messages||[],l=n.sessionId||this.extractSessionIdFromFilename(r),c=n.projectHash||"",u=await this.resolveWorkspace(c),d,p,m;for(let f of a){let T=mt(f.timestamp),E=f.type,I=q(Js(f.content));if(mc(E)){let _=Js(f.content);_&&o.push(_);let v=I.trim();v&&(d||(d=D(v,80)),p=D(v,80)),i.push({role:"user",timestamp:T,content:v||I});continue}if(Vs(E)){f.model&&(m=f.model);for(let _ of f.thoughts||[]){let v=[_.subject,_.description].filter(Boolean).join(`
|
|
1968
|
+
`).trim();v&&i.push({role:"thinking",timestamp:mt(_.timestamp,T),content:q(v)})}i.push({role:"assistant",timestamp:T,content:I,model:f.model});continue}let w=E?`[${E}] `:"";i.push({role:"system",timestamp:T,content:`${w}${I}`.trim()})}let h=mt(n.startTime,s.createdAt),g=mt(n.lastUpdated,s.modifiedAt),y=fc(a);return{provider:"gemini",sessionId:l,cwd:u,createdAt:h,modifiedAt:g,model:m,startCommand:"gemini",firstUserMessage:d,lastUserMessage:p,messageCount:i.filter(f=>f.role==="user"||f.role==="assistant").length,filePath:r,totalInputTokens:y.totalInputTokens||void 0,totalCachedInputTokens:y.totalCachedInputTokens||void 0,totalOutputTokens:y.totalOutputTokens||void 0,totalReasoningOutputTokens:y.totalReasoningOutputTokens||void 0,lastInputTokens:y.lastInputTokens||void 0,lastTokenUsage:y.lastTokenUsage,messages:i,userPrompts:o}}async extractSummary(e){let r=await this.readSessionFile(e);if(!r)return null;let n=await Z(e),s=r.messages||[],i=r.sessionId||this.extractSessionIdFromFilename(e),o=r.projectHash||"",a=await this.resolveWorkspace(o),l,c,u,d=0;for(let m of s)if(mc(m.type)){d++;let h=Js(m.content).trim();h&&(l||(l=D(q(h),80)),c=D(q(h),80))}else Vs(m.type)&&(d++,m.model&&(u=m.model));let p=fc(s);return{provider:"gemini",sessionId:i,cwd:a,createdAt:mt(r.startTime,n.createdAt),modifiedAt:mt(r.lastUpdated,n.modifiedAt),model:u,startCommand:"gemini",firstUserMessage:l,lastUserMessage:c,messageCount:d,filePath:e,totalInputTokens:p.totalInputTokens||void 0,totalCachedInputTokens:p.totalCachedInputTokens||void 0,totalOutputTokens:p.totalOutputTokens||void 0,totalReasoningOutputTokens:p.totalReasoningOutputTokens||void 0,lastInputTokens:p.lastInputTokens||void 0,lastTokenUsage:p.lastTokenUsage}}async readSessionFile(e){let r=await uc(e,"utf-8");if(dr(r)==="unknown")return R({event:"gemini_session_format_unknown",provider:"gemini",file:e,preview:r.slice(0,120),message:`gemini session file at ${e} matches neither old (.json with messages[]) nor new (.jsonl with kind metadata) format. Skipping; lmctl ls / audit / stats will not see this session.`}),null;try{return wn(r)}catch{return null}}extractSessionIdFromFilename(e){let r=Dh(e).replace(/\.jsonl?$/,""),n=r.match(/session-\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-(.+)$/);return n?n[1]:r}async findSessionFiles(){let e=[],r;try{r=await ur(this.geminiTmpDir)}catch{return e}for(let n of r){let s=ye(this.geminiTmpDir,n,"chats");if(!(await vn(s).catch(()=>null))?.isDirectory())continue;let o;try{o=await ur(s)}catch{continue}for(let a of o)a.startsWith("session-")&&(!a.endsWith(".json")&&!a.endsWith(".jsonl")||e.push(ye(s,a)))}return e}async resolveSessionPath(e){return this.resolveSessionFile(e)}async deleteSession(e){let r=await this.resolveSessionFile(e);return r?(await Oh(r),!0):!1}async resolveSessionFile(e){let r=await this.findSessionFiles(),n=[];for(let s of r){let i=await this.readSessionFile(s).catch(()=>null),o=this.extractSessionIdFromFilename(s),a=i?.sessionId||o,l=a===e||a.startsWith(e),c=o===e||o.startsWith(e)||o.length>=8&&e.startsWith(o);if(!l&&!c)continue;let u=await Z(s).catch(()=>({createdAt:new Date(0),modifiedAt:new Date(0)}));n.push({filePath:s,modifiedAt:mt(i?.lastUpdated,u.modifiedAt)})}return n.sort((s,i)=>{let o=i.modifiedAt.getTime()-s.modifiedAt.getTime();return o!==0?o:i.filePath.localeCompare(s.filePath)}),n[0]?.filePath??null}async resolveWorkspace(e){return e?(await this.getWorkspaceHashMap()).get(e)||`[hash:${e.slice(0,16)}]`:"(unknown workspace)"}async getWorkspaceHashMap(){if(this.workspaceHashMap)return this.workspaceHashMap;let e=new Set;mr(e,Fh());for(let n of this.extraWorkspacePaths)mr(e,n);for(let n of await this.collectGeminiProjectPaths())mr(e,n);for(let n of await this.collectCodexCwds())mr(e,n);for(let n of await this.collectClaudeCwds())mr(e,n);let r=new Map;for(let n of e)r.set($h(n),n);return this.workspaceHashMap=r,r}async collectGeminiProjectPaths(){let e;try{e=await uc(this.geminiProjectsFile,"utf-8")}catch{return[]}try{let n=JSON.parse(e).projects;return!n||typeof n!="object"||Array.isArray(n)?[]:Object.keys(n)}catch{return[]}}async collectCodexCwds(){let e=new Set;for(let r of this.codexSessionDirs){let n=await this.findJsonlFiles(r);for(let s of n){let o=(await Ee(s,1).catch(()=>[]))[0]?.payload?.cwd;o&&e.add(o)}}return[...e]}async collectClaudeCwds(){let e=new Set,r;try{r=await ur(this.claudeProjectsDir)}catch{return[]}for(let n of r){let s=ye(this.claudeProjectsDir,n);if(!(await vn(s).catch(()=>null))?.isDirectory())continue;let o;try{o=await ur(s)}catch{continue}for(let a of o){if(!a.endsWith(".jsonl"))continue;let l=ye(s,a),u=(await Ee(l,1).catch(()=>[]))[0]?.cwd;u&&e.add(u)}}return[...e]}async findJsonlFiles(e){let r=[];if(!(await vn(e).catch(()=>null))?.isDirectory())return r;let s;try{s=await ur(e)}catch{return r}for(let i of s){let o=ye(e,i),a=await vn(o).catch(()=>null);if(a)if(a.isDirectory()){let l=await this.findJsonlFiles(o);r.push(...l)}else i.endsWith(".jsonl")&&r.push(o)}return r}};function Ys(t){return new Ks(t)}var Ks=class extends G{geminiDir;constructor(e){super({provider:new An(e),capabilities:{canCreate:!0,canResumeInteractive:!0,canFork:!0,forkSupport:"automatic",canStructuredTurn:!0,canStreamDeltas:!0,canCancel:!0},injection:{leaderMode:"skill-file",leaderSetupHint:"Place skill files in the project's .gemini/ directory"},binary:"gemini",seedArgs:["-p",W,"-y","--skip-trust"],resumeTemplate:"gemini --resume {{session_id}} --skip-trust",startTemplate:"gemini --skip-trust",transport:(r,n)=>Le(r,{...n,acpTool:"gemini"})}),this.geminiDir=e?.geminiDir}openSession(e){return Ce({...e,env:this.geminiDir!==void 0?{...e.env??process.env,GEMINI_DIR:this.geminiDir}:e.env,binary:"gemini",acpTool:"gemini"})}forkHint(e){return["Gemini fork: copies the session file with a new ID.","The forked session has the same conversation history","but diverges from that point forward."].join(`
|
|
1969
|
+
`)}seedArgsFor(e){let r=super.seedArgsFor(e);return e?.model?[...r,"--model",e.model]:r}manualSeedHint(e){return{launchCommand:`cd ${e} && gemini --skip-trust`,postLaunchNote:sn,lsCommand:`lmctl ls --provider gemini --sessiondir ${e}`}}async fork(e,r){let n=await this.resolvePath(e);if(!n)return{success:!1,error:`Session file not found for ${e}`};try{let s=jh(n,"utf-8"),i=dr(s),o=wn(s),a=qh();o.sessionId=a,o.kind="main";let l=Xh(n),c=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),u=i==="jsonl"?".jsonl":".json",d=`session-${c}-${a.slice(0,8)}${u}`,p=Hh(l,d);return Wh(l,{recursive:!0}),Bh(p,dc(o,i),"utf-8"),{success:!0,sessionId:a,filePath:p}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}};import{readdir as pc,readFile as Gh,rm as Jh,stat as Ot}from"node:fs/promises";import{basename as Vh,join as xe}from"node:path";function Kh(t){if(!t)return null;let e={inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheWriteTokens:0,reasoningTokens:0},r=!1;for(let n of Object.values(t))n?.usage&&(r=!0,e.inputTokens+=n.usage.inputTokens??0,e.outputTokens+=n.usage.outputTokens??0,e.cacheReadTokens+=n.usage.cacheReadTokens??0,e.cacheWriteTokens+=n.usage.cacheWriteTokens??0,e.reasoningTokens+=n.usage.reasoningTokens??0);return r?e:null}function zs(){return{shutdownTotals:null,assistantOutputSum:0}}function gc(t,e){if(e.type==="assistant.message"){let r=e.data?.outputTokens;typeof r=="number"&&(t.assistantOutputSum+=r,t.lastAssistantOutputTokens=r)}else if(e.type==="session.shutdown"){let r=Kh(e.data?.modelMetrics);r&&(t.shutdownTotals=r)}}function hc(t){let e=t.shutdownTotals,r=t.lastAssistantOutputTokens!==void 0?{outputTokens:t.lastAssistantOutputTokens}:void 0;return{totalInputTokens:e?.inputTokens,totalCachedInputTokens:e?.cacheReadTokens,totalCacheWriteInputTokens:e?.cacheWriteTokens,totalOutputTokens:e?.outputTokens??(t.lastAssistantOutputTokens===void 0?void 0:t.assistantOutputSum),totalReasoningOutputTokens:e?.reasoningTokens,lastTokenUsage:r}}function Yh(t){let e={};for(let r of t.split(`
|
|
1970
|
+
`)){let n=r.match(/^(\w+):\s*(.*)$/);n&&(e[n[1]]=n[2].trim())}return{id:e.id,cwd:e.cwd,summary_count:e.summary_count?parseInt(e.summary_count,10):void 0,created_at:e.created_at,updated_at:e.updated_at,summary:e.summary}}function ft(t){if(!t)return;let e=new Date(t);return Number.isNaN(e.getTime())?void 0:e}async function zh(t){let e=0,r=zs(),n;for await(let s of Q(t)){if(s.type==="user.message"){e++;let i=(s.data?.content||"").trim();i&&(n=D(i,80))}else s.type==="assistant.message"&&(s.data?.content||"").trim()&&e++;gc(r,s)}return{messageCount:e,tokens:r,lastUserMessage:n}}var xn=class{name="copilot";sessionStateDir;constructor(e={}){let r=e.copilotDir||xe(U,".copilot");this.sessionStateDir=xe(r,"session-state")}getWatchPaths(){return[{directory:this.sessionStateDir,filePattern:/events\.jsonl$/}]}async discoverSessions(){let e=[],r;try{r=await pc(this.sessionStateDir)}catch{return e}for(let n of r){let s=xe(this.sessionStateDir,n);if((await Ot(s).catch(()=>null))?.isDirectory())try{let o=await this.extractSummary(s,n);o&&e.push(o)}catch{}}return e}async loadSession(e){let r=await this.resolveSessionDir(e);if(!r)return null;let n=await this.readWorkspaceYaml(r),s=xe(r,"events.jsonl"),i=await Ot(s).catch(()=>null),o=i?s:xe(r,"workspace.yaml"),a=await Z(i?s:r),l=[],c=[],u=n?.cwd||"(unknown workspace)",d,p,m,h,g,y,f=n?.id||Vh(r)||e,T=zs();if(i)for await(let E of Q(s)){let I=ft(E.timestamp)||a.modifiedAt;if(gc(T,E),E.type==="session.start"&&E.data){E.data.sessionId&&(f=E.data.sessionId),E.data.copilotVersion&&(p=E.data.copilotVersion),E.data.startTime&&(y=ft(E.data.startTime)),E.data.selectedModel&&(d=E.data.selectedModel),E.data.context&&(E.data.context.cwd&&(u=E.data.context.cwd),E.data.context.branch&&(m=E.data.context.branch));continue}if(E.type==="session.model_change"&&E.data?.newModel){d=E.data.newModel;continue}if(E.type==="user.message"&&E.data){let w=E.data.content||"";w&&c.push(w);let _=w.trim();_&&(h||(h=D(_,80)),g=D(_,80)),l.push({role:"user",timestamp:I,content:q(_||w)});continue}if(E.type==="assistant.message"&&E.data){let w=(E.data.content||"").trim();if(w&&l.push({role:"assistant",timestamp:I,content:q(w),model:d}),E.data.toolRequests)for(let _ of E.data.toolRequests)l.push({role:"tool_use",timestamp:I,content:_.name||"unknown tool",toolName:_.name,toolInput:_.arguments?JSON.stringify(_.arguments,null,2):void 0,toolInputData:ve(_.arguments),toolCallId:_.toolCallId});continue}if(E.type==="tool.execution_complete"&&E.data){let w=E.data.result?.content||"",_=E.data.result?.detailedContent||"";l.push({role:"tool_result",timestamp:I,content:q(w),toolDetailedContent:_?q(_):void 0,toolCallId:E.data.toolCallId});continue}if(E.type==="assistant.reasoning"&&E.data?.content){l.push({role:"thinking",timestamp:I,content:q(E.data.content)});continue}if(E.type==="session.error"||E.type==="session.warning"||E.type==="session.info"||E.type==="system.message"){let w=E.data?.message||"";w.trim()&&l.push({role:"system",timestamp:I,content:q(w)});continue}}if(!h){let E=(n?.summary||"").trim();E&&(h=D(E,80))}return Qh(l),{provider:"copilot",sessionId:f,cwd:u,createdAt:y??ft(n?.created_at)??a.createdAt,modifiedAt:ft(n?.updated_at)??a.modifiedAt,model:d,cliVersion:p,startCommand:"copilot",gitBranch:m,firstUserMessage:h,lastUserMessage:g,messageCount:l.filter(E=>E.role==="user"||E.role==="assistant").length,filePath:o,...hc(T),messages:l,userPrompts:c}}async extractSummary(e,r){let n=await this.readWorkspaceYaml(e),s=xe(e,"events.jsonl"),i=await Ot(s).catch(()=>null),o=i?s:xe(e,"workspace.yaml"),a=await Z(i?s:e),l=i?await Ee(s,20):[],c=n?.id||r,u=n?.cwd||"(unknown workspace)",d,p,m,h,g;for(let f of l)if(f.type==="session.start"&&f.data&&(f.data.sessionId&&(c=f.data.sessionId),f.data.copilotVersion&&(p=f.data.copilotVersion),f.data.startTime&&(m=ft(f.data.startTime)),f.data.selectedModel&&(d=f.data.selectedModel),f.data.context?.cwd&&(u=f.data.context.cwd)),f.type==="session.model_change"&&f.data?.newModel&&(d||(d=f.data.newModel)),f.type==="user.message"&&f.data){let T=(f.data.content||"").trim();T&&(h||(h=D(T,80)),g=D(T,80))}if(!h){let f=(n?.summary||"").trim();f&&(h=D(f,80))}let y=i?await zh(s):{messageCount:0,tokens:zs()};return{provider:"copilot",sessionId:c,cwd:u,createdAt:m??ft(n?.created_at)??a.createdAt,modifiedAt:ft(n?.updated_at)??a.modifiedAt,model:d,cliVersion:p,startCommand:"copilot",firstUserMessage:h,lastUserMessage:y.lastUserMessage??g,messageCount:y.messageCount,filePath:o,...hc(y.tokens)}}async readWorkspaceYaml(e){let r=xe(e,"workspace.yaml");try{let n=await Gh(r,"utf-8");return Yh(n)}catch{return null}}async resolveSessionPath(e){return this.resolveSessionDir(e)}async deleteSession(e){let r=await this.resolveSessionDir(e);return r?(await Jh(r,{recursive:!0}),!0):!1}async resolveSessionDir(e){let r;try{r=await pc(this.sessionStateDir)}catch{return null}if(r.includes(e)){let s=xe(this.sessionStateDir,e);if((await Ot(s).catch(()=>null))?.isDirectory())return s}let n=[];for(let s of r)if(s.startsWith(e)){let i=xe(this.sessionStateDir,s);(await Ot(i).catch(()=>null))?.isDirectory()&&n.push(i)}if(n.length===1)return n[0];for(let s of r){let i=xe(this.sessionStateDir,s);if(!(await Ot(i).catch(()=>null))?.isDirectory())continue;let a=await this.readWorkspaceYaml(i);if(a&&(a.id===e||a.id?.startsWith(e)))return i}return null}};function Qh(t){let e=Zh(t),r=new Map;for(let n of t){if(n.role!=="tool_use"||n.toolCallId===void 0)continue;if(n.toolName==="bash"){let l=e.get(n.toolCallId),u=[l?.content,l?.toolDetailedContent].filter(p=>typeof p=="string").join(`
|
|
1971
|
+
`).match(/<command (?:started in (?:detached )?background with|with) shellId:\s*([^>\s]+)/i)?.[1];if(u===void 0)continue;let d=`copilot-shell:${u}:${n.toolCallId}`;r.set(u,d),n.backgroundTaskId=d,l!==void 0&&(l.backgroundTaskId=d);continue}if(!["read_bash","write_bash","stop_bash"].includes(n.toolName??""))continue;let s=n.toolInputData?.shellId;if(typeof s!="string"&&typeof s!="number")continue;let i=String(s),o=r.get(i);if(o===void 0)continue;n.backgroundTaskId=o;let a=e.get(n.toolCallId);a!==void 0&&(a.backgroundTaskId=o)}}function Zh(t){let e=new Map;for(let r of t)r.role==="tool_result"&&r.toolCallId!==void 0&&e.set(r.toolCallId,r);return e}function Zs(t){return new Qs(t)}var Qs=class extends G{copilotDir;constructor(e){super({provider:new xn(e),capabilities:{canCreate:!0,canResumeInteractive:!0,canFork:!1,forkSupport:"manual",canStructuredTurn:!0,canStreamDeltas:!0,canCancel:!0},injection:{leaderMode:"prompt-append"},binary:"copilot",seedArgs:["-p",W,"--yolo"],resumeTemplate:"copilot --resume={{session_id}}",startTemplate:"copilot",transport:(r,n)=>Le(r,{...n,acpTool:"copilot"})}),this.copilotDir=e?.copilotDir}openSession(e){return Ce({...e,env:this.copilotDir!==void 0?{...e.env??process.env,COPILOT_HOME:this.copilotDir}:e.env,binary:"copilot",acpTool:"copilot"})}async seed(e,r){let n=await super.seed(e,r);if(r?.model===void 0||r.model.trim().length===0)return n;let s="copilot seed does not implement per-session model selection";return he({event:"model_ignored",provider:"copilot",model:r.model,reason:s}),{...n,warnings:[...n.warnings??[],`copilot seed ignored model=${r.model}: ${s}`]}}};function ti(){return new ei}var ei=class extends G{constructor(){super({provider:new Lt,capabilities:{canCreate:!0,canResumeInteractive:!0,canFork:!1,forkSupport:"manual",canStructuredTurn:!0,canStreamDeltas:!0,canCancel:!0},injection:{leaderMode:"custom-tool",leaderSetupHint:"OpenCode supports custom tools via .opencode/tools/ directory"},binary:"opencode",seedArgs:["run",W],resumeTemplate:"opencode --session {{session_id}}",startTemplate:"opencode",transport:(e,r)=>Le(e,{...r,acpTool:"opencode"})})}openSession(e){return Ce({...e,binary:"opencode",acpTool:"opencode"})}seedArgsFor(e){let r=["run"];return e?.model&&r.push("--model",e.model),e?.effort&&r.push("--variant",e.effort),r.push(e?.prompt??W),r}};import{appendFile as eg,mkdir as tg,readFile as _c,readdir as Ec,rm as rg,stat as yc}from"node:fs/promises";import{basename as ng,dirname as sg,isAbsolute as Tc,join as pt,relative as ig,resolve as ri}from"node:path";var og="1.4",ag="1.5",lg=new Set([og,ag]),Rn=class{name="kimi";homeDir;sessionsDir;constructor(e){this.homeDir=ri(e?.kimiHome??process.env.KIMI_CODE_HOME??pt(U,".kimi-code")),this.sessionsDir=pt(this.homeDir,"sessions")}async discoverSessions(){let e=[];for(let r of await this.sessionFiles())try{let n=await this.summary(r);n&&e.push(n)}catch{}return e.sort((r,n)=>n.modifiedAt.getTime()-r.modifiedAt.getTime())}async loadSession(e){let r=await this.findSession(e);if(!r)return null;let n=await this.summary(r);if(!n)return null;let s=await this.parseWire(r.wirePath);return{...n,messages:s.messages,userPrompts:s.userPrompts}}async resolveSessionPath(e){return(await this.findSession(e))?.wirePath??null}async deleteSession(e){let r=await this.findSession(e);return r?(await rg(r.sessionDir,{recursive:!0,force:!0}),await tg(sg(this.indexPath()),{recursive:!0,mode:448}),await eg(this.indexPath(),`${JSON.stringify({sessionId:r.sessionId,deleted:!0})}
|
|
1972
|
+
`,"utf-8"),!0):!1}getWatchPaths(){return[{directory:this.sessionsDir,filePattern:/wire\.jsonl$/}]}indexPath(){return pt(this.homeDir,"session_index.jsonl")}async sessionFiles(){let e=await this.readIndex(),r=new Map;for(let s of e.values())this.validSessionDir(s.sessionDir,s.sessionId)&&r.set(s.sessionId,this.filesFor(s.sessionId,s.sessionDir,s.workDir));let n;try{n=await Ec(this.sessionsDir,{withFileTypes:!0})}catch{return[...r.values()]}for(let s of n){if(!s.isDirectory())continue;let i=pt(this.sessionsDir,s.name),o;try{o=await Ec(i,{withFileTypes:!0})}catch{continue}for(let a of o){if(!a.isDirectory()||r.has(a.name))continue;let l=pt(i,a.name);r.set(a.name,this.filesFor(a.name,l))}}return[...r.values()]}async readIndex(){let e;try{e=await _c(this.indexPath(),"utf-8")}catch{return new Map}let r=new Map;for(let n of e.split(/\r?\n/))if(n.trim())try{let s=JSON.parse(n);if(typeof s.sessionId!="string")continue;s.deleted===!0?r.delete(s.sessionId):typeof s.sessionDir=="string"&&typeof s.workDir=="string"&&r.set(s.sessionId,{sessionId:s.sessionId,sessionDir:ri(s.sessionDir),workDir:s.workDir})}catch{}return r}filesFor(e,r,n){return{sessionId:e,sessionDir:r,statePath:pt(r,"state.json"),wirePath:pt(r,"agents","main","wire.jsonl"),indexedWorkDir:n}}validSessionDir(e,r){if(!Tc(e)||ng(e)!==r)return!1;let n=ig(this.sessionsDir,ri(e));return n!==""&&n!==".."&&!n.startsWith(`..${process.platform==="win32"?"\\":"/"}`)&&!Tc(n)}async findSession(e){let r=await this.sessionFiles(),n=r.find(i=>i.sessionId===e);if(n)return n;let s=r.filter(i=>i.sessionId.startsWith(e));return s.length===1?s[0]:null}async readState(e){try{let r=JSON.parse(await _c(e,"utf-8"));return r!==null&&typeof r=="object"&&!Array.isArray(r)?r:null}catch{return null}}async summary(e){let r=await this.readState(e.statePath);if(!r)return null;let n;try{n=await yc(e.wirePath)}catch{return null}let s=await yc(e.statePath).catch(()=>n),i=await this.parseWire(e.wirePath),o=ni(r.createdAt)??s.birthtime,a=ni(r.updatedAt)??(s.mtime>n.mtime?s.mtime:n.mtime);return{provider:"kimi",sessionId:e.sessionId,slug:r.title,cwd:r.workDir??e.indexedWorkDir??"(unknown)",createdAt:o,modifiedAt:a,model:i.model,startCommand:"kimi",firstUserMessage:i.firstUserMessage,lastUserMessage:i.lastUserMessage??(r.lastPrompt?D(r.lastPrompt.trim(),80):void 0),messageCount:i.messageCount,filePath:e.wirePath,filePaths:[e.statePath,e.wirePath],totalInputTokens:i.totalInputTokens,totalCachedInputTokens:i.totalCachedInputTokens,totalCacheWriteInputTokens:i.totalCacheWriteInputTokens,totalOutputTokens:i.totalOutputTokens,lastInputTokens:i.lastInputTokens,lastTokenUsage:i.lastTokenUsage}}async parseWire(e){let r=[],n=[],s=new Set,i=!0,o,a,l,c=0,u=0,d=0,p=0,m=!1,h=0,g,y;for await(let f of Q(e)){let T=cg(f.time??f.created_at);if(i&&(i=!1,f.type==="metadata"&&!lg.has(f.protocol_version))){let I=`Kimi transcript wire protocol version ${JSON.stringify(f.protocol_version)} is not supported by this lmctl version.`;return{messages:[{role:"system",timestamp:T,content:I}],userPrompts:[],messageCount:1,firstUserMessage:I,lastUserMessage:I}}if((f.type==="config.update"||f.type==="profile.bind")&&f.modelAlias&&(o=f.modelAlias),f.type==="usage.record"){f.model&&(o=f.model),m||=f.usage!==void 0;let I=f.usage?.inputOther??0,w=f.usage?.inputCacheRead??0,_=f.usage?.inputCacheCreation??0,v=f.usage?.output??0;c+=I,u+=w,d+=_,p+=v,f.usageScope==="turn"&&(g=I+w+_,y={inputTokens:I,cachedInputTokens:w,cacheWriteInputTokens:_,outputTokens:v,totalTokens:g+v});continue}if(f.type==="turn.prompt"&&f.origin?.kind==="user"){let I=Sc(f.input);I&&((!f.promptId||!s.has(f.promptId))&&(n.push(I),f.promptId&&s.add(f.promptId)),a??=D(I,80),l=D(I,80),r.push({role:"user",timestamp:T,content:I}),h++);continue}if(f.type==="turn.steer"){let I=Sc(f.input);I&&(r.push({role:"system",timestamp:T,content:I}),h++);continue}if(f.type!=="context.append_loop_event"||!f.event)continue;let E=f.event;E.type==="content.part"&&E.part?.type==="text"&&E.part.text?(r.push({role:"assistant",timestamp:T,content:E.part.text,model:o}),h++):E.type==="content.part"&&E.part?.type==="think"&&E.part.think?r.push({role:"thinking",timestamp:T,content:E.part.think,model:o}):E.type==="tool.call"?r.push({role:"tool_use",timestamp:T,content:E.name??"tool",toolName:E.name,toolInput:wc(E.args),toolInputData:ve(E.args),toolCallId:E.toolCallId,model:o}):E.type==="tool.result"&&r.push({role:"tool_result",timestamp:T,content:dg(E.result),toolCallId:E.toolCallId,model:o})}return ug(r),{messages:r,userPrompts:n,messageCount:h,model:o,firstUserMessage:a,lastUserMessage:l,totalInputTokens:m?c:void 0,totalCachedInputTokens:m?u:void 0,totalCacheWriteInputTokens:m?d:void 0,totalOutputTokens:m?p:void 0,lastInputTokens:g,lastTokenUsage:y}}};function ni(t){if(!t)return;let e=new Date(t);return Number.isNaN(e.getTime())?void 0:e}function cg(t){return typeof t=="number"?new Date(t):ni(t)??new Date(0)}function Sc(t){return typeof t=="string"?t.trim():Array.isArray(t)?t.map(e=>e&&typeof e=="object"&&"text"in e&&typeof e.text=="string"?e.text:"").filter(Boolean).join(`
|
|
1973
|
+
`).trim():""}function wc(t){if(t!==void 0)try{return JSON.stringify(t)}catch{return String(t)}}function dg(t){return t&&typeof t=="object"&&"output"in t&&typeof t.output=="string"?t.output:wc(t)??""}function ug(t){let e=mg(t),r=new Set;for(let n of t){if(n.role!=="tool_use"||n.toolName!=="Bash"||n.toolInputData?.run_in_background!==!0||n.toolCallId===void 0)continue;let s=e.get(n.toolCallId);if(s===void 0)continue;let i=s.content.match(/(?:^|\n)task_id:\s*([^\s]+)/)?.[1];i!==void 0&&(r.add(i),n.backgroundTaskId=i,s.backgroundTaskId=i)}for(let n of t){if(n.role!=="tool_use"||n.toolName!=="TaskOutput"&&n.toolName!=="TaskStop"||n.toolCallId===void 0)continue;let s=n.toolInputData?.task_id;if(typeof s!="string"||!r.has(s))continue;n.backgroundTaskId=s;let i=e.get(n.toolCallId);i!==void 0&&(i.backgroundTaskId=s)}}function mg(t){let e=new Map;for(let r of t)r.role==="tool_result"&&r.toolCallId!==void 0&&e.set(r.toolCallId,r);return e}function ii(t){return new si(t)}var si=class extends G{kimiHome;constructor(e){super({provider:new Rn(e),capabilities:{canCreate:!0,canResumeInteractive:!0,canFork:!1,forkSupport:"manual",canStructuredTurn:!0,canStreamDeltas:!0,canCancel:!0},injection:{leaderMode:"prompt-append",leaderSetupHint:"Kimi supports skills through ~/.kimi-code/skills and --skills-dir."},binary:"kimi",seedArgs:["-p",W,"--output-format","stream-json"],resumeTemplate:"kimi --session {{session_id}} --auto",startTemplate:"kimi --auto",transport:(r,n)=>Le(r,{...n,acpTool:"kimi"})}),this.kimiHome=e?.kimiHome}openSession(e){return Ce({...e,env:this.kimiHome!==void 0?{...e.env??process.env,KIMI_CODE_HOME:this.kimiHome}:e.env,binary:"kimi",acpTool:"kimi"})}seedArgsFor(e){let r=[];return e?.model&&r.push("--model",e.model),r.push("-p",e?.prompt??W,"--output-format","stream-json"),r}};import{spawn as fg}from"node:child_process";import{mkdirSync as pg}from"node:fs";function ai(t){return new oi(t)}var oi=class extends G{constructor(e){super({provider:new Lt({providerName:"lmplayer",startCommand:"lmplayer",dbPath:e?.lmplayerDbPath}),capabilities:{canCreate:!0,canResumeInteractive:!0,canFork:!1,forkSupport:"manual",canStructuredTurn:!0,canStreamDeltas:!1,canCancel:!0},injection:{leaderMode:"none"},binary:"lmplayer",seedArgs:["run","--format","json","--dangerously-skip-permissions",W],resumeTemplate:"lmplayer tui --session {{session_id}}",startTemplate:"lmplayer run --dangerously-skip-permissions",transport:hg})}seedArgsFor(e){return vc({prompt:e?.prompt??W,model:e?.model,effort:e?.effort,formatJson:!0,permissionMode:"yolo"})}async seed(e,r){pg(e,{recursive:!0});let n=this.seedArgsFor(r);se("lmplayer",n);try{let s=await Ac(this.binary,n,{cwd:e,env:Nt(void 0,e)});return s.code!==0&&s.code!==null?{success:!1,error:Ic(s)}:s.sessionId?{success:!0,sessionId:s.sessionId}:{success:!1,error:"lmplayer seed failed; provider did not report a sessionID"}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}manualSeedHint(e){return{launchCommand:`cd ${e} && lmplayer run --format json --dangerously-skip-permissions "${W}"`,postLaunchNote:"Copy the sessionID reported by lmplayer into this member's sessionid= field.",lsCommand:`lmctl ls --provider lmplayer --sessiondir ${e}`}}};async function hg(t,e){let r=Date.now(),n=vc({prompt:t,sessionId:e.sessionId,model:e.model,effort:e.effort,formatJson:!0,permissionMode:e.permissionMode??"yolo"});se("lmplayer",n,e.permissionMode??"yolo");let s=await Ac(e.binary,n,{cwd:e.cwd,env:oe(e.env,e.cwd,e.sessionId),signal:e.signal,onText:i=>{e.onProgress?.({kind:"text",summary:i.slice(0,120)}),e.onDelta?.(i)}});if(s.code!==0&&s.code!==null)throw new Error(Ic(s));return{text:s.text.trim(),sessionId:s.sessionId??e.sessionId,durationMs:Date.now()-r}}function vc(t){let e=["run"];return t.model&&e.push("--model",t.model),t.sessionId&&e.push("--session",t.sessionId),t.formatJson&&e.push("--format","json"),t.effort&&e.push("--effort",t.effort),e.push(...Ve("lmplayer",t.permissionMode)??[]),e.push("--",t.prompt),e}function Ic(t){if(t.error)return t.error;let e=Qt(t.stderr).trim();return e?e.slice(0,500):`exit code ${t.code}`}function Ac(t,e,r){return new Promise((n,s)=>{let i;try{i=fg(t,e,{cwd:r.cwd,env:r.env,stdio:["ignore","pipe","pipe"]})}catch(g){s(g);return}let o="",a="",l="",c,u,d,p=[],m=!1,h=g=>{let y=g.trim();if(!y)return;let f;try{f=JSON.parse(y)}catch{p.push(g),r.onText?.(g);return}if(!Dt(f))return;let T=bn(f,!1);c===void 0&&T!==void 0&&(c=T),u=bn(f,!0)??u;let E=gg(f);E!==void 0&&(d=E);let I=xc(f);I&&(p.push(I),r.onText?.(I))};i.stdout?.on("data",g=>{let y=g.toString("utf8");o+=y,l+=y;let f=l.indexOf(`
|
|
1974
|
+
`);for(;f>=0;){let T=l.slice(0,f);l=l.slice(f+1),h(T),f=l.indexOf(`
|
|
1975
|
+
`)}}),i.stderr?.on("data",g=>{a+=g.toString("utf8")}),r.signal&&(r.signal.aborted?i.kill():r.signal.addEventListener("abort",()=>i.kill(),{once:!0})),i.on("exit",g=>{m||(m=!0,l.length>0&&h(l),n({code:g,stdout:o,stderr:a,sessionId:c??u,text:p.join(""),error:d}))}),i.on("error",g=>{m||(m=!0,s(g))})})}function gg(t){let e=t.error;if(typeof e=="string"&&e.length>0)return e;if(Dt(e)){let r=e.data;if(Dt(r)&&typeof r.message=="string"&&r.message.length>0)return typeof e.name=="string"?`${e.name}: ${r.message}`:r.message;if(typeof e.message=="string"&&e.message.length>0)return e.message}}function xc(t){for(let e of["text","content","delta","output","message"]){let r=t[e];if(typeof r=="string")return r}for(let e of["data","event","payload","part"]){let r=t[e];if(Dt(r)){let n=xc(r);if(n)return n}}}function bn(t,e){for(let n of["sessionID","sessionId","session_id"]){let s=t[n];if(typeof s=="string"&&s.length>0)return s}let r=t.session;if(typeof r=="string"&&r.length>0)return r;if(Dt(r)){let n=bn(r,e);if(n!==void 0)return n}if(e){let n=t.id;if(typeof n=="string"&&n.length>0)return n}for(let n of["data","event","payload","part"]){let s=t[n];if(Dt(s)){let i=bn(s,e);if(i!==void 0)return i}}}function Dt(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}import{readdir as Nn,readFile as _g,rm as Eg}from"node:fs/promises";import{basename as Rc,join as Ze}from"node:path";function yg(){return{observed:!1,totalInputTokens:0,totalCachedInputTokens:0,totalOutputTokens:0,totalReasoningOutputTokens:0}}function fr(t){let e=Number(t??0);return Number.isFinite(e)?Math.max(0,Math.round(e)):0}function Tg(t,e){if(!e)return;t.observed=!0;let r=fr(e.promptTokenCount),n=fr(e.cachedContentTokenCount),s=fr(e.candidatesTokenCount),i=fr(e.thoughtsTokenCount);t.totalInputTokens+=r,t.totalCachedInputTokens+=n,t.totalOutputTokens+=s,t.totalReasoningOutputTokens+=i,t.lastInputTokens=r,t.lastTokenUsage={inputTokens:Math.max(r-n,0),cachedInputTokens:n,outputTokens:s,reasoningOutputTokens:i,totalTokens:fr(e.totalTokenCount)||r+s}}function Sg(t){return{totalInputTokens:t.observed?t.totalInputTokens:void 0,totalCachedInputTokens:t.observed?t.totalCachedInputTokens:void 0,totalOutputTokens:t.observed?t.totalOutputTokens:void 0,totalReasoningOutputTokens:t.observed?t.totalReasoningOutputTokens:void 0,lastInputTokens:t.lastInputTokens,lastTokenUsage:t.lastTokenUsage}}function bc(t){return t.type==="user"||t.message?.role==="user"}function Nc(t){return t.type==="assistant"||t.message?.role==="assistant"||t.message?.role==="model"}function kc(t){let e=t.message;return e?typeof e.content=="string"?e.content:Array.isArray(e.content)?e.content.filter(r=>r.type==="text").map(r=>r.text||"").join(`
|
|
1976
|
+
`):Array.isArray(e.parts)?e.parts.filter(r=>!r.thought&&r.type!=="thinking").map(r=>r.text||"").join(`
|
|
1977
|
+
`):"":""}function Lc(t){return t.model||t.message?.model}function wg(t){let e=t.message?.content;return typeof e=="string"?e.length>0?1:0:Oc(t).filter(r=>!r.thought&&r.type!=="thinking"&&typeof r.text=="string"&&r.text.length>0).length}function pr(t,e=!1){if(t!==void 0){if(typeof t=="string")return t;try{return JSON.stringify(t,null,e?2:void 0)}catch{return String(t)}}}function vg(t){if(t!==null&&typeof t=="object"&&!Array.isArray(t)){let e=t;return pr(e.output??e.error??t)}return pr(t)}function Oc(t){return Array.isArray(t.message?.content)?t.message.content:t.message?.parts??[]}function Cc(t,e,r){let n=t.name||"tool";return{role:"tool_use",timestamp:e,content:n,toolName:n,toolInput:pr(t.args,!0),toolInputData:ve(t.args),toolCallId:t.id,model:r}}var kn=class{name="qwen";baseDir;constructor(e){this.baseDir=e?.qwenDir||Ze(U,".qwen")}async discoverSessions(){let e=Ze(this.baseDir,"projects"),r;try{r=await Nn(e)}catch{return[]}let n=[];for(let s of r){let i=Ze(e,s,"chats"),o;try{o=await Nn(i)}catch{continue}for(let a of o){if(!a.endsWith(".jsonl"))continue;let l=a.replace(/\.jsonl$/,""),c=Ze(i,a);try{let u=await this.extractSummary(c,l);u&&n.push(u)}catch{}}}return n}async extractSummary(e,r){let n=!1,s=await Z(e),i="(unknown)",o,a,l,c,u=0;for await(let d of Q(e)){if(n=!0,d.cwd&&(i=d.cwd,d.version&&(a=d.version)),d.type==="system"&&d.cwd&&(i=d.cwd,d.version&&(a=d.version),d.model&&(o=d.model)),bc(d)){let p=kc(d).trim();p&&(l||(l=D(p,80)),c=D(p,80),u++)}if(Nc(d)){let p=Lc(d);p&&(o=p),u+=wg(d)}}return n?{provider:"qwen",sessionId:r,cwd:i,createdAt:s.createdAt,modifiedAt:s.modifiedAt,model:o,cliVersion:a,startCommand:"qwen",firstUserMessage:l,lastUserMessage:c,messageCount:u,filePath:e}:null}async loadSession(e){let r=await this.resolveSessionPath(e);if(!r)return null;let n=Rc(r,".jsonl");return this.loadFromFile(r,n)}async loadFromFile(e,r){let n=await Z(e),s="(unknown)",i,o,a,l,c,u,d=[],p=yg();for await(let m of Q(e)){if(Tg(p,m.usageMetadata),m.cwd&&(s=m.cwd,m.version&&(o=m.version),m.gitBranch&&(a=m.gitBranch)),m.type==="system"&&m.cwd&&(s=m.cwd,m.version&&(o=m.version),m.model&&(i=m.model),m.gitBranch&&(a=m.gitBranch)),!m.message)continue;let h=m.message,g=m.timestamp?new Date(m.timestamp):n.modifiedAt;if(m.type==="tool_result"){let y=Oc(m).filter(f=>f.functionResponse!==void 0);y.length===0&&m.toolCallResult?.callId&&d.push({role:"tool_result",timestamp:g,content:pr(m.toolCallResult.resultDisplay??m.toolCallResult.error??m.toolCallResult.status)??"tool result",toolCallId:m.toolCallResult.callId});for(let f of y){let T=f.functionResponse,E=vg(T.response),I=pr(m.toolCallResult?.resultDisplay);d.push({role:"tool_result",timestamp:g,content:I??E??m.toolCallResult?.status??"tool result",toolName:T.name,toolCallId:m.toolCallResult?.callId??T.id,...E!==void 0?{toolDetailedContent:E}:{}})}}else if(bc(m)){let y=kc(m);y.trim()&&(c||(c=D(y.trim(),80)),u=D(y.trim(),80)),d.push({role:"user",timestamp:g,content:y})}else if(Nc(m)){let y=Lc(m);if(y&&(i=y),Array.isArray(h.content))for(let f of h.content)f.type==="text"&&f.text?d.push({role:"assistant",timestamp:g,content:f.text,model:y}):f.type==="thinking"&&f.thinking?d.push({role:"thinking",timestamp:g,content:f.thinking}):f.functionCall&&d.push(Cc(f.functionCall,g,y));else if(typeof h.content=="string")d.push({role:"assistant",timestamp:g,content:h.content,model:y});else if(Array.isArray(h.parts))for(let f of h.parts)if(f.thought||f.type==="thinking"){let T=f.thinking||f.text;T&&d.push({role:"thinking",timestamp:g,content:T})}else f.functionCall?d.push(Cc(f.functionCall,g,y)):f.text&&d.push({role:"assistant",timestamp:g,content:f.text,model:y})}}return{provider:"qwen",sessionId:r,slug:l,cwd:s,createdAt:n.createdAt,modifiedAt:n.modifiedAt,model:i,cliVersion:o,gitBranch:a,startCommand:"qwen",firstUserMessage:c,lastUserMessage:u,messageCount:d.filter(m=>m.role==="user"||m.role==="assistant").length,filePath:e,...Sg(p),messages:d}}async resolveSessionPath(e){let r=Ze(this.baseDir,"projects");try{let n=await Nn(r),s=[];for(let i of n){let o=Ze(r,i,"chats",`${e}.jsonl`);try{return await _g(o,{flag:"r"}),o}catch{continue}}for(let i of n){let o=Ze(r,i,"chats"),a;try{a=await Nn(o)}catch{continue}for(let l of a){if(!l.endsWith(".jsonl"))continue;Rc(l,".jsonl").startsWith(e)&&s.push(Ze(o,l))}}if(s.length===1)return s[0]}catch{}return null}async deleteSession(e){let r=await this.resolveSessionPath(e);if(!r)return!1;try{return await Eg(r),!0}catch{return!1}}};function ci(){return new li}var li=class extends G{constructor(){super({provider:new kn,capabilities:{canCreate:!0,canResumeInteractive:!0,canFork:!1,forkSupport:"manual",canStructuredTurn:!0,canStreamDeltas:!0,canCancel:!0},injection:{leaderMode:"prompt-append"},binary:"qwen",seedArgs:["-p",W,"--approval-mode","yolo"],resumeTemplate:"qwen --resume {{session_id}}",startTemplate:"qwen",transport:yn})}openSession(e){return Tn({...e,binary:"qwen"})}seedArgsFor(e){let r=super.seedArgsFor(e);return e?.model?[...r,"--model",e.model]:r}};import{readdir as Dc,readFile as Mc,rm as Fc,stat as Pc}from"node:fs/promises";import{basename as di,join as Oe}from"node:path";import{fileURLToPath as Ig}from"node:url";var Ln=class{name="agy";baseDir;constructor(e={}){this.baseDir=e.agyDir||Oe(U,".gemini","antigravity-cli")}getWatchPaths(){return[{directory:Oe(this.baseDir,"conversations"),filePattern:/\.db$/}]}async discoverSessions(){let e=Oe(this.baseDir,"conversations"),r;try{r=await Dc(e)}catch{return[]}let n=[];for(let s of r){if(!s.endsWith(".db"))continue;let i=di(s,".db");try{let o=await this.extractSummary(i);o&&n.push(o)}catch{}}return n}conversationPath(e){return Oe(this.baseDir,"conversations",`${e}.db`)}transcriptPath(e,r){return Oe(this.baseDir,"brain",e,".system_generated","logs",r?"transcript_full.jsonl":"transcript.jsonl")}async existingTranscriptPath(e){for(let r of[this.transcriptPath(e,!0),this.transcriptPath(e,!1)])try{return await Pc(r),r}catch{}return null}async extractSummary(e){let r=this.conversationPath(e),n=await this.existingTranscriptPath(e),s=n??r,i=await Ag([r,n].filter(Boolean)),o=await this.resolveCwd(e,n),a,l,c,u=0;if(n)for await(let d of Q(n)){let p=Bc(d.content);if(p&&(a=p),Uc(d)){let m=jc(d.content).trim();m&&(l||(l=D(m,80)),c=D(m,80)),u++}else $c(d)&&d.content&&u++}return{provider:"agy",sessionId:e,cwd:o,createdAt:i.createdAt,modifiedAt:i.modifiedAt,model:a,startCommand:"agy",firstUserMessage:l,lastUserMessage:c,messageCount:u,filePath:s,filePaths:n?[r,n]:[r]}}async loadSession(e){let r=await this.resolveSessionPath(e);if(!r)return null;let n=Hc(r);if(!n)return null;let s=await this.extractSummary(n);if(!s)return null;let i=await this.existingTranscriptPath(n),o=[],a=s.model,l=s.firstUserMessage,c=s.lastUserMessage,u=[],d=[];if(i)for await(let p of Q(i)){let m=xg(p.created_at,s.modifiedAt),h=Bc(p.content);if(h&&(a=h),Uc(p)){let g=jc(p.content),y=g.trim();y&&(l||(l=D(y,80)),c=D(y,80)),o.push({role:"user",timestamp:m,content:g});continue}if(Array.isArray(p.tool_calls))for(let g of p.tool_calls){let y=g.name||"tool",f=bg(g.args),T=ve(g.args),E={role:"tool_use",timestamp:m,content:f,toolName:y,toolInput:f,toolInputData:T};o.push(E),u.push({name:y,stepIndex:p.step_index,input:T,message:E})}if($c(p)&&p.content)o.push({role:"assistant",timestamp:m,content:p.content,model:a});else if(Rg(p)&&p.content){let g=Cg(p,n),y=g===void 0?null:await this.readTaskLog(n,g),f={role:"tool_result",timestamp:y?.modifiedAt??m,content:p.content,toolName:p.type?.toLowerCase(),backgroundTaskId:g,...y===null?{}:{toolDetailedContent:y.content}};o.push(f),d.push({event:p,message:f})}p.thinking&&o.push({role:"thinking",timestamp:m,content:p.thinking})}return Og(u,d),{...s,model:a,firstUserMessage:l,lastUserMessage:c,messageCount:o.filter(p=>p.role==="user"||p.role==="assistant").length,messages:o}}async resolveSessionPath(e){let r=this.conversationPath(e);try{return await Pc(r),r}catch{}let n=Oe(this.baseDir,"conversations");try{let s=[];for(let i of await Dc(n)){if(!i.endsWith(".db"))continue;di(i,".db").startsWith(e)&&s.push(Oe(n,i))}if(s.length===1)return s[0]}catch{}return null}async deleteSession(e){let r=await this.resolveSessionPath(e);if(!r)return!1;let n=Hc(r);return n?(await Fc(this.conversationPath(n),{force:!0}),await Fc(Oe(this.baseDir,"brain",n),{recursive:!0,force:!0}),!0):!1}async resolveCwd(e,r){let n=await this.cwdFromLastConversationCache(e);if(n)return n;if(r){let s=await Ng(r);if(s)return s}return"(unknown)"}async cwdFromLastConversationCache(e){let r=Oe(this.baseDir,"cache","last_conversations.json");try{let n=JSON.parse(await Mc(r,"utf8"));for(let[s,i]of Object.entries(n))if(i===e)return s}catch{}return null}async readTaskLog(e,r){if(!/^task-\d+$/.test(r))return null;let n=Oe(this.baseDir,"brain",e,".system_generated","tasks",`${r}.log`);try{let[s,i]=await Promise.all([Mc(n,"utf8"),Z(n)]);return{content:s,modifiedAt:i.modifiedAt}}catch{return null}}};async function Ag(t){let e=await Promise.all(t.map(r=>Z(r)));return{createdAt:new Date(Math.min(...e.map(r=>r.createdAt.getTime()))),modifiedAt:new Date(Math.max(...e.map(r=>r.modifiedAt.getTime())))}}function xg(t,e){if(!t)return e;let r=new Date(t);return Number.isNaN(r.getTime())?e:r}function Uc(t){return t.type==="USER_INPUT"}function $c(t){return t.source==="MODEL"&&t.type==="PLANNER_RESPONSE"}function Rg(t){return t.source==="MODEL"&&t.type!=="PLANNER_RESPONSE"}function jc(t){if(!t)return"";let e=/<USER_REQUEST>\n?([\s\S]*?)\n?<\/USER_REQUEST>/.exec(t);return e?e[1]:t}function Bc(t){if(!t)return;let e=/Model Selection` from [^\n]+? to ([^\n]+)/.exec(t);if(e)return e[1].replace(/\. No need\b[\s\S]*$/,"").replace(/\. If reporting\b[\s\S]*$/,"").replace(/\.\s*$/,"").trim()}function bg(t){if(t===void 0)return"";try{return JSON.stringify(t)}catch{return String(t)}}async function Ng(t){for await(let e of Q(t)){let r=e.tool_calls?.map(s=>s.args)??[];for(let s of r){let i=kg(s);if(i)return i}let n=Lg(e.content);if(n)return n}return null}function kg(t){if(!t||typeof t!="object"||Array.isArray(t))return null;let e=t,r=e.Cwd??e.cwd??e.DirectoryPath;return typeof r!="string"?null:r.replace(/^"|"$/g,"")}function Lg(t){return t?/"Cwd":"([^"]+)"/.exec(t)?.[1]??null:null}function Cg(t,e){if(t.status!=="RUNNING"||!t.content)return;let r=/task id:\s*([^/\s]+)\/(task-(\d+))\b/.exec(t.content);if(!(!r||r[1]!==e)&&!(t.step_index===void 0||Number(r[3])!==t.step_index))return r[2]}function Og(t,e){let r=new Set;for(let n of e){let s=Dg(t,r,n);if(!s)continue;r.add(s);let i=n.event.step_index===void 0?void 0:`agy-step-${n.event.step_index}`;s.message.toolCallId=i,s.message.backgroundTaskId=n.message.backgroundTaskId,n.message.toolName=s.name,n.message.toolCallId=i}}function Dg(t,e,r){let n=r.message.backgroundTaskId===void 0?void 0:Ug(r.event.content);if(n!==void 0)return Wc(t.filter(i=>!e.has(i)&&$g(i)===n),r.event.step_index);let s=Pg(r.event);if(s!==void 0)return Wc(t.filter(i=>!e.has(i)&&Mg(i.name,r.event.type)&&Xc(Fg(i))===s),r.event.step_index)}function Wc(t,e){if(t.length===0)return;if(t.length===1)return t[0];if(e===void 0)return;let r=t.map(n=>({call:n,distance:n.stepIndex===void 0?Number.POSITIVE_INFINITY:Math.abs(e-n.stepIndex)})).sort((n,s)=>n.distance-s.distance);return r[0].distance<r[1].distance?r[0].call:void 0}function Mg(t,e){return e==="VIEW_FILE"?t==="view_file":e!=="CODE_ACTION"?!1:t==="write_to_file"||t==="replace_file_content"||t==="multi_replace_file_content"}function Fg(t){let e=t.name==="view_file"?t.input?.AbsolutePath:t.input?.TargetFile;return typeof e=="string"?e:void 0}function Pg(t){if(!t.content)return;let e;return t.type==="VIEW_FILE"?e=/File Path:\s*`?([^`\n]+)`?/.exec(t.content)?.[1]:t.type==="CODE_ACTION"&&(e=/Created file\s+(.+?)\s+with requested content/.exec(t.content)?.[1]??/changes were made by .*? tool to:\s*(.+?)\.\s*(?:If relevant|$)/s.exec(t.content)?.[1]),Xc(e)}function Xc(t){if(!t)return;let e=t.trim().replace(/^`|`$/g,"");if(!e.startsWith("file://"))return e;try{return Ig(e)}catch{return}}function Ug(t){if(t)return/Task Description:\s*([^\n]+)/.exec(t)?.[1]?.trim()}function $g(t){if(t.name==="run_command"){let e=t.input?.CommandLine;return typeof e=="string"?e:void 0}if(t.name==="schedule"){let e=t.input?.DurationSeconds,r=t.input?.Prompt;return typeof e!="string"&&typeof e!="number"||typeof r!="string"?void 0:`Timer: ${e}s, Prompt: ${r}`}}function Hc(t){if(t.endsWith(".db"))return di(t,".db");let e="/brain/",r=t.indexOf(e);return r===-1?null:t.slice(r+e.length).split("/")[0]||null}import{spawn as jg}from"node:child_process";import{StringDecoder as qc}from"node:string_decoder";function Cn(t){return async(e,r)=>{let n=Date.now(),s=t.buildArgs(e,r);t.assertArgs?.(s,r),r.onProgress?.({kind:"system",summary:`${t.label} -p one-shot started (no streaming events)`});let{stdout:i}=await Bg(t.label,r.binary,s,{cwd:r.cwd,env:oe(r.env,r.cwd,r.sessionId),signal:r.signal});return r.onProgress?.({kind:"system",summary:`${t.label} -p one-shot completed`}),{text:i.trimEnd(),sessionId:r.sessionId,durationMs:Date.now()-n}}}function Bg(t,e,r,n){return new Promise((s,i)=>{if(n.signal?.aborted){i(new Error(`${t} turn aborted`));return}let o;try{o=jg(e,r,{cwd:n.cwd,env:n.env,stdio:["ignore","pipe","pipe"]})}catch(p){i(p);return}let a="",l="",c=new qc("utf8"),u=new qc("utf8");o.stdout?.on("data",p=>{a+=c.write(p)}),o.stderr?.on("data",p=>{l+=u.write(p)});let d=()=>{o.kill("SIGTERM"),i(new Error(`${t} turn aborted`))};o.on("error",p=>{n.signal?.removeEventListener("abort",d),i(p)}),o.on("close",(p,m)=>{if(n.signal?.removeEventListener("abort",d),a+=c.end(),l+=u.end(),p===0){s({stdout:a,stderr:l});return}let h=m?`signal ${m}`:`exit code ${p}`,g=l.trim()||a.trim();i(new Error(`${t} failed (${h})${g?`: ${g}`:""}`))}),n.signal?.aborted?d():n.signal?.addEventListener("abort",d,{once:!0})})}function mi(t){return new ui(t)}var ui=class extends G{constructor(e){super({provider:new Ln(e),capabilities:{canCreate:!0,canResumeInteractive:!0,canFork:!1,forkSupport:"manual",canStructuredTurn:!0,canStreamDeltas:!1,canCancel:!1},injection:{leaderMode:"prompt-append",leaderSetupHint:"Antigravity uses one-shot print turns; no streaming events are available."},binary:"agy",seedArgs:["-p",W,"--dangerously-skip-permissions","--print-timeout","2m"],resumeTemplate:"agy --conversation {{session_id}} --dangerously-skip-permissions",startTemplate:"agy --dangerously-skip-permissions",transport:Wg})}seedArgsFor(e){let r=[...super.seedArgsFor(e)];return e?.model&&r.push("--model",e.model),r}manualSeedHint(e){return{launchCommand:`cd ${e} && agy --dangerously-skip-permissions`,postLaunchNote:"Send the lmctl seed instruction, wait for the conversation to write, then exit.",lsCommand:`lmctl ls --provider agy --sessiondir ${e}`}}},Wg=Cn({label:"agy",buildArgs:(t,e)=>{let r=["--conversation",e.sessionId,"-p",t,"--dangerously-skip-permissions","--print-timeout",Hg(e.timeoutMs)];return e.model&&r.push("--model",e.model),r},assertArgs:(t,e)=>se("agy",t,e.permissionMode??"yolo")});function Hg(t){return!t||t<=0?"8h":`${Math.max(1,Math.ceil(t/1e3))}s`}import{randomUUID as d_}from"node:crypto";import{existsSync as Yc}from"node:fs";import{readFile as u_,mkdir as m_}from"node:fs/promises";import{readdir as fi,rm as r_,stat as n_}from"node:fs/promises";import{join as et}from"node:path";import Xg from"node:zlib";var qg=Xg.zstdDecompressSync,Gg=40,Jg=181,Vg=47,Kg=253,Yg=42,zg=77,Qg=24;function Zg(t,e){return t[e]===Gg&&t[e+1]===Jg&&t[e+2]===Vg&&t[e+3]===Kg}function Gc(t,e){return(t[e]&240)===80&&t[e+1]===Yg&&t[e+2]===zg&&t[e+3]===Qg}function e_(t,e){if(Gc(t,e))return e+8>t.length?void 0:8+t.readUInt32LE(e+4);if(!Zg(t,e))return;let r=e+4;if(r+1>t.length)return;let n=t[r];r+=1;let s=n>>6,i=(n&32)!==0,o=(n&4)!==0,a=n&3;i||(r+=1),r+=[0,1,2,4][a];let l=s===0?i?1:0:[2,4,8][s-1];if(r+=l,!(r>t.length)){for(;;){if(r+3>t.length)return;let c=t[r]|t[r+1]<<8|t[r+2]<<16,u=(c&1)!==0,d=c>>1&3,p=c>>3;if(r+=3,d===3||(r+=d===1?1:p,r>t.length))return;if(u)break}if(o&&(r+=4),!(r>t.length))return r-e}}function t_(t){let e=[],r=0;for(;r+4<=t.length;){let n=e_(t,r);if(n===void 0||n<=0)break;e.push(t.subarray(r,r+n)),r+=n}return e}function On(t){let e=[];for(let r of t_(t))Gc(r,0)||e.push(qg(r).toString("utf8"));return e.join("")}var Mn=class{name="dsh";sessionsDir;constructor(e={}){let r=e.dshHome||et(U,".dsh");this.sessionsDir=et(r,"sessions")}async discoverSessions(){let e=[],r;try{r=await fi(this.sessionsDir)}catch{return[]}for(let n of r){let s;try{s=await fi(et(this.sessionsDir,n))}catch{continue}for(let i of s)if(i.startsWith("session-"))try{let o=await this.readSummary(n,i);o&&e.push(o)}catch{}}return e}async loadSession(e){let r=await this.findSessionDir(e);if(!r)return null;let n=await this.readRecords(r.cwdDir,r.sessionDir);if(n.length===0)return null;let s=Jc(n),i=Vc(n,r.filePath,s);return i?{...i,turnStatus:o_(n),messages:s}:null}async resolveSessionPath(e){return(await this.findSessionDir(e))?.filePath??null}async deleteSession(e){let r=await this.findSessionDir(e);return r?(await r_(et(this.sessionsDir,r.cwdDir,r.sessionDir),{recursive:!0,force:!0}),!0):!1}sessionFilePath(e,r){return et(this.sessionsDir,s_(e),r,"session.jsonl.zstd")}async findSessionDir(e){let r;try{r=await fi(this.sessionsDir)}catch{return null}for(let n of r){let s=e,i=et(this.sessionsDir,n,s,"session.jsonl.zstd");try{return await n_(i),{cwdDir:n,sessionDir:s,filePath:i}}catch{}}return null}async readRecords(e,r){let{readFile:n}=await import("node:fs/promises"),s=et(this.sessionsDir,e,r,"session.jsonl.zstd"),i=await n(s),o=On(i),a=[];for(let l of o.split(`
|
|
1978
|
+
`))if(l.trim())try{let c=JSON.parse(l);if(c.type?.endsWith("-chunks")||c.type==="assistant/chunk")continue;a.push(c)}catch{}return a}async readSummary(e,r){let n=await this.readRecords(e,r);if(n.length===0)return null;let s=et(this.sessionsDir,e,r,"session.jsonl.zstd");return Vc(n,s,Jc(n))}};function s_(t){return"--"+t.replace(/^\/+|\/+$/g,"").replace(/\//g,"-")+"--"}function pi(t){if(typeof t=="string")return t;if(!Array.isArray(t))return"";let e=[];for(let r of t)r&&typeof r=="object"&&r.type==="text"&&typeof r.text=="string"&&e.push(r.text);return e.join("")}function i_(t){if(!Array.isArray(t))return[];let e=[];for(let r of t)r&&typeof r=="object"&&r.type==="reasoning"&&typeof r.text=="string"&&e.push(r.text);return e}function Jc(t){let e=[];for(let r of t){let n=r.data??{},s=r.time?new Date(r.time):new Date(0);if(r.type==="user/message"){let i=n;if(i.source?.kind!==void 0&&i.source.kind!=="user")continue;e.push({role:"user",timestamp:s,content:pi(i.content)})}else if(r.type==="assistant/message"){let i=n.message;for(let o of i_(i?.content))e.push({role:"thinking",timestamp:s,content:o});e.push({role:"assistant",timestamp:s,content:pi(i?.content),model:i?.source?.model})}else if(r.type==="tool/call"){let i=n,o;if(typeof i.arguments=="string")try{o=JSON.parse(i.arguments)}catch{}else i.arguments&&typeof i.arguments=="object"&&(o=i.arguments);e.push({role:"tool_use",timestamp:s,content:typeof i.arguments=="string"?i.arguments:JSON.stringify(i.arguments??{}),toolName:i.name,toolCallId:i.callId,toolInputData:o})}else if(r.type==="tool/result"){let i=n,a=(Array.isArray(i.message?.content)?i.message.content:[])[0];e.push({role:"tool_result",timestamp:s,content:pi(a?.content??i.message?.content),toolCallId:a?.toolCallId??i.message?.source?.callId})}}return e}function o_(t){for(let e=t.length-1;e>=0;e--){let r=t[e];if(r.type==="turn/end")return r.data?.reason?.kind==="completed"?"complete":"aborted";if(r.type==="turn/start")return"in_progress"}}function Vc(t,e,r){let n=t.find(m=>m.type==="session");if(!n)return null;let s=n,i=n.data,o=s.id??i?.id;if(!o)return null;let a;for(let m of t)if(m.type==="request/header"){let h=m.data?.header;h?.config?.model&&(a=h.config.model)}let l=t.map(m=>m.time).filter(m=>typeof m=="number"),c=s.createdAt??i?.createdAt,u=c?new Date(c):new Date(0),d=l.length>0?new Date(Math.max(...l)):u,p=r.filter(m=>m.role==="user");return{provider:"dsh",sessionId:o,cwd:s.cwd??i?.cwd??"",createdAt:u,modifiedAt:d,model:a,firstUserMessage:p[0]?.content,lastUserMessage:p.at(-1)?.content,messageCount:r.filter(m=>m.role==="user"||m.role==="assistant").length,filePath:e,...a_(t)}}function a_(t){let e=!1,r=0,n=0,s=0,i=0,o,a;for(let l of t){if(l.type!=="assistant/message")continue;let c=l.data?.usage;if(!c)continue;e=!0;let u=Dn(c.inputTokens),d=Dn(c.cacheReadTokens),p=Dn(c.outputTokens),m=Dn(c.reasoningTokens);r+=u,n+=d,s+=p,i+=m,o=u+d,a={inputTokens:u,cachedInputTokens:d,outputTokens:p,reasoningOutputTokens:m,totalTokens:u+d+p}}return{totalInputTokens:e?r:void 0,totalCachedInputTokens:e?n:void 0,totalOutputTokens:e?s:void 0,totalReasoningOutputTokens:e?i:void 0,lastInputTokens:o,lastTokenUsage:a}}function Dn(t){let e=Number(t??0);return Number.isFinite(e)?Math.max(0,Math.round(e)):0}import{spawn as l_}from"node:child_process";var c_=/dsh web:\s*(https?:\/\/\S+)/,Kc=2e4,Mt=class t extends Error{method;detail;constructor(e,r){super(`dsh RPC ${e} failed: ${JSON.stringify(r)}`),this.name="DshRpcCallError",this.method=e,this.detail=r,Object.setPrototypeOf(this,t.prototype)}},hi=class t{baseUrl;child;constructor(e,r){this.baseUrl=e,this.child=r}static forTesting(e){return new t(e,void 0)}async rpc(e,r){let n=`${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s;try{s=await fetch(`${this.baseUrl}/api/${e}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({type:"client-request",rpcId:n,method:e,payload:r})})}catch(a){throw new Mt(e,`transport error: ${a instanceof Error?a.message:String(a)}`)}let i;try{i=await s.json()}catch{i=void 0}if(!s.ok)throw new Mt(e,i??s.statusText);let o=i&&typeof i=="object"?i.result:void 0;if(!o||typeof o!="object"||typeof o.ok!="boolean")throw new Mt(e,"malformed response: HTTP 200 but body is not a well-formed {result:{ok,\u2026}} envelope");if(o.ok===!1)throw new Mt(e,o.error??o);return"value"in o?o.value:void 0}get alive(){return this.child!==void 0&&this.child.exitCode===null&&this.child.signalCode===null}shutdown(){this.child!==void 0&&this.alive&&this.child.kill("SIGTERM")}static spawn(e){return new Promise((r,n)=>{let s=l_("dsh",["web","--no-open","--port","0"],{env:e,stdio:["ignore","pipe","pipe"]}),i=!1,o="",a="",l=setTimeout(()=>{i||(i=!0,s.kill("SIGTERM"),n(new Error(`dsh web sidecar did not report a boot URL within ${Kc}ms (stdout: ${o.slice(0,500)}; stderr: ${a.slice(0,500)})`)))},Kc);s.stdout?.on("data",c=>{if(o+=c.toString(),i)return;let u=c_.exec(o);u&&(i=!0,clearTimeout(l),r(new t(u[1],s)))}),s.stderr?.on("data",c=>{a+=c.toString()}),s.on("error",c=>{i||(i=!0,clearTimeout(l),n(c))}),s.on("exit",(c,u)=>{if(i)return;i=!0,clearTimeout(l);let d=u?`signal ${u}`:`exit code ${c}`;n(new Error(`dsh web exited before reporting a boot URL (${d}): ${a.slice(0,500)}`))})})}},tt;async function Fn(t,e=r=>hi.spawn(r)){if(tt){let r=await tt.catch(()=>{});if(r?.alive)return r;tt=void 0}return tt=e(t),tt}async function hr(){if(!tt)return;(await tt.catch(()=>{}))?.shutdown(),tt=void 0}var f_=500,gi=8*60*60*1e3;function yi(t){return new Ei(t)}var Ei=class extends G{dshProvider;constructor(e){let r=new Mn(e);super({provider:r,capabilities:{canCreate:!0,canResumeInteractive:!1,canFork:!1,forkSupport:"manual",canStructuredTurn:!0,canStreamDeltas:!1,canCancel:!1},injection:{leaderMode:"prompt-append",leaderSetupHint:"dsh has no in-session leader-injection mechanism; the seed prompt carries lmctl's leader instructions."},binary:"dsh",seedArgs:[],resumeTemplate:"dsh web --no-open --port 0 # continuity is via the RPC sidecar, not a resume flag",startTemplate:"dsh web --no-open --port 0",transport:(n,s)=>this.dshPromptTurn(n,s)}),this.dshProvider=r}manualSeedHint(e){return{launchCommand:`cd ${e} && dsh web`,postLaunchNote:"dsh has no interactive terminal session to seed into \u2014 continuity lives in the web profile's session store, not a TTY. Boot the sidecar with the command above, open the printed http:// URL, and start a session rooted at this directory in the web UI; lmctl's managed sidecar can then cold-resume it by id (cross-profile session sharing is verified). Send lmctl's seed instruction there, wait for the reply, then find the new session id with the ls command below and register it manually.",lsCommand:`lmctl ls --provider dsh --sessiondir ${e}`}}async seed(e,r){await m_(e,{recursive:!0});let n=`session-${d_()}`,s=_i(process.env);se("dsh",[],"yolo");try{let i;try{i=await Fn(s)}catch(a){return{success:!1,error:`dsh sidecar failed to start: ${Pn(a)}`}}try{await i.rpc("session.create",{sessionId:n,cwd:e})}catch(a){return{success:!1,error:`session.create failed: ${Pn(a)}`}}if(r?.model)try{await i.rpc("session.selectModel",{sessionId:n,provider:"deepseek-official",model:r.model})}catch(a){return{success:!1,error:`session.selectModel("${r.model}") failed: ${Pn(a)}`}}let o=r?.prompt??W;try{await this.promptAndWait(i,e,n,o,gi)}catch(a){return{success:!1,error:`seed turn failed: ${Pn(a)}`}}return{success:!0,sessionId:n}}finally{await hr()}}async dshPromptTurn(e,r){let n=Date.now();if(r.bundleSession!==void 0){let o=r.bundleSession;if(o.provider!=="dsh")throw new Error(`bundle session provider mismatch: session serves "${o.provider}", turn targets "dsh"`);let a=await o.sendTurn(e,{signal:r.signal});return{text:a.text,sessionId:a.sessionId,durationMs:a.durationMs,...a.warnings!==void 0?{warnings:a.warnings}:{}}}let s=_i(r.env??process.env);se("dsh",[],r.permissionMode??"yolo");let i;try{let o=await Fn(s);r.model&&(await o.rpc("session.selectModel",{sessionId:r.sessionId,provider:"deepseek-official",model:r.model}),r.onProgress?.({kind:"system",summary:`dsh model set to ${r.model}`})),r.onProgress?.({kind:"system",summary:"dsh session.prompt sent"}),i=await this.promptAndWait(o,r.cwd,r.sessionId,e,r.timeoutMs&&r.timeoutMs>0?r.timeoutMs:gi)}finally{await hr()}return r.onProgress?.({kind:"system",summary:"dsh turn completed"}),{text:i,sessionId:r.sessionId,durationMs:Date.now()-n}}async openSession(e){let r=_i(e.env??process.env);se("dsh",[],e.permissionMode??"yolo");let n=await Fn(r),s=this.dshProvider.sessionFilePath(e.cwd,e.sessionId);if(!Yc(s))throw await hr(),new Error(`dsh bundle: session file does not exist for session "${e.sessionId}" (${s}) \u2014 the session must exist before a bundle can resume it`);e.model&&await n.rpc("session.selectModel",{sessionId:e.sessionId,provider:"deepseek-official",model:e.model});let i=e.sessionId,o=this,a=0,l=!1,c=null,u=!1,d=!1,p=async()=>{d||(d=!0,await hr())};return{provider:"dsh",sessionId:i,get completedTurns(){return a},async sendTurn(m,h={}){if(l||c!==null)throw new Error("dsh bundle session is closed");if(u)throw new Error("dsh bundle session has a turn still in flight");if(h.signal?.aborted)throw new Error("Aborted");if(!Yc(s))throw new Error(`dsh bundle: session file for session "${i}" disappeared mid-bundle \u2014 identity re-check failed (external re-seed?)`);u=!0;let g=Date.now();try{let y=o.promptAndWait(n,e.cwd,i,m,gi,h.signal);y.catch(()=>{});let f=await Promise.race([y,new Promise((T,E)=>{h.signal?.addEventListener("abort",()=>{(async()=>{l=!0,await p()})().finally(()=>E(new Error("Aborted")))},{once:!0})})]);return a+=1,{text:f,sessionId:i,durationMs:Date.now()-g}}finally{u=!1}},close(){return c!==null||(c=(async()=>{l=!0,await p()})()),c}}}async promptAndWait(e,r,n,s,i,o){let a=this.dshProvider.sessionFilePath(r,n),l=await h_(a);await e.rpc("session.prompt",{sessionId:n,mode:"queue",content:[{type:"text",text:s}]});let c=Date.now()+i;for(;;){if(o?.aborted)throw new Error("Aborted");let u=await zc(a),d=u.find(p=>p.type==="turn/end"&&(p.seq??-1)>l);if(d){let p=d.data?.reason,m=[...u].reverse().find(g=>g.type==="assistant/message"),h=m?g_(m):"";if(p?.kind!=="completed"&&!h)throw new Error(p_(p));return h}if(Date.now()>c)throw new Error(`dsh turn timed out after ${i}ms waiting for turn/end`);await new Promise(p=>setTimeout(p,f_))}}};function _i(t){return{...t,DSH_PERMISSION_MODE:t.DSH_PERMISSION_MODE??"danger-full-access"}}function p_(t){let e=t?.kind??"unknown",r=t?.error?.message;return r?`dsh turn ended with reason=${e}: ${r}`:`dsh turn ended with reason=${e} and no assistant text`}function Pn(t){return t instanceof Error?t.message:String(t)}async function h_(t){let e=await zc(t),r=-1;for(let n of e)n.type==="turn/end"&&typeof n.seq=="number"&&n.seq>r&&(r=n.seq);return r}async function zc(t){let e;try{e=await u_(t)}catch{return[]}let r=On(e),n=[];for(let s of r.split(`
|
|
1979
|
+
`))if(s.trim())try{let i=JSON.parse(s);i!==null&&typeof i=="object"&&!Array.isArray(i)&&n.push(i)}catch{}return n}function g_(t){let r=t.data?.message?.content;if(typeof r=="string")return r;if(!Array.isArray(r))return"";let n=[];for(let s of r)s&&typeof s=="object"&&s.type==="text"&&typeof s.text=="string"&&n.push(s.text);return n.join("")}import{mkdir as A_}from"node:fs/promises";import{existsSync as __}from"node:fs";import{join as rd,resolve as E_}from"node:path";import{createRequire as y_}from"node:module";var Ti=null;function T_(){return Ti===null&&(Ti=y_(import.meta.url)("node:sqlite").DatabaseSync),Ti}var Qc="acp";function Si(t={}){return E_(t.hermesHome?.trim()||process.env.HERMES_HOME?.trim()||rd(U,".hermes"))}function S_(t={}){return rd(Si(t),"state.db")}var Zc=`id, source, model, model_config, started_at,
|
|
1980
|
+
last_activity_at, message_count, input_tokens, output_tokens,
|
|
1981
|
+
cache_read_tokens, cache_write_tokens, reasoning_tokens, cwd, title`;function gr(t){let e=typeof t=="number"&&Number.isFinite(t)?t:0;return new Date(e*1e3)}function fe(t){return typeof t=="string"&&t.length>0?t:void 0}function w_(t){if(!t)return{};try{let e=JSON.parse(t);return e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{}}catch{return{}}}function ed(t){return fe(t.cwd)??fe(w_(t.model_config).cwd)??"(unknown)"}var Un=class{name="hermes";dbPath;busyTimeoutMs;discoverLimit;constructor(e){this.dbPath=S_(e),this.busyTimeoutMs=e?.busyTimeoutMs??5e3,this.discoverLimit=e?.discoverLimit??200}get stateDbPath(){return this.dbPath}openDb(){if(!__(this.dbPath))return null;let e=null;try{return e=new(T_())(this.dbPath,{open:!0,readOnly:!0}),e.exec(`PRAGMA busy_timeout = ${this.busyTimeoutMs}`),e}catch(r){return e?.close(),R({event:"hermes_store_unavailable",provider:this.name,db_path:this.dbPath,error_message:r instanceof Error?r.message:String(r)}),null}}selectSessionRow(e,r){return e.prepare(`SELECT ${Zc} FROM sessions WHERE id = ? AND source = ?`).get(r,Qc)??null}async discoverSessions(){let e=this.openDb();if(!e)return[];try{let r=e.prepare(`SELECT ${Zc} FROM sessions
|
|
1982
|
+
WHERE source = ?
|
|
1983
|
+
ORDER BY COALESCE(last_activity_at, started_at) DESC
|
|
1984
|
+
LIMIT ?`).all(Qc,this.discoverLimit),n=[];for(let s of r){let i=this.previewTexts(e,s.id);n.push({provider:this.name,sessionId:s.id,slug:fe(s.title),cwd:ed(s),createdAt:gr(s.started_at),modifiedAt:gr(s.last_activity_at??s.started_at),model:fe(s.model),startCommand:this.name,firstUserMessage:i.first,lastUserMessage:i.last,messageCount:s.message_count??0,filePath:this.dbPath,...td(s)})}return n}catch(r){return R({event:"hermes_discover_sessions_failed",provider:this.name,db_path:this.dbPath,error_message:r instanceof Error?r.message:String(r)}),[]}finally{e.close()}}activeMessageRows(e,r){let n=new Set(e.prepare("PRAGMA table_info(messages)").all().map(a=>a.name)),i=`id, session_id, role, content, tool_call_id, tool_calls, tool_name,
|
|
1985
|
+
timestamp, finish_reason${["_compressed_summary","display_kind"].filter(a=>n.has(a)).map(a=>`, ${a}`).join("")}`,o="WHERE session_id = ? AND role IN ('user', 'assistant', 'tool')";try{return e.prepare(`SELECT ${i} FROM messages ${o} AND active = 1 ORDER BY id ASC`).all(r)}catch(a){if(!/no such column/i.test(a instanceof Error?a.message:String(a)))throw a;return e.prepare(`SELECT ${i} FROM messages ${o} ORDER BY id ASC`).all(r)}}previewTexts(e,r){try{let[n,s]=["ASC","DESC"].map(i=>{let o=`SELECT content FROM messages WHERE session_id = ?
|
|
1986
|
+
AND role = 'user' AND content != ''`,a;try{a=e.prepare(`${o} AND active = 1 ORDER BY id ${i} LIMIT 1`).get(r)}catch(l){if(!/no such column: active/i.test(String(l)))throw l;a=e.prepare(`${o} ORDER BY id ${i} LIMIT 1`).get(r)}return a?D(a.content,80):void 0});return{first:n,last:s}}catch{return{}}}async loadSession(e){let r=this.openDb();if(!r)return null;try{let n=this.selectSessionRow(r,e);if(!n)return null;let s=this.activeMessageRows(r,e),i=[],o=[],a,l;for(let c of s){let u=gr(c.timestamp),d=c.content??"";if(c.role==="user"){d&&c._compressed_summary!==1&&c.display_kind!=="hidden"&&o.push(d),d.length>0&&(a||(a=D(d,80)),l=D(d,80)),i.push({role:"user",timestamp:u,content:d||"(empty)"});continue}if(c.role==="tool"){i.push({role:"tool_result",timestamp:u,content:d,toolCallId:fe(c.tool_call_id),toolName:fe(c.tool_name)});continue}d.length>0&&i.push({role:"assistant",timestamp:u,content:d,model:fe(n.model),stopReason:fe(c.finish_reason)});for(let p of v_(c.tool_calls)){let m=I_(p.function?.arguments);i.push({role:"tool_use",timestamp:u,content:fe(p.function?.name)??"tool_call",toolName:fe(p.function?.name),toolCallId:fe(p.call_id)??fe(p.id),toolInput:typeof p.function?.arguments=="string"?p.function.arguments:JSON.stringify(p.function?.arguments??{}),toolInputData:ve(m)})}}return{provider:this.name,sessionId:n.id,slug:fe(n.title),cwd:ed(n),createdAt:gr(n.started_at),modifiedAt:gr(n.last_activity_at??n.started_at),model:fe(n.model),startCommand:this.name,firstUserMessage:a,lastUserMessage:l,messageCount:n.message_count??i.length,filePath:this.dbPath,...td(n),messages:i,userPrompts:o}}catch(n){return R({event:"hermes_load_session_failed",provider:this.name,session_id:e,db_path:this.dbPath,error_message:n instanceof Error?n.message:String(n)}),null}finally{r.close()}}async resolveSessionPath(e){let r=this.openDb();if(!r)return null;try{return this.selectSessionRow(r,e)?this.dbPath:null}catch{return null}finally{r.close()}}async deleteSession(e){return!1}};function v_(t){if(!t)return[];try{let e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}function I_(t){if(t!==null&&typeof t=="object"&&!Array.isArray(t))return t;if(typeof t!="string")return{};try{let e=JSON.parse(t);return e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{}}catch{return{}}}function td(t){let e=t.input_tokens??0,r=t.output_tokens??0,n=t.cache_read_tokens??0,s=t.cache_write_tokens??0,i=t.reasoning_tokens??0;return(t.message_count??0)>0&&e+r+n+s+i>0?{totalInputTokens:e,totalCachedInputTokens:n,totalCacheWriteInputTokens:s,totalOutputTokens:r,totalReasoningOutputTokens:i}:{}}var x_=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function R_(t){return x_.test(t)}var b_="dont_ask";function nd(t){if(t==="plan")throw new Error(`provider "hermes" does not support --permission-mode plan: Hermes's ACP mode ladder (default/accept_edits/dont_ask) governs file edits only and has no plan-equivalent, so lmctl refuses rather than silently running the member with edit auto-approval.`);return b_}function vi(t){return new wi(t)}var wi=class extends G{hermesProvider;hermesHome;constructor(e){let r=new Un(e);super({provider:r,capabilities:{canCreate:!0,canResumeInteractive:!1,canFork:!1,forkSupport:"manual",canStructuredTurn:!0,canStreamDeltas:!0,canCancel:!0},injection:{leaderMode:"prompt-append",leaderSetupHint:"Hermes has no provider-side leader-injection mechanism; the seed prompt carries lmctl's leader instructions."},binary:"hermes",seedArgs:[],resumeTemplate:"hermes --yolo --resume {{session_id}}",startTemplate:"hermes",transport:async(n,s)=>Le(n,{...s,requireResume:s.requireResume??!!s.sessionId,env:{...s.env??process.env,HERMES_HOME:this.hermesHome},acpTool:"hermes",acpMode:nd(s.permissionMode)})}),this.hermesProvider=r,this.hermesHome=Si(e)}async openSession(e){return Ce({...e,env:{...e.env??process.env,HERMES_HOME:this.hermesHome},binary:"hermes",acpTool:"hermes",acpMode:nd(e.permissionMode)})}get stateDbPath(){return this.hermesProvider.stateDbPath}async seed(e,r){await A_(e,{recursive:!0});let n=[];if(r?.effort){let i="hermes has no ACP-level effort surface";R({event:"hermes_effort_ignored",provider:this.name,effort:r.effort,reason:i}),n.push(`hermes seed ignored effort=${r.effort}: ${i}`)}let s;try{s=await this.sendTurn(r?.prompt??W,{sessionId:"",cwd:e,model:r?.model})}catch(i){return{success:!1,error:`hermes ACP seed failed: ${i instanceof Error?i.message:String(i)}`}}return R_(s.sessionId)?(n.push(...s.warnings??[]),{success:!0,sessionId:s.sessionId,...n.length>0?{warnings:n}:{}}):(R({event:"hermes_seed_contract_violation",provider:this.name,session_id:s.sessionId,reason:"session/new did not return a UUID session id"}),{success:!1,error:`hermes ACP session/new did not return a UUID session id (got ${JSON.stringify(s.sessionId)})`})}};import{readdir as sd,rm as N_,stat as k_}from"node:fs/promises";import{join as Ii}from"node:path";var $n=class{name="pi";baseDir;constructor(e={}){this.baseDir=e.piDir||Ii(U,".pi","agent","sessions")}getWatchPaths(){return[{directory:this.baseDir,filePattern:/\.jsonl$/}]}async discoverSessions(){let e=[];for(let r of await this.listSessionFiles())try{let n=await this.extractSummary(r);n&&e.push(n)}catch{}return e}async listSessionFiles(){let e;try{e=await sd(this.baseDir)}catch{return[]}let r=[];for(let n of e){let s=Ii(this.baseDir,n);try{if(!(await k_(s)).isDirectory())continue;for(let i of await sd(s))i.endsWith(".jsonl")&&r.push(Ii(s,i))}catch{}}return r}async readHeader(e){for await(let r of Q(e))return r.type==="session"?r:null;return null}async extractSummary(e){let r=await this.readHeader(e);if(!r)return null;let n=await Z(e),s,i,o,a=0,l=0,c=0,u=0,d=0,p=0,m=0,h;for await(let g of Q(e)){if(g.type==="model_change"&&g.provider&&g.modelId){s=`${g.provider}/${g.modelId}`;continue}if(g.type!=="message"||!g.message)continue;let y=g.message;if(y.provider&&y.model&&(s=`${y.provider}/${y.model}`),y.role==="user"){let f=Ai(y).trim();f&&(i||(i=D(f,80)),o=D(f,80)),a++}else if(y.role==="assistant"){a++;let f=y.usage;f&&(l+=f.input??0,c+=f.cacheRead??0,u+=f.cacheWrite??0,d+=f.output??0,p+=f.reasoning??0,m=f.input??0,h={inputTokens:f.input,cachedInputTokens:f.cacheRead,cacheWriteInputTokens:f.cacheWrite,outputTokens:f.output,reasoningOutputTokens:f.reasoning,totalTokens:f.totalTokens})}}return{provider:"pi",sessionId:r.id,cwd:r.cwd??"(unknown)",createdAt:n.createdAt,modifiedAt:n.modifiedAt,model:s,startCommand:"pi",firstUserMessage:i,lastUserMessage:o,messageCount:a,filePath:e,totalInputTokens:l,totalCachedInputTokens:c,totalCacheWriteInputTokens:u,totalOutputTokens:d,totalReasoningOutputTokens:p,lastInputTokens:m,lastTokenUsage:h}}async loadSession(e){let r=await this.resolveSessionPath(e);if(!r)return null;let n=await this.extractSummary(r);if(!n)return null;let s=[],i=n.model;for await(let o of Q(r)){if(o.type==="model_change"&&o.provider&&o.modelId){i=`${o.provider}/${o.modelId}`;continue}if(o.type!=="message"||!o.message)continue;let a=o.message;a.provider&&a.model&&(i=`${a.provider}/${a.model}`);let l=a.timestamp?new Date(a.timestamp):n.modifiedAt;if(a.role==="user")s.push({role:"user",timestamp:l,content:Ai(a)});else if(a.role==="assistant"&&Array.isArray(a.content))for(let c of a.content)c.type==="text"&&c.text?s.push({role:"assistant",timestamp:l,content:c.text,model:i}):c.type==="thinking"&&c.thinking?s.push({role:"thinking",timestamp:l,content:c.thinking}):c.type==="toolCall"&&s.push({role:"tool_use",timestamp:l,content:id(c.arguments),toolName:c.name??"tool",toolInput:id(c.arguments),toolInputData:c.arguments,toolCallId:c.id});else a.role==="toolResult"&&s.push({role:"tool_result",timestamp:l,content:Ai(a),toolName:a.toolName,toolCallId:a.toolCallId})}return{...n,model:i,messages:s}}async resolveSessionPath(e){let r=`_${e}.jsonl`,n=[];for(let s of await this.listSessionFiles()){if(s.endsWith(r))return s;s.split("_").pop()?.replace(/\.jsonl$/,"")?.startsWith(e)&&n.push(s)}return n.length===1?n[0]:null}async deleteSession(e){let r=await this.resolveSessionPath(e);return r?(await N_(r,{force:!0}),!0):!1}};function Ai(t){return typeof t.content=="string"?t.content:Array.isArray(t.content)?t.content.filter(e=>e.type==="text"&&e.text).map(e=>e.text).join(" "):""}function id(t){if(t===void 0)return"";try{return JSON.stringify(t)}catch{return String(t)}}function Ri(t){return new xi(t)}var xi=class extends G{constructor(e){super({provider:new $n(e),capabilities:{canCreate:!0,canResumeInteractive:!0,canFork:!1,forkSupport:"manual",canStructuredTurn:!0,canStreamDeltas:!1,canCancel:!1},injection:{leaderMode:"prompt-append",leaderSetupHint:"pi uses one-shot print turns; no streaming events are available."},binary:"pi",seedArgs:["-p",W],resumeTemplate:"pi --session {{session_id}}",startTemplate:"pi",transport:L_})}seedArgsFor(e){let r=[...super.seedArgsFor(e)];return e?.model&&r.push("--model",e.model),r}manualSeedHint(e){return{launchCommand:`cd ${e} && pi`,postLaunchNote:"Send the lmctl seed instruction, wait for the session file to write, then exit.",lsCommand:`lmctl ls --provider pi --sessiondir ${e}`}}},L_=Cn({label:"pi",buildArgs:(t,e)=>{let r=["--session",e.sessionId,"-p",t];return e.model&&r.push("--model",e.model),r},assertArgs:(t,e)=>se("pi",t,e.permissionMode??"yolo")});import{createHash as C_}from"node:crypto";import{existsSync as O_,mkdirSync as Ni,readFileSync as D_,renameSync as M_,rmdirSync as fd,statSync as F_,writeFileSync as P_}from"node:fs";import{dirname as Oi,join as od,resolve as bi}from"node:path";var Ft=new Map;function U_(t){return C_("sha256").update(t).digest("hex").slice(0,8)}function $_(t){let e=t.trim().toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"");return e.length>0?e:"session"}function j_(t,e){let r=e?.prompt??"",n=/\bYou are alias\s+([A-Za-z][A-Za-z0-9_-]*)\b/.exec(r);return n!==null?n[1]:t.split(/[\\/]/).filter(Boolean).pop()??"session"}function pd(t){return t.split(/\r?\n/,1)[0]?.trim()||"(empty prompt)"}function jn(t){return Math.max(1,Math.ceil(t.length/4))}function Pt(t=process.cwd()){let e=process.env.LMCTL_CLAUDE_MOCK_STORE;if(e!==void 0&&e.trim().length>0)return bi(e);let r=process.env.LMCTL_DB;return r!==void 0&&r.trim().length>0?od(Oi(bi(r)),".lmctl-claude-mock","sessions.json"):od(bi(t),".lmctl-claude-mock","sessions.json")}function ad(){return{schemaVersion:1,sessions:{}}}function _r(t){if(!O_(t))return ad();try{let e=JSON.parse(D_(t,"utf8")),r=typeof e.sessions=="object"&&e.sessions!==null?e.sessions:{},n=typeof e.script=="object"&&e.script!==null?e.script:void 0,s=typeof e.scriptContains=="object"&&e.scriptContains!==null?e.scriptContains:void 0,i=ki(e.defaultDelayMs);return{schemaVersion:1,sessions:r,...i!==void 0?{defaultDelayMs:i}:{},...n!==void 0?{script:n}:{},...s!==void 0?{scriptContains:s}:{}}}catch{return ad()}}function hd(t,e){Ni(Oi(t),{recursive:!0});let r=`${t}.${process.pid}.${Date.now()}.tmp`;P_(r,`${JSON.stringify(e,null,2)}
|
|
1987
|
+
`,"utf8"),M_(r,t)}var B_=5e3,W_=15,ld=1e4;function H_(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}function X_(t){let e=`${t}.lock`;Ni(Oi(t),{recursive:!0});let r=Date.now()+ld;for(;;)try{return Ni(e),e}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-F_(e).mtimeMs>B_){try{fd(e)}catch{}continue}}catch{continue}if(Date.now()>=r)throw new Error(`ClaudeMock store lock timeout after ${ld}ms: ${e}`);H_(W_)}}function q_(t){try{fd(t)}catch{}}function gd(t,e){let r=X_(t);try{return e()}finally{q_(r)}}function G_(t){return{...t,timestamp:t.timestamp.toISOString()}}function J_(t){return{...t,timestamp:new Date(t.timestamp)}}function V_(t){return{...t,createdAt:t.createdAt.toISOString(),modifiedAt:t.modifiedAt.toISOString(),messages:t.messages.map(G_)}}function _d(t){return{...t,createdAt:new Date(t.createdAt),modifiedAt:new Date(t.modifiedAt),messages:t.messages.map(J_)}}function Bn(t,e=process.cwd()){let r=Ft.get(t);if(r!==void 0)return r;let s=_r(Pt(e)).sessions[t];if(s===void 0)return;let i=_d(s);return Ft.set(i.sessionId,i),i}function cd(t){Ft.set(t.sessionId,t);let e=Pt(t.cwd);gd(e,()=>{let r=_r(e);r.sessions[t.sessionId]=V_({...t,filePath:e}),hd(e,r)})}function K_(t,e=process.cwd()){let r=Pt(e);return gd(r,()=>{let n=_r(r),s=n.sessions[t]!==void 0;return s&&(delete n.sessions[t],hd(r,n)),s})}function Y_(){let t=_r(Pt()),e=Object.values(t.sessions).map(_d);for(let r of e)Ft.set(r.sessionId,r);return e}function ki(t){return typeof t=="number"&&Number.isFinite(t)&&t>=0?t:void 0}function dd(t){if(typeof t=="string")return{kind:"success",text:t};if(t!==void 0&&typeof t.text=="string"&&typeof t.error!="string"){let e=ki(t.delayMs);return{kind:"success",text:t.text,...e!==void 0?{delayMs:e}:{}}}if(t!==void 0&&typeof t.error=="string"&&typeof t.text!="string"){let e=ki(t.delayMs);return{kind:"error",error:t.error,...e!==void 0?{delayMs:e}:{}}}}async function ud(t){t!==void 0&&t>0&&await new Promise(e=>setTimeout(e,t))}function z_(t,e){let{script:r,scriptContains:n}=e;if(r!==void 0){let s=dd(r[t]??r[pd(t)]);if(s!==void 0)return s}if(n!==void 0){for(let s of Object.keys(n))if(t.includes(s)){let i=dd(n[s]);if(i!==void 0)return i}}}function md(t){return{provider:"ClaudeMock",sessionId:t.sessionId,cwd:t.cwd,createdAt:t.createdAt,modifiedAt:t.modifiedAt,messageCount:t.messages.length,filePath:t.filePath,cliVersion:"ClaudeMock/0",model:"claude-mock",totalInputTokens:t.totalInputTokens,totalOutputTokens:t.totalOutputTokens,lastTokenUsage:{totalTokens:t.totalInputTokens+t.totalOutputTokens}}}var Li=class{name="ClaudeMock";async discoverSessions(){let e=new Map;for(let r of Y_())e.set(r.sessionId,r);for(let r of Ft.values())e.set(r.sessionId,r);return[...e.values()].map(md)}async loadSession(e){let r=Bn(e);return r===void 0?null:{...md(r),messages:r.messages.slice()}}async resolveSessionPath(e){return Bn(e)?.filePath??null}async deleteSession(e){let r=Ft.delete(e),n=K_(e);return r||n}},Ci=class{name="ClaudeMock";capabilities={canCreate:!0,canResumeInteractive:!1,canFork:!1,forkSupport:"manual",canStructuredTurn:!0,canStreamDeltas:!1,canCancel:!1};injection={leaderMode:"none"};provider=new Li;discover(){return this.provider.discoverSessions()}load(e){return this.provider.loadSession(e)}resolvePath(e){return this.provider.resolveSessionPath(e)}delete(e){return this.provider.deleteSession(e)}getWatchPaths(){return[]}async seed(e,r){let n=$_(j_(e,r)),s=`mock-${n}-${U_(`${e}:${n}`)}`,i=new Date,o=Pt(e),a=Bn(s,e),l=r?.prompt??"ClaudeMock seed",c=jn(l),u={sessionId:s,cwd:e,filePath:o,createdAt:a?.createdAt??i,modifiedAt:i,messages:a?.messages.slice()??[],totalInputTokens:a?.totalInputTokens??0,totalOutputTokens:a?.totalOutputTokens??0};return u.messages.push({role:"user",timestamp:i,content:l}),u.messages.push({role:"assistant",timestamp:i,content:"ACK: ClaudeMock seeded"}),u.totalInputTokens+=c,u.totalOutputTokens+=jn("ACK: ClaudeMock seeded"),cd(u),{success:!0,sessionId:s}}resumeCommand(e){return`ClaudeMock --resume ${e}`}startCommand(){return"ClaudeMock"}manualSeedHint(e){return{launchCommand:`cd ${e} && ClaudeMock`,postLaunchNote:"ClaudeMock is a hermetic test provider; no manual seed is required.",lsCommand:`lmctl ls --provider ClaudeMock --sessiondir ${e}`}}forkHint(e){return"ClaudeMock does not support fork."}async fork(e,r){return{success:!1,error:"ClaudeMock does not support fork."}}async sendTurn(e,r){let n=Date.now(),s=Bn(r.sessionId,r.cwd);if(s===void 0)throw new Error(`ClaudeMock session not found: ${r.sessionId}`);let i=new Date,o=_r(Pt(r.cwd)),a=z_(e,o),l=a?.delayMs??o.defaultDelayMs;if(a?.kind==="error")throw await ud(l),new Error(a.error);let c=a?.kind==="success"?a.text:`ClaudeMock ack: ${pd(e)}`;return s.messages.push({role:"user",timestamp:i,content:e}),s.messages.push({role:"assistant",timestamp:i,content:c,model:r.model??"claude-mock"}),s.modifiedAt=i,s.totalInputTokens+=jn(e),s.totalOutputTokens+=jn(c),cd(s),r.onProgress?.({kind:"text",summary:"ClaudeMock deterministic reply"}),await ud(l),{text:c,sessionId:r.sessionId,durationMs:Math.max(1,Date.now()-n),stopReason:"mock_stop",numTurns:1,status:"ok"}}};function Di(){return new Ci}function ht(t){let e=[Hs({claudeDir:t?.claudeDir}),Gs({codexDir:t?.codexDir,codeDir:t?.codeDir}),Ys({geminiDir:t?.geminiDir,claudeDir:t?.claudeDir,codexDir:t?.codexDir,codeDir:t?.codeDir}),Zs({copilotDir:t?.copilotDir}),ti(),ii({kimiHome:t?.kimiHome}),ai({lmplayerDbPath:t?.lmplayerDbPath}),ci(),mi({agyDir:t?.agyDir}),yi({dshHome:t?.dshHome}),vi({hermesHome:t?.hermesHome}),Ri({piDir:t?.piDir})];return process.env.LMCTL_ENABLE_MOCK_PROVIDER==="1"&&e.push(Di()),e}var Mi=["claude","qwen","codex","dsh","gemini","copilot","opencode","kimi","hermes"],Fi=["agy","pi","lmplayer"];var Pi=null;function Wn(){return Pi===null&&(Pi=dt(ht())),Pi}function Ui(t,e){let r=t.getAdapter(e);if(!r)throw new Error(`provider "${e}" is not registered in this registry`);return r}async function Hn(t){let e=t.registry??Wn(),r=Ui(e,t.provider),n={sessionId:t.sessionId,cwd:t.cwd,env:t.env,onDelta:t.onDelta,onProgress:t.onProgress,signal:t.signal,timeoutMs:t.timeoutMs,model:t.model,effort:t.effort,progPath:t.progPath,alias:t.alias,isLead:t.isLead,permissionMode:t.permissionMode,holdOpen:t.holdOpen,requireResume:t.requireResume,bundleSession:t.bundleSession},s=await r.sendTurn(t.prompt,n);return{text:s.text,sessionId:s.sessionId,durationMs:s.durationMs,stopReason:s.stopReason,numTurns:s.numTurns,status:s.status,stalledAfterMs:s.stalledAfterMs,...s.warnings!==void 0?{warnings:s.warnings}:{}}}function $i(t){return(t??Wn()).getAllAdapters().filter(r=>r.openSession!==void 0).map(r=>r.name)}async function yd(t){let e=t.registry??Wn(),r=Ui(e,t.provider);if(r.openSession===void 0)throw new Error(`provider "${t.provider}" does not support bundle sessions in this version (supported: ${$i(e).join(", ")})`);return r.openSession(t)}async function Td(t){let e=t.registry??Wn(),r=Ui(e,t.provider),n=await Ed(e,t.provider,t.cwd),s=await r.seed(t.cwd,{model:t.model,effort:t.effort,prompt:t.prompt}),i=s.warnings!==void 0&&s.warnings.length>0?{warnings:s.warnings}:{};if(!s.success)return{success:!1,error:s.error,...i};if(s.sessionId)return{success:!0,sessionId:s.sessionId,...i};let o=await Ed(e,t.provider,t.cwd),a=Q_(n,o);return a?{success:!0,sessionId:a,...i}:{success:!0,...i}}async function Ed(t,e,r){let n=await t.listAll({provider:e,workspace:r}),s=new Map;for(let i of n)s.set(i.sessionId,i.modifiedAt);return s}function Q_(t,e){let r=[];for(let n of e.keys())t.has(n)||r.push(n);return r.length===1?r[0]:void 0}var Z_={claude:["--dangerously-skip-permissions"],codex:["--dangerously-bypass-approvals-and-sandbox"],gemini:["-y"],copilot:["--yolo"],opencode:[],qwen:["--approval-mode","yolo"],agy:[],pi:[],lmplayer:["--auto"],kimi:[],hermes:[]};var Yx=new Set(Object.keys(Z_));var ji=null;function Sd(){return ji===null&&(ji=dt(ht())),ji}function wd(t,e){return Sd().getSession(t,e)}async function vd(t){return(await Sd().resolveSessions(t)).map(r=>r.provider.name)}var Id=36e5;function eE(t=process.env){let e=t.LMCTL_SESSION_IDLE_TIMEOUT_MS;if(e===void 0||e.trim()==="")return Id;let r=Number(e);return!Number.isFinite(r)||r<=0?Id:r}async function tE(t,e,r){try{let n=st(e,r,t),s=n.sessionid;if(typeof s!="string"||s.trim()===""||s===".")return null;let i;if(typeof n.provider=="string"&&n.provider.trim()!=="")i=n.provider;else{let c=await vd(s);if(c.length!==1)return null;i=c[0]}let o=await wd(s,i);if(o===null)return null;let a=o.modifiedAt;if(!(a instanceof Date))return null;let l=a.getTime();return Number.isFinite(l)?Date.now()-l:null}catch{return null}}async function Ad(t,e,r,n,s){if(!e.busy||e.reason!=="in-flight")return!1;let i=s??eE(),o=await tE(t,r,n),a=o!==null&&o>=i;return a&&R({event:"session_idle_reclaim",receiver_teamfile:r,receiver_alias:n,idle_ms:o,idle_minutes:o===null?null:Math.round(o/6e4),threshold_ms:i,reason:"in-flight holder idle past session-idle threshold; lease will be force-reclaimed"}),a}var xd=eo(As(),1);function rE(t){return t===null?null:_e(t)?"live":"dead"}function Bi(t){let e=t.nowMs??Date.now(),r=Date.parse(t.since);return{holder_pid:t.holderPid,holder_liveness:rE(t.holderPid),since:t.since,idle_ms:Number.isFinite(r)?Math.max(0,e-r):null}}function nE(t){return(0,xd.formatDuration)(t)}function Wi(t){let e=[];return t.idle_ms!==null&&e.push(`active ${nE(t.idle_ms)}`),e.push(`since ${t.since}`),e.push(t.holder_pid===null?"holder_pid=unavailable":`holder_pid=${t.holder_pid}, ${t.holder_liveness}`),`(${e.join("; ")})`}import{hostname as sE,networkInterfaces as iR}from"node:os";var iE=12e4;function oE(t=process.env){return aE(t.LMCTL_TERMINAL_LOCK_STALE_MS,iE)}function Hi(t,e={}){let r=e.now??new Date,n=e.localHost??sE(),s=e.staleMs??oE();if(t.holder_host===n)return(e.isProcessAlive??lE)(t.holder_pid)?{live:!0,reason:"local-pid-alive"}:{live:!1,reason:"dead-pid"};let i=Date.parse(t.last_heartbeat);return Number.isFinite(i)?r.getTime()-i<=s?{live:!0,reason:"remote-heartbeat-fresh"}:{live:!1,reason:"stale-heartbeat"}:{live:!1,reason:"stale-heartbeat"}}function Er(t){return`${t.alias} is held by a terminal on ${t.holder_host} since ${t.started_at}; retry later`}function aE(t,e){if(t===void 0||t.trim()==="")return e;let r=t.trim(),n=Number.parseInt(r,10);return!Number.isFinite(n)||n<=0||String(n)!==r?e:n}function lE(t){if(!Number.isInteger(t)||t<=0)return!1;try{return process.kill(t,0),!0}catch(e){return(e!==null&&typeof e=="object"&&"code"in e?e.code:void 0)!=="ESRCH"}}function Xn(t){return`lmctl ${t}: LMCTL_SELF_SESSIONID is set but does not match any member of a registered team.
|
|
1988
|
+
The session marker may be stale or the team may not be registered in this lmctl database.
|
|
1989
|
+
Consulted ${qa(Pe())}
|
|
1990
|
+
To experiment with it manually: https://lmctl.com/lmctl/docs/manual-invocation`}function qn(t,e){let r=cE(t,e);return r.ok?{ok:!0,identity:r.identity,source:"session"}:r}function cE(t,e){let r=t[bs];if(r===void 0||r.length===0)return{ok:!1,reason:"unset"};let n=[];for(let i of e.listRootTeams()){let o;try{o=Tt(i.teamfile_path,e)}catch{continue}for(let a of o.members)a.teamfile===void 0&&a.session===r&&n.push(`${i.teamfile_path}:${a.alias}`)}let s=[...new Set(n)];if(s.length===0)return{ok:!1,reason:"not-found"};if(s.length>1)throw new Error("LMCTL_SELF_SESSIONID matches multiple team members; the team registry is ambiguous");return{ok:!0,identity:s[0]}}function Gn(t){let e=as(t);if(e===null)throw new Error(`invalid agent identity: ${t}`);return{teamfile:e.teamfile,alias:e.alias,value:t}}var yR=60*60*1e3,dE=2e3,uE=5e3;function Xi(t,e,r){let n=`${e.teamfile}:${e.alias}`,s=null,i=()=>t.dal!==void 0?t.dal:(s===null&&(s=lt({path:Pe()})),s),o=()=>{if(s===null)return;let a=s;s=null;try{a.close()}catch{}};return{hasOutstandingWork:()=>i().listAgentInflight().some(a=>a.sender_teamfile===e.teamfile&&a.sender_alias===e.alias&&!(a.receiver_teamfile===e.teamfile&&a.receiver_alias===e.alias)&&a.holder_pid!==null&&_e(a.holder_pid)),pollMs:dE,settleMs:uE,maxHoldMs:At(r),onHold:()=>R({event:"delivery_hold_open_started",receiver:n}),onRelease:a=>{o(),!(!a.held&&a.reason==="cleared")&&R({event:"delivery_hold_open_released",receiver:n,elapsed_ms:a.elapsedMs,held:a.held,reason:a.reason})}}}async function Rd(t){let e=mE(t.newMessage,{newMessageFrom:t.newMessageFrom??fE(t.sender)});if(e.length===0)throw new Error(`no message to deliver for ${t.sender.teamfile}:${t.sender.alias} -> ${t.receiver.teamfile}:${t.receiver.alias}`);let r=!1,n=K(),s=0,i=0,o=0,a={provider:t.receiver.provider,sessionId:t.receiver.sessionId,cwd:t.receiver.cwd,prompt:e,permissionMode:t.permissionMode,env:t.env,onDelta:c=>{r=!0,n&&(s+=1,o=Buffer.byteLength(c,"utf8"),i+=o),t.onDelta?.(c)},onProgress:c=>t.onProgress?.(c)};t.receiver.model!==void 0&&(a.model=t.receiver.model),t.receiver.effort!==void 0&&(a.effort=t.receiver.effort),a.alias=t.receiver.alias,a.isLead=t.receiver.isLead,t.idleTimeoutMs!==void 0&&(a.timeoutMs=t.idleTimeoutMs),t.requireResume!==void 0&&(a.requireResume=t.requireResume),t.bundleSession!==void 0&&(a.bundleSession=t.bundleSession),a.holdOpen=Xi(t.io,t.receiver,t.env),await t.onPromptBuilt?.(e);let l=await Hn(a);if(t.requireResume&&l.sessionId!==t.receiver.sessionId)throw new Error(`provider session changed: expected ${t.receiver.sessionId}, received ${l.sessionId??"(missing)"}`);return n&&ge(JSON.stringify({event:"chat_return",alias:t.receiver.alias,provider:t.receiver.provider,streamed:r,blockCount:s,streamedBytes:i,resultTextBytes:Buffer.byteLength(l.text,"utf8"),lastChunkBytes:o,tailPreview:l.text.slice(-200)})),l.status==="stalled"?{status:"stalled",receipt:l.text,prompt:e,wroteDelta:r,durationMs:l.durationMs,stalledAfterMs:l.stalledAfterMs,...l.warnings!==void 0?{warnings:l.warnings}:{}}:{status:"ok",receipt:l.text,prompt:e,wroteDelta:r,durationMs:l.durationMs,...l.warnings!==void 0?{warnings:l.warnings}:{}}}function mE(t,e={}){return[`--- new prompt (from ${e.newMessageFrom??"operator"}) ---`,t].join(`
|
|
1991
|
+
`)}function fE(t){return`${t.teamfile}:${t.alias}`}var bd=256*1024,Ld=3e4;async function Gi(t){let e=t.onEvent??(()=>{}),r=pE(t.io,e),n=null,s=null,i=null,o,a,l=null,c=!1,u=null,d=t.prompt;try{let p=await $(r,k=>st(t.teamfile,t.alias,k));if(t.expectedSession!==void 0&&(p.provider!==t.expectedSession.provider||p.sessionid!==t.expectedSession.sessionid))throw new Te(`session changed for ${p.alias}; expected ${t.expectedSession.provider}:${t.expectedSession.sessionid}, found ${p.provider}:${p.sessionid}`);let m=p.teamfile,h=await $(r,k=>AE(k,t.env??process.env)),g=h.sender,y=await xE(r,{explicitRoot:t.rootFlag,sender:g,receiverTeamfile:m,operatorOrigin:h.origin==="operator"}),f=g===null?null:await RE(r,{rootTeamfile:y,sender:g,receiverTeamfile:m,receiverAlias:p.alias});f!==null&&!f.allowed&&e({kind:"warning",message:`warning: out-of-policy chat send: ${f.reason}
|
|
1992
|
+
`});let T=t.env??process.env,E=await $(r,k=>k.getRootTeam(y)?.name??null);E!==null&&(T.LMBEE_TEAM_NAME=E),i=await EE(r,{receiverTeamfile:m,receiverAlias:p.alias,sender:g,rootTeamfile:y,provider:p.provider,model:p.model,sessionId:p.sessionid,cwd:p.sessiondir,prompt:t.prompt,origin:h.origin,parentInvocationId:Qr(T.LMCTL_INVOCATION_ID)}),o=wE(r,i),i!==null&&(T.LMCTL_INVOCATION_ID=String(i));try{ko(r,Xt(m),m)}catch{}n={root_teamfile:y,sender_teamfile:g?.teamfile??null,sender_alias:g?.alias??null,receiver_teamfile:m,receiver_alias:p.alias,receiver_provider:p.provider,receiver_session_id:p.sessionid,origin:h.origin,message_type:t.messageType??null,policy:f};let I=await Od(r,m,p.alias);if(I!==null){let k=Er(I);return gt(i,n,t.prompt,k,"unavailable"),u=qi(k,null),{status:"busy",message:k,teamChatLogId:null}}let w=!1;if(t.heldLease!==void 0){let k=t.heldLease;if(!await $(r,re=>{let z=re.getAgentInflight(m,p.alias);return z===null||z.sender_teamfile!==k.row.sender_teamfile||z.sender_alias!==k.row.sender_alias||z.started_at!==k.row.started_at||z.holder_pid!==process.pid?!1:re.heartbeatAgentInflight(k.row,k.leaseId,new Date().toISOString())})){let re=`bundle lease lost for ${p.alias}: this batch no longer holds the in-flight lease (reclaimed or taken over); aborting before this prompt instead of dispatching unsynchronized`;return gt(i,n,t.prompt,re,"unavailable"),u=yr(re,null),{status:"error",errorKind:"provider",message:re,teamChatLogId:null,messageId:null}}}else{let k=await hE(r,m,p.alias);if(k.busy){let P=await gE(r,m,p.alias);return P+=await _E(r,m,p.alias),gt(i,n,t.prompt,P,"unavailable"),u=qi(P,null),{status:"busy",message:P,teamChatLogId:null}}w=k.idleReclaim}if(g!==null&&g.teamfile!==m){let k=await $(r,P=>Jo(P,{root:y,sender:g,receiverTeamfile:m,receiverAlias:p.alias,now:new Date}));if(k.stop){let P=Ko(k.chain);return gt(i,n,t.prompt,P,"cycle"),u=yr(P,null),{status:"error",errorKind:"cycle",message:P,teamChatLogId:null,messageId:null}}}if(t.heldLease===void 0){let k=await kE(r,{receiver_teamfile:m,receiver_alias:p.alias,sender_teamfile:g?.teamfile??m,sender_alias:g?.alias??"operator",...w?{force:!0,reclaimReason:"session-idle"}:{}});if(!k.acquired){let P=Dd(m,p.alias,k.current);return P+=` ${Wi(Bi({holderPid:k.current.holder_pid,since:k.current.started_at}))}`,gt(i,n,t.prompt,P,"unavailable"),u=qi(P,null),{status:"busy",message:P,teamChatLogId:null}}s={row:k.lease,leaseId:k.leaseId},a=Wr(P=>$(r,re=>re.heartbeatAgentInflight(s.row,s.leaseId,P)),{intervalMs:Ld,onError:P=>{K()&&ge(JSON.stringify({event:"agent_inflight_heartbeat_error",receiver:{teamfile:s.row.receiver_teamfile,alias:s.row.receiver_alias},error:P instanceof Error?P.message:String(P)}))}})}let _=await Rd({sender:g??{teamfile:m,alias:"operator"},receiver:{teamfile:m,alias:p.alias,provider:p.provider,sessionId:p.sessionid,cwd:p.sessiondir,...p.model!==void 0?{model:p.model}:{},...p.effort!==void 0?{effort:p.effort}:{},...p.isLead!==void 0?{isLead:p.isLead}:{}},newMessage:t.prompt,newMessageFrom:g===null?"operator":`${g.teamfile}:${g.alias}`,io:r,permissionMode:t.permissionMode,...t.expectedSession!==void 0?{requireResume:!0}:{},...t.bundleSession!==void 0?{bundleSession:t.bundleSession}:{},env:t.env??process.env,...t.idleTimeoutMs!==void 0?{idleTimeoutMs:t.idleTimeoutMs}:{},onDelta:k=>e({kind:"delta",chunk:k}),onProgress:k=>e({kind:"progress",alias:p.alias,event:k}),onPromptBuilt:async k=>{d=k,l===null&&(l=await CE(r,{...n,message:k}),l!==null&&(t.onAccepted?.(Fe(l)),i!==null&&await SE(r,i,l))),i!==null&&await TE(r,i,k)}});d=_.prompt;let v=_.status==="stalled",S=null,A=v?`provider stalled${_.stalledAfterMs!==void 0?` after ${_.stalledAfterMs}ms`:""}`:_.status==="error"?_.error??_.receipt:n.policy?.outOfPolicy===!0?n.policy.reason:null,x=v||_.status==="error"?"error":n.policy?.outOfPolicy===!0?"out_of_policy":"ok";l!==null?(await kd(r,l,{...n,message:d,response:_.receipt,status:x,error_detail:A}),c=!0,S=l):S=await DE(r,{...n,message:d,response:_.receipt,status:x,error_detail:A});let b=_.status!=="error"?_.warnings:void 0;if(v){let k=A;gt(i,n,d,k,"error"),u=yr(k,S,_.receipt,b)}else u=vE(_.receipt,S,b);return{status:v?"stalled":"ok",replyText:_.receipt,wroteDelta:_.wroteDelta,teamChatLogId:S,messageId:S===null?null:Fe(S),durationMs:_.durationMs}}catch(p){let m=p instanceof Error?p.message:String(p);return l!==null&&!c&&n!==null&&(await kd(r,l,{...n,message:d,response:null,status:"error",error_detail:m}),c=!0),gt(i,n,d,m,"error"),u=yr(m,l),{status:"error",errorKind:p instanceof Te?"target":"provider",message:m,teamChatLogId:l,messageId:l===null?null:Fe(l)}}finally{o!==void 0&&clearInterval(o),a!==void 0&&clearInterval(a),l!==null&&await OE(r,n,Fe(l)),s!==null&&await LE(r,s.row,s.leaseId),i!==null&&await yE(r,i,u??yr("chat turn exited without a terminal outcome",null))}}function pE(t,e){return{...t,stdout:{write:()=>{}},stderr:{write:r=>{e({kind:"warning",message:r})}}}}async function hE(t,e,r){let n=await $(t,i=>(Zr(i,e,r),Xr(i,e,r)));if(!n.busy)return{busy:!1,idleReclaim:!1};let s=await $(t,i=>Ad(i,n,e,r));return{busy:!s,idleReclaim:s}}async function gE(t,e,r){let n=await Od(t,e,r);if(n!==null)return Er(n);let s=await $(t,i=>i.getAgentInflight(e,r));return s!==null?Dd(e,r,s):`${r} is busy; wait and retry`}async function _E(t,e,r){let n=await $(t,s=>s.getAgentInflight(e,r));return n===null?"":` ${Wi(Bi({holderPid:n.holder_pid,since:n.started_at}))}`}async function EE(t,e){try{return(await $(t,n=>n.startTrackedInvocation({kind:"chat",origin:e.origin,scope_teamfile:e.receiverTeamfile,from_identity:e.sender===null?"operator":`${e.sender.teamfile}:${e.sender.alias}`,target_teamfile:e.receiverTeamfile,target_alias:e.receiverAlias,root_teamfile:e.rootTeamfile,cwd:e.cwd??null,command:IE(e.receiverTeamfile,e.receiverAlias,e.prompt),holder_pid:process.pid,request_payload:e.prompt,parent_invocation_id:e.parentInvocationId,meta:JSON.stringify({provider:e.provider,model:e.model??null,sessionid:e.sessionId??null})}))).id}catch(r){return K()&&ge(JSON.stringify({event:"tracked_invocation_start_error",error:r instanceof Error?r.message:String(r)})),null}}async function yE(t,e,r){try{await $(t,n=>{n.finishTrackedInvocation(e,r)})}catch(n){K()&&ge(JSON.stringify({event:"tracked_invocation_finish_error",id:e,error:n instanceof Error?n.message:String(n)}))}}async function TE(t,e,r){try{await $(t,n=>{n.updateTrackedInvocationRequestPayload(e,r)})}catch(n){K()&&ge(JSON.stringify({event:"tracked_invocation_request_payload_error",id:e,error:n instanceof Error?n.message:String(n)}))}}async function SE(t,e,r){try{await $(t,n=>{n.linkTrackedInvocationMessage(e,r)})}catch(n){K()&&ge(JSON.stringify({event:"tracked_invocation_message_link_error",id:e,team_chat_log_id:r,error:n instanceof Error?n.message:String(n)}))}}function wE(t,e){if(e===null)return;let r=setInterval(()=>{$(t,n=>n.heartbeatTrackedInvocation(e)).catch(n=>{K()&&ge(JSON.stringify({event:"tracked_invocation_heartbeat_error",id:e,error:n instanceof Error?n.message:String(n)}))})},Ld);return r.unref?.(),r}function Cd(t){return t!==void 0&&t.length>0?{config_warnings:JSON.stringify(t)}:{}}function vE(t,e,r){return{status:"done",result_summary:Tr(t),error:null,team_chat_log_id:e,...Cd(r)}}function qi(t,e){return{status:"busy",result_summary:Tr(t),error:t,team_chat_log_id:e}}function yr(t,e,r,n){return{status:"error",result_summary:Tr(r===void 0?t:r),error:t,team_chat_log_id:e,...Cd(n)}}function Tr(t){let e=t.replace(/\s+/gu," ").trim();return e.length<=500?e:`${e.slice(0,497)}...`}function IE(t,e,r){return`lmctl prompt ${JSON.stringify(t)} ${e} ${JSON.stringify(r)}`}function AE(t,e){let r=qn(e,t);if(r.ok)return{sender:Gn(r.identity),origin:"agent"};if(r.reason==="unset")return{sender:null,origin:"operator"};throw new Error(Xn("chat"))}async function xE(t,e){if(e.explicitRoot!==void 0)return await $(t,n=>nt(e.explicitRoot,n));if(e.operatorOrigin||e.sender===null)return e.receiverTeamfile;let r=e.sender;return await $(t,n=>Vo(n,{sender:r,now:new Date})??e.receiverTeamfile)}async function RE(t,e){return await $(t,r=>Xo({rootTeamfile:e.rootTeamfile,fromTeamfile:e.sender.teamfile,fromAlias:e.sender.alias,toTeamfile:e.receiverTeamfile,toAlias:e.receiverAlias,registry:bE(r,e.sender.teamfile,e.receiverTeamfile)}))}function bE(t,e,r){return{teams:[e,r].map(s=>NE(s,t))}}function NE(t,e){let r=Tt(t,e),n=qt(r);return{teamfile:t,aliases:r.members.map(s=>s.alias),leadAlias:n?.alias??null}}async function kE(t,e){return await $(t,r=>{let n=K(),s=Hr(r,{receiver_teamfile:e.receiver_teamfile,receiver_alias:e.receiver_alias,sender_teamfile:e.sender_teamfile,sender_alias:e.sender_alias,ttlMs:vt(),...e.force===!0?{force:!0}:{},...e.reclaimReason===void 0?{}:{reclaimReason:e.reclaimReason}});return s.acquired?(n&&ge(JSON.stringify({event:"inflight_acquire",receiver:{teamfile:e.receiver_teamfile,alias:e.receiver_alias},sender:{teamfile:e.sender_teamfile,alias:e.sender_alias},result:s.reclaimReason===null?"acquired":"reclaimed",...s.reclaimReason===null?{}:{reclaim_reason:s.reclaimReason,holder:Nd(s.previous)}})),{acquired:!0,lease:s.lease,leaseId:s.leaseId}):(n&&ge(JSON.stringify({event:"inflight_acquire",receiver:{teamfile:e.receiver_teamfile,alias:e.receiver_alias},sender:{teamfile:e.sender_teamfile,alias:e.sender_alias},result:"rejected",holder:Nd(s.current)})),{acquired:!1,current:s.current})})}async function Od(t,e,r){return await $(t,n=>{for(let i=0;i<2;i+=1){let o=n.getTerminalLock(e,r);if(o===null)return null;if(Hi(o).live)return o;let l=n.getAgentInflight(e,r);if(n.clearTerminalLock(e,r,o.lock_id))return l!==null&&l.sender_teamfile===e&&l.sender_alias==="terminal"&&n.clearObservedTerminalAgentInflight(e,r,{sender_teamfile:l.sender_teamfile,sender_alias:l.sender_alias,started_at:l.started_at,holder_pid:l.holder_pid}),null}let s=n.getTerminalLock(e,r);return s===null?null:Hi(s).live?s:null})}function Nd(t){return t===null?null:{sender_teamfile:t.sender_teamfile,sender_alias:t.sender_alias,holder_pid:t.holder_pid,started_at:t.started_at}}async function LE(t,e,r){try{await $(t,n=>{n.releaseAgentInflight(e,r)})}catch(n){t.stderr.write(`warning: failed to release chat in-flight slot: ${n instanceof Error?n.message:String(n)}
|
|
1993
|
+
`)}}function Dd(t,e,r){return`${e} is servicing ${r.sender_alias} (${r.sender_teamfile}) since ${r.started_at} \u2014 wait and retry, or inspect without waking it: lmctl tail "${t}" ${e}`}async function CE(t,e){let r=Sr(e.message);try{return await $(t,n=>n.beginTeamChatLog({root_teamfile:e.root_teamfile,sender_teamfile:e.sender_teamfile,sender_alias:e.sender_alias,receiver_teamfile:e.receiver_teamfile,receiver_alias:e.receiver_alias,receiver_provider:e.receiver_provider,receiver_session_id:e.receiver_session_id,provider_prompt:e.message,message:r.text,response:null,origin:e.origin,status:"running",error_detail:null,truncated:r.truncated?1:0,message_type:e.message_type??null,created_at:new Date().toISOString()}))}catch(n){return t.stderr.write(`warning: failed to begin chat log: ${n instanceof Error?n.message:String(n)}
|
|
1994
|
+
`),null}}async function kd(t,e,r){let n=Sr(r.message),s=r.response===null?null:Sr(r.response);try{await $(t,i=>i.finishTeamChatLog(e,{root_teamfile:r.root_teamfile,sender_teamfile:r.sender_teamfile,sender_alias:r.sender_alias,receiver_teamfile:r.receiver_teamfile,receiver_alias:r.receiver_alias,receiver_provider:r.receiver_provider,receiver_session_id:r.receiver_session_id,provider_prompt:r.message,message:n.text,response:s?.text??null,origin:r.origin,status:r.status,error_detail:r.error_detail,truncated:n.truncated||s?.truncated?1:0,created_at:new Date().toISOString()}))}catch(i){t.stderr.write(`warning: failed to finish chat log ${e}: ${i instanceof Error?i.message:String(i)}
|
|
1995
|
+
`)}}async function OE(t,e,r){if(e!==null)try{await $(t,n=>{n.clearCurrentlyHandlingMessage(e.receiver_teamfile,e.receiver_alias,r)})}catch(n){t.stderr.write(`warning: failed to clear chat causal pointer: ${n instanceof Error?n.message:String(n)}
|
|
1996
|
+
`)}}async function DE(t,e){let r=Sr(e.message),n=e.response===null?null:Sr(e.response);try{return await $(t,s=>s.insertTeamChatLog({root_teamfile:e.root_teamfile,sender_teamfile:e.sender_teamfile,sender_alias:e.sender_alias,receiver_teamfile:e.receiver_teamfile,receiver_alias:e.receiver_alias,receiver_provider:e.receiver_provider,receiver_session_id:e.receiver_session_id,provider_prompt:e.message,message:r.text,response:n?.text??null,origin:e.origin,status:e.status,error_detail:e.error_detail,truncated:r.truncated||n?.truncated?1:0,message_type:e.message_type??null,created_at:new Date().toISOString()}))}catch(s){return t.stderr.write(`warning: failed to record chat log: ${s instanceof Error?s.message:String(s)}
|
|
1997
|
+
`),null}}function gt(t,e,r,n,s){t!==null||e===null||R({event:"chat_attempt_error",reason:s,root_teamfile:e.root_teamfile,sender_teamfile:e.sender_teamfile,sender_alias:e.sender_alias,receiver_teamfile:e.receiver_teamfile,receiver_alias:e.receiver_alias,origin:e.origin,error_detail:n,message_preview:Tr(r)})}function Sr(t){return t.length<=bd?{text:t,truncated:!1}:{text:t.slice(0,bd),truncated:!0}}import{spawnSync as ME}from"node:child_process";import{existsSync as FE}from"node:fs";import{homedir as Vi}from"node:os";import{delimiter as PE,join as Ki}from"node:path";var Md=["all","codex","agy","claude","kimi"],UE=15,$E=4;function jE(t,e,r){let n=ME(t,e,{encoding:"utf8",timeout:r,maxBuffer:16777216});return{status:n.status,stdout:typeof n.stdout=="string"?n.stdout:"",stderr:typeof n.stderr=="string"?n.stderr:"",...n.signal!==null?{signal:n.signal}:{},...n.error!==void 0?{error:n.error}:{}}}var BE={exists:FE},WE=jE,Ji=BE;function HE(t){return t==="~"?Vi():t.startsWith("~/")?Ki(Vi(),t.slice(2)):t}function XE(t){let e=t.LMCTL_RATELIMIT_BIN;if(e!==void 0&&e!==""){let n=HE(e);if(Ji.exists(n))return n}let r=Ki(Vi(),"repos","tools","lmratelimit","bin","lmratelimit");if(Ji.exists(r))return r;for(let n of(t.PATH??"").split(PE)){if(n==="")continue;let s=Ki(n,"lmratelimit");if(Ji.exists(s))return s}return null}function Fd(t){return typeof t=="object"&&t!==null}function qE(t){let e;try{e=JSON.parse(t)}catch{return null}return Fd(e)?Array.isArray(e.readings)?e.readings.filter(Fd):typeof e.provider=="string"&&typeof e.status=="string"?[e]:null:null}function Pd(t,e){let r=t.trim();return r.length<=e?r:`${r.slice(0,e)}\u2026`}function Ud(t={}){let e=t.targets??t.providers??["all"];if(!Array.isArray(e)||e.length===0||e.some(c=>typeof c!="string"))return{status:"error",error:"providers must be a non-empty list of provider names",readings:[]};for(let c of e)if(!Md.includes(c))return{status:"error",error:`unknown provider: ${c} (valid targets: ${Md.join(", ")})`,readings:[]};let r=t.timeoutSeconds??UE;if(!Number.isFinite(r)||r<=0)return{status:"error",error:"timeoutSeconds must be a positive finite number",readings:[]};let n=t.env??process.env,s=XE(n);if(s===null)return{status:"error",error:"lmratelimit binary not found (looked at LMCTL_RATELIMIT_BIN, ~/repos/tools/lmratelimit/bin/lmratelimit, and PATH).",readings:[]};let i=e.includes("all")?$E:e.length,o=Math.ceil(2*r*i*1e3);t.progress?.(`querying ${e.join(" ")} live (timeout ${r}s per provider) ...`);let a=WE(s,[...e,"--pretty","--timeout",String(r)],o);if(a.error!==void 0){let c=a.error.code==="ETIMEDOUT"?`timed out after ${Math.round(o/1e3)}s (--timeout ${r}s x ${i} provider(s))`:a.error.message;return{status:"error",error:`failed to run lmratelimit (${s}): ${c}`,readings:[]}}if(a.status!==0){let c=a.signal!==null&&a.signal!==void 0?`signal ${a.signal}`:`status ${a.status}`,u=Pd(a.stderr,500);return{status:"error",error:`lmratelimit exited with ${c}${u!==""?`: ${u}`:""}`,readings:[]}}let l=qE(a.stdout);return l===null?{status:"error",error:`could not parse lmratelimit output as JSON: ${Pd(a.stdout,300)}`,readings:[]}:{status:"ok",readings:l}}var Ut=class{batchHandles=new Map;loggedErrors=[];registerBatch(e){this.batchHandles.set(e.id,e)}getBatch(e){return this.batchHandles.get(e)}getOpenBatches(){return Array.from(this.batchHandles.values()).filter(e=>!e.closed)}recordError(e){this.loggedErrors.push(e)}getErrors(){return[...this.loggedErrors]}hasErrors(){return this.loggedErrors.length>0}async forceCloseAll(e){for(let r of this.getOpenBatches())await $d(r,e,"error","script execution interrupted or terminated without orderly close");this.batchHandles.clear()}};async function VE(t){let e=t.provider.trim().toLowerCase();return Fi.includes(e)||tl().tools[e]?.agent!==void 0||!Mi.includes(e)?!1:$i().includes(e)}async function Yi(t,e){try{await $(t,r=>{r.releaseAgentInflight(e.row,e.leaseId)})}catch(r){t.stderr.write(`warning: failed to release batch bundle lease: ${r instanceof Error?r.message:String(r)}
|
|
1998
|
+
`)}}function KE(t,e){let r=qn(t,e);if(r.ok)return Gn(r.identity);if(r.reason==="unset")return null;throw new Error(Xn("batch"))}async function YE(t,e){try{let{member:r}=e;return await $(t,n=>n.startTrackedInvocation({kind:"exec",origin:"operator",scope_teamfile:r.teamfile,from_identity:`${r.teamfile}:batch`,target_teamfile:r.teamfile,target_alias:r.alias,root_teamfile:r.teamfile,cwd:r.sessiondir,command:`lmctl batch ${r.teamfile} ${r.alias} ${e.batchfile}`,holder_pid:process.pid,launch_source:"exec",parent_invocation_id:e.parentInvocationId,meta:JSON.stringify({batchfile:e.batchfile,prompt_count:e.promptCount,provider:r.provider,sessionid:r.sessionid,...r.model!==void 0?{model:r.model}:{}})}).id)}catch(r){return t.stderr.write(`warning: failed to start batch root invocation: ${r instanceof Error?r.message:String(r)}
|
|
1999
|
+
`),null}}function zE(t,e,r,n){try{if(t.dal!==void 0){t.dal.finishTrackedInvocation(e,r);return}let s=lt({path:Pe(n?.LMCTL_DB)});try{s.finishTrackedInvocation(e,r)}finally{s.close()}}catch{}}async function $d(t,e,r,n){if(!t.closed&&(t.closed=!0,t.kind!=="agent")){if(t.bundleSession)try{await t.bundleSession.close()}catch{}if(t.heartbeatTimer&&t.heartbeatTimer.stop(),t.heldLease&&await Yi(e,t.heldLease),t.rootId!==null){let s=r==="done"?{status:"done",exit_code:0,result_summary:`batch completed ${t.promptCount}/${t.promptCount} prompts`}:{status:t.rootFinish.status??(r==="cancelled"?"cancelled":"error"),exit_code:1,error:n??t.rootFinish.error,result_summary:t.rootFinish.result_summary};try{await $(e,i=>{i.finishTrackedInvocation(t.rootId,s)})}catch(i){e.stderr.write(`warning: failed to finish batch root invocation: ${i instanceof Error?i.message:String(i)}
|
|
2000
|
+
`)}}r==="done"&&e.stderr.write(`batch ${Je()}: completed ${t.promptCount}/${t.promptCount} prompts
|
|
2001
|
+
`)}}var zi=[{name:"lm_batch_open",category:"lmctl Automation",signature:"lm_batch_open(teamfile, alias, batchfile, options = {}); lm_batch_open(member, options = {})",description:"Opens a managed teamfile batch, or a file-free member-map batch using sequential native agent turns. The map form retains session identity without team leases, bundle optimization, or team tracking.",parameters:[{name:"teamfile",type:"string|map",description:"Teamfile path for the legacy form, or a member map for the two-argument form"},{name:"alias",type:"string",description:"Team member alias to target"},{name:"batchfile",type:"string",description:"Legacy form only: source label for tracking; not read by this function"},{name:"options",type:"map",description:"(optional) Teamfile form: promptCount, legacy. Member-map form: permissionMode, idleTimeoutMs, as for lm_agent"}],returns:{type:"map",description:"Batch handle object or null on error"},example:'handle = lm_batch_open("team.lmctl", "reviewer", "prompts.txt", { promptCount: 5 });'},{name:"lm_batch_turn",category:"lmctl Automation",signature:"lm_batch_turn(handle, prompt, index, total)",description:"Executes a single prompt turn within an active batch session, handling heartbeats and status reporting.",parameters:[{name:"handle",type:"map",description:"Active batch handle returned from lm_batch_open"},{name:"prompt",type:"string",description:"Prompt text to execute"},{name:"index",type:"number",description:"1-based prompt index"},{name:"total",type:"number",description:"Total number of prompts in batch"}],returns:{type:"map",description:"{ status: 'ok'|'busy'|'stalled'|'error', reply: string, error: string|null }"},example:'turn = lm_batch_turn(handle, "Summarize this diff", 1, 5);'},{name:"lm_batch_close",category:"lmctl Automation",signature:'lm_batch_close(handle, status = "done", error = null)',description:"Closes an active batch session and finalizes tracked invocations and bundle leases.",parameters:[{name:"handle",type:"map",description:"Active batch handle to close"},{name:"status",type:"string",description:"(optional) Terminal status: 'done', 'cancelled', or 'error' (default: 'done')"},{name:"error",type:"string",description:"(optional) Error message if batch failed"}],returns:{type:"bool",description:"true if successfully closed, false otherwise"},example:'lm_batch_close(handle, "done");'},{name:"lm_prompt",category:"lmctl Automation",signature:"lm_prompt(teamfile, alias, prompt, options = {})",description:"Sends a direct one-shot prompt to a team member and returns the reply.",parameters:[{name:"teamfile",type:"string",description:"Path to team configuration file"},{name:"alias",type:"string",description:"Target team member alias"},{name:"prompt",type:"string",description:"Prompt text"},{name:"options",type:"map",description:"(optional) Execution options: permissionMode, idleTimeoutMs, messageType"}],returns:{type:"map",description:"{ status, reply, error, message_id, team_chat_log_id }"},example:'res = lm_prompt("team.lmctl", "coder", "Hello agent");'},{name:"lm_agent",category:"lmctl Automation",signature:"lm_agent(member, prompt, options = {})",description:"Prompts a provider directly without a teamfile. Creates a session when sessionid is absent and writes its ID back into member for subsequent turns or explicit persistence.",parameters:[{name:"member",type:"map",description:"Required provider; optional alias, model, effort, sessiondir (default cwd), sessionid. Updated in place with sessionid."},{name:"prompt",type:"string",description:"Prompt text"},{name:"options",type:"map",description:"(optional) permissionMode (yolo or plan), idleTimeoutMs. Fresh agy/pi/dsh sessions require a preliminary seed in yolo mode."}],returns:{type:"map",description:"{ status, reply, error, message_id: null, team_chat_log_id: null }; no team mailbox or log is created"},example:'agent = { provider: "codex" }; res = lm_agent(agent, "Summarize this repository");'},{name:"lm_ratelimit_readings",category:"lmctl Automation",signature:"lm_ratelimit_readings(options = {})",description:"Queries live provider quota readings using the existing ratelimit reader; preserves raw fields without cost aggregation or inferred availability.",parameters:[{name:"options",type:"map",description:"(optional) providers: string[] or provider: string (default all); timeoutSeconds: positive number (default 15)"}],returns:{type:"map",description:'{ status: "ok", readings: map[] } or { status: "error", error: string, readings: [] }. Provider-level failures remain reading data; inspect each reading.status and bucket flags.'},example:'quota = lm_ratelimit_readings({ providers: ["codex", "claude"] });'},{name:"lm_read_prompts",category:"lmctl Automation",signature:"lm_read_prompts(batchfile, single = false)",description:"Reads prompt file with BOM and CRLF normalization, splitting into paragraphs or reading entire file as single prompt.",parameters:[{name:"batchfile",type:"string",description:"Path to prompt file"},{name:"single",type:"bool",description:"(optional) If true, treats entire file as one prompt; if false, splits on blank lines"}],returns:{type:"string[]",description:"List of prompt strings"},example:'prompts = lm_read_prompts("prompts.txt");'},{name:"lm_read_paragraphs",category:"lmctl Automation",signature:"lm_read_paragraphs(batchfile)",description:"Reads a prompt file and splits it into blank-line-separated paragraphs.",parameters:[{name:"batchfile",type:"string",description:"Path to prompt file"}],returns:{type:"string[]",description:"List of paragraph strings"},example:'paragraphs = lm_read_paragraphs("spec.md");'},{name:"lm_members",category:"lmctl Automation",signature:"lm_members(teamfile)",description:"Resolves all team members declared in a team configuration file.",parameters:[{name:"teamfile",type:"string",description:"Path to team configuration file"}],returns:{type:"map[]",description:"List of member records { alias, provider, model, sessionid, sessiondir }"},example:'members = lm_members("team.lmctl");'},{name:"lm_member",category:"lmctl Automation",signature:"lm_member(teamfile, alias)",description:"Resolves a specific member in a team configuration file.",parameters:[{name:"teamfile",type:"string",description:"Path to team configuration file"},{name:"alias",type:"string",description:"Member alias to look up"}],returns:{type:"map|null",description:"Member record { alias, provider, model, sessionid, sessiondir, isLead, teamfile } or null"},example:'m = lm_member("team.lmctl", "reviewer");'},{name:"lm_log",category:"lmctl Automation",signature:"lm_log(...args)",description:"Writes formatted log messages to standard error with trailing newline.",parameters:[{name:"args",type:"any[]",description:"Values or messages to log to stderr"}],returns:{type:"string",description:"The formatted text"},example:'lm_log("Step completed successfully");'},{name:"lm_error",category:"lmctl Automation",signature:"lm_error(...args)",description:"Writes error messages to standard error prefixed with 'error: '.",parameters:[{name:"args",type:"any[]",description:"Error details to write to stderr"}],returns:{type:"string",description:"The formatted error text"},example:'lm_error("Failed to connect to team member");'},{name:"lm_exit",category:"lmctl Automation",signature:"lm_exit(code = 0)",description:"Immediately terminates script execution with the specified integer exit code (0-255).",parameters:[{name:"code",type:"number",description:"(optional) Exit status code between 0 and 255 (default: 0)"}],returns:{type:"never",description:"Raises LMScriptExit control flow"},example:"lm_exit(1);"}].map(t=>({...t,module:"lmctl"}));function QE(t){for(let e of zi)t.registerFunctionDoc(e)}function jd(t={}){let e=new Me;e.isAsyncMode=!0;let r=t.scriptArgs??[];if(e.setGlobal("args",[...r]),e.setGlobal("ARGV",[...r]),t.io){let n=t.io;e.registerFunction("print",(...s)=>{let i=s.map(o=>typeof o=="object"?JSON.stringify(o):String(o)).join(" ");return n.stdout.write(i+`
|
|
2002
|
+
`),i},void 0,{description:"Prints formatted values to stdout",allowOverwrite:!0}),e.registerFunction("println",(...s)=>{let i=s.map(o=>typeof o=="object"?JSON.stringify(o):String(o)).join(" ");return n.stdout.write(i+`
|
|
2003
|
+
`),i},void 0,{description:"Prints line to stdout",allowOverwrite:!0}),e.registerFunction("prompt_human",s=>{if(e.isAsyncMode){let i=n.stdin??(typeof process<"u"?process.stdin:null),o=n.stdout??(typeof process<"u"?process.stdout:null);return Ht(s,i,o)}return Wt(s)},{min:0,max:1},{description:"Prompts operator on stdin/terminal, returning input string or null if closed/non-interactive",allowOverwrite:!0})}return e}function Bd(t,e,r,n=process.env){t.registerFunction("lm_exit",(m=0)=>{let h=Math.floor(Number(m)),g=Number.isFinite(h)&&h>=0&&h<=255?h:1;throw new pe(g)},{min:0,max:1},"Exits the LMScript execution with an exit code"),t.registerFunction("lm_log",(...m)=>{let h=m.map(g=>typeof g=="object"?JSON.stringify(g):String(g)).join(" ");return e.stderr.write(h+(h.endsWith(`
|
|
2004
|
+
`)?"":`
|
|
2005
|
+
`)),h},void 0,"Writes formatted log message to stderr"),t.registerFunction("lm_error",(...m)=>{let h=m.map(g=>typeof g=="object"?JSON.stringify(g):String(g)).join(" ");return e.stderr.write(`error: ${h}
|
|
2006
|
+
`),r.recordError(h),h},void 0,"Writes error message to stderr and records it for end-of-run error summary");let s=(m,h=!1)=>{try{let g=GE(String(m),"utf8").replace(/^\uFEFF/u,"").replace(/\r\n?/gu,`
|
|
2007
|
+
`);return!!h?[g.trim()].filter(f=>f.length>0):g.split(/\n\s*\n/u).map(f=>f.trim()).filter(Boolean)}catch(g){throw ct(e,`batch: ${g instanceof Error?g.message:String(g)}`),new pe(1)}};t.registerFunction("lm_read_prompts",(m,h=!1)=>s(m,h),{min:1,max:2},"Reads prompt file with BOM and CRLF normalization, splitting into paragraphs or single prompt"),t.registerFunction("lm_read_paragraphs",m=>s(m,!1),1,"Reads file and splits into blank-line-separated paragraphs"),t.registerFunction("lm_members",m=>{try{return Xt(String(m)).members.map(g=>({alias:g.alias,provider:g.provider,model:g.model,sessionid:g.session,sessiondir:g.sessiondir}))}catch(h){throw new Error(`Failed to read teamfile '${m}': ${h?.message||String(h)}`)}},1,"Resolves all members declared in a teamfile"),t.registerFunction("lm_member",(m,h)=>{try{let g=st(String(m),String(h),e.dal);return{alias:g.alias,provider:g.provider,model:g.model,sessionid:g.sessionid,sessiondir:g.sessiondir,isLead:g.isLead,teamfile:g.teamfile}}catch{return null}},2,"Resolves a specific member in a teamfile"),t.registerFunction("lm_batch_open",async(m,h,g,y={})=>{if(typeof m!="string"){if(!m||Array.isArray(m)||typeof m!="object"||typeof m.provider!="string"||!m.provider.trim())throw new Error("lm_batch_open: member map requires provider");let b=h??{};if(typeof b!="object"||Array.isArray(b)||g!==void 0)throw new Error("lm_batch_open(member, options): options must be a map");let k={kind:"agent",id:`batch-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,member:{...m},sourceMember:m,options:{...b},closed:!1,failed:!1,inFlight:!1};return r.registerBatch(k),k}if(typeof h!="string"||typeof g!="string")throw new Error("lm_batch_open(teamfile, alias, batchfile, options): alias and batchfile are required");let f;try{f=st(String(m),String(h),e.dal)}catch(b){return ct(e,`batch: ${b?.message||String(b)}`),null}let T=Number(y?.promptCount??1),I=!!!y?.legacy&&T>1&&await VE(f),w={...e.env??n},_=await YE(e,{member:f,batchfile:String(g),promptCount:T,parentInvocationId:Qr(w.LMCTL_INVOCATION_ID)});_!==null&&(w.LMCTL_INVOCATION_ID=String(_));let v,S,A,x=!1;e.stderr.write(`batch ${Je()}: starting ${T} prompt${T===1?"":"s"} -> ${f.alias} (teamfile=${m} input=${g})
|
|
2008
|
+
`);try{if(I){let P=await $(e,B=>(Zr(B,f.teamfile,f.alias),Xr(B,f.teamfile,f.alias)));if(P.busy){let B=P.reason==="in-flight"?`${f.alias} is servicing ${P.inFlight.sender_alias} (${P.inFlight.sender_teamfile}) since ${P.inFlight.started_at} \u2014 wait and retry`:P.source==="terminal-lock"?Er(P.terminalLock):`${f.alias} is busy (interactive terminal); wait and retry`;return _!==null&&await $(e,ce=>{ce.finishTrackedInvocation(_,{status:"busy",exit_code:1,error:B,result_summary:"0 prompts completed"})}),ct(e,`batch: cannot start bundle: ${B}`),null}let re=await $(e,B=>KE(w,B)),z=await $(e,B=>Hr(B,{receiver_teamfile:f.teamfile,receiver_alias:f.alias,sender_teamfile:re?.teamfile??f.teamfile,sender_alias:re?.alias??"operator",ttlMs:vt(w)}));if(!z.acquired){let B=`${f.alias} is servicing ${z.current.sender_alias} (${z.current.sender_teamfile}) since ${z.current.started_at} \u2014 wait and retry`;return _!==null&&await $(e,ce=>{ce.finishTrackedInvocation(_,{status:"busy",exit_code:1,error:B,result_summary:"0 prompts completed"})}),ct(e,`batch: cannot start bundle: ${B}`),null}v={row:z.lease,leaseId:z.leaseId};let ae=Wr(B=>$(e,ce=>ce.heartbeatAgentInflight(v.row,v.leaseId,B)));A={stop:()=>clearInterval(ae)};let ie=zr(e,B=>`batch ${Je()}: opening provider session (${B}s elapsed)
|
|
2009
|
+
`);try{let B={...w};try{let ce=await $(e,De=>De.getRootTeam(f.teamfile)?.name??null);ce!==null&&(B.LMBEE_TEAM_NAME=ce)}catch{}S=await yd({provider:f.provider,sessionId:f.sessionid,cwd:f.sessiondir,env:B,...f.model!==void 0?{model:f.model}:{},...f.effort!==void 0?{effort:f.effort}:{},alias:f.alias,isLead:f.isLead,permissionMode:"yolo",holdOpen:Xi(e,{teamfile:f.teamfile,alias:f.alias},B)}),x=!0}catch{A&&A.stop(),A=void 0,await Yi(e,v),v=void 0,x=!1}finally{ie.stop()}}let k={id:`batch-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,teamfile:String(m),alias:String(h),batchfile:String(g),member:f,promptCount:T,useBundle:x,rootId:_,rootFinish:{status:"error",error:"batch exited without a terminal outcome"},heldLease:v,bundleSession:S,heartbeatTimer:A,closed:!1,env:w};return r.registerBatch(k),k}catch(b){if(A){try{A.stop()}catch{}A=void 0}if(v){try{await Yi(e,v)}catch{}v=void 0}if(S){try{await S.close()}catch{}S=void 0}if(_!==null)try{await $(e,k=>{k.finishTrackedInvocation(_,{status:"error",exit_code:1,error:b?.message||String(b),result_summary:"0 prompts completed"})})}catch{}throw b}},{min:1,max:4},"Opens a batch from a member map or a teamfile with lifecycle management"),t.registerFunction("lm_batch_turn",async(m,h,g,y)=>{let f=typeof m=="string"?r.getBatch(m):m?.id?r.getBatch(m.id)??m:void 0;if(!f)throw new Error("Invalid or unmanaged batch handle");if(f.kind==="agent"){if(r.getBatch(f.id)!==f)throw new Error("Invalid or unmanaged batch handle");if(f.closed||f.failed)return{status:"error",reply:"",error:"Batch is closed or stopped after a failed turn"};if(f.inFlight)return{status:"busy",reply:"",error:"Batch already has an active turn"};f.inFlight=!0;try{let w=f.member.sessionid,_=await u(f.member,String(h),f.options);return f.member.sessionid&&f.sourceMember.provider===f.member.provider&&f.sourceMember.sessionid===w&&(f.sourceMember.sessionid=f.member.sessionid),_.status!=="ok"&&(f.failed=!0),{status:_.status,reply:_.reply.replace(/\n+$/u,""),error:_.error}}finally{f.inFlight=!1}}let T=Number(g),E=Number(y);e.stderr.write(`batch ${Je()}: prompt ${T}/${E} -> ${f.member.alias}
|
|
2010
|
+
`);let I=zr(e,w=>`batch ${Je()}: prompt ${T}/${E} still running (${w}s elapsed)
|
|
2011
|
+
`);try{let w=await Gi({teamfile:f.member.teamfile,alias:f.member.alias,prompt:String(h),expectedSession:{provider:f.member.provider,sessionid:f.member.sessionid},permissionMode:"yolo",env:{...f.env},messageType:"batch",...f.heldLease!==void 0?{heldLease:f.heldLease}:{},...f.bundleSession!==void 0?{bundleSession:f.bundleSession}:{},io:e,onEvent:v=>{I.poke(),v.kind==="warning"&&e.stderr.write(v.message)}}),_=w.replyText?String(w.replyText).replace(/\n+$/u,""):"";if(w.status!=="ok"){let v=w.status==="stalled"?"provider stalled":w.message,S=`batch: stopped at prompt ${T}/${E} (${T-1} completed): ${v}; later prompts were not sent`;return f.rootFinish={status:w.status==="busy"?"busy":"error",exit_code:1,error:S,result_summary:`${T-1}/${E} prompts completed`},ct(e,S),{status:w.status,reply:_,error:S}}return{status:"ok",reply:_,error:null}}catch(w){let _=`batch: stopped at prompt ${T}/${E} (${T-1} completed): ${w instanceof Error?w.message:String(w)}; later prompts were not sent`;return f.rootFinish={status:"error",exit_code:1,error:_,result_summary:`${T-1}/${E} prompts completed`},ct(e,_),{status:"error",reply:"",error:_}}finally{I.stop()}},4,"Executes a prompt turn within a batch session"),t.registerFunction("lm_batch_close",async(m,h="done",g)=>{let y=typeof m=="string"?r.getBatch(m):m?.id?r.getBatch(m.id)??m:void 0;return y?(await $d(y,e,h==="done"?"done":h==="cancelled"?"cancelled":"error",g),!0):!1},{min:1,max:3},"Closes a batch session and cleans up resources"),t.registerFunction("lm_ratelimit_readings",async(m={})=>{try{if(!m||typeof m!="object"||Array.isArray(m))throw new Error("lm_ratelimit_readings: options must be a map");let h=m.providers??(m.provider===void 0?["all"]:[m.provider]);if(!Array.isArray(h)||h.some(y=>typeof y!="string"||!y||y.startsWith("-")))throw new Error("lm_ratelimit_readings: providers must be a list of provider names");let g=m.timeoutSeconds??15;if(typeof g!="number"||!Number.isFinite(g)||g<=0)throw new Error("lm_ratelimit_readings: timeoutSeconds must be a positive finite number");return Ud({providers:h.length?h:["all"],timeoutSeconds:g,env:e.env??n,progress:y=>{e.stderr.write(`${y}
|
|
2012
|
+
`)}})}catch(h){return{status:"error",error:h instanceof Error?h.message:String(h),readings:[]}}},{min:0,max:1},"Reads live provider quota values without analytics or aggregation");let i=new WeakSet,o=new Set,a=new Set,l=new Map,c=async(m,h,g={},y=!1)=>{let f=(w,_="",v=null)=>({status:w,reply:_,error:v,message_id:null,team_chat_log_id:null}),T,E=!1,I;try{if(!m||typeof m!="object"||Array.isArray(m))throw new Error("lm_agent: member must be a map");for(let b of["provider","alias","model","effort","sessiondir","sessionid"]){let k=m[b];if(k!=null&&(typeof k!="string"||!k.trim()))throw new Error(`lm_agent: ${b} must be a nonempty string when supplied`)}if(!m.provider)throw new Error("lm_agent: provider is required");if(typeof h!="string")throw new Error("lm_agent: prompt must be a string");if(!g||typeof g!="object"||Array.isArray(g))throw new Error("lm_agent: options must be a map");let w=g.permissionMode??"yolo";if(w!=="yolo"&&w!=="plan")throw new Error("lm_agent: permissionMode must be yolo or plan");if(g.idleTimeoutMs!=null&&(typeof g.idleTimeoutMs!="number"||!Number.isFinite(g.idleTimeoutMs)||g.idleTimeoutMs<0))throw new Error("lm_agent: idleTimeoutMs must be a finite nonnegative number");let _=m.provider,v=m.sessiondir??process.cwd(),S=m.sessionid??"";if(T=S?JSON.stringify([_,S]):void 0,i.has(m)||T!==void 0&&(o.has(T)||!y&&a.has(T)))return f("busy","","lm_agent: session already has an active turn in this engine");i.add(m),T!==void 0&&o.add(T),E=!0,e.stderr.write(`agent ${Je()}: prompting ${m.alias??_}
|
|
2013
|
+
`),I=zr(e,b=>`agent ${Je()}: still running (${b}s elapsed)
|
|
2014
|
+
`);let A=S;if(!A&&["agy","pi","dsh"].includes(_)){if(w!=="yolo")throw new Error(`lm_agent: fresh ${_} sessions require yolo seed; supply sessionid for resume`);let b=await Td({provider:_,cwd:v,model:m.model,effort:m.effort});for(let k of b.warnings??[])e.stderr.write(`warning: ${k}
|
|
2015
|
+
`);if(!b.success||!b.sessionId)throw new Error(b.error??"lm_agent: provider did not identify the seeded session");A=b.sessionId,m.sessionid=A,T=JSON.stringify([_,A]),o.add(T)}let x=await Hn({provider:_,cwd:v,sessionId:A,prompt:h,model:m.model,effort:m.effort,alias:m.alias,isLead:!1,permissionMode:w,timeoutMs:g.idleTimeoutMs,requireResume:!!A,env:{...e.env??n},onDelta:()=>I?.poke(),onProgress:()=>I?.poke()});for(let b of x.warnings??[])e.stderr.write(`warning: ${b}
|
|
2016
|
+
`);return A&&x.sessionId!==A?f("error","","lm_agent: provider changed session identity during resume"):(x.sessionId&&(m.sessionid=x.sessionId),x.status==="stalled"?f("stalled",x.text,"provider stalled"):x.sessionId?f("ok",x.text):f("error",x.text,"lm_agent: provider did not return a session ID"))}catch(w){return f("error","",w instanceof Error?w.message:String(w))}finally{I?.stop(),E&&(i.delete(m),T!==void 0&&o.delete(T))}},u=async(m,h,g={},y=!1)=>{let f=await c(m,h,g,y);if(m?.sessionid&&f.status!=="busy"){let T=JSON.stringify([m.provider,m.sessionid]),E=l.get(T)??{lines:[],options:{}};E.lines.push(`You: ${h}`),f.reply&&E.lines.push(`Agent: ${f.reply}`),f.error&&E.lines.push(`${f.status}: ${f.error}`),E.options={...g},l.set(T,E)}return f};t.registerFunction("lm_agent",u,{min:2,max:3},"Prompts an agent described by a map without a teamfile");let d=!1,p=async m=>{let h=m!==null&&typeof m=="object";if(d)throw new Error("prompt_human: another operator prompt is active");d=!0;let g,y;try{let f=e.stdin??process.stdin;if(!h)return await Ht(m,f,e.stdout);let T={...m};if(Array.isArray(m)||typeof T.provider!="string"||!T.provider.trim()||typeof T.sessionid!="string"||!T.sessionid.trim())return{command:"error",args:["prompt_human: session map requires provider and sessionid; call lm_agent first"]};let E=JSON.stringify([T.provider,T.sessionid]);if(o.has(E))return{command:"busy",args:["Agent turn is still running"]};a.add(E),y=E;let I=f;if(I.destroyed||I.readableEnded)return{command:"eof",args:[]};g=JE({input:I,output:e.stdout,terminal:!!I.isTTY,crlfDelay:1/0});let w=g[Symbol.asyncIterator](),_=!1;g.on("SIGINT",()=>{_=!0,g?.close()}),e.stdout.write(`Session ${T.alias??T.provider} (${T.sessionid})
|
|
2017
|
+
`);let v=l.get(E);if(v)for(let S of v.lines)e.stdout.write(`${S}
|
|
2018
|
+
`);else{let S=await dt(ht()).getSession(T.sessionid,T.provider);if(!S)return{command:"error",args:["Could not load session history"]};for(let A of S.messages)(A.role==="user"||A.role==="assistant")&&e.stdout.write(`${A.role==="user"?"You":"Agent"}: ${A.content}
|
|
2019
|
+
`)}for(e.stdout.write(`Talk to the agent. Return to the script with /exit [command] [args...].
|
|
2020
|
+
`);;){e.stdout.write("You> ");let S=await w.next();if(_)return{command:"cancelled",args:[]};if(S.done)return{command:"eof",args:[]};let A=S.value.trim();if(!A)continue;if(/^\/exit(?:\s|$)/u.test(A)){let b=A.split(/\s+/u).slice(1);return{command:b.shift()??"exit",args:b}}let x=await u(T,S.value,v?.options??{},!0);if(x.reply&&e.stdout.write(`Agent: ${x.reply}
|
|
2021
|
+
`),x.status!=="ok")return e.stdout.write(`${x.status}: ${x.error}
|
|
2022
|
+
`),{command:x.status,args:[x.error??"Agent turn failed"]}}}catch(f){if(!h)throw f;return{command:"error",args:[f instanceof Error?f.message:String(f)]}}finally{g?.close(),y!==void 0&&a.delete(y),d=!1}};t.registerFunction("prompt_human",m=>{if(!t.isAsyncMode&&(m===null||typeof m!="object")){if(d)throw new Error("prompt_human: another operator prompt is active");return Wt(m)}return p(m)},{min:0,max:1},{description:"Prompts for a string, or hands an agent session to the operator and returns a decision map",allowOverwrite:!0}),t.registerFunctionDoc({name:"prompt_human",module:"core",category:"System & Process",signature:"prompt_human([question: string]): string|null; prompt_human(session: map): map",description:'Question form reads one line. In the lmctl engine, a session map opens an agent conversation showing script history. /exit retry a b returns {command: "retry", args: ["a", "b"]}; arguments are whitespace-separated. Bare /exit returns command "exit"; closed input returns "eof". Errors, stalls, busy sessions and Ctrl-C return "error", "stalled", "busy" and "cancelled" maps. All map results have args: string[].',example:'agent = { provider: "codex" }; lm_agent(agent, "Review this change"); decision = prompt_human(agent); if (decision.command == "retry") { lm_agent(agent, join(decision.args, " ")); }'}),t.registerFunction("lm_prompt",async(m,h,g,y={})=>{try{let f=await Gi({teamfile:String(m),alias:String(h),prompt:String(g),permissionMode:y?.permissionMode??"yolo",idleTimeoutMs:y?.idleTimeoutMs,env:{...e.env??n},messageType:y?.messageType,io:e});return{status:f.status,reply:f.replyText??"",error:f.message??null,message_id:f.messageId??null,team_chat_log_id:f.teamChatLogId??null}}catch(f){return{status:"error",reply:"",error:f?.message||String(f),message_id:null,team_chat_log_id:null}}},{min:3,max:4},"Sends a prompt directly to a team member and returns the reply")}var Wd={name:"lmctl",description:"lmctl Automation & Orchestration Host Functions",docs:zi,register(t,e){Bd(t,e.io,e.registry,e.env)}};function Hd(t,e,r=new Ut,n=process.env){return t.registerModule(Wd,{io:e,registry:r,env:n})}function Xd(t,e=[],r=new Ut,n=process.env){let s=jd({scriptArgs:e,io:t,env:n});return Hd(s,t,r,n),s}async function ZE(t,e,r={stdout:process.stdout,stderr:process.stderr},n=process.env,s){let i=new Ut,o=u=>{for(let d of i.getOpenBatches()){if(d.kind==="agent"){d.closed=!0;continue}if(d.heartbeatTimer){try{d.heartbeatTimer.stop()}catch{}d.heartbeatTimer=void 0}if(d.heldLease){try{if(r.dal)r.dal.releaseAgentInflight(d.heldLease.row,d.heldLease.leaseId);else{let p=lt({path:Pe(n?.LMCTL_DB)});try{p.releaseAgentInflight(d.heldLease.row,d.heldLease.leaseId)}finally{p.close()}}}catch{}d.heldLease=void 0}d.rootId!==null&&zE(r,d.rootId,{status:"cancelled",signal:u,error:`batch interrupted by ${u}`},n)}process.exit(u==="SIGINT"?130:143)};process.once("SIGINT",o),process.once("SIGTERM",o);let a=!1,l,c=()=>{if(a)return;a=!0;let u=i.getErrors(),d=l?l.getRecordedErrors():[],p=[...u];for(let m of d)p.includes(m)||p.push(m);if(p.length>0){r.stderr.write(`
|
|
2023
|
+
=== LMScript Error Summary (${p.length} error${p.length===1?"":"s"}) ===
|
|
2024
|
+
`);for(let m=0;m<p.length;m++)r.stderr.write(` ${m+1}. ${p[m]}
|
|
2025
|
+
`);r.stderr.write(`==========================================
|
|
2026
|
+
`)}};try{let u=Xd(r,e,i,n);l=u;let d=await u.runAsync(t,{file:s,stderr:p=>{r.stderr.write(p.endsWith(`
|
|
2027
|
+
`)?p:`${p}
|
|
2028
|
+
`)}});if(c(),d.exitCode!==void 0)return d.exitCode;if(!d.success){for(let p of d.diagnostics){let m=p.file?`${p.file}:${p.line}:${p.column}`:`${p.line}:${p.column}`;r.stderr.write(`error:${m}: ${p.message}
|
|
2029
|
+
`)}return 1}return i.hasErrors()||d.errors&&d.errors.length>0?1:0}catch(u){return c(),u instanceof pe||u?.name==="LMScriptExit"?u.exitCode:(r.stderr.write(`error: ${u instanceof Error?u.message:String(u)}
|
|
2030
|
+
`),1)}finally{process.removeListener("SIGINT",o),process.removeListener("SIGTERM",o),await i.forceCloseAll(r)}}var ey=`# batchscript.lms - Test-only comparison with procedural lmctl batch
|
|
2031
|
+
# Arguments: [teamfile, alias, batchfile, flags...]
|
|
2032
|
+
|
|
2033
|
+
if (includes(args, "--help") || includes(args, "-h")) {
|
|
2034
|
+
println("usage: lmctl batch <teamfile> <alias> <batchfile> [--legacy] [--single]");
|
|
2035
|
+
lm_exit(0);
|
|
2036
|
+
}
|
|
2037
|
+
|
|
2038
|
+
if (len(args) < 3) {
|
|
2039
|
+
lm_error("usage: lmctl batch <teamfile> <alias> <batchfile> [--legacy] [--single]");
|
|
2040
|
+
lm_exit(1);
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
teamfile = args[0];
|
|
2044
|
+
alias = args[1];
|
|
2045
|
+
batchfile = args[2];
|
|
2046
|
+
legacy = false;
|
|
2047
|
+
single = false;
|
|
2048
|
+
for (flag_index = 3; flag_index < len(args); flag_index = flag_index + 1) {
|
|
2049
|
+
if (args[flag_index] == "--legacy") {
|
|
2050
|
+
legacy = true;
|
|
2051
|
+
} else if (args[flag_index] == "--single") {
|
|
2052
|
+
single = true;
|
|
2053
|
+
} else {
|
|
2054
|
+
lm_error("batch: unexpected argument: " + args[flag_index]);
|
|
2055
|
+
lm_exit(1);
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
# 1. Read prompts
|
|
2060
|
+
prompts = lm_read_prompts(batchfile, single);
|
|
2061
|
+
|
|
2062
|
+
if (len(prompts) == 0) {
|
|
2063
|
+
lm_error("batch: " + batchfile + ": no prompts found");
|
|
2064
|
+
lm_exit(1);
|
|
2065
|
+
}
|
|
2066
|
+
|
|
2067
|
+
# 2. Open batch session
|
|
2068
|
+
handle = lm_batch_open(teamfile, alias, batchfile, {
|
|
2069
|
+
promptCount: len(prompts),
|
|
2070
|
+
legacy: legacy,
|
|
2071
|
+
single: single
|
|
2072
|
+
});
|
|
2073
|
+
|
|
2074
|
+
if (handle == null) {
|
|
2075
|
+
lm_exit(1);
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2078
|
+
# 3. Sequential prompt execution
|
|
2079
|
+
for (i = 0; i < len(prompts); i = i + 1) {
|
|
2080
|
+
promptText = prompts[i];
|
|
2081
|
+
res = lm_batch_turn(handle, promptText, i + 1, len(prompts));
|
|
2082
|
+
|
|
2083
|
+
# Output reply or partial reply on stall
|
|
2084
|
+
if (res.reply != null && len(res.reply) > 0) {
|
|
2085
|
+
print(res.reply);
|
|
2086
|
+
print(""); # Blank line separator
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
if (res.status != "ok") {
|
|
2090
|
+
lm_batch_close(handle, "error", res.error);
|
|
2091
|
+
lm_exit(1);
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2094
|
+
|
|
2095
|
+
lm_batch_close(handle, "done");
|
|
2096
|
+
lm_exit(0);
|
|
2097
|
+
`;export{ey as BATCH_LMS,zi as LMCTL_FUNCTION_DOCS,Me as LMScript,pe as LMScriptExit,Ut as ResourceRegistry,jd as createBaseScriptEngine,Xd as createLmScriptEngine,Wd as lmctlModule,QE as registerLmctlDocs,Bd as registerLmctlHostFunctions,Hd as registerLmctlModule,ZE as runScriptEngine};
|