@lmctl-ai/lmctl 0.2.274 → 0.2.275
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 +1 -1
- package/build-info.json +1 -1
- package/dist/cli/index.js +429 -430
- package/dist/cli/lmscript.js +217 -217
- package/dist/lmbee.js +1 -1
- package/package.json +1 -1
package/dist/lmbee.js
CHANGED
|
@@ -2012,7 +2012,7 @@ ${nt(m,{provider:"dsh"})}`:"(no output captured)")))},mN);s.stdout?.on("data",m=
|
|
|
2012
2012
|
LIMIT ?`).all(EN,this.discoverLimit),r=[];for(let s of n){let o=this.previewTexts(t,s.id);r.push({provider:this.name,sessionId:s.id,slug:un(s.title),cwd:wN(s),createdAt:Jc(s.started_at),modifiedAt:Jc(s.last_activity_at??s.started_at),model:un(s.model),startCommand:this.name,firstUserMessage:o.first,lastUserMessage:o.last,messageCount:s.message_count??0,filePath:this.dbPath,...TN(s)})}return r}catch(n){return ne({event:"hermes_discover_sessions_failed",provider:this.name,db_path:this.dbPath,error_message:n instanceof Error?n.message:String(n)}),[]}finally{t.close()}}activeMessageRows(t,n){let r=new Set(t.prepare("PRAGMA table_info(messages)").all().map(a=>a.name)),o=`id, session_id, role, content, tool_call_id, tool_calls, tool_name,
|
|
2013
2013
|
timestamp, finish_reason${["_compressed_summary","display_kind"].filter(a=>r.has(a)).map(a=>`, ${a}`).join("")}`,i="WHERE session_id = ? AND role IN ('user', 'assistant', 'tool')";try{return t.prepare(`SELECT ${o} FROM messages ${i} AND active = 1 ORDER BY id ASC`).all(n)}catch(a){if(!/no such column/i.test(a instanceof Error?a.message:String(a)))throw a;return t.prepare(`SELECT ${o} FROM messages ${i} ORDER BY id ASC`).all(n)}}previewTexts(t,n){try{let[r,s]=["ASC","DESC"].map(o=>{let i=`SELECT content FROM messages WHERE session_id = ?
|
|
2014
2014
|
AND role = 'user' AND content != ''`,a;try{a=t.prepare(`${i} AND active = 1 ORDER BY id ${o} LIMIT 1`).get(n)}catch(c){if(!/no such column: active/i.test(String(c)))throw c;a=t.prepare(`${i} ORDER BY id ${o} LIMIT 1`).get(n)}return a?de(a.content,80):void 0});return{first:r,last:s}}catch{return{}}}async loadSession(t){let n=this.openDb();if(!n)return null;try{let r=this.selectSessionRow(n,t);if(!r)return null;let s=this.activeMessageRows(n,t),o=[],i=[],a,c;for(let l of s){let d=Jc(l.timestamp),u=l.content??"";if(l.role==="user"){u&&l._compressed_summary!==1&&l.display_kind!=="hidden"&&i.push(u),u.length>0&&(a||(a=de(u,80)),c=de(u,80)),o.push({role:"user",timestamp:d,content:u||"(empty)"});continue}if(l.role==="tool"){o.push({role:"tool_result",timestamp:d,content:u,toolCallId:un(l.tool_call_id),toolName:un(l.tool_name)});continue}u.length>0&&o.push({role:"assistant",timestamp:d,content:u,model:un(r.model),stopReason:un(l.finish_reason)});for(let f of Tz(l.tool_calls)){let m=vz(f.function?.arguments);o.push({role:"tool_use",timestamp:d,content:un(f.function?.name)??"tool_call",toolName:un(f.function?.name),toolCallId:un(f.call_id)??un(f.id),toolInput:typeof f.function?.arguments=="string"?f.function.arguments:JSON.stringify(f.function?.arguments??{}),toolInputData:Dn(m)})}}return{provider:this.name,sessionId:r.id,slug:un(r.title),cwd:wN(r),createdAt:Jc(r.started_at),modifiedAt:Jc(r.last_activity_at??r.started_at),model:un(r.model),startCommand:this.name,firstUserMessage:a,lastUserMessage:c,messageCount:r.message_count??o.length,filePath:this.dbPath,...TN(r),messages:o,userPrompts:i}}catch(r){return ne({event:"hermes_load_session_failed",provider:this.name,session_id:t,db_path:this.dbPath,error_message:r instanceof Error?r.message:String(r)}),null}finally{n.close()}}async resolveSessionPath(t){let n=this.openDb();if(!n)return null;try{return this.selectSessionRow(n,t)?this.dbPath:null}catch{return null}finally{n.close()}}async deleteSession(t){return!1}};function Tz(e){if(!e)return[];try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}function vz(e){if(e!==null&&typeof e=="object"&&!Array.isArray(e))return e;if(typeof e!="string")return{};try{let t=JSON.parse(e);return t!==null&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return{}}}function TN(e){let t=e.input_tokens??0,n=e.output_tokens??0,r=e.cache_read_tokens??0,s=e.cache_write_tokens??0,o=e.reasoning_tokens??0;return(e.message_count??0)>0&&t+n+r+s+o>0?{totalInputTokens:t,totalCachedInputTokens:r,totalCacheWriteInputTokens:s,totalOutputTokens:n,totalReasoningOutputTokens:o}:{}}var bz=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Az(e){return bz.test(e)}var Iz="dont_ask";function SN(e){if(e==="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 Iz}function Hg(e){return new qg(e)}var qg=class extends Pe{hermesProvider;hermesHome;constructor(t){let n=new Ef(t);super({provider:n,protocol:{transport:"acp",perTurnCancellation:"process",persistentCancellation:"turn",persistentResume:!0},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(r,s)=>Wn(r,{...s,requireResume:s.requireResume??!!s.sessionId,env:{...s.env??process.env,HERMES_HOME:this.hermesHome},acpTool:"hermes",acpMode:SN(s.permissionMode)})}),this.hermesProvider=n,this.hermesHome=jg(t)}async openSession(t){return Er({...t,env:{...t.env??process.env,HERMES_HOME:this.hermesHome},binary:"hermes",acpTool:"hermes",acpMode:SN(t.permissionMode)})}get stateDbPath(){return this.hermesProvider.stateDbPath}async seed(t,n){await Sz(t,{recursive:!0});let r=[];if(n?.effort){let o="hermes has no ACP-level effort surface";ne({event:"hermes_effort_ignored",provider:this.name,effort:n.effort,reason:o}),r.push(`hermes seed ignored effort=${n.effort}: ${o}`)}let s;try{n?.signal?.throwIfAborted();try{n?.onDispatch?.()}catch{}s=await this.sendTurn(n?.prompt??be,{sessionId:"",cwd:t,env:n?.env,signal:n?.signal,model:n?.model})}catch(o){return{success:!1,error:`hermes ACP seed failed: ${o instanceof Error?o.message:String(o)}`}}return Az(s.sessionId)?(r.push(...s.warnings??[]),{success:!0,sessionId:s.sessionId,usage:s.usage,...r.length>0?{warnings:r}:{}}):(ne({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 bN,rm as kz,stat as Rz}from"node:fs/promises";import{join as Wg}from"node:path";var yf=class{name="pi";baseDir;constructor(t={}){this.baseDir=t.piDir||Wg(ge,".pi","agent","sessions")}getWatchPaths(){return[{directory:this.baseDir,filePattern:/\.jsonl$/}]}async discoverSessions(){let t=[];for(let n of await this.listSessionFiles())try{let r=await this.extractSummary(n);r&&t.push(r)}catch{}return t}async listSessionFiles(){let t;try{t=await bN(this.baseDir)}catch{return[]}let n=[];for(let r of t){let s=Wg(this.baseDir,r);try{if(!(await Rz(s)).isDirectory())continue;for(let o of await bN(s))o.endsWith(".jsonl")&&n.push(Wg(s,o))}catch{}}return n}async readHeader(t){for await(let n of ze(t))return n.type==="session"?n:null;return null}async extractSummary(t){let n=await this.readHeader(t);if(!n)return null;let r=await dt(t),s,o,i,a=0,c=0,l=0,d=0,u=0,f=0,m=0,p;for await(let h of ze(t)){if(h.type==="model_change"&&h.provider&&h.modelId){s=`${h.provider}/${h.modelId}`;continue}if(h.type!=="message"||!h.message)continue;let _=h.message;if(_.provider&&_.model&&(s=`${_.provider}/${_.model}`),_.role==="user"){let g=Bg(_).trim();g&&(o||(o=de(g,80)),i=de(g,80)),a++}else if(_.role==="assistant"){a++;let g=_.usage;g&&(c+=g.input??0,l+=g.cacheRead??0,d+=g.cacheWrite??0,u+=g.output??0,f+=g.reasoning??0,m=g.input??0,p={inputTokens:g.input,cachedInputTokens:g.cacheRead,cacheWriteInputTokens:g.cacheWrite,outputTokens:g.output,reasoningOutputTokens:g.reasoning,totalTokens:g.totalTokens})}}return{provider:"pi",sessionId:n.id,cwd:n.cwd??"(unknown)",createdAt:r.createdAt,modifiedAt:r.modifiedAt,model:s,startCommand:"pi",firstUserMessage:o,lastUserMessage:i,messageCount:a,filePath:t,totalInputTokens:c,totalCachedInputTokens:l,totalCacheWriteInputTokens:d,totalOutputTokens:u,totalReasoningOutputTokens:f,lastInputTokens:m,lastTokenUsage:p}}async loadSession(t){let n=await this.resolveSessionPath(t);if(!n)return null;let r=await this.extractSummary(n);if(!r)return null;let s=[],o=r.model;for await(let i of ze(n)){if(i.type==="model_change"&&i.provider&&i.modelId){o=`${i.provider}/${i.modelId}`;continue}if(i.type!=="message"||!i.message)continue;let a=i.message;a.provider&&a.model&&(o=`${a.provider}/${a.model}`);let c=a.timestamp?new Date(a.timestamp):r.modifiedAt;if(a.role==="user")s.push({role:"user",timestamp:c,content:Bg(a)});else if(a.role==="assistant"&&Array.isArray(a.content))for(let l of a.content)l.type==="text"&&l.text?s.push({role:"assistant",timestamp:c,content:l.text,model:o}):l.type==="thinking"&&l.thinking?s.push({role:"thinking",timestamp:c,content:l.thinking}):l.type==="toolCall"&&s.push({role:"tool_use",timestamp:c,content:AN(l.arguments),toolName:l.name??"tool",toolInput:AN(l.arguments),toolInputData:l.arguments,toolCallId:l.id});else a.role==="toolResult"&&s.push({role:"tool_result",timestamp:c,content:Bg(a),toolName:a.toolName,toolCallId:a.toolCallId})}return{...r,model:o,messages:s}}async resolveSessionPath(t){let n=`_${t}.jsonl`,r=[];for(let s of await this.listSessionFiles()){if(s.endsWith(n))return s;s.split("_").pop()?.replace(/\.jsonl$/,"")?.startsWith(t)&&r.push(s)}return r.length===1?r[0]:null}async deleteSession(t){let n=await this.resolveSessionPath(t);return n?(await kz(n,{force:!0}),!0):!1}};function Bg(e){return typeof e.content=="string"?e.content:Array.isArray(e.content)?e.content.filter(t=>t.type==="text"&&t.text).map(t=>t.text).join(" "):""}function AN(e){if(e===void 0)return"";try{return JSON.stringify(e)}catch{return String(e)}}function Xg(e){return new Gg(e)}var Gg=class extends Pe{constructor(t){super({provider:new yf(t),protocol:{transport:"print",perTurnCancellation:"process"},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",be],resumeTemplate:"pi --session {{session_id}}",startTemplate:"pi",transport:Nz})}seedArgsFor(t){let n=[...super.seedArgsFor(t)];return t?.model&&n.push("--model",t.model),n}manualSeedHint(t){return{launchCommand:`cd ${t} && pi`,postLaunchNote:"Send the lmctl seed instruction, wait for the session file to write, then exit.",lsCommand:`lmctl ls --provider pi --sessiondir ${t}`}}},Nz=mf({label:"pi",buildArgs:(e,t)=>{let n=[...t.sessionId?["--session",t.sessionId]:[],"-p",e];return t.model&&n.push("--model",t.model),n},assertArgs:(e,t)=>St("pi",e,t.permissionMode??"yolo")});import{createHash as xz}from"node:crypto";import{existsSync as Lz,mkdirSync as Jg,readFileSync as Cz,renameSync as Oz,rmdirSync as ON,statSync as Dz,writeFileSync as $z}from"node:fs";import{dirname as Qg,join as IN,resolve as Vg}from"node:path";var ta=new Map;function Mz(e){return xz("sha256").update(e).digest("hex").slice(0,8)}function Pz(e){let t=e.trim().toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"");return t.length>0?t:"session"}function Uz(e,t){let n=t?.prompt??"",r=/\bYou are alias\s+([A-Za-z][A-Za-z0-9_-]*)\b/.exec(n);return r!==null?r[1]:e.split(/[\\/]/).filter(Boolean).pop()??"session"}function DN(e){return e.split(/\r?\n/,1)[0]?.trim()||"(empty prompt)"}function wf(e){return Math.max(1,Math.ceil(e.length/4))}function na(e=process.cwd()){let t=process.env.LMCTL_CLAUDE_MOCK_STORE;if(t!==void 0&&t.trim().length>0)return Vg(t);let n=process.env.LMCTL_DB;return n!==void 0&&n.trim().length>0?IN(Qg(Vg(n)),".lmctl-claude-mock","sessions.json"):IN(Vg(e),".lmctl-claude-mock","sessions.json")}function kN(){return{schemaVersion:1,sessions:{}}}function Yc(e){if(!Lz(e))return kN();try{let t=JSON.parse(Cz(e,"utf8")),n=typeof t.sessions=="object"&&t.sessions!==null?t.sessions:{},r=typeof t.script=="object"&&t.script!==null?t.script:void 0,s=typeof t.scriptContains=="object"&&t.scriptContains!==null?t.scriptContains:void 0,o=Yg(t.defaultDelayMs);return{schemaVersion:1,sessions:n,...o!==void 0?{defaultDelayMs:o}:{},...r!==void 0?{script:r}:{},...s!==void 0?{scriptContains:s}:{}}}catch{return kN()}}function $N(e,t){Jg(Qg(e),{recursive:!0});let n=`${e}.${process.pid}.${Date.now()}.tmp`;$z(n,`${JSON.stringify(t,null,2)}
|
|
2015
|
-
`,"utf8"),Oz(n,e)}var Fz=5e3,jz=15,RN=1e4;function qz(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function Hz(e){let t=`${e}.lock`;Jg(Qg(e),{recursive:!0});let n=Date.now()+RN;for(;;)try{return Jg(t),t}catch(r){if(r.code!=="EEXIST")throw r;try{if(Date.now()-Dz(t).mtimeMs>Fz){try{ON(t)}catch{}continue}}catch{continue}if(Date.now()>=n)throw new Error(`ClaudeMock store lock timeout after ${RN}ms: ${t}`);qz(jz)}}function Wz(e){try{ON(e)}catch{}}function MN(e,t){let n=Hz(e);try{return t()}finally{Wz(n)}}function Bz(e){return{...e,timestamp:e.timestamp.toISOString()}}function Gz(e){return{...e,timestamp:new Date(e.timestamp)}}function Xz(e){return{...e,createdAt:e.createdAt.toISOString(),modifiedAt:e.modifiedAt.toISOString(),messages:e.messages.map(Bz)}}function PN(e){return{...e,createdAt:new Date(e.createdAt),modifiedAt:new Date(e.modifiedAt),messages:e.messages.map(Gz)}}function Tf(e,t=process.cwd()){let n=ta.get(e);if(n!==void 0)return n;let s=Yc(na(t)).sessions[e];if(s===void 0)return;let o=PN(s);return ta.set(o.sessionId,o),o}function NN(e){ta.set(e.sessionId,e);let t=na(e.cwd);MN(t,()=>{let n=Yc(t);n.sessions[e.sessionId]=Xz({...e,filePath:t}),$N(t,n)})}function Vz(e,t=process.cwd()){let n=na(t);return MN(n,()=>{let r=Yc(n),s=r.sessions[e]!==void 0;return s&&(delete r.sessions[e],$N(n,r)),s})}function Jz(){let e=Yc(na()),t=Object.values(e.sessions).map(PN);for(let n of t)ta.set(n.sessionId,n);return t}function Yg(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function xN(e){if(typeof e=="string")return{kind:"success",text:e};if(e!==void 0&&typeof e.text=="string"&&typeof e.error!="string"){let t=Yg(e.delayMs);return{kind:"success",text:e.text,...t!==void 0?{delayMs:t}:{}}}if(e!==void 0&&typeof e.error=="string"&&typeof e.text!="string"){let t=Yg(e.delayMs);return{kind:"error",error:e.error,...t!==void 0?{delayMs:t}:{}}}}async function LN(e){e!==void 0&&e>0&&await new Promise(t=>setTimeout(t,e))}function Yz(e,t){let{script:n,scriptContains:r}=t;if(n!==void 0){let s=xN(n[e]??n[DN(e)]);if(s!==void 0)return s}if(r!==void 0){for(let s of Object.keys(r))if(e.includes(s)){let o=xN(r[s]);if(o!==void 0)return o}}}function CN(e){return{provider:"ClaudeMock",sessionId:e.sessionId,cwd:e.cwd,createdAt:e.createdAt,modifiedAt:e.modifiedAt,messageCount:e.messages.length,filePath:e.filePath,cliVersion:"ClaudeMock/0",model:"claude-mock",totalInputTokens:e.totalInputTokens,totalOutputTokens:e.totalOutputTokens,lastTokenUsage:{totalTokens:e.totalInputTokens+e.totalOutputTokens}}}var Kg=class{name="ClaudeMock";async discoverSessions(){let t=new Map;for(let n of Jz())t.set(n.sessionId,n);for(let n of ta.values())t.set(n.sessionId,n);return[...t.values()].map(CN)}async loadSession(t){let n=Tf(t);return n===void 0?null:{...CN(n),messages:n.messages.slice()}}async resolveSessionPath(t){return Tf(t)?.filePath??null}async deleteSession(t){let n=ta.delete(t),r=Vz(t);return n||r}},zg=class{name="ClaudeMock";capabilities={canCreate:!0,canResumeInteractive:!1,canFork:!1,forkSupport:"manual",canStructuredTurn:!0,canStreamDeltas:!1,canCancel:!1};injection={leaderMode:"none"};provider=new Kg;discover(){return this.provider.discoverSessions()}load(t){return this.provider.loadSession(t)}resolvePath(t){return this.provider.resolveSessionPath(t)}delete(t){return this.provider.deleteSession(t)}getWatchPaths(){return[]}async seed(t,n){try{n?.onDispatch?.()}catch{}let r=Pz(Uz(t,n)),s=`mock-${r}-${Mz(`${t}:${r}`)}`,o=new Date,i=na(t),a=Tf(s,t),c=n?.prompt??"ClaudeMock seed",l=wf(c),d={sessionId:s,cwd:t,filePath:i,createdAt:a?.createdAt??o,modifiedAt:o,messages:a?.messages.slice()??[],totalInputTokens:a?.totalInputTokens??0,totalOutputTokens:a?.totalOutputTokens??0};return d.messages.push({role:"user",timestamp:o,content:c}),d.messages.push({role:"assistant",timestamp:o,content:"ACK: ClaudeMock seeded"}),d.totalInputTokens+=l,d.totalOutputTokens+=wf("ACK: ClaudeMock seeded"),NN(d),{success:!0,sessionId:s}}resumeCommand(t){return`ClaudeMock --resume ${t}`}startCommand(){return"ClaudeMock"}manualSeedHint(t){return{launchCommand:`cd ${t} && ClaudeMock`,postLaunchNote:"ClaudeMock is a hermetic test provider; no manual seed is required.",lsCommand:`lmctl ls --provider ClaudeMock --sessiondir ${t}`}}forkHint(t){return"ClaudeMock does not support fork."}async fork(t,n){return{success:!1,error:"ClaudeMock does not support fork."}}async sendTurn(t,n){let r=Date.now(),s=Tf(n.sessionId,n.cwd);if(s===void 0)throw new Error(`ClaudeMock session not found: ${n.sessionId}`);let o=new Date,i=Yc(na(n.cwd)),a=Yz(t,i),c=a?.delayMs??i.defaultDelayMs;if(a?.kind==="error")throw await LN(c),new Error(a.error);let l=a?.kind==="success"?a.text:`ClaudeMock ack: ${DN(t)}`;return s.messages.push({role:"user",timestamp:o,content:t}),s.messages.push({role:"assistant",timestamp:o,content:l,model:n.model??"claude-mock"}),s.modifiedAt=o,s.totalInputTokens+=wf(t),s.totalOutputTokens+=wf(l),NN(s),n.onProgress?.({kind:"text",summary:"ClaudeMock deterministic reply"}),await LN(c),{text:l,sessionId:n.sessionId,durationMs:Math.max(1,Date.now()-r),stopReason:"mock_stop",numTurns:1,status:"ok"}}};function Zg(){return new zg}function Bs(e){let t=[B_({museDataHome:e?.museDataHome}),rg({miniplayerHome:e?.miniplayerHome}),og({claudeDir:e?.claudeDir}),lg({codexDir:e?.codexDir,codeDir:e?.codeDir}),mg({geminiDir:e?.geminiDir,claudeDir:e?.claudeDir,codexDir:e?.codexDir,codeDir:e?.codeDir}),_g({copilotDir:e?.copilotDir}),Eg({dbPaths:e?.opencodeDbPaths}),vg({kimiHome:e?.kimiHome}),bg({lmplayerDbPath:e?.lmplayerDbPath,lmplayerDbPaths:e?.lmplayerDbPaths}),Ig({qwenDir:e?.qwenDir}),Ng({agyDir:e?.agyDir}),Ug({dshHome:e?.dshHome}),Hg({hermesHome:e?.hermesHome}),Xg({piDir:e?.piDir})];return process.env.LMCTL_ENABLE_MOCK_PROVIDER==="1"&&t.push(Zg()),t}var eE=null;function UN(){return eE===null&&(eE=Ms(Bs())),eE}function FN(e,t){Iu(t);let n=e.getAdapter(t);if(!n)throw new Error(`provider "${t}" is not registered in this registry`);return n}async function jN(e){let t=e.registry??UN(),n=FN(t,e.provider),r={sessionId:e.sessionId,cwd:e.cwd,env:e.env,onDelta:e.onDelta,onProgress:e.onProgress,signal:e.signal,timeoutMs:e.timeoutMs,model:e.model,effort:e.effort,progPath:e.progPath,alias:e.alias,isLead:e.isLead,permissionMode:e.permissionMode,holdOpen:e.holdOpen,requireResume:e.requireResume,bundleSession:e.bundleSession},s=e.bundleSession===void 0?await N_(n,{...r,execution:"per-turn",requireResume:e.requireResume??!1}):void 0,o;try{o=s?await s.sendTurn(e.prompt,{onDelta:e.onDelta,onProgress:e.onProgress,signal:e.signal}):await n.sendTurn(e.prompt,r)}finally{await s?.close()}return{text:o.text,...o.usage?{usage:o.usage}:{},sessionId:o.sessionId,durationMs:o.durationMs,stopReason:o.stopReason,numTurns:o.numTurns,status:o.status,stalledAfterMs:o.stalledAfterMs,...o.warnings!==void 0?{warnings:o.warnings}:{}}}async function qN(e){return N_(FN(e.registry??UN(),e.provider),e)}import{join as Wt}from"node:path";var HN=new WeakMap;function Kc(e){let t=HN.get(e);if(t)return t;let n=e.env.HOME;if(!n)return Ms(Bs());let r=e.env.XDG_DATA_HOME||Wt(n,".local/share"),s=e.env.XDG_CONFIG_HOME||Wt(n,".config");return t=Ms(Bs({museDataHome:r,miniplayerHome:e.env.MINIPLAYER_HOME||Wt(r,"miniplayer"),claudeDir:Wt(n,".claude"),codexDir:Wt(n,".codex"),codeDir:Wt(n,".code"),geminiDir:Wt(n,".gemini"),copilotDir:Wt(n,".copilot"),qwenDir:Wt(n,".qwen"),opencodeDbPaths:[Wt(r,"opencode/opencode.db"),Wt(s,"opencode/opencode.db")],agyDir:Wt(n,".gemini/antigravity-cli"),dshHome:Wt(n,".dsh"),hermesHome:e.env.HERMES_HOME??Wt(n,".hermes"),kimiHome:e.env.KIMI_CODE_HOME??Wt(n,".kimi-code"),piDir:Wt(n,".pi/agent/sessions"),lmplayerDbPaths:Z_(e.env,n)})),HN.set(e,t),t}var Xs=e=>{if(e&&typeof e=="object"){for(let t of Object.values(e))Xs(t);Object.freeze(e)}return e},vSe=Xs(["invalid_argument","not_found","missing","read","syntax","schema","busy","provider","noninteractive","cancelled","internal","closed","service_unavailable","outcome_unknown"]),SSe=Xs({status:"string",error:"string|null",code:"ErrorCode?"}),bSe=Xs(["Provider1","Provider2","Provider3","Model1","Model2","Model3"]),ASe=Xs(["Provider1.Provider","Provider1.Model1","Provider1.Model2","Provider1.Model3","Provider2.Provider","Provider2.Model1","Provider2.Model2","Provider2.Model3","Provider3.Provider","Provider3.Model1","Provider3.Model2","Provider3.Model3"]),ISe=Xs(["Provider1","Provider2","Provider3"]),kSe=Xs({Provider1:"PROPS.Provider1.Provider",Provider2:"PROPS.Provider2.Provider",Provider3:"PROPS.Provider3.Provider",Model1:"PROPS.Provider1.Model1",Model2:"PROPS.Provider2.Model1",Model3:"PROPS.Provider3.Model1"}),De={name:"ctx",type:"context"},tE={name:"options",type:"map",optional:!0,keys:[{name:"path",type:"string"}]},Tr={name:"teamfile",type:"string"},vf={name:"alias",type:"string"},Gs={name:"prompt",type:"string"},Sf={name:"member",type:"map",keys:[{name:"provider",type:"string",required:!0},{name:"alias",type:"string"},{name:"model",type:"string"},{name:"effort",type:"string"},{name:"sessiondir",type:"string"},{name:"sessionid",type:"string"}]},Af=[{name:"permissionMode",type:"string",values:["yolo","plan"]},{name:"idleTimeoutMs",type:"number"}],ra={name:"options",type:"map",optional:!0,keys:Af},WN={name:"options",type:"map",optional:!0,keys:[{name:"preamble",type:"string|map"}]},BN={name:"options",type:"map",optional:!0,keys:[{name:"providers",type:"list"},{name:"provider",type:"string"},{name:"timeoutSeconds",type:"number"}]},GN={name:"options",type:"map",keys:[{name:"force",type:"boolean",required:!0,values:[!0]}]},sa={name:"target",type:"map",keys:[{name:"provider",type:"string",required:!0},{name:"sessionid",type:"string",required:!0}]},bf={name:"member",type:"map",keys:[{name:"provider",type:"string",required:!0},{name:"sessionid",type:"string",required:!0},{name:"sessiondir",type:"string"},{name:"model",type:"string"},{name:"effort",type:"string"}]},Kz=[{name:"teamfile",type:"string"},{name:"member",type:"string"},{name:"since",type:"string"},{name:"tree",type:"boolean"}],XN={name:"options",type:"map",optional:!0,keys:Kz},VN={error:"string|null",reply:"string",sessionid:"string|null",messageId:"string|null",teamChatLogId:"number|null"},zz=Xs([{name:"resolveProfilePath",implemented:!0,params:[De,tE],statuses:["ok","error"],results:{error:"string|null",path:"string"},effects:[],summary:"Resolve a profile path solely from explicit context."},{name:"loadProfile",implemented:!0,params:[De,tE],statuses:["ok","error"],results:{error:"string|null",profile:"{path,raw,config}",values:"{Provider1..3,Model1..3,Directory,NonInteractive}",path:"string?",line:"number?",column:"number?"},effects:["file-read"],summary:"Read and validate the complete init profile without discovery or writes."},{name:"profileValues",implemented:!0,params:[{name:"config",type:"map"}],statuses:["ok","error"],results:{error:"string|null",Provider1:"string",Provider2:"string",Provider3:"string",Model1:"string",Model2:"string",Model3:"string"},effects:[],summary:"Validate and map slots to first-model environment values."},{name:"readPrompts",implemented:!0,params:[De,{name:"path",type:"string"},{name:"options",type:"map",optional:!0,keys:[{name:"single",type:"boolean"}]}],statuses:["ok","error"],results:{error:"string|null",prompts:"string[]"},effects:["file-read"],summary:"Read prompt records without exiting the caller.",scriptBinding:{name:"lm_read_prompts",params:[{name:"batchfile",type:"string"},{name:"single",type:"boolean",optional:!0}]}},{name:"listMembers",implemented:!0,params:[De,Tr],statuses:["ok","error"],results:{error:"string|null",members:"Member[]"},effects:["file-read"],summary:"List team members.",scriptBinding:{name:"lm_members",params:[Tr]}},{name:"resolveMember",implemented:!0,params:[De,Tr,vf],statuses:["ok","not_found","error"],results:{error:"string|null",member:"Member",isLead:"boolean",teamfile:"string"},effects:["file-read","db"],summary:"Resolve a team member with an explicit missing outcome.",scriptBinding:{name:"lm_member",params:[Tr,vf]}},{name:"lintTeam",implemented:!0,params:[De,Tr],statuses:["ok","error"],results:{error:"string|null",errors:"list",warnings:"list",counts:"map"},effects:["file-read","db"],summary:"Return structured lint findings.",scriptBinding:{name:"lm_lint",params:[Tr]}},{name:"seedTeam",implemented:!0,params:[De,Tr,WN],statuses:["ok","error"],results:{error:"string|null",seeded:"SeededMember[]"},effects:["provider","db","file-write"],summary:"Seed a team with explicit optional preambles.",scriptBinding:{name:"lm_seed",params:[Tr,WN]}},{name:"promptAgent",implemented:!0,params:[De,Sf,Gs,ra],statuses:["ok","busy","stalled","empty","cancelled","error"],results:{...VN,messageId:"null",teamChatLogId:"null"},effects:["provider","db"],summary:"Turn a provider session without mutating the input member.",scriptBinding:{name:"lm_agent",params:[Sf,Gs,ra]}},{name:"promptMember",implemented:!0,params:[De,{name:"request",type:"map",keys:[{name:"teamfile",type:"string",required:!0},{name:"alias",type:"string",required:!0},{name:"prompt",type:"string",required:!0},{name:"messageType",type:"string"},...Af]}],statuses:["ok","busy","stalled","empty","cancelled","error"],results:{error:"string|null",reply:"string",messageId:"string|null",teamChatLogId:"number|null"},effects:["provider","db"],summary:"Turn a team member through native team admission.",scriptBinding:{name:"lm_prompt",params:[Tr,vf,Gs,{name:"options",type:"map",optional:!0,keys:[...Af,{name:"messageType",type:"string"}]}]}},{name:"listSessions",implemented:!0,params:[De,{name:"options",type:"map",optional:!0,keys:[{name:"provider",type:"string"},{name:"workspace",type:"string"},{name:"all",type:"boolean"}]}],statuses:["ok","error"],results:{error:"string|null",sessions:"Session[]"},effects:["file-read"],summary:"List native sessions in an explicit workspace.",scriptBinding:{name:"lm_session_list",params:[{name:"options",type:"map",optional:!0,keys:[{name:"provider",type:"string"},{name:"sessiondir",type:"string"},{name:"all",type:"boolean"}]}]}},{name:"deleteSession",implemented:!0,params:[De,sa,GN],statuses:["deleted","not_found","busy","error"],results:{error:"string|null"},effects:["provider","file-write"],summary:"Delete a session only with explicit force admission.",scriptBinding:{name:"lm_session_delete",params:[Sf,{...GN,optional:!0}]}},{name:"getSession",implemented:!0,params:[De,sa],statuses:["ok","not_found","error"],results:{error:"string|null",messages:"{role,content}[]"},effects:["provider","file-read"],summary:"Read native session messages.",scriptBinding:{name:"lm_session_get",params:[sa]}},{name:"reserveSession",implemented:!0,params:[De,sa],statuses:["ok","busy","error"],results:{error:"string|null",reservation:"SessionReservation"},effects:[],summary:"Reserve context-local handoff admission and return a capability."},{name:"releaseSession",implemented:!0,params:[De,sa,{name:"reservation",type:"SessionReservation",optional:!0}],statuses:["ok","error"],results:{error:"string|null"},effects:[],summary:"Release context-local handoff admission; an optional capability makes owned cleanup idempotent and replacement-safe."},{name:"openTeamBatch",returnsResource:!0,implemented:!0,params:[De,{name:"request",type:"map",keys:[{name:"teamfile",type:"string",required:!0},{name:"alias",type:"string",required:!0},{name:"label",type:"string",required:!0},{name:"promptCount",type:"number",required:!0},{name:"legacy",type:"boolean"},...Af]}],statuses:["ok","busy","error"],results:{error:"string|null",batch:"opaque context-bound BatchRef"},effects:["provider","db"],summary:"Open a managed team batch; member-map composition remains language-owned."},{name:"batchTurn",implemented:!0,params:[De,{name:"batch",type:"BatchRef"},Gs,{name:"index",type:"number"},{name:"total",type:"number"}],statuses:["ok","busy","stalled","empty","cancelled","error"],results:{error:"string|null",reply:"string",messageId:"string|null",teamChatLogId:"number|null"},effects:["provider","db"],summary:"Turn an owned live batch reference."},{name:"closeBatch",implemented:!0,params:[De,{name:"batch",type:"BatchRef"},{name:"options",type:"map",keys:[{name:"status",type:"string",required:!0,values:["done","error","cancelled"]},{name:"error",type:"string"}]}],statuses:["ok","error"],results:{error:"string|null"},effects:["provider","db"],summary:"Idempotently close an owned batch."},{name:"readRatelimits",implemented:!0,params:[De,BN],statuses:["ok","error"],results:{error:"string|null",readings:"list"},effects:["file-read","network"],summary:"Read provider rate-limit data.",scriptBinding:{name:"lm_ratelimit_readings",params:[BN]}},{name:"openTerminal",implemented:!0,params:[De,{name:"target",type:"map",keys:[{name:"teamfile",type:"string",required:!0},{name:"alias",type:"string",required:!0}]},{name:"streams",type:"map",keys:[{name:"stdin",type:"stream",required:!0},{name:"stdout",type:"stream",required:!0},{name:"stderr",type:"stream",required:!0}]}],statuses:["ok","error"],results:{error:"string|null",code:"number|null",signal:"string|null"},effects:["provider","db","tty"],summary:"Open a native terminal with caller-supplied streams.",scriptBinding:{name:"lm_terminal",params:[Tr,vf]}},{name:"sessionAdmission",implemented:!0,params:[De,sa],statuses:["ok","busy","error"],results:{error:"string|null",busyReason:"turn|handoff?"},effects:[],summary:"Query context-local session admission without exposing mutable sets."},{name:"promptReservedAgent",implemented:!0,params:[De,{name:"reservation",type:"SessionReservation"},Sf,Gs,ra],statuses:["ok","busy","stalled","empty","error"],results:{...VN,messageId:"null",teamChatLogId:"null"},effects:["provider"],summary:"Turn only the session authorized by a live context-bound reservation."},{name:"finalizeBatchSync",implemented:!0,params:[De,{name:"batch",type:"BatchRef"}],statuses:["ok","error"],results:{error:"string|null"},effects:["db"],summary:"Synchronously release one batch on a close deadline without cancelling unrelated batches."},{name:"inspectBatch",implemented:!0,params:[De,{name:"batch",type:"BatchRef"}],statuses:["ok","error"],results:{error:"string|null",id:"string",closed:"boolean",member:"Member",rootId:"number|null"},effects:[],summary:"Read batch metadata without exposing native transports or lease capabilities."},{name:"openNativeSession",returnsResource:!0,implemented:!0,params:[De,{name:"member",type:"map",keys:[{name:"provider",type:"string",required:!0},{name:"sessionid",type:"string",required:!0},{name:"sessiondir",type:"string"},{name:"model",type:"string"},{name:"effort",type:"string"}]},ra],statuses:["ok","busy","error"],results:{error:"string|null",session:"opaque context-bound NativeSessionRef"},effects:["provider","db","file-read"],summary:"Open a script-owned native conversation with existing receiver admission."},{name:"nativeSessionTurn",implemented:!0,params:[De,{name:"session",type:"NativeSessionRef"},Gs],statuses:["ok","busy","stalled","empty","error"],results:{error:"string|null",reply:"string",messageId:"string|null",teamChatLogId:"number|null"},effects:["provider","db"],summary:"Record one unframed conversational turn through the existing recorder."},{name:"closeNativeSession",implemented:!0,params:[De,{name:"session",type:"NativeSessionRef"}],statuses:["ok","error"],results:{error:"string|null"},effects:["provider","db"],summary:"Idempotently close a script-owned native conversation and release its lease."},{name:"finalizeNativeSessionSync",implemented:!0,params:[De,{name:"session",type:"NativeSessionRef"}],statuses:["ok","error"],results:{error:"string|null"},effects:["db"],summary:"Critical synchronous native conversation lease release."},{name:"nativeSessionRequest",implemented:!0,params:[De,bf,Gs,ra],statuses:["ok","busy","stalled","empty","error"],results:{error:"string|null",reply:"string",messageId:"string|null",teamChatLogId:"number|null",code:"ErrorCode?",outcome:"not_sent|completed|unknown?",service_epoch:"string|null?",connection_epoch:"number|null?",connection_state:"new|reused|reinitialized|null?"},effects:["provider","db","network"],summary:"Send a stateless native-id turn to a qualified conversation in the configured running lmbee service.",scriptBinding:{name:"lm_session_turn",params:[bf,Gs,ra]}},{name:"nativeSessionClose",implemented:!0,params:[De,bf],statuses:["ok","busy","error"],results:{error:"string|null",code:"ErrorCode?",outcome:"not_sent|completed|unknown?",service_epoch:"string|null?",connection_epoch:"number|null?",connection_state:"new|reused|reinitialized|null?"},effects:["provider","db","network"],summary:"Close an idle service-hosted native conversation; an absent entry is already closed.",scriptBinding:{name:"lm_session_close",params:[bf]}},{name:"loadProperties",implemented:!0,params:[De,tE],statuses:["ok","error"],results:{error:"string|null",path:"string",properties:"map",flat:"map",line:"number?",column:"number?"},effects:["file-read"],summary:"Read the complete hierarchical init.toml properties document through the canonical reader."},{name:"listRunning",implemented:!0,params:[De,XN],statuses:["ok","error"],results:{error:"string|null",running:"RunningRow[]",dead:"DeadRow[]",idle:"IdleRow[]"},effects:["db"],summary:"DB-wide view of tracked invocation activity. Observation only; dispatch and branch on status busy, never gate on this.",scriptBinding:{name:"lm_running",params:[XN]}}]);function nE(e){if(!KI(e))return Be("invalid_argument","Expected a context created by createLmctlContext");if(e.closed)return Be("cancelled","Context is closed")}function JN(e,t){let n=r=>s=>{t?.(s,r),r==="stderr"&&s.startsWith("warning:")?e.onWarning(s):e.onProgress(s,r)};return{cwd:e.cwd,env:{...e.env,LMCTL_DB:e.dbPath},dal:e.dal,stdout:{write:n("stdout")},stderr:{write:n("stderr")}}}import{readFileSync as Zz,writeFileSync as USe,renameSync as FSe,existsSync as e4}from"node:fs";import{basename as t4,resolve as kf,dirname as rE}from"node:path";var If=["title","description","members"],Qz=new Set(If),vr=class extends Error{constructor(t){super(t),this.name="FrontmatterError"}};function YN(e){if(e.length===0||!e.startsWith("---"))throw new vr("frontmatter must start at line 1 with `---` on its own line");let t=e.split(`
|
|
2015
|
+
`,"utf8"),Oz(n,e)}var Fz=5e3,jz=15,RN=1e4;function qz(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function Hz(e){let t=`${e}.lock`;Jg(Qg(e),{recursive:!0});let n=Date.now()+RN;for(;;)try{return Jg(t),t}catch(r){if(r.code!=="EEXIST")throw r;try{if(Date.now()-Dz(t).mtimeMs>Fz){try{ON(t)}catch{}continue}}catch{continue}if(Date.now()>=n)throw new Error(`ClaudeMock store lock timeout after ${RN}ms: ${t}`);qz(jz)}}function Wz(e){try{ON(e)}catch{}}function MN(e,t){let n=Hz(e);try{return t()}finally{Wz(n)}}function Bz(e){return{...e,timestamp:e.timestamp.toISOString()}}function Gz(e){return{...e,timestamp:new Date(e.timestamp)}}function Xz(e){return{...e,createdAt:e.createdAt.toISOString(),modifiedAt:e.modifiedAt.toISOString(),messages:e.messages.map(Bz)}}function PN(e){return{...e,createdAt:new Date(e.createdAt),modifiedAt:new Date(e.modifiedAt),messages:e.messages.map(Gz)}}function Tf(e,t=process.cwd()){let n=ta.get(e);if(n!==void 0)return n;let s=Yc(na(t)).sessions[e];if(s===void 0)return;let o=PN(s);return ta.set(o.sessionId,o),o}function NN(e){ta.set(e.sessionId,e);let t=na(e.cwd);MN(t,()=>{let n=Yc(t);n.sessions[e.sessionId]=Xz({...e,filePath:t}),$N(t,n)})}function Vz(e,t=process.cwd()){let n=na(t);return MN(n,()=>{let r=Yc(n),s=r.sessions[e]!==void 0;return s&&(delete r.sessions[e],$N(n,r)),s})}function Jz(){let e=Yc(na()),t=Object.values(e.sessions).map(PN);for(let n of t)ta.set(n.sessionId,n);return t}function Yg(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function xN(e){if(typeof e=="string")return{kind:"success",text:e};if(e!==void 0&&typeof e.text=="string"&&typeof e.error!="string"){let t=Yg(e.delayMs);return{kind:"success",text:e.text,...t!==void 0?{delayMs:t}:{}}}if(e!==void 0&&typeof e.error=="string"&&typeof e.text!="string"){let t=Yg(e.delayMs);return{kind:"error",error:e.error,...t!==void 0?{delayMs:t}:{}}}}async function LN(e){e!==void 0&&e>0&&await new Promise(t=>setTimeout(t,e))}function Yz(e,t){let{script:n,scriptContains:r}=t;if(n!==void 0){let s=xN(n[e]??n[DN(e)]);if(s!==void 0)return s}if(r!==void 0){for(let s of Object.keys(r))if(e.includes(s)){let o=xN(r[s]);if(o!==void 0)return o}}}function CN(e){return{provider:"ClaudeMock",sessionId:e.sessionId,cwd:e.cwd,createdAt:e.createdAt,modifiedAt:e.modifiedAt,messageCount:e.messages.length,filePath:e.filePath,cliVersion:"ClaudeMock/0",model:"claude-mock",totalInputTokens:e.totalInputTokens,totalOutputTokens:e.totalOutputTokens,lastTokenUsage:{totalTokens:e.totalInputTokens+e.totalOutputTokens}}}var Kg=class{name="ClaudeMock";async discoverSessions(){let t=new Map;for(let n of Jz())t.set(n.sessionId,n);for(let n of ta.values())t.set(n.sessionId,n);return[...t.values()].map(CN)}async loadSession(t){let n=Tf(t);return n===void 0?null:{...CN(n),messages:n.messages.slice()}}async resolveSessionPath(t){return Tf(t)?.filePath??null}async deleteSession(t){let n=ta.delete(t),r=Vz(t);return n||r}},zg=class{name="ClaudeMock";capabilities={canCreate:!0,canResumeInteractive:!1,canFork:!1,forkSupport:"manual",canStructuredTurn:!0,canStreamDeltas:!1,canCancel:!1};injection={leaderMode:"none"};provider=new Kg;discover(){return this.provider.discoverSessions()}load(t){return this.provider.loadSession(t)}resolvePath(t){return this.provider.resolveSessionPath(t)}delete(t){return this.provider.deleteSession(t)}getWatchPaths(){return[]}async seed(t,n){try{n?.onDispatch?.()}catch{}let r=Pz(Uz(t,n)),s=`mock-${r}-${Mz(`${t}:${r}`)}`,o=new Date,i=na(t),a=Tf(s,t),c=n?.prompt??"ClaudeMock seed",l=wf(c),d={sessionId:s,cwd:t,filePath:i,createdAt:a?.createdAt??o,modifiedAt:o,messages:a?.messages.slice()??[],totalInputTokens:a?.totalInputTokens??0,totalOutputTokens:a?.totalOutputTokens??0};return d.messages.push({role:"user",timestamp:o,content:c}),d.messages.push({role:"assistant",timestamp:o,content:"ACK: ClaudeMock seeded"}),d.totalInputTokens+=l,d.totalOutputTokens+=wf("ACK: ClaudeMock seeded"),NN(d),{success:!0,sessionId:s}}resumeCommand(t){return`ClaudeMock --resume ${t}`}startCommand(){return"ClaudeMock"}manualSeedHint(t){return{launchCommand:`cd ${t} && ClaudeMock`,postLaunchNote:"ClaudeMock is a hermetic test provider; no manual seed is required.",lsCommand:`lmctl ls --provider ClaudeMock --sessiondir ${t}`}}forkHint(t){return"ClaudeMock does not support fork."}async fork(t,n){return{success:!1,error:"ClaudeMock does not support fork."}}async sendTurn(t,n){let r=Date.now(),s=Tf(n.sessionId,n.cwd);if(s===void 0)throw new Error(`ClaudeMock session not found: ${n.sessionId}`);let o=new Date,i=Yc(na(n.cwd)),a=Yz(t,i),c=a?.delayMs??i.defaultDelayMs;if(a?.kind==="error")throw await LN(c),new Error(a.error);let l=a?.kind==="success"?a.text:`ClaudeMock ack: ${DN(t)}`;return s.messages.push({role:"user",timestamp:o,content:t}),s.messages.push({role:"assistant",timestamp:o,content:l,model:n.model??"claude-mock"}),s.modifiedAt=o,s.totalInputTokens+=wf(t),s.totalOutputTokens+=wf(l),NN(s),n.onProgress?.({kind:"text",summary:"ClaudeMock deterministic reply"}),await LN(c),{text:l,sessionId:n.sessionId,durationMs:Math.max(1,Date.now()-r),stopReason:"mock_stop",numTurns:1,status:"ok"}}};function Zg(){return new zg}function Bs(e){let t=[B_({museDataHome:e?.museDataHome}),rg({miniplayerHome:e?.miniplayerHome}),og({claudeDir:e?.claudeDir}),lg({codexDir:e?.codexDir,codeDir:e?.codeDir}),mg({geminiDir:e?.geminiDir,claudeDir:e?.claudeDir,codexDir:e?.codexDir,codeDir:e?.codeDir}),_g({copilotDir:e?.copilotDir}),Eg({dbPaths:e?.opencodeDbPaths}),vg({kimiHome:e?.kimiHome}),bg({lmplayerDbPath:e?.lmplayerDbPath,lmplayerDbPaths:e?.lmplayerDbPaths}),Ig({qwenDir:e?.qwenDir}),Ng({agyDir:e?.agyDir}),Ug({dshHome:e?.dshHome}),Hg({hermesHome:e?.hermesHome}),Xg({piDir:e?.piDir})];return process.env.LMCTL_ENABLE_MOCK_PROVIDER==="1"&&t.push(Zg()),t}var eE=null;function UN(){return eE===null&&(eE=Ms(Bs())),eE}function FN(e,t){Iu(t);let n=e.getAdapter(t);if(!n)throw new Error(`provider "${t}" is not registered in this registry`);return n}async function jN(e){let t=e.registry??UN(),n=FN(t,e.provider),r={sessionId:e.sessionId,cwd:e.cwd,env:e.env,onDelta:e.onDelta,onProgress:e.onProgress,signal:e.signal,timeoutMs:e.timeoutMs,model:e.model,effort:e.effort,progPath:e.progPath,alias:e.alias,isLead:e.isLead,permissionMode:e.permissionMode,holdOpen:e.holdOpen,requireResume:e.requireResume,bundleSession:e.bundleSession},s=e.bundleSession===void 0?await N_(n,{...r,execution:"per-turn",requireResume:e.requireResume??!1}):void 0,o;try{o=s?await s.sendTurn(e.prompt,{onDelta:e.onDelta,onProgress:e.onProgress,signal:e.signal}):await n.sendTurn(e.prompt,r)}finally{await s?.close()}return{text:o.text,...o.usage?{usage:o.usage}:{},sessionId:o.sessionId,durationMs:o.durationMs,stopReason:o.stopReason,numTurns:o.numTurns,status:o.status,stalledAfterMs:o.stalledAfterMs,...o.warnings!==void 0?{warnings:o.warnings}:{}}}async function qN(e){return N_(FN(e.registry??UN(),e.provider),e)}import{join as Wt}from"node:path";var HN=new WeakMap;function Kc(e){let t=HN.get(e);if(t)return t;let n=e.env.HOME;if(!n)return Ms(Bs());let r=e.env.XDG_DATA_HOME||Wt(n,".local/share"),s=e.env.XDG_CONFIG_HOME||Wt(n,".config");return t=Ms(Bs({museDataHome:r,miniplayerHome:e.env.MINIPLAYER_HOME||Wt(r,"miniplayer"),claudeDir:Wt(n,".claude"),codexDir:Wt(n,".codex"),codeDir:Wt(n,".code"),geminiDir:Wt(n,".gemini"),copilotDir:Wt(n,".copilot"),qwenDir:Wt(n,".qwen"),opencodeDbPaths:[Wt(r,"opencode/opencode.db"),Wt(s,"opencode/opencode.db")],agyDir:Wt(n,".gemini/antigravity-cli"),dshHome:Wt(n,".dsh"),hermesHome:e.env.HERMES_HOME??Wt(n,".hermes"),kimiHome:e.env.KIMI_CODE_HOME??Wt(n,".kimi-code"),piDir:Wt(n,".pi/agent/sessions"),lmplayerDbPaths:Z_(e.env,n)})),HN.set(e,t),t}var Xs=e=>{if(e&&typeof e=="object"){for(let t of Object.values(e))Xs(t);Object.freeze(e)}return e},vSe=Xs(["invalid_argument","not_found","missing","read","syntax","schema","busy","provider","noninteractive","cancelled","internal","closed","service_unavailable","outcome_unknown"]),SSe=Xs({status:"string",error:"string|null",code:"ErrorCode?"}),bSe=Xs(["Provider1","Provider2","Provider3","Model1","Model2","Model3"]),ASe=Xs(["Provider1.Provider","Provider1.Model1","Provider2.Provider","Provider2.Model1","Provider3.Provider","Provider3.Model1"]),ISe=Xs(["Provider1","Provider2","Provider3"]),kSe=Xs({Provider1:"PROPS.Provider1.Provider",Provider2:"PROPS.Provider2.Provider",Provider3:"PROPS.Provider3.Provider",Model1:"PROPS.Provider1.Model1",Model2:"PROPS.Provider2.Model1",Model3:"PROPS.Provider3.Model1"}),De={name:"ctx",type:"context"},tE={name:"options",type:"map",optional:!0,keys:[{name:"path",type:"string"}]},Tr={name:"teamfile",type:"string"},vf={name:"alias",type:"string"},Gs={name:"prompt",type:"string"},Sf={name:"member",type:"map",keys:[{name:"provider",type:"string",required:!0},{name:"alias",type:"string"},{name:"model",type:"string"},{name:"effort",type:"string"},{name:"sessiondir",type:"string"},{name:"sessionid",type:"string"}]},Af=[{name:"permissionMode",type:"string",values:["yolo","plan"]},{name:"idleTimeoutMs",type:"number"}],ra={name:"options",type:"map",optional:!0,keys:Af},WN={name:"options",type:"map",optional:!0,keys:[{name:"preamble",type:"string|map"}]},BN={name:"options",type:"map",optional:!0,keys:[{name:"providers",type:"list"},{name:"provider",type:"string"},{name:"timeoutSeconds",type:"number"}]},GN={name:"options",type:"map",keys:[{name:"force",type:"boolean",required:!0,values:[!0]}]},sa={name:"target",type:"map",keys:[{name:"provider",type:"string",required:!0},{name:"sessionid",type:"string",required:!0}]},bf={name:"member",type:"map",keys:[{name:"provider",type:"string",required:!0},{name:"sessionid",type:"string",required:!0},{name:"sessiondir",type:"string"},{name:"model",type:"string"},{name:"effort",type:"string"}]},Kz=[{name:"teamfile",type:"string"},{name:"member",type:"string"},{name:"since",type:"string"},{name:"tree",type:"boolean"}],XN={name:"options",type:"map",optional:!0,keys:Kz},VN={error:"string|null",reply:"string",sessionid:"string|null",messageId:"string|null",teamChatLogId:"number|null"},zz=Xs([{name:"resolveProfilePath",implemented:!0,params:[De,tE],statuses:["ok","error"],results:{error:"string|null",path:"string"},effects:[],summary:"Resolve a profile path solely from explicit context."},{name:"loadProfile",implemented:!0,params:[De,tE],statuses:["ok","error"],results:{error:"string|null",profile:"{path,raw,config}",values:"{Provider1..3,Model1..3,Directory,NonInteractive}",path:"string?",line:"number?",column:"number?"},effects:["file-read"],summary:"Read and validate the complete init profile without discovery or writes."},{name:"profileValues",implemented:!0,params:[{name:"config",type:"map"}],statuses:["ok","error"],results:{error:"string|null",Provider1:"string",Provider2:"string",Provider3:"string",Model1:"string",Model2:"string",Model3:"string"},effects:[],summary:"Validate and map slots to first-model environment values."},{name:"readPrompts",implemented:!0,params:[De,{name:"path",type:"string"},{name:"options",type:"map",optional:!0,keys:[{name:"single",type:"boolean"}]}],statuses:["ok","error"],results:{error:"string|null",prompts:"string[]"},effects:["file-read"],summary:"Read prompt records without exiting the caller.",scriptBinding:{name:"lm_read_prompts",params:[{name:"batchfile",type:"string"},{name:"single",type:"boolean",optional:!0}]}},{name:"listMembers",implemented:!0,params:[De,Tr],statuses:["ok","error"],results:{error:"string|null",members:"Member[]"},effects:["file-read"],summary:"List team members.",scriptBinding:{name:"lm_members",params:[Tr]}},{name:"resolveMember",implemented:!0,params:[De,Tr,vf],statuses:["ok","not_found","error"],results:{error:"string|null",member:"Member",isLead:"boolean",teamfile:"string"},effects:["file-read","db"],summary:"Resolve a team member with an explicit missing outcome.",scriptBinding:{name:"lm_member",params:[Tr,vf]}},{name:"lintTeam",implemented:!0,params:[De,Tr],statuses:["ok","error"],results:{error:"string|null",errors:"list",warnings:"list",counts:"map"},effects:["file-read","db"],summary:"Return structured lint findings.",scriptBinding:{name:"lm_lint",params:[Tr]}},{name:"seedTeam",implemented:!0,params:[De,Tr,WN],statuses:["ok","error"],results:{error:"string|null",seeded:"SeededMember[]"},effects:["provider","db","file-write"],summary:"Seed a team with explicit optional preambles.",scriptBinding:{name:"lm_seed",params:[Tr,WN]}},{name:"promptAgent",implemented:!0,params:[De,Sf,Gs,ra],statuses:["ok","busy","stalled","empty","cancelled","error"],results:{...VN,messageId:"null",teamChatLogId:"null"},effects:["provider","db"],summary:"Turn a provider session without mutating the input member.",scriptBinding:{name:"lm_agent",params:[Sf,Gs,ra]}},{name:"promptMember",implemented:!0,params:[De,{name:"request",type:"map",keys:[{name:"teamfile",type:"string",required:!0},{name:"alias",type:"string",required:!0},{name:"prompt",type:"string",required:!0},{name:"messageType",type:"string"},...Af]}],statuses:["ok","busy","stalled","empty","cancelled","error"],results:{error:"string|null",reply:"string",messageId:"string|null",teamChatLogId:"number|null"},effects:["provider","db"],summary:"Turn a team member through native team admission.",scriptBinding:{name:"lm_prompt",params:[Tr,vf,Gs,{name:"options",type:"map",optional:!0,keys:[...Af,{name:"messageType",type:"string"}]}]}},{name:"listSessions",implemented:!0,params:[De,{name:"options",type:"map",optional:!0,keys:[{name:"provider",type:"string"},{name:"workspace",type:"string"},{name:"all",type:"boolean"}]}],statuses:["ok","error"],results:{error:"string|null",sessions:"Session[]"},effects:["file-read"],summary:"List native sessions in an explicit workspace.",scriptBinding:{name:"lm_session_list",params:[{name:"options",type:"map",optional:!0,keys:[{name:"provider",type:"string"},{name:"sessiondir",type:"string"},{name:"all",type:"boolean"}]}]}},{name:"deleteSession",implemented:!0,params:[De,sa,GN],statuses:["deleted","not_found","busy","error"],results:{error:"string|null"},effects:["provider","file-write"],summary:"Delete a session only with explicit force admission.",scriptBinding:{name:"lm_session_delete",params:[Sf,{...GN,optional:!0}]}},{name:"getSession",implemented:!0,params:[De,sa],statuses:["ok","not_found","error"],results:{error:"string|null",messages:"{role,content}[]"},effects:["provider","file-read"],summary:"Read native session messages.",scriptBinding:{name:"lm_session_get",params:[sa]}},{name:"reserveSession",implemented:!0,params:[De,sa],statuses:["ok","busy","error"],results:{error:"string|null",reservation:"SessionReservation"},effects:[],summary:"Reserve context-local handoff admission and return a capability."},{name:"releaseSession",implemented:!0,params:[De,sa,{name:"reservation",type:"SessionReservation",optional:!0}],statuses:["ok","error"],results:{error:"string|null"},effects:[],summary:"Release context-local handoff admission; an optional capability makes owned cleanup idempotent and replacement-safe."},{name:"openTeamBatch",returnsResource:!0,implemented:!0,params:[De,{name:"request",type:"map",keys:[{name:"teamfile",type:"string",required:!0},{name:"alias",type:"string",required:!0},{name:"label",type:"string",required:!0},{name:"promptCount",type:"number",required:!0},{name:"legacy",type:"boolean"},...Af]}],statuses:["ok","busy","error"],results:{error:"string|null",batch:"opaque context-bound BatchRef"},effects:["provider","db"],summary:"Open a managed team batch; member-map composition remains language-owned."},{name:"batchTurn",implemented:!0,params:[De,{name:"batch",type:"BatchRef"},Gs,{name:"index",type:"number"},{name:"total",type:"number"}],statuses:["ok","busy","stalled","empty","cancelled","error"],results:{error:"string|null",reply:"string",messageId:"string|null",teamChatLogId:"number|null"},effects:["provider","db"],summary:"Turn an owned live batch reference."},{name:"closeBatch",implemented:!0,params:[De,{name:"batch",type:"BatchRef"},{name:"options",type:"map",keys:[{name:"status",type:"string",required:!0,values:["done","error","cancelled"]},{name:"error",type:"string"}]}],statuses:["ok","error"],results:{error:"string|null"},effects:["provider","db"],summary:"Idempotently close an owned batch."},{name:"readRatelimits",implemented:!0,params:[De,BN],statuses:["ok","error"],results:{error:"string|null",readings:"list"},effects:["file-read","network"],summary:"Read provider rate-limit data.",scriptBinding:{name:"lm_ratelimit_readings",params:[BN]}},{name:"openTerminal",implemented:!0,params:[De,{name:"target",type:"map",keys:[{name:"teamfile",type:"string",required:!0},{name:"alias",type:"string",required:!0}]},{name:"streams",type:"map",keys:[{name:"stdin",type:"stream",required:!0},{name:"stdout",type:"stream",required:!0},{name:"stderr",type:"stream",required:!0}]}],statuses:["ok","error"],results:{error:"string|null",code:"number|null",signal:"string|null"},effects:["provider","db","tty"],summary:"Open a native terminal with caller-supplied streams.",scriptBinding:{name:"lm_terminal",params:[Tr,vf]}},{name:"sessionAdmission",implemented:!0,params:[De,sa],statuses:["ok","busy","error"],results:{error:"string|null",busyReason:"turn|handoff?"},effects:[],summary:"Query context-local session admission without exposing mutable sets."},{name:"promptReservedAgent",implemented:!0,params:[De,{name:"reservation",type:"SessionReservation"},Sf,Gs,ra],statuses:["ok","busy","stalled","empty","error"],results:{...VN,messageId:"null",teamChatLogId:"null"},effects:["provider"],summary:"Turn only the session authorized by a live context-bound reservation."},{name:"finalizeBatchSync",implemented:!0,params:[De,{name:"batch",type:"BatchRef"}],statuses:["ok","error"],results:{error:"string|null"},effects:["db"],summary:"Synchronously release one batch on a close deadline without cancelling unrelated batches."},{name:"inspectBatch",implemented:!0,params:[De,{name:"batch",type:"BatchRef"}],statuses:["ok","error"],results:{error:"string|null",id:"string",closed:"boolean",member:"Member",rootId:"number|null"},effects:[],summary:"Read batch metadata without exposing native transports or lease capabilities."},{name:"openNativeSession",returnsResource:!0,implemented:!0,params:[De,{name:"member",type:"map",keys:[{name:"provider",type:"string",required:!0},{name:"sessionid",type:"string",required:!0},{name:"sessiondir",type:"string"},{name:"model",type:"string"},{name:"effort",type:"string"}]},ra],statuses:["ok","busy","error"],results:{error:"string|null",session:"opaque context-bound NativeSessionRef"},effects:["provider","db","file-read"],summary:"Open a script-owned native conversation with existing receiver admission."},{name:"nativeSessionTurn",implemented:!0,params:[De,{name:"session",type:"NativeSessionRef"},Gs],statuses:["ok","busy","stalled","empty","error"],results:{error:"string|null",reply:"string",messageId:"string|null",teamChatLogId:"number|null"},effects:["provider","db"],summary:"Record one unframed conversational turn through the existing recorder."},{name:"closeNativeSession",implemented:!0,params:[De,{name:"session",type:"NativeSessionRef"}],statuses:["ok","error"],results:{error:"string|null"},effects:["provider","db"],summary:"Idempotently close a script-owned native conversation and release its lease."},{name:"finalizeNativeSessionSync",implemented:!0,params:[De,{name:"session",type:"NativeSessionRef"}],statuses:["ok","error"],results:{error:"string|null"},effects:["db"],summary:"Critical synchronous native conversation lease release."},{name:"nativeSessionRequest",implemented:!0,params:[De,bf,Gs,ra],statuses:["ok","busy","stalled","empty","error"],results:{error:"string|null",reply:"string",messageId:"string|null",teamChatLogId:"number|null",code:"ErrorCode?",outcome:"not_sent|completed|unknown?",service_epoch:"string|null?",connection_epoch:"number|null?",connection_state:"new|reused|reinitialized|null?"},effects:["provider","db","network"],summary:"Send a stateless native-id turn to a qualified conversation in the configured running lmbee service.",scriptBinding:{name:"lm_session_turn",params:[bf,Gs,ra]}},{name:"nativeSessionClose",implemented:!0,params:[De,bf],statuses:["ok","busy","error"],results:{error:"string|null",code:"ErrorCode?",outcome:"not_sent|completed|unknown?",service_epoch:"string|null?",connection_epoch:"number|null?",connection_state:"new|reused|reinitialized|null?"},effects:["provider","db","network"],summary:"Close an idle service-hosted native conversation; an absent entry is already closed.",scriptBinding:{name:"lm_session_close",params:[bf]}},{name:"loadProperties",implemented:!0,params:[De,tE],statuses:["ok","error"],results:{error:"string|null",path:"string",properties:"map",flat:"map",line:"number?",column:"number?"},effects:["file-read"],summary:"Read the complete hierarchical init.toml properties document through the canonical reader."},{name:"listRunning",implemented:!0,params:[De,XN],statuses:["ok","error"],results:{error:"string|null",running:"RunningRow[]",dead:"DeadRow[]",idle:"IdleRow[]"},effects:["db"],summary:"DB-wide view of tracked invocation activity. Observation only; dispatch and branch on status busy, never gate on this.",scriptBinding:{name:"lm_running",params:[XN]}}]);function nE(e){if(!KI(e))return Be("invalid_argument","Expected a context created by createLmctlContext");if(e.closed)return Be("cancelled","Context is closed")}function JN(e,t){let n=r=>s=>{t?.(s,r),r==="stderr"&&s.startsWith("warning:")?e.onWarning(s):e.onProgress(s,r)};return{cwd:e.cwd,env:{...e.env,LMCTL_DB:e.dbPath},dal:e.dal,stdout:{write:n("stdout")},stderr:{write:n("stderr")}}}import{readFileSync as Zz,writeFileSync as USe,renameSync as FSe,existsSync as e4}from"node:fs";import{basename as t4,resolve as kf,dirname as rE}from"node:path";var If=["title","description","members"],Qz=new Set(If),vr=class extends Error{constructor(t){super(t),this.name="FrontmatterError"}};function YN(e){if(e.length===0||!e.startsWith("---"))throw new vr("frontmatter must start at line 1 with `---` on its own line");let t=e.split(`
|
|
2016
2016
|
`);if(t[0]!=="---")throw new vr("frontmatter must start at line 1 with `---` on its own line");let n={},r=-1;for(let i=1;i<t.length;i++){let a=t[i];if(a==="---"){r=i;break}if(a.trim()==="")continue;let c=a.match(/^([a-zA-Z][a-zA-Z0-9_-]*)\s*:\s*(.*)$/);if(!c)throw new vr(`malformed frontmatter line ${i+1}: ${JSON.stringify(a)} (expected "key: value" or "---")`);let l=c[1],d=c[2].trim();if(!Qz.has(l))throw new vr(`unknown frontmatter key "${l}" \u2014 allowed keys: ${If.join(", ")}`);n[l]=d}if(r===-1)throw new vr("frontmatter not closed (missing trailing `---` on its own line)");for(let i of If)if(n[i]===void 0)throw new vr(`missing required frontmatter key "${i}" \u2014 required: ${If.join(", ")}`);let s=0;for(let i=0;i<=r;i++)s+=t[i].length+1;s>e.length&&(s=e.length);let o=n.members.split(",").map(i=>i.trim()).filter(Boolean);return{title:n.title,description:n.description,members:o,bodyOffset:s}}var n4="Lead";function r4(e){let t={},n=/(\w+)=(?:"([^"]*)"|([\S]*))/g,r;for(;(r=n.exec(e))!==null;){let s=r[1],o=r[2]!==void 0?r[2]:r[3];t[s]=o}return t}function s4(e){return/^\s*_MEMBER_\s+\S/.test(e)}function o4(e){return/^\s*_SESSION_\s+\S/.test(e)}function i4(e){return/^\s*_SKILL_(?:\s|$)/.test(e)}function sE(e){return/\.(?:lmctl|lmc)$/i.test(e)}function oE(e){return t4(e).replace(/\.(?:lmctl|lmc)$/i,"")}function iE(e){let t=Zz(e,"utf-8"),n=rE(kf(e)),r=aE(t,oE(e),{baseDir:n,sourcePath:kf(e)});for(let s of r.members)s.sessiondir&&!s.sessiondir.startsWith("/")&&(s.sessiondir=kf(n,s.sessiondir));return r}var KN=["alias","provider","sessionid","sessiondir","teamfile","model","effort"];function aE(e,t,n={}){let r=[],s=[];n.sourcePath,n.baseDir;let o=e;if(o.startsWith("#teamfile:")){let c=o.indexOf(`
|
|
2017
2017
|
`);o=c>=0?o.slice(c+1):""}let i=null;if(o.startsWith("---"))try{i=YN(o)}catch(c){if(c instanceof vr)s.push(`frontmatter: ${c.message}`);else throw c}let a=e.split(`
|
|
2018
2018
|
`);for(let c=0;c<a.length;c++){let l=a[c],d=c+1;if(o4(l))throw new Error(`line ${d}: _SESSION_ is the legacy prefix. Rename to _MEMBER_. (line: ${l.trim()})`);if(i4(l)||!s4(l))continue;let u=r4(l);for(let m of Object.keys(u))if(!KN.includes(m))throw new Error(`line ${d}: unknown key "${m}" on _MEMBER_ line: ${l.trim()}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmctl-ai/lmctl",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.275",
|
|
4
4
|
"description": "A provider-agnostic control plane for teams of AI coding agents — across providers, with independent review and durable memory.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://lmctl.com",
|