@lmctl-ai/lmctl 0.1.151 → 0.1.152
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
|
@@ -2310,7 +2310,7 @@ Show provider session details, team rollups, or managed run state/token totals.`
|
|
|
2310
2310
|
[--recursive] [--all] [--format table|teamfile|json] [--json]
|
|
2311
2311
|
lmctl ls --runs [--limit N] [--format table|json] [--json]
|
|
2312
2312
|
|
|
2313
|
-
List native provider sessions in scope, or list recent managed runs with --runs.`,kW=50,$S=500});import{existsSync as Ps,readFileSync as jS}from"node:fs";import{homedir as RW}from"node:os";import{dirname as DS,resolve as $n}from"node:path";import{fileURLToPath as LW}from"node:url";function pf(e,t={}){let r=[],n=CW(t.modelSelectionDocPath);for(let s of e){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=UW(t.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}": `+(Ca??"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: ${BW(o)}`)}return r}function CW(e){if(!e&&Ds)return Ds;let t=new Map,r,n=e??MW();if(!Ps(n))return r=`${n} not found`,e||ff(t),e||(Ds=t),e||(Ca=r),t;let s;try{s=jS(n,"utf-8")}catch(i){return r=`${n} could not be read: ${i instanceof Error?i.message:String(i)}`,e||ff(t),e||(Ds=t),e||(Ca=r),t}for(let[i,o]of Object.entries(OW)){let a=PW(s,o),l=FW(a);l.length>0&&t.set(i,l)}return t.size===0&&(r=`${n} has no tested model rows`),!e&&t.size===0&&ff(t),e||(Ds=t),e||(Ca=r),t}function MW(){return jW(DS(LW(import.meta.url)))}function jW(e){let t=DW(e);if(t){let n=$n(t,"durable-memory","model_selection.md");if(Ps(n))return n}let r=[$n(e,"..","..","durable-memory","model_selection.md"),$n(e,"..","..","..","durable-memory","model_selection.md")];for(let n of r)if(Ps(n))return n;return r[r.length-1]}function DW(e){let t=$n(e);for(;;){if(Ps($n(t,"package.json")))return t;let r=DS(t);if(r===t)return null;t=r}}function ff(e){for(let[t,r]of Object.entries($W))e.set(t,r)}function PW(e,t){let n=new RegExp(`^## ${qW(t)}\\s*$`,"m").exec(e);if(!n)return"";let s=n.index+n[0].length,i=e.slice(s),o=/^##\s+/m.exec(i);return o?i.slice(0,o.index):i}function FW(e){let t=new Set;for(let r of e.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="&&t.add(i)}return[...t]}function UW(e){let t=e??$n(RW(),".config","opencode","opencode.json");if(!Ps(t))return{available:!0,models:[]};let r;try{r=JSON.parse(jS(t,"utf-8"))}catch(n){return{available:!1,models:[],reason:`${t} could not be parsed: ${n instanceof Error?n.message:String(n)}`}}return{available:!0,models:WW(r)}}function WW(e){if(!mf(e))return[];let t=$a(e.provider)??$a(e.providers);if(!t)return[];let r=new Set;for(let[n,s]of Object.entries(t)){if(!mf(s))continue;let i=$a(s.models)??$a(s.model);if(i)for(let o of Object.keys(i))r.add(o.startsWith(`${n}/`)?o:`${n}/${o}`)}return[...r].sort()}function $a(e){return mf(e)?e:null}function mf(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function BW(e){return e.length>0?e.join(", "):"(none)"}function qW(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var OW,$W,Ds,Ca,PS=T(()=>{"use strict";OW={claude:"Claude",codex:"Codex",gemini:"Gemini",qwen:"Qwen",agy:"Antigravity"},$W={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.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-1.5-flash","gemini-1.5-pro","gemini-3.5-flash","gemini-3.1-pro","gpt-oss-120b","gpt-4-turbo","gpt-4","gpt-3.5-turbo","claude-3-opus","claude-3-sonnet","claude-3-haiku"]},Ds=null});import{homedir as HW}from"node:os";import{basename as JW}from"node:path";function Ma(e,t){let r=new Set;return{text:e.replace(GW,(s,i)=>{let o=i.trim(),a=XW[o];return a===void 0?(r.add(o),s):a(t)}),unknownNames:[...r].sort()}}function ja(e){return{workdir:e.workdir,teamfile:e.teamfile,date:VW(e.date)}}function VW(e){return e.toISOString().slice(0,10)}var XW,GW,_f=T(()=>{"use strict";XW={workdir:e=>e.workdir,teamfile:e=>e.teamfile,teamname:e=>{let t=JW(e.teamfile);return t.endsWith(".lmctl")?t.slice(0,-6):t},home:()=>HW(),date:e=>e.date},GW=/{{\s*([A-Za-z0-9_-]+)\s*}}/g});var Ws={};we(Ws,{GEMINI_PROVIDER_NOTICE:()=>BS,_setLintSessiondirFsOpsForTests:()=>rB,_setTeamfileSeedForTests:()=>tB,buildRootTeamRegistrationRow:()=>GS,registerRootTeam:()=>VS,runHire:()=>dB,runLint:()=>cB,runRefresh:()=>uB,runSeed:()=>JS,sha256Text:()=>XS});import{createHash as KW}from"node:crypto";import{accessSync as YW,constants as FS,existsSync as zW,readFileSync as Fa,realpathSync as yf,statSync as ZW,writeFileSync as Pa}from"node:fs";import{dirname as Jr,resolve as WS}from"node:path";function tB(e){qS=e??(async t=>{let{seed:r}=await Promise.resolve().then(()=>(vt(),dc)),n=await r(t);return n.success?{sessionId:n.sessionId,warnings:n.warnings}:{error:n.error??"provider seed failed"}})}function rB(e){Hr=e===null?wf:{...wf,...e}}function nB(e,t){let r=Jr(t),n=new Set,s=[];for(let i of e){if(i.teamfile!==void 0)continue;let o=i.sessiondir??r,a=WS(o);if(n.has(a))continue;let l=sB(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 sB(e){try{if(Hr.existsSync(e)){if(!Hr.statSync(e).isDirectory())return"ENOTDIR";Hr.accessSync(e,FS.W_OK);return}let t=aB(e);if(t===void 0)return;if(!Hr.statSync(t).isDirectory())return"ENOTDIR";Hr.accessSync(t,FS.W_OK);return}catch(t){return lB(t)??"permission check failed"}}function iB(e,t){let r=[];for(let n of e)n.teamfile!==void 0||n.sessiondir===void 0||HS(n.sessiondir,t)&&r.push(`${n.alias}: sessiondir equals the teamfile directory and is redundant; lmctl seed will remove it`);return r}function oB(e,t,r,n){let s=!1;for(let i of e){if(i.teamfile!==void 0||i.sessiondir===void 0||!HS(i.sessiondir,n))continue;let o=r.get(i.alias.toLowerCase());if(o===void 0)continue;let a=KS(t[o],"sessiondir");a!==t[o]&&(t[o]=a,s=!0),i.sessiondir=void 0}return s}function HS(e,t){return US(e)===US(t)}function US(e){let t=WS(e);try{return yf(t)}catch{return t}}function aB(e){let t=e;for(;;){try{if(Hr.existsSync(t))return t}catch{return}let r=Jr(t);if(r===t)return;t=r}}function lB(e){if(typeof e=="object"&&e!==null&&"code"in e){let t=e.code;if(typeof t=="string"&&t.length>0)return t}}async function cB(e,t={stdout:process.stdout,stderr:process.stderr}){if(e[0]==="--help"||e[0]==="-h"||e[0]==="help")return t.stdout.write(QW),0;if(e.length!==1)return t.stderr.write(`usage: lmctl lint <teamfile.lmctl>
|
|
2313
|
+
List native provider sessions in scope, or list recent managed runs with --runs.`,kW=50,$S=500});import{existsSync as Ps,readFileSync as jS}from"node:fs";import{homedir as RW}from"node:os";import{dirname as DS,resolve as $n}from"node:path";import{fileURLToPath as LW}from"node:url";function pf(e,t={}){let r=[],n=CW(t.modelSelectionDocPath);for(let s of e){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=UW(t.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}": `+(Ca??"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: ${BW(o)}`)}return r}function CW(e){if(!e&&Ds)return Ds;let t=new Map,r,n=e??MW();if(!Ps(n))return r=`${n} not found`,e||ff(t),e||(Ds=t),e||(Ca=r),t;let s;try{s=jS(n,"utf-8")}catch(i){return r=`${n} could not be read: ${i instanceof Error?i.message:String(i)}`,e||ff(t),e||(Ds=t),e||(Ca=r),t}for(let[i,o]of Object.entries(OW)){let a=PW(s,o),l=FW(a);l.length>0&&t.set(i,l)}return t.size===0&&(r=`${n} has no tested model rows`),!e&&t.size===0&&ff(t),e||(Ds=t),e||(Ca=r),t}function MW(){return jW(DS(LW(import.meta.url)))}function jW(e){let t=DW(e);if(t){let n=$n(t,"durable-memory","model_selection.md");if(Ps(n))return n}let r=[$n(e,"..","..","durable-memory","model_selection.md"),$n(e,"..","..","..","durable-memory","model_selection.md")];for(let n of r)if(Ps(n))return n;return r[r.length-1]}function DW(e){let t=$n(e);for(;;){if(Ps($n(t,"package.json")))return t;let r=DS(t);if(r===t)return null;t=r}}function ff(e){for(let[t,r]of Object.entries($W))e.set(t,r)}function PW(e,t){let n=new RegExp(`^## ${qW(t)}\\s*$`,"m").exec(e);if(!n)return"";let s=n.index+n[0].length,i=e.slice(s),o=/^##\s+/m.exec(i);return o?i.slice(0,o.index):i}function FW(e){let t=new Set;for(let r of e.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="&&t.add(i)}return[...t]}function UW(e){let t=e??$n(RW(),".config","opencode","opencode.json");if(!Ps(t))return{available:!0,models:[]};let r;try{r=JSON.parse(jS(t,"utf-8"))}catch(n){return{available:!1,models:[],reason:`${t} could not be parsed: ${n instanceof Error?n.message:String(n)}`}}return{available:!0,models:WW(r)}}function WW(e){if(!mf(e))return[];let t=$a(e.provider)??$a(e.providers);if(!t)return[];let r=new Set;for(let[n,s]of Object.entries(t)){if(!mf(s))continue;let i=$a(s.models)??$a(s.model);if(i)for(let o of Object.keys(i))r.add(o.startsWith(`${n}/`)?o:`${n}/${o}`)}return[...r].sort()}function $a(e){return mf(e)?e:null}function mf(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function BW(e){return e.length>0?e.join(", "):"(none)"}function qW(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var OW,$W,Ds,Ca,PS=T(()=>{"use strict";OW={claude:"Claude",codex:"Codex",gemini:"Gemini",qwen:"Qwen",agy:"Antigravity"},$W={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-1.5-flash","gemini-1.5-pro","gemini-3.5-flash","gemini-3.1-pro","gpt-oss-120b","gpt-4-turbo","gpt-4","gpt-3.5-turbo","claude-3-opus","claude-3-sonnet","claude-3-haiku"]},Ds=null});import{homedir as HW}from"node:os";import{basename as JW}from"node:path";function Ma(e,t){let r=new Set;return{text:e.replace(GW,(s,i)=>{let o=i.trim(),a=XW[o];return a===void 0?(r.add(o),s):a(t)}),unknownNames:[...r].sort()}}function ja(e){return{workdir:e.workdir,teamfile:e.teamfile,date:VW(e.date)}}function VW(e){return e.toISOString().slice(0,10)}var XW,GW,_f=T(()=>{"use strict";XW={workdir:e=>e.workdir,teamfile:e=>e.teamfile,teamname:e=>{let t=JW(e.teamfile);return t.endsWith(".lmctl")?t.slice(0,-6):t},home:()=>HW(),date:e=>e.date},GW=/{{\s*([A-Za-z0-9_-]+)\s*}}/g});var Ws={};we(Ws,{GEMINI_PROVIDER_NOTICE:()=>BS,_setLintSessiondirFsOpsForTests:()=>rB,_setTeamfileSeedForTests:()=>tB,buildRootTeamRegistrationRow:()=>GS,registerRootTeam:()=>VS,runHire:()=>dB,runLint:()=>cB,runRefresh:()=>uB,runSeed:()=>JS,sha256Text:()=>XS});import{createHash as KW}from"node:crypto";import{accessSync as YW,constants as FS,existsSync as zW,readFileSync as Fa,realpathSync as yf,statSync as ZW,writeFileSync as Pa}from"node:fs";import{dirname as Jr,resolve as WS}from"node:path";function tB(e){qS=e??(async t=>{let{seed:r}=await Promise.resolve().then(()=>(vt(),dc)),n=await r(t);return n.success?{sessionId:n.sessionId,warnings:n.warnings}:{error:n.error??"provider seed failed"}})}function rB(e){Hr=e===null?wf:{...wf,...e}}function nB(e,t){let r=Jr(t),n=new Set,s=[];for(let i of e){if(i.teamfile!==void 0)continue;let o=i.sessiondir??r,a=WS(o);if(n.has(a))continue;let l=sB(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 sB(e){try{if(Hr.existsSync(e)){if(!Hr.statSync(e).isDirectory())return"ENOTDIR";Hr.accessSync(e,FS.W_OK);return}let t=aB(e);if(t===void 0)return;if(!Hr.statSync(t).isDirectory())return"ENOTDIR";Hr.accessSync(t,FS.W_OK);return}catch(t){return lB(t)??"permission check failed"}}function iB(e,t){let r=[];for(let n of e)n.teamfile!==void 0||n.sessiondir===void 0||HS(n.sessiondir,t)&&r.push(`${n.alias}: sessiondir equals the teamfile directory and is redundant; lmctl seed will remove it`);return r}function oB(e,t,r,n){let s=!1;for(let i of e){if(i.teamfile!==void 0||i.sessiondir===void 0||!HS(i.sessiondir,n))continue;let o=r.get(i.alias.toLowerCase());if(o===void 0)continue;let a=KS(t[o],"sessiondir");a!==t[o]&&(t[o]=a,s=!0),i.sessiondir=void 0}return s}function HS(e,t){return US(e)===US(t)}function US(e){let t=WS(e);try{return yf(t)}catch{return t}}function aB(e){let t=e;for(;;){try{if(Hr.existsSync(t))return t}catch{return}let r=Jr(t);if(r===t)return;t=r}}function lB(e){if(typeof e=="object"&&e!==null&&"code"in e){let t=e.code;if(typeof t=="string"&&t.length>0)return t}}async function cB(e,t={stdout:process.stdout,stderr:process.stderr}){if(e[0]==="--help"||e[0]==="-h"||e[0]==="help")return t.stdout.write(QW),0;if(e.length!==1)return t.stderr.write(`usage: lmctl lint <teamfile.lmctl>
|
|
2314
2314
|
`),2;let r=e[0],n;try{n=await $(t,c=>Ee(r,c))}catch(c){return $e(t,`${r}: ${c instanceof Error?c.message:String(c)}`)}let s;try{s=De(n)}catch(c){return $e(t,`${r}: ${c instanceof Error?c.message:String(c)}`)}let i=Yd(s,Jr(n)),o=pf(s.members),a=Fa(n,"utf8"),l=Ma(a,ja({workdir:Jr(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(...Sl(s.members,Jr(n))),o.push(...nB(s.members,n)),o.push(...iB(s.members,Jr(n)));for(let c of i)t.stderr.write(`error: ${c.field}: ${c.message}
|
|
2315
2315
|
`);for(let c of s.members)Tf([c],t),c.session!==void 0&&c.session.length<Fs&&o.push(`${c.alias}: sessionid is shorter than ${Fs} chars; run lmctl seed to refresh it`);for(let c of o)t.stderr.write(`warning: ${c}
|
|
2316
2316
|
`);return await $(t,c=>{IE(n,c,d=>t.stderr.write(`${d}
|
|
@@ -40,6 +40,7 @@ or retiring tested model ids.
|
|
|
40
40
|
| `gpt-5.2` | Ported from lmctl0 tested-model catalog. |
|
|
41
41
|
| `gpt-5.4` | Ported from lmctl0 tested-model catalog. |
|
|
42
42
|
| `gpt-5.5` | Ported from lmctl0 tested-model catalog. |
|
|
43
|
+
| `gpt-5.6-sol` | Operator-confirmed for Codex review team use on 2026-07-19. |
|
|
43
44
|
| `gpt-5.4-mini` | Ported from lmctl0 tested-model catalog. |
|
|
44
45
|
| `gpt-5.3-codex` | Ported from lmctl0 tested-model catalog. |
|
|
45
46
|
| `gpt-5.3-codex-spark` | 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.
|
|
3
|
+
"version": "0.1.152",
|
|
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",
|