@lmctl-ai/lmctl 0.1.193 → 0.1.195

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -1085,11 +1085,11 @@ var GI=Object.defineProperty;var E=(t,e)=>()=>(t&&(e=t(t=0)),e);var pe=(t,e)=>{f
1085
1085
  holder_pid = ?, holder_host = ?, started_at = ?,
1086
1086
  last_heartbeat_at = NULL, last_seq = ?
1087
1087
  WHERE receiver_teamfile = ? AND receiver_alias = ?
1088
- AND lease_id IS NULL AND last_seq = ?`).run(c,e.sender_teamfile,e.sender_alias,e.holder_pid,o,e.started_at,d,e.receiver_teamfile,e.receiver_alias,a.last_seq);Kt(u.changes,"INFLIGHT_TAKE")})}function bs(t,e,r,n){let s=yn(t,e.receiver_teamfile,e.receiver_alias);if(s===null||s.lease_id===null)throw new Error("agent_state lease is missing during inflight release");Se(t,{stream_id:s.lease_id,event_type:r,observedLastSeq:s.last_seq,payload:{receiver:Vt(e.receiver_teamfile,e.receiver_alias),...r==="INFLIGHT_RECLAIM"?{reason:n??"stale",previous_holder:SA(e)}:{lease_id:s.lease_id}}},i=>Pp(t,s,i,r))}function Up(t,e){let r=yn(t,e.teamfile,e.alias),n=r?.last_seq??0;Se(t,{stream_id:e.lock_id,event_type:"TERMINAL_LOCK_TAKE",observedLastSeq:n,ts:e.started_at,payload:{receiver:Vt(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
1088
+ AND lease_id IS NULL AND last_seq = ?`).run(c,e.sender_teamfile,e.sender_alias,e.holder_pid,o,e.started_at,d,e.receiver_teamfile,e.receiver_alias,a.last_seq);Kt(u.changes,"INFLIGHT_TAKE")})}function bs(t,e,r,n){let s=yn(t,e.receiver_teamfile,e.receiver_alias);s===null||s.lease_id===null||Se(t,{stream_id:s.lease_id,event_type:r,observedLastSeq:s.last_seq,payload:{receiver:Vt(e.receiver_teamfile,e.receiver_alias),...r==="INFLIGHT_RECLAIM"?{reason:n??"stale",previous_holder:SA(e)}:{lease_id:s.lease_id}}},i=>Pp(t,s,i,r))}function Up(t,e){let r=yn(t,e.teamfile,e.alias),n=r?.last_seq??0;Se(t,{stream_id:e.lock_id,event_type:"TERMINAL_LOCK_TAKE",observedLastSeq:n,ts:e.started_at,payload:{receiver:Vt(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
1089
1089
  (receiver_teamfile, receiver_alias, terminal_lock_id, last_seq)
1090
1090
  VALUES (?, ?, ?, ?)`).run(e.teamfile,e.alias,e.lock_id,s);return}let i=t.prepare(`UPDATE agent_state SET terminal_lock_id = ?, last_seq = ?
1091
1091
  WHERE receiver_teamfile = ? AND receiver_alias = ?
1092
- AND terminal_lock_id IS NULL AND last_seq = ?`).run(e.lock_id,s,e.teamfile,e.alias,r.last_seq);Kt(i.changes,"TERMINAL_LOCK_TAKE")})}function Zl(t,e,r=!1){let n=yn(t,e.teamfile,e.alias);if(n===null||n.terminal_lock_id!==e.lock_id)throw new Error("agent_state terminal lock is missing during release");Se(t,{stream_id:e.lock_id,event_type:r?"TERMINAL_LOCK_EXPIRE":"TERMINAL_LOCK_RELEASE",observedLastSeq:n.last_seq,payload:{receiver:Vt(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 = ?
1092
+ AND terminal_lock_id IS NULL AND last_seq = ?`).run(e.lock_id,s,e.teamfile,e.alias,r.last_seq);Kt(i.changes,"TERMINAL_LOCK_TAKE")})}function Zl(t,e,r=!1){let n=yn(t,e.teamfile,e.alias);n===null||n.terminal_lock_id!==e.lock_id||Se(t,{stream_id:e.lock_id,event_type:r?"TERMINAL_LOCK_EXPIRE":"TERMINAL_LOCK_RELEASE",observedLastSeq:n.last_seq,payload:{receiver:Vt(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 = ?
1093
1093
  WHERE receiver_teamfile = ? AND receiver_alias = ?
1094
1094
  AND terminal_lock_id = ? AND last_seq = ?`).run(s,e.teamfile,e.alias,e.lock_id,n.last_seq);Kt(i.changes,r?"TERMINAL_LOCK_EXPIRE":"TERMINAL_LOCK_RELEASE")})}function Wp(t,e,r){let n=yn(t,r.targetTeamfile,r.targetAlias);if(n===null){t.prepare(`INSERT INTO agent_state
1095
1095
  (receiver_teamfile, receiver_alias, terminal_invocation_id,
@@ -1104,7 +1104,7 @@ var GI=Object.defineProperty;var E=(t,e)=>()=>(t&&(e=t(t=0)),e);var pe=(t,e)=>{f
1104
1104
  SET terminal_invocation_heartbeat_at = ?
1105
1105
  WHERE terminal_invocation_id = ?`).run(r,e).changes===1}function Bp(t,e,r){let n=t.prepare(`SELECT receiver_teamfile, receiver_alias, lease_id, terminal_lock_id,
1106
1106
  terminal_invocation_id, last_seq
1107
- FROM agent_state WHERE terminal_invocation_id = ?`).get(r);if(n===void 0)throw new Error("agent_state terminal invocation is missing during finish");let s=t.prepare(`UPDATE agent_state
1107
+ FROM agent_state WHERE terminal_invocation_id = ?`).get(r);if(n===void 0)return;let s=t.prepare(`UPDATE agent_state
1108
1108
  SET terminal_invocation_id = NULL, terminal_invocation_pid = NULL,
1109
1109
  terminal_invocation_host = NULL,
1110
1110
  terminal_invocation_heartbeat_at = NULL, last_seq = ?
@@ -2909,7 +2909,7 @@ Show provider session details, team rollups, or managed run state/token totals.`
2909
2909
  [--recursive] [--all] [--format table|teamfile|json] [--json]
2910
2910
  lmctl ls --runs [--limit N] [--format table|json] [--json]
2911
2911
 
2912
- List native provider sessions in scope, or list recent managed runs with --runs.`,rH=50,rk=500});import{existsSync as hi,readFileSync as ik}from"node:fs";import{homedir as aH}from"node:os";import{dirname as ok,resolve as as}from"node:path";import{fileURLToPath as lH}from"node:url";function mf(t,e={}){let r=[],n=uH(e.modelSelectionDocPath);for(let s of t){let i=s.provider.trim().toLowerCase();if(s.effort&&i!=="opencode"&&i!=="lmplayer"&&i!=="qwen"&&r.push(`[${s.alias}] effort="${s.effort}" is ignored: effort selection is only supported for opencode and lmplayer.`),i==="qwen"&&s.effort&&r.push(`[${s.alias}] effort="${s.effort}" is not a qwen CLI flag: Qwen Code does not expose reasoning-effort selection. Use a thinking/effort model id in model= instead.`),i==="copilot"){if(!s.model)continue;r.push(`[${s.alias}] model="${s.model}" is ignored: copilot does not support lmctl model selection.`);continue}if(i==="lmplayer"&&!s.model){r.push(`[${s.alias}] provider=lmplayer has no model= \u2014 lmplayer will choose its own default model, which may not be visible in the teamfile. Set model= explicitly (e.g. github-copilot/gpt-5.4).`);continue}if(i==="lmplayer")continue;if(i==="opencode"){if(s.effort&&!s.model&&r.push(`[${s.alias}] effort="${s.effort}" has no effect without model= on an opencode member.`),!s.model){r.push(`[${s.alias}] provider=opencode has no model= \u2014 opencode will choose its own default model, which may not be servable and isn't visible in the teamfile. Set model= explicitly (e.g. github-copilot/gpt-5.4).`);continue}let a=gH(e.opencodeConfigPath);if(!a.available){r.push(`[${s.alias}] model="${s.model}" cannot be verified for opencode: ${a.reason}.`);continue}if(a.models.includes(s.model)||/^github-copilot\/(gpt|gemini|o[0-9])/.test(s.model))continue;if(!s.model.includes("/")){let l=a.models.filter(c=>c.endsWith(`/${s.model}`));r.push(l.length>0?`[${s.alias}] model="${s.model}" has no provider prefix \u2014 opencode model ids are <provider>/<model>. Your opencode.json declares it as ${l.join(" / ")}; set model=${l[0]}.`:`[${s.alias}] model="${s.model}" has no provider prefix \u2014 opencode model ids are <provider>/<model> (e.g. github-copilot/${s.model}). Declare it in ~/.config/opencode/opencode.json (see https://lmctl.com/examples/opencode.json).`);continue}r.push(`[${s.alias}] model="${s.model}" is not declared in your opencode.json. opencode resolves github-copilot GPT/Gemini config-free, but copilot Claude and custom providers must be declared \u2014 copy https://lmctl.com/examples/opencode.json to ~/.config/opencode/opencode.json and adjust for your account.`);continue}if(!s.model)continue;let o=n.get(i);if(!o){r.push(`[${s.alias}] model="${s.model}" cannot be verified for provider "${i}": `+(_l??"no tested models found in durable-memory/model_selection.md"));continue}o.includes(s.model)||r.push(`[${s.alias}] model="${s.model}" is not in the tested model list for provider "${i}". Valid tested models: ${EH(o)}`)}return r}function uH(t){if(!t&&_i)return _i;let e=new Map,r,n=t??mH();if(!hi(n))return r=`${n} not found`,t||df(e),t||(_i=e),t||(_l=r),e;let s;try{s=ik(n,"utf-8")}catch(i){return r=`${n} could not be read: ${i instanceof Error?i.message:String(i)}`,t||df(e),t||(_i=e),t||(_l=r),e}for(let[i,o]of Object.entries(cH)){let a=_H(s,o),l=hH(a);l.length>0&&e.set(i,l)}return e.size===0&&(r=`${n} has no tested model rows`),!t&&e.size===0&&df(e),t||(_i=e),t||(_l=r),e}function mH(){return fH(ok(lH(import.meta.url)))}function fH(t){let e=pH(t);if(e){let n=as(e,"durable-memory","model_selection.md");if(hi(n))return n}let r=[as(t,"..","..","durable-memory","model_selection.md"),as(t,"..","..","..","durable-memory","model_selection.md")];for(let n of r)if(hi(n))return n;return r[r.length-1]}function pH(t){let e=as(t);for(;;){if(hi(as(e,"package.json")))return e;let r=ok(e);if(r===e)return null;e=r}}function df(t){for(let[e,r]of Object.entries(dH))t.set(e,r)}function _H(t,e){let n=new RegExp(`^## ${wH(e)}\\s*$`,"m").exec(t);if(!n)return"";let s=n.index+n[0].length,i=t.slice(s),o=/^##\s+/m.exec(i);return o?i.slice(0,o.index):i}function hH(t){let e=new Set;for(let r of t.split(/\r?\n/)){let n=r.trim();if(!n.startsWith("| `"))continue;let s=/^\|\s*`([^`]+)`\s*\|/.exec(n);if(!s)continue;let i=s[1].trim();i&&i!=="Configured `model="&&e.add(i)}return[...e]}function gH(t){let e=t??as(aH(),".config","opencode","opencode.json");if(!hi(e))return{available:!0,models:[]};let r;try{r=JSON.parse(ik(e,"utf-8"))}catch(n){return{available:!1,models:[],reason:`${e} could not be parsed: ${n instanceof Error?n.message:String(n)}`}}return{available:!0,models:yH(r)}}function yH(t){if(!uf(t))return[];let e=pl(t.provider)??pl(t.providers);if(!e)return[];let r=new Set;for(let[n,s]of Object.entries(e)){if(!uf(s))continue;let i=pl(s.models)??pl(s.model);if(i)for(let o of Object.keys(i))r.add(o.startsWith(`${n}/`)?o:`${n}/${o}`)}return[...r].sort()}function pl(t){return uf(t)?t:null}function uf(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}function EH(t){return t.length>0?t.join(", "):"(none)"}function wH(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var cH,dH,_i,_l,ak=E(()=>{"use strict";cH={claude:"Claude",codex:"Codex",gemini:"Gemini",qwen:"Qwen",agy:"Antigravity"},dH={claude:["claude-opus-4-6","claude-opus-4-7","claude-opus-4-8","claude-sonnet-4-6","claude-sonnet-5","claude-haiku-4-5","claude-fable-5"],codex:["gpt-5.2","gpt-5.4","gpt-5.5","gpt-5.6-sol","gpt-5.4-mini","gpt-5.3-codex","gpt-5.3-codex-spark"],gemini:["gemini-3.1-pro-preview","gemini-3-flash-preview","gemini-3.1-flash-lite-preview","gemini-2.5-flash","gemini-2.5-flash-lite"],qwen:["qwen3.5-plus","qwen3.6-plus"],agy:["Gemini 3.5 Flash (Medium)","Gemini 3.5 Flash (High)","Gemini 3.5 Flash (Low)","Gemini 3.1 Pro (Low)","Gemini 3.1 Pro (High)","Claude Sonnet 4.6 (Thinking)","Claude Opus 4.6 (Thinking)","GPT-OSS 120B (Medium)"]},_i=null});import{homedir as TH}from"node:os";import{basename as vH}from"node:path";function hl(t,e){let r=new Set;return{text:t.replace(SH,(s,i)=>{let o=i.trim(),a=bH[o];return a===void 0?(r.add(o),s):a(e)}),unknownNames:[...r].sort()}}function gl(t){return{workdir:t.workdir,teamfile:t.teamfile,date:kH(t.date)}}function kH(t){return t.toISOString().slice(0,10)}var bH,SH,ff=E(()=>{"use strict";bH={workdir:t=>t.workdir,teamfile:t=>t.teamfile,teamname:t=>{let e=vH(t.teamfile);return e.endsWith(".lmctl")?e.slice(0,-6):e},home:()=>TH(),date:t=>t.date},SH=/{{\s*([A-Za-z0-9_-]+)\s*}}/g});var Ei={};pe(Ei,{GEMINI_PROVIDER_NOTICE:()=>uk,_setLintOpenCodeConfigProbeForTests:()=>CH,_setLintSessiondirFsOpsForTests:()=>$H,_setTeamfileSeedForTests:()=>OH,buildRootTeamRegistrationRow:()=>gk,registerRootTeam:()=>yk,runHire:()=>BH,runLint:()=>qH,runRefresh:()=>HH,runSeed:()=>_k,sha256Text:()=>hk});import{createHash as IH}from"node:crypto";import{accessSync as NH,constants as lk,existsSync as AH,readFileSync as wl,realpathSync as hf,statSync as xH,writeFileSync as El}from"node:fs";import{dirname as Fr,resolve as dk}from"node:path";function OH(t){mk=t??(async e=>{let{seed:r}=await Promise.resolve().then(()=>(Mt(),cd)),n=await r(e);return n.success?{sessionId:n.sessionId,warnings:n.warnings}:{error:n.error??"provider seed failed"}})}function $H(t){dn=t===null?gf:{...gf,...t}}function CH(t){fk=t??bc}async function MH(t,e,r){let n=t.filter(i=>i.teamfile===void 0&&i.provider.trim().toLowerCase()==="opencode"&&i.model!==void 0&&i.model.length>0);return(await Promise.all(n.map(async i=>({member:i,result:await fk({cwd:i.sessiondir??e,model:i.model,...i.effort!==void 0?{effort:i.effort}:{},...r!==void 0?{env:r}:{}})})))).flatMap(({member:i,result:o})=>o.status==="rejected"?[`[${i.alias}] ${o.option}="${o.value}" rejected by opencode: ${o.error}`]:[])}function DH(t,e){let r=Fr(e),n=new Set,s=[];for(let i of t){if(i.teamfile!==void 0)continue;let o=i.sessiondir??r,a=dk(o);if(n.has(a))continue;let l=jH(a);l!==void 0&&(n.add(a),s.push(`${i.alias}: sessiondir ${a} is not writable (seed would fail: ${l}) \u2014 fix permissions or set a writable sessiondir`))}return s}function jH(t){try{if(dn.existsSync(t)){if(!dn.statSync(t).isDirectory())return"ENOTDIR";dn.accessSync(t,lk.W_OK);return}let e=UH(t);if(e===void 0)return;if(!dn.statSync(e).isDirectory())return"ENOTDIR";dn.accessSync(e,lk.W_OK);return}catch(e){return WH(e)??"permission check failed"}}function PH(t,e){let r=[];for(let n of t)n.teamfile!==void 0||n.sessiondir===void 0||pk(n.sessiondir,e)&&r.push(`${n.alias}: sessiondir equals the teamfile directory and is redundant; lmctl seed will remove it`);return r}function FH(t,e,r,n){let s=!1;for(let i of t){if(i.teamfile!==void 0||i.sessiondir===void 0||!pk(i.sessiondir,n))continue;let o=r.get(i.alias.toLowerCase());if(o===void 0)continue;let a=Ek(e[o],"sessiondir");a!==e[o]&&(e[o]=a,s=!0),i.sessiondir=void 0}return s}function pk(t,e){return ck(t)===ck(e)}function ck(t){let e=dk(t);try{return hf(e)}catch{return e}}function UH(t){let e=t;for(;;){try{if(dn.existsSync(e))return e}catch{return}let r=Fr(e);if(r===e)return;e=r}}function WH(t){if(typeof t=="object"&&t!==null&&"code"in t){let e=t.code;if(typeof e=="string"&&e.length>0)return e}}async function qH(t,e={stdout:process.stdout,stderr:process.stderr}){if(t[0]==="--help"||t[0]==="-h"||t[0]==="help")return e.stdout.write(RH),0;if(t.length!==1)return e.stderr.write(`usage: lmctl lint <teamfile.lmctl>
2912
+ List native provider sessions in scope, or list recent managed runs with --runs.`,rH=50,rk=500});import{existsSync as hi,readFileSync as ik}from"node:fs";import{homedir as aH}from"node:os";import{dirname as ok,resolve as as}from"node:path";import{fileURLToPath as lH}from"node:url";function mf(t,e={}){let r=[],n=uH(e.modelSelectionDocPath);for(let s of t){let i=s.provider.trim().toLowerCase();if(s.effort&&i!=="opencode"&&i!=="lmplayer"&&i!=="qwen"&&r.push(`[${s.alias}] effort="${s.effort}" is ignored: effort selection is only supported for opencode and lmplayer.`),i==="qwen"&&s.effort&&r.push(`[${s.alias}] effort="${s.effort}" is not a qwen CLI flag: Qwen Code does not expose reasoning-effort selection. Use a thinking/effort model id in model= instead.`),i==="copilot"){if(!s.model)continue;r.push(`[${s.alias}] model="${s.model}" is ignored: copilot does not support lmctl model selection.`);continue}if(i==="lmplayer"&&!s.model){r.push(`[${s.alias}] provider=lmplayer has no model= \u2014 lmplayer will choose its own default model, which may not be visible in the teamfile. Set model= explicitly (e.g. github-copilot/gpt-5.4).`);continue}if(i==="lmplayer")continue;if(i==="opencode"){if(s.effort&&!s.model&&r.push(`[${s.alias}] effort="${s.effort}" has no effect without model= on an opencode member.`),!s.model){r.push(`[${s.alias}] provider=opencode has no model= \u2014 opencode will choose its own default model, which may not be servable and isn't visible in the teamfile. Set model= explicitly (e.g. github-copilot/gpt-5.4).`);continue}let a=gH(e.opencodeConfigPath);if(!a.available){r.push(`[${s.alias}] model="${s.model}" cannot be verified for opencode: ${a.reason}.`);continue}if(a.models.includes(s.model)||/^github-copilot\/(gpt|gemini|o[0-9])/.test(s.model))continue;if(!s.model.includes("/")){let l=a.models.filter(c=>c.endsWith(`/${s.model}`));r.push(l.length>0?`[${s.alias}] model="${s.model}" has no provider prefix \u2014 opencode model ids are <provider>/<model>. Your opencode.json declares it as ${l.join(" / ")}; set model=${l[0]}.`:`[${s.alias}] model="${s.model}" has no provider prefix \u2014 opencode model ids are <provider>/<model> (e.g. github-copilot/${s.model}). Declare it in ~/.config/opencode/opencode.json (see https://lmctl.com/examples/opencode.json).`);continue}r.push(`[${s.alias}] model="${s.model}" is not declared in your opencode.json. opencode resolves github-copilot GPT/Gemini config-free, but copilot Claude and custom providers must be declared \u2014 copy https://lmctl.com/examples/opencode.json to ~/.config/opencode/opencode.json and adjust for your account.`);continue}if(!s.model)continue;let o=n.get(i);if(!o){r.push(`[${s.alias}] model="${s.model}" cannot be verified for provider "${i}": `+(_l??"no tested models found in durable-memory/model_selection.md"));continue}o.includes(s.model)||r.push(`[${s.alias}] model="${s.model}" is not in the tested model list for provider "${i}". Valid tested models: ${EH(o)}`)}return r}function uH(t){if(!t&&_i)return _i;let e=new Map,r,n=t??mH();if(!hi(n))return r=`${n} not found`,t||df(e),t||(_i=e),t||(_l=r),e;let s;try{s=ik(n,"utf-8")}catch(i){return r=`${n} could not be read: ${i instanceof Error?i.message:String(i)}`,t||df(e),t||(_i=e),t||(_l=r),e}for(let[i,o]of Object.entries(cH)){let a=_H(s,o),l=hH(a);l.length>0&&e.set(i,l)}return e.size===0&&(r=`${n} has no tested model rows`),!t&&e.size===0&&df(e),t||(_i=e),t||(_l=r),e}function mH(){return fH(ok(lH(import.meta.url)))}function fH(t){let e=pH(t);if(e){let n=as(e,"durable-memory","model_selection.md");if(hi(n))return n}let r=[as(t,"..","..","durable-memory","model_selection.md"),as(t,"..","..","..","durable-memory","model_selection.md")];for(let n of r)if(hi(n))return n;return r[r.length-1]}function pH(t){let e=as(t);for(;;){if(hi(as(e,"package.json")))return e;let r=ok(e);if(r===e)return null;e=r}}function df(t){for(let[e,r]of Object.entries(dH))t.set(e,r)}function _H(t,e){let n=new RegExp(`^## ${wH(e)}\\s*$`,"m").exec(t);if(!n)return"";let s=n.index+n[0].length,i=t.slice(s),o=/^##\s+/m.exec(i);return o?i.slice(0,o.index):i}function hH(t){let e=new Set;for(let r of t.split(/\r?\n/)){let n=r.trim();if(!n.startsWith("| `"))continue;let s=/^\|\s*`([^`]+)`\s*\|/.exec(n);if(!s)continue;let i=s[1].trim();i&&i!=="Configured `model="&&e.add(i)}return[...e]}function gH(t){let e=t??as(aH(),".config","opencode","opencode.json");if(!hi(e))return{available:!0,models:[]};let r;try{r=JSON.parse(ik(e,"utf-8"))}catch(n){return{available:!1,models:[],reason:`${e} could not be parsed: ${n instanceof Error?n.message:String(n)}`}}return{available:!0,models:yH(r)}}function yH(t){if(!uf(t))return[];let e=pl(t.provider)??pl(t.providers);if(!e)return[];let r=new Set;for(let[n,s]of Object.entries(e)){if(!uf(s))continue;let i=pl(s.models)??pl(s.model);if(i)for(let o of Object.keys(i))r.add(o.startsWith(`${n}/`)?o:`${n}/${o}`)}return[...r].sort()}function pl(t){return uf(t)?t:null}function uf(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}function EH(t){return t.length>0?t.join(", "):"(none)"}function wH(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var cH,dH,_i,_l,ak=E(()=>{"use strict";cH={claude:"Claude",codex:"Codex",gemini:"Gemini",qwen:"Qwen",agy:"Antigravity"},dH={claude:["claude-opus-4-6","claude-opus-4-7","claude-opus-4-8","claude-opus-5","claude-sonnet-4-6","claude-sonnet-5","claude-haiku-4-5","claude-fable-5"],codex:["gpt-5.2","gpt-5.4","gpt-5.5","gpt-5.6-sol","gpt-5.4-mini","gpt-5.3-codex","gpt-5.3-codex-spark"],gemini:["gemini-3.1-pro-preview","gemini-3-flash-preview","gemini-3.1-flash-lite-preview","gemini-2.5-flash","gemini-2.5-flash-lite"],qwen:["qwen3.5-plus","qwen3.6-plus"],agy:["Gemini 3.5 Flash (Medium)","Gemini 3.5 Flash (High)","Gemini 3.5 Flash (Low)","Gemini 3.1 Pro (Low)","Gemini 3.1 Pro (High)","Claude Sonnet 4.6 (Thinking)","Claude Opus 4.6 (Thinking)","GPT-OSS 120B (Medium)"]},_i=null});import{homedir as TH}from"node:os";import{basename as vH}from"node:path";function hl(t,e){let r=new Set;return{text:t.replace(SH,(s,i)=>{let o=i.trim(),a=bH[o];return a===void 0?(r.add(o),s):a(e)}),unknownNames:[...r].sort()}}function gl(t){return{workdir:t.workdir,teamfile:t.teamfile,date:kH(t.date)}}function kH(t){return t.toISOString().slice(0,10)}var bH,SH,ff=E(()=>{"use strict";bH={workdir:t=>t.workdir,teamfile:t=>t.teamfile,teamname:t=>{let e=vH(t.teamfile);return e.endsWith(".lmctl")?e.slice(0,-6):e},home:()=>TH(),date:t=>t.date},SH=/{{\s*([A-Za-z0-9_-]+)\s*}}/g});var Ei={};pe(Ei,{GEMINI_PROVIDER_NOTICE:()=>uk,_setLintOpenCodeConfigProbeForTests:()=>CH,_setLintSessiondirFsOpsForTests:()=>$H,_setTeamfileSeedForTests:()=>OH,buildRootTeamRegistrationRow:()=>gk,registerRootTeam:()=>yk,runHire:()=>BH,runLint:()=>qH,runRefresh:()=>HH,runSeed:()=>_k,sha256Text:()=>hk});import{createHash as IH}from"node:crypto";import{accessSync as NH,constants as lk,existsSync as AH,readFileSync as wl,realpathSync as hf,statSync as xH,writeFileSync as El}from"node:fs";import{dirname as Fr,resolve as dk}from"node:path";function OH(t){mk=t??(async e=>{let{seed:r}=await Promise.resolve().then(()=>(Mt(),cd)),n=await r(e);return n.success?{sessionId:n.sessionId,warnings:n.warnings}:{error:n.error??"provider seed failed"}})}function $H(t){dn=t===null?gf:{...gf,...t}}function CH(t){fk=t??bc}async function MH(t,e,r){let n=t.filter(i=>i.teamfile===void 0&&i.provider.trim().toLowerCase()==="opencode"&&i.model!==void 0&&i.model.length>0);return(await Promise.all(n.map(async i=>({member:i,result:await fk({cwd:i.sessiondir??e,model:i.model,...i.effort!==void 0?{effort:i.effort}:{},...r!==void 0?{env:r}:{}})})))).flatMap(({member:i,result:o})=>o.status==="rejected"?[`[${i.alias}] ${o.option}="${o.value}" rejected by opencode: ${o.error}`]:[])}function DH(t,e){let r=Fr(e),n=new Set,s=[];for(let i of t){if(i.teamfile!==void 0)continue;let o=i.sessiondir??r,a=dk(o);if(n.has(a))continue;let l=jH(a);l!==void 0&&(n.add(a),s.push(`${i.alias}: sessiondir ${a} is not writable (seed would fail: ${l}) \u2014 fix permissions or set a writable sessiondir`))}return s}function jH(t){try{if(dn.existsSync(t)){if(!dn.statSync(t).isDirectory())return"ENOTDIR";dn.accessSync(t,lk.W_OK);return}let e=UH(t);if(e===void 0)return;if(!dn.statSync(e).isDirectory())return"ENOTDIR";dn.accessSync(e,lk.W_OK);return}catch(e){return WH(e)??"permission check failed"}}function PH(t,e){let r=[];for(let n of t)n.teamfile!==void 0||n.sessiondir===void 0||pk(n.sessiondir,e)&&r.push(`${n.alias}: sessiondir equals the teamfile directory and is redundant; lmctl seed will remove it`);return r}function FH(t,e,r,n){let s=!1;for(let i of t){if(i.teamfile!==void 0||i.sessiondir===void 0||!pk(i.sessiondir,n))continue;let o=r.get(i.alias.toLowerCase());if(o===void 0)continue;let a=Ek(e[o],"sessiondir");a!==e[o]&&(e[o]=a,s=!0),i.sessiondir=void 0}return s}function pk(t,e){return ck(t)===ck(e)}function ck(t){let e=dk(t);try{return hf(e)}catch{return e}}function UH(t){let e=t;for(;;){try{if(dn.existsSync(e))return e}catch{return}let r=Fr(e);if(r===e)return;e=r}}function WH(t){if(typeof t=="object"&&t!==null&&"code"in t){let e=t.code;if(typeof e=="string"&&e.length>0)return e}}async function qH(t,e={stdout:process.stdout,stderr:process.stderr}){if(t[0]==="--help"||t[0]==="-h"||t[0]==="help")return e.stdout.write(RH),0;if(t.length!==1)return e.stderr.write(`usage: lmctl lint <teamfile.lmctl>
2913
2913
  `),2;let r=t[0],n;try{n=await O(e,c=>Ne(r,c))}catch(c){return Pe(e,`${r}: ${c instanceof Error?c.message:String(c)}`)}let s;try{s=st(n)}catch(c){return Pe(e,`${r}: ${c instanceof Error?c.message:String(c)}`)}let i=Ku(s,Fr(n)),o=mf(s.members),a=wl(n,"utf8"),l=hl(a,gl({workdir:Fr(n),teamfile:n,date:new Date})).unknownNames;l.length>0&&o.push(`unknown template placeholder${l.length===1?"":"s"}: ${l.map(c=>`{{${c}}}`).join(", ")}`),o.push(...Ec(s.members,Fr(n))),o.push(...DH(s.members,n)),o.push(...PH(s.members,Fr(n))),o.push(...await MH(s.members,Fr(n),e.env));for(let c of i)e.stderr.write(`error: ${c.field}: ${c.message}
2914
2914
  `);for(let c of s.members)Ef([c],e),c.session!==void 0&&c.session.length<gi&&o.push(`${c.alias}: sessionid is shorter than ${gi} chars; run lmctl seed to refresh it`);for(let c of o)e.stderr.write(`warning: ${c}
2915
2915
  `);return i.length>0?1:(e.stdout.write(`ok
@@ -31,6 +31,7 @@ or retiring tested model ids.
31
31
  | `claude-opus-4-6` | Ported from lmctl0 tested-model catalog. |
32
32
  | `claude-opus-4-7` | Ported from lmctl0 tested-model catalog. |
33
33
  | `claude-opus-4-8` | Added from operator-confirmed availability on 2026-06-13; `lmctl lint` compatibility smoke accepts it. |
34
+ | `claude-opus-5` | Operator-confirmed valid 2026-07-25; next-gen Opus release following the `-5` naming (cf. `claude-sonnet-5`/`claude-fable-5`, dropping the `-4-` infix). Added to the lint tested-model catalog. |
34
35
  | `claude-sonnet-4-6` | Ported from lmctl0 tested-model catalog. |
35
36
  | `claude-sonnet-5` | Operator-confirmed 2026-07-05 (via GitHub Copilot: `opencode --model github-copilot/claude-sonnet-5 run …` → "build · claude-sonnet-5"). Also a valid native Claude Code model id (`claude --model claude-sonnet-5`). |
36
37
  | `claude-haiku-4-5` | Ported from lmctl0 tested-model catalog. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lmctl-ai/lmctl",
3
- "version": "0.1.193",
3
+ "version": "0.1.195",
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",