@lmctl-ai/lmctl 0.2.7 → 0.2.9

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.
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `lmctl init` — the first command in the onboarding sequence (operator,
3
+ * 2026-09-29): writes ~/.lmctl/init.toml, a starting-point config of three
4
+ * provider SLOTS (Provider1/2/3), each with three model tiers, used by
5
+ * `lmctl plan` and `lmctl quickrun` to fill ${ProviderN}/${ModelN}
6
+ * placeholders without asking the user provider/model questions directly.
7
+ *
8
+ * Presence detection only -- never a usage ranking (see init-config.ts's
9
+ * own header comment for why session-count ranking was confirmed wrong on
10
+ * a real machine, not just assumed). The bar for the generated file is
11
+ * "useful starting point", not "correct": it is shown to the user and
12
+ * clearly marked as theirs to edit.
13
+ */
14
+ import type { CliIo } from './common.js';
15
+ export interface InitDeps {
16
+ /** Test seam: defaults to ~/.lmctl/init.toml (getDefaultInitConfigPath()). */
17
+ configPath?: string;
18
+ /** Test seam: defaults to real filesystem presence detection. */
19
+ detectProviders?: () => string[];
20
+ }
21
+ export declare function runInit(args: string[], io?: CliIo, deps?: InitDeps): Promise<number>;
@@ -16,5 +16,14 @@ export interface PlanDeps {
16
16
  editFile?: (path: string) => void;
17
17
  /** Overrides stdin TTY detection (wizard auto-trigger). */
18
18
  stdinIsTTY?: boolean;
19
+ /** Test seam: defaults to ~/.lmctl/init.toml (getDefaultInitConfigPath()). */
20
+ initConfigPath?: string;
19
21
  }
20
22
  export declare function runPlan(args: string[], io?: CliIo, deps?: PlanDeps): Promise<number>;
23
+ /** Reads a `--from`-style source: a local file, a directory holding exactly
24
+ * one .lmctl file, or an https:// URL (https-only, redirect-pinned).
25
+ * Exported for reuse by quickrun/hello, which fetch the same kinds of
26
+ * sources (a teamfile template, or a per-provider example) via the same
27
+ * rules -- no local http://, https-only redirects, one candidate file per
28
+ * directory. */
29
+ export declare function readPlanSource(source: string, fetchFn: typeof fetch, cwd: string): Promise<string>;
@@ -0,0 +1,11 @@
1
+ import type { CliIo } from './common.js';
2
+ import { runTerminal } from './terminal.js';
3
+ export interface QuickrunDeps {
4
+ fetchFn?: typeof fetch;
5
+ cwd?: string;
6
+ /** Test seam: defaults to ~/.lmctl/init.toml (getDefaultInitConfigPath()). */
7
+ initConfigPath?: string;
8
+ /** Test seam: defaults to the real runTerminal (a live provider TUI). */
9
+ openTerminal?: typeof runTerminal;
10
+ }
11
+ export declare function runQuickrun(args: string[], io?: CliIo, deps?: QuickrunDeps): Promise<number>;
@@ -1910,7 +1910,7 @@ fn clamp(val, low, high) {
1910
1910
  AND status = 'running'`,e,t),s=0;for(let i of n)ep(r,i)!==null&&(s+=1);return s}import{platform as Ya}from"node:os";import{realpathSync as tp}from"node:fs";import{resolve as rp}from"node:path";function Rs(r){let e=rp(r);try{return tp(e)}catch{return e}}var rn=class{providers=[];adapters=new Map;register(e){this.providers.push(e)}async listAll(e){let t=[],n=e?.provider?this.providers.filter(o=>o.name===e.provider):this.providers,s=await Promise.all(n.map(o=>o.discoverSessions()));for(let o of s)t.push(...o);let i=t;if(e?.workspace){let o=Rs(e.workspace);i=i.filter(a=>Rs(a.cwd)===o)}if(e?.from){let o=e.from.getTime();i=i.filter(a=>a.modifiedAt.getTime()>=o)}if(e?.to){let o=e.to.getTime();i=i.filter(a=>a.modifiedAt.getTime()<=o)}return i.sort((o,a)=>a.modifiedAt.getTime()-o.modifiedAt.getTime()),e?.limit&&(i=i.slice(0,e.limit)),i}async getSession(e,t){let n=t?this.providers.filter(s=>s.name===t):this.providers;for(let s of n){let i=await s.loadSession(e);if(i)return i}return null}async resolveSession(e,t){let n=await this.resolveSessions(e,t);return n.length===1?n[0]:null}async resolveSessions(e,t){let n=t?this.providers.filter(i=>i.name===t):this.providers,s=[];for(let i of n){let o=await i.resolveSessionPath(e);o&&s.push({provider:i,filePath:o})}return s}getWatchTargets(){let e=Ya()==="darwin"||Ya()==="win32",t=[];for(let n of this.providers)if(typeof n.getWatchPaths=="function")for(let s of n.getWatchPaths())t.push({provider:n.name,directory:s.directory,recursive:e,filePattern:s.filePattern});return t}async deleteSession(e,t){let n=await this.resolveSession(e,t);return n?n.provider.deleteSession(e):!1}registerAdapter(e){this.adapters.set(e.name,e),this.providers.push({name:e.name,discoverSessions:()=>e.discover(),loadSession:t=>e.load(t),resolveSessionPath:t=>e.resolvePath(t),deleteSession:t=>e.delete(t),getWatchPaths:()=>e.getWatchPaths?.()??[]})}getAdapter(e){return this.adapters.get(e)}getAllAdapters(){return[...this.adapters.values()]}};function dt(r){let e=new rn;for(let t of r)e.registerAdapter(t);return e}import{join as lc}from"node:path";import{readdir as nn,stat as el,unlink as ip}from"node:fs/promises";import{join as Nt,basename as tl}from"node:path";import{createReadStream as za}from"node:fs";import{createInterface as Qa}from"node:readline";import{stat as np}from"node:fs/promises";import{homedir as sp}from"node:os";var U=sp();function Za(r){try{let e=JSON.parse(r);return e===null||typeof e!="object"||Array.isArray(e)?void 0:e}catch{return}}async function*Q(r){let e=za(r,{encoding:"utf-8"}),t=Qa({input:e,crlfDelay:1/0});try{for await(let n of t){let s=n.trim();if(!s)continue;let i=Za(s);i!==void 0&&(yield i)}}finally{e.destroy()}}async function Ee(r,e){let t=[],n=za(r,{encoding:"utf-8"}),s=Qa({input:n,crlfDelay:1/0});try{for await(let i of s){let o=i.trim();if(!o)continue;let a=Za(o);if(a!==void 0&&t.push(a),t.length>=e)break}}finally{s.close(),n.destroy()}return t}async function Z(r){let e=await np(r);return{createdAt:e.birthtime,modifiedAt:e.mtime}}function q(r){return r.replace(/\\n/g,`
1911
1911
  `).replace(/\\t/g," ").replace(/\\r/g,"\r")}function M(r,e){return r.length<=e?r:r.slice(0,e-3)+"..."}function ve(r){return r!==null&&typeof r=="object"&&!Array.isArray(r)?r:void 0}function op(r){return r==="file-history-snapshot"||r==="progress"||r==="system"||r==="queue-operation"}function ap(r){if(r.type==="system"){let e=r.message?.content;if(typeof e=="string"&&e.trim())return q(e.trim());if(e!==void 0)return JSON.stringify(e,null,2)}return r.type==="progress"&&r.data!==void 0?JSON.stringify(r.data,null,2):JSON.stringify(r,null,2)}async function rl(r){let e=0,t=0,n=0,s=0,i=0,o=0,a,l;for await(let c of Q(r))if(!c.isSidechain){if(c.type==="user"&&!c.isMeta&&c.message){let u=c.message.content;if(typeof u=="string"){if(u.includes("<command-name>")||u.includes("<local-command-"))continue;e++,l=M(u.trim(),80)}}else if(c.type==="assistant"&&c.message){let u=c.message.content;if(Array.isArray(u))for(let p of u)p.type==="text"&&e++;let d=c.message.usage;if(d){let p=d.input_tokens||0,m=d.cache_creation_input_tokens||0,h=d.cache_read_input_tokens||0,g=d.output_tokens||0;t+=p+m+h,n+=h,s+=m,i+=g;let T=p+m+h;T&&(o=T),a={inputTokens:p,cacheWriteInputTokens:m,cachedInputTokens:h,outputTokens:g}}}}return{messageCount:e,totalInputTokens:t,totalCacheReadInputTokens:n,totalCacheWriteInputTokens:s,totalOutputTokens:i,lastInputTokens:o,lastTokenUsage:a,lastUserMessage:l}}var sn=class{name="claude";claudeDir;projectsDir;constructor(e={}){this.claudeDir=e.claudeDir||Nt(U,".claude"),this.projectsDir=Nt(this.claudeDir,"projects")}getWatchPaths(){return[{directory:this.projectsDir,filePattern:/\.jsonl$/}]}async discoverSessions(){let e=[],t;try{t=await nn(this.projectsDir)}catch{return e}for(let n of t){let s=Nt(this.projectsDir,n);if(!(await el(s).catch(()=>null))?.isDirectory())continue;let o;try{o=await nn(s)}catch{continue}for(let a of o){if(!a.endsWith(".jsonl"))continue;let l=tl(a,".jsonl");if(!/^[0-9a-f]{8}-/.test(l))continue;let c=Nt(s,a);try{let u=await this.extractSummary(c,l);u&&e.push(u)}catch{}}}return e}async extractSummary(e,t){let n=await Ee(e,50),s=await Z(e),i="",o,a,l,c,u,d;for(let m of n)if(!op(m.type)&&(!i&&m.cwd&&(i=m.cwd),!o&&m.slug&&(o=m.slug),!a&&m.version&&(a=m.version),!d&&m.timestamp&&(d=new Date(m.timestamp)),m.type==="assistant"&&m.message?.model&&(l=m.message.model),m.type==="user"&&!m.isMeta&&m.message)){let h=m.message.content;if(typeof h=="string"){if(h.includes("<command-name>")||h.includes("<local-command-"))continue;c||(c=M(h.trim(),80)),u=M(h.trim(),80)}}if(!i)return null;let p=await rl(e);return{provider:"claude",sessionId:t,slug:o,cwd:i,createdAt:d||s.createdAt,modifiedAt:s.modifiedAt,model:l,cliVersion:a,startCommand:"claude",firstUserMessage:c,lastUserMessage:p.lastUserMessage??u,messageCount:p.messageCount,filePath:e,totalInputTokens:p.totalInputTokens||void 0,totalCachedInputTokens:p.totalCacheReadInputTokens||void 0,totalCacheWriteInputTokens:p.totalCacheWriteInputTokens||void 0,totalOutputTokens:p.totalOutputTokens||void 0,lastInputTokens:p.lastInputTokens||void 0,lastTokenUsage:p.lastTokenUsage}}async loadSession(e){let t=await this.resolveSessionFile(e);if(!t)return null;let n=await Z(t),s=[],i="",o,a,l,c,u,d,p,m=e,h,g=[];for await(let f of Q(t))if(f.type!=="file-history-snapshot"&&!f.isSidechain){if(!i&&f.cwd&&(i=f.cwd),!o&&f.slug&&(o=f.slug),!a&&f.version&&(a=f.version),!c&&f.gitBranch&&(c=f.gitBranch),!p&&f.timestamp&&(p=new Date(f.timestamp)),f.sessionId&&(m=f.sessionId),f.type==="system"||f.type==="progress"||f.type==="queue-operation"){s.push({role:"system",timestamp:new Date(f.timestamp||0),content:ap(f)});continue}if(f.type==="user"&&f.message){if(f.isMeta)continue;let E=new Date(f.timestamp||0),y=f.message.content;if(f.isCompactSummary!==!0&&f.isVisibleInTranscriptOnly!==!0&&f.promptSource!=="system"&&f.toolUseResult===void 0&&f.origin?.kind!=="task-notification"&&f.interruptedMessageId===void 0&&f.interruptedByShutdown!==!0&&f.scheduledTaskId===void 0&&f.scheduledFireId===void 0&&!(Array.isArray(y)&&y.some(I=>I.type==="tool_result"))){let I=typeof y=="string"?y:Array.isArray(y)?y.filter(v=>v.type==="text"&&typeof v.text=="string").map(v=>v.text).join(`
1912
1912
  `):"";I&&!/^<(?:command-name>|local-command-)/u.test(I.trimStart())&&g.push(I)}if(typeof y=="string"){if(y.includes("<command-name>")||y.includes("<local-command-"))continue;u||(u=M(y.trim(),80)),d=M(y.trim(),80),h=void 0,s.push({role:"user",timestamp:E,content:q(y.trim())})}else if(Array.isArray(y)){for(let I of y)if(I.type==="tool_result"){let v=typeof I.content=="string"?q(I.content):JSON.stringify(I.content);s.push({role:"tool_result",timestamp:E,content:v,toolCallId:I.tool_use_id})}}}if(f.type==="assistant"&&f.message){f.message.stop_reason===null||f.message.stop_reason==="tool_use"?h="in_progress":typeof f.message.stop_reason=="string"&&(h="complete"),f.message.model&&(l=f.message.model);let E=new Date(f.timestamp||0),y=f.message.content;if(Array.isArray(y))for(let I of y)I.type==="text"&&I.text?s.push({role:"assistant",timestamp:E,content:q(I.text),model:f.message.model,...typeof f.message.stop_reason=="string"?{stopReason:f.message.stop_reason}:{}}):I.type==="tool_use"?s.push({role:"tool_use",timestamp:E,content:I.name||"unknown tool",toolName:I.name,toolInput:JSON.stringify(I.input,null,2),toolInputData:I.input,toolCallId:I.id,model:f.message.model,...typeof f.message.stop_reason=="string"?{stopReason:f.message.stop_reason}:{}}):I.type==="thinking"&&I.thinking&&s.push({role:"thinking",timestamp:E,content:I.thinking})}}if(!i)return null;lp(s);let T=await rl(t);return{provider:"claude",sessionId:m,slug:o,cwd:i,createdAt:p||n.createdAt,modifiedAt:n.modifiedAt,model:l,cliVersion:a,startCommand:"claude",gitBranch:c,turnStatus:h,firstUserMessage:u,lastUserMessage:d,messageCount:T.messageCount,filePath:t,totalInputTokens:T.totalInputTokens||void 0,totalCachedInputTokens:T.totalCacheReadInputTokens||void 0,totalCacheWriteInputTokens:T.totalCacheWriteInputTokens||void 0,totalOutputTokens:T.totalOutputTokens||void 0,lastInputTokens:T.lastInputTokens||void 0,lastTokenUsage:T.lastTokenUsage,messages:s,userPrompts:g}}async resolveSessionPath(e){return this.resolveSessionFile(e)}async deleteSession(e){let t=await this.resolveSessionFile(e);return t?(await ip(t),!0):!1}async resolveSessionFile(e){let t;try{t=await nn(this.projectsDir)}catch{return null}let n=[];for(let o of t){let a=Nt(this.projectsDir,o);if(!(await el(a).catch(()=>null))?.isDirectory())continue;let c;try{c=await nn(a)}catch{continue}for(let u of c){if(!u.endsWith(".jsonl"))continue;let d=tl(u,".jsonl");/^[0-9a-f]{8}-/.test(d)&&n.push({filePath:Nt(a,u),fileSessionId:d})}}let s=n.find(o=>o.fileSessionId===e);if(s)return s.filePath;let i=n.filter(o=>o.fileSessionId.startsWith(e));if(i.length===1)return i[0].filePath;for(let o of n){let a=await Ee(o.filePath,20);for(let l of a)if(l.slug&&l.slug===e)return o.filePath}return null}};function lp(r){let e=cp(r),t=new Set;for(let n of r){if(n.role!=="tool_use"||n.toolName!=="Bash"||n.toolInputData?.run_in_background!==!0||n.toolCallId===void 0)continue;let s=e.get(n.toolCallId);if(s===void 0)continue;let i=s.content.match(/Command running in background with ID:\s*([A-Za-z0-9_-]+)/)?.[1];i!==void 0&&(t.add(i),n.backgroundTaskId=i,s.backgroundTaskId=i)}for(let n of r){if(n.role!=="tool_use"||n.toolName!=="TaskOutput"&&n.toolName!=="TaskStop"||n.toolCallId===void 0)continue;let s=n.toolInputData?.task_id;if(typeof s!="string"||!t.has(s))continue;n.backgroundTaskId=s;let i=e.get(n.toolCallId);i!==void 0&&(i.backgroundTaskId=s)}}function cp(r){let e=new Map;for(let t of r)t.role==="tool_result"&&t.toolCallId!==void 0&&e.set(t.toolCallId,t);return e}import{spawn as cl}from"node:child_process";import{mkdirSync as Ip}from"node:fs";import{readFileSync as dp,writeFileSync as dS,mkdirSync as uS}from"node:fs";import{join as up,dirname as fS}from"node:path";import{homedir as mp}from"node:os";var Ns={claude:{start:"claude",resume:"claude --resume {{session_id}} --dangerously-skip-permissions",profiles:{default:{description:"Default profile",flags:""}}},codex:{start:"codex",resume:"codex resume {{session_id}} --dangerously-bypass-approvals-and-sandbox",profiles:{default:{description:"Default profile",flags:""}}},opencode:{start:"opencode",resume:"opencode --session {{session_id}}",profiles:{default:{description:"Default profile",flags:""}}},gemini:{start:"gemini",resume:"gemini --resume {{session_id}} -y",profiles:{default:{description:"Default profile",flags:""}}},copilot:{start:"copilot",resume:"copilot --resume={{session_id}} --yolo",profiles:{default:{description:"Default profile",flags:""}}},qwen:{start:"qwen",resume:"qwen --resume {{session_id}} --approval-mode yolo",profiles:{default:{description:"Default profile",flags:""}}},agy:{start:"agy",resume:"agy --conversation {{session_id}} --dangerously-skip-permissions",profiles:{default:{description:"Default profile",flags:""}}},kimi:{start:"kimi --auto",resume:"kimi --session {{session_id}} --auto",profiles:{default:{description:"Default profile",flags:""}}},hermes:{start:"hermes",resume:"hermes --yolo --resume {{session_id}}",profiles:{default:{description:"Default profile",flags:""}}}},fp={claude:{mode:"argv",argv:["claude","-p","{{prompt}}","--resume","{{session_id}}"]},codex:{mode:"argv",argv:["codex","exec","--dangerously-bypass-approvals-and-sandbox","--skip-git-repo-check","resume","{{session_id}}","{{prompt}}"]},opencode:{mode:"argv",argv:["opencode","run","--session","{{session_id}}","{{prompt}}"]},gemini:{mode:"argv",argv:["gemini","-p","{{prompt}}","--resume","{{session_id}}"]},copilot:{mode:"argv",argv:["gh","copilot","--","--resume={{session_id}}","-p","{{prompt}}","-s","--allow-all-tools"]},qwen:{mode:"argv",argv:["qwen","-p","{{prompt}}","--resume","{{session_id}}","--approval-mode","yolo"]},agy:{mode:"argv",argv:["agy","--conversation","{{session_id}}","-p","{{prompt}}","--dangerously-skip-permissions","--print-timeout","8h"]},kimi:{mode:"argv",argv:["kimi","-p","{{prompt}}","--session","{{session_id}}","--output-format","stream-json"]},hermes:{mode:"argv",argv:["hermes","--yolo","-z","{{prompt}}","--resume","{{session_id}}"]}};function pp(r){return r.startsWith('"')&&r.endsWith('"')||r.startsWith("'")&&r.endsWith("'")?r.slice(1,-1):r}function hp(r){let e=r.indexOf("=");if(e===-1)return null;let t=r.slice(0,e).trim(),n=pp(r.slice(e+1).trim());return t?{key:t,value:n}:null}function gp(r){let e=r.trim();return e.startsWith("[")&&e.endsWith("]")?e.slice(1,-1).trim():null}function on(r){return"'"+r.replace(/'/g,"'\\''")+"'"}function _p(){return up(mp(),".lmctl","config.toml")}function sl(r){let e=r??_p(),t;try{t=dp(e,"utf-8")}catch{return{tools:{}}}return Ep(t)}function nl(r){if(typeof r=="number")return Number.isFinite(r)?r:null;let e=String(r).trim();if(!e)return null;let t=e.match(/^(\d+(?:\.\d+)?)\s*([KkMm]?)$/);if(!t)return null;let n=parseFloat(t[1]);if(!Number.isFinite(n))return null;switch(t[2]){case"K":case"k":return Math.round(n*1e3);case"M":case"m":return Math.round(n*1e6);default:return Math.round(n)}}function Ep(r){let e={},t={},n=r.split(`
1913
- `),s={kind:"none"},i={},o=!1,a={};function l(){if(s.kind==="tool"){let d=e[s.tool]??{};if(s.profile){let p=d.profiles?.[s.profile]??{};i.description&&(p.description=i.description),i.flags!==void 0&&(p.flags=i.flags),d.profiles||(d.profiles={}),d.profiles[s.profile]=p}else i.start&&(d.start=i.start),i.resume&&(d.resume=i.resume),i.agent&&(d.agent=i.agent),i.profile_flag!==void 0&&(d.profile_flag=i.profile_flag);e[s.tool]=d}else if(s.kind==="compact"){let d=s.provider?t.providers?.[s.provider]??{}:t.global??{};if(i.min!==void 0){let p=nl(i.min);p!==null&&(d.min=p)}if(i.max!==void 0){let p=nl(i.max);p!==null&&(d.max=p)}s.provider?(t.providers||(t.providers={}),t.providers[s.provider]=d):t.global=d}i={}}for(let d of n){let p=d.trim();if(!p||p.startsWith("#"))continue;let m=gp(p);if(m!==null){if(o=!0,l(),m.startsWith("tool.")){let g=".profile.",T=m.indexOf(g);T!==-1?s={kind:"tool",tool:m.slice(5,T),profile:m.slice(T+g.length)}:s={kind:"tool",tool:m.slice(5),profile:null}}else m==="compact"?s={kind:"compact",provider:null}:m.startsWith("compact.")?s={kind:"compact",provider:m.slice(8)}:s={kind:"none"};continue}let h=hp(p);h&&s.kind!=="none"?i[h.key]=h.value:h&&!o&&(a[h.key]=h.value)}l();let c={tools:e};(t.global||t.providers)&&(c.compact=t);let u=a.site_name;return u!==void 0&&u.length>0&&(c.site_name=u),c}function yp(r,e,t){if(!t)return"";let n=r.tools[e]??Ns[e],s=n?.profiles?.[t]?.flags??Ns[e]?.profiles?.[t]?.flags;if(s!==void 0)return s.trim();if(n?.profile_flag)return n.profile_flag.replace(/\{\{profile\}\}/g,t).trim();throw new Error(`Profile "${t}" is not configured for tool "${e}"`)}function il(r,e){return!!r.tools[e]}function ol(r,e,t,n,s){let i=r.tools[e]??Ns[e],o;if(i?.agent){let l=on(n);o=i.agent.replace(/\{\{session_id\}\}/g,t).replace(/\{\{prompt\}\}/g,l)}else{let l=fp[e];if(!l)throw new Error(`No agent command configured for tool "${e}"`);let c=l.argv.map(u=>u.replace(/\{\{session_id\}\}/g,t).replace(/\{\{prompt\}\}/g,n));if(l.mode==="stdin"){let u=c.map(on).join(" ");o=`printf '%s\\n' ${on(n)} | ${u}`}else o=c.map(on).join(" ")}let a=yp(r,e,s);return a&&(o+=" "+a),o}function al(r=process.env){let e=r.LMCTL_ONE_SHOT_TIMEOUT_MS;if(!e)return 6e5;let t=Number(e);return!Number.isFinite(t)||t<=0?6e5:t}var Tp="ACK: waiting for explicit lmctl task.",B=`lmctl seed initial connection only. Create or pin this provider session, then stop. Do not inspect files, run commands, infer a task, delegate, or edit. A dispatch that dies mid-turn is usually a timeout you set -- use --idle-timeout, not a shell timeout. Reply exactly: ${Tp}`,an=`send this exact lmctl seed instruction: "${B}"`;import{existsSync as Sp}from"node:fs";var ks="LMCTL_SELF_SESSIONID",wp="LMCTL_LAUNCH_SOURCE";function ll(r){let e=r.CLAUDE_CODE_EXECPATH;if(e===void 0||e.length===0)return r;let t=process.platform!=="win32"&&e.toLowerCase().endsWith(".exe"),n=!t&&!Sp(e);if(!t&&!n)return r;b({event:"claude_execpath_sanitized",reason:t?"wrong_platform_exe":"missing_file",value:e,platform:process.platform});let s={...r};return delete s.CLAUDE_CODE_EXECPATH,s}function kt(r,e){let t={...r??process.env,PWD:e};return delete t.OLDPWD,t}function vp(r,e){return e===void 0||e.length===0?r:{...r??process.env,[ks]:e}}function ae(r,e,t,n="chat"){return{...vp(kt(r,e),t),[wp]:n}}function er(r){return r.replace(/\x1b\[[0-9;]*[a-zA-Z]/g,"")}var Ls=class r extends Error{cancelReason;constructor(e,t){super(e),this.name="TurnAbortError",this.cancelReason=t,Object.setPrototypeOf(this,r.prototype)}},G=class r{name;capabilities;injection;provider;binary;seedArgs;seedStdin;resumeTemplate;startTemplate;transportFn;constructor(e){this.name=e.provider.name,this.provider=e.provider,this.capabilities=e.capabilities,this.injection=e.injection,this.binary=e.binary,this.seedArgs=e.seedArgs,this.seedStdin=e.seedStdin,this.resumeTemplate=e.resumeTemplate,this.startTemplate=e.startTemplate,this.transportFn=e.transport}discover(){return this.provider.discoverSessions()}load(e){return this.provider.loadSession(e)}resolvePath(e){return this.provider.resolveSessionPath(e)}delete(e){return this.provider.deleteSession(e)}getWatchPaths(){return this.provider.getWatchPaths?.()??[]}seedArgsFor(e){let t=e?.prompt;return t===void 0?this.seedArgs:this.seedArgs.map(n=>n===B?t:n)}turnOptsFor(e){return e}seed(e,t){return Ip(e,{recursive:!0}),new Promise(n=>{let s;try{s=cl(this.binary,this.seedArgsFor(t),{cwd:e,env:kt(void 0,e),stdio:["pipe","pipe","pipe"],timeout:6e4})}catch(l){return n({success:!1,error:l instanceof Error?l.message:String(l)})}let i="",o="";s.stdout?.on("data",l=>{i+=l.toString()}),s.stderr?.on("data",l=>{o+=l.toString()});let a=t?.prompt!==void 0&&this.seedStdin!==void 0?`${t.prompt}
1913
+ `),s={kind:"none"},i={},o=!1,a={};function l(){if(s.kind==="tool"){let d=e[s.tool]??{};if(s.profile){let p=d.profiles?.[s.profile]??{};i.description&&(p.description=i.description),i.flags!==void 0&&(p.flags=i.flags),d.profiles||(d.profiles={}),d.profiles[s.profile]=p}else i.start&&(d.start=i.start),i.resume&&(d.resume=i.resume),i.agent&&(d.agent=i.agent),i.profile_flag!==void 0&&(d.profile_flag=i.profile_flag);e[s.tool]=d}else if(s.kind==="compact"){let d=s.provider?t.providers?.[s.provider]??{}:t.global??{};if(i.min!==void 0){let p=nl(i.min);p!==null&&(d.min=p)}if(i.max!==void 0){let p=nl(i.max);p!==null&&(d.max=p)}s.provider?(t.providers||(t.providers={}),t.providers[s.provider]=d):t.global=d}i={}}for(let d of n){let p=d.trim();if(!p||p.startsWith("#"))continue;let m=gp(p);if(m!==null){if(o=!0,l(),m.startsWith("tool.")){let g=".profile.",T=m.indexOf(g);T!==-1?s={kind:"tool",tool:m.slice(5,T),profile:m.slice(T+g.length)}:s={kind:"tool",tool:m.slice(5),profile:null}}else m==="compact"?s={kind:"compact",provider:null}:m.startsWith("compact.")?s={kind:"compact",provider:m.slice(8)}:s={kind:"none"};continue}let h=hp(p);h&&s.kind!=="none"?i[h.key]=h.value:h&&!o&&(a[h.key]=h.value)}l();let c={tools:e};(t.global||t.providers)&&(c.compact=t);let u=a.site_name;return u!==void 0&&u.length>0&&(c.site_name=u),c}function yp(r,e,t){if(!t)return"";let n=r.tools[e]??Ns[e],s=n?.profiles?.[t]?.flags??Ns[e]?.profiles?.[t]?.flags;if(s!==void 0)return s.trim();if(n?.profile_flag)return n.profile_flag.replace(/\{\{profile\}\}/g,t).trim();throw new Error(`Profile "${t}" is not configured for tool "${e}"`)}function il(r,e){return!!r.tools[e]}function ol(r,e,t,n,s){let i=r.tools[e]??Ns[e],o;if(i?.agent){let l=on(n);o=i.agent.replace(/\{\{session_id\}\}/g,t).replace(/\{\{prompt\}\}/g,l)}else{let l=fp[e];if(!l)throw new Error(`No agent command configured for tool "${e}"`);let c=l.argv.map(u=>u.replace(/\{\{session_id\}\}/g,t).replace(/\{\{prompt\}\}/g,n));if(l.mode==="stdin"){let u=c.map(on).join(" ");o=`printf '%s\\n' ${on(n)} | ${u}`}else o=c.map(on).join(" ")}let a=yp(r,e,s);return a&&(o+=" "+a),o}function al(r=process.env){let e=r.LMCTL_ONE_SHOT_TIMEOUT_MS;if(!e)return 6e5;let t=Number(e);return!Number.isFinite(t)||t<=0?6e5:t}var Tp="ACK: waiting for explicit lmctl task.",B=`lmctl seed initial connection only. Create or pin this provider session, then stop. Do not inspect files, run commands, infer a task, delegate, or edit. Reply exactly: ${Tp}`,an=`send this exact lmctl seed instruction: "${B}"`;import{existsSync as Sp}from"node:fs";var ks="LMCTL_SELF_SESSIONID",wp="LMCTL_LAUNCH_SOURCE";function ll(r){let e=r.CLAUDE_CODE_EXECPATH;if(e===void 0||e.length===0)return r;let t=process.platform!=="win32"&&e.toLowerCase().endsWith(".exe"),n=!t&&!Sp(e);if(!t&&!n)return r;b({event:"claude_execpath_sanitized",reason:t?"wrong_platform_exe":"missing_file",value:e,platform:process.platform});let s={...r};return delete s.CLAUDE_CODE_EXECPATH,s}function kt(r,e){let t={...r??process.env,PWD:e};return delete t.OLDPWD,t}function vp(r,e){return e===void 0||e.length===0?r:{...r??process.env,[ks]:e}}function ae(r,e,t,n="chat"){return{...vp(kt(r,e),t),[wp]:n}}function er(r){return r.replace(/\x1b\[[0-9;]*[a-zA-Z]/g,"")}var Ls=class r extends Error{cancelReason;constructor(e,t){super(e),this.name="TurnAbortError",this.cancelReason=t,Object.setPrototypeOf(this,r.prototype)}},G=class r{name;capabilities;injection;provider;binary;seedArgs;seedStdin;resumeTemplate;startTemplate;transportFn;constructor(e){this.name=e.provider.name,this.provider=e.provider,this.capabilities=e.capabilities,this.injection=e.injection,this.binary=e.binary,this.seedArgs=e.seedArgs,this.seedStdin=e.seedStdin,this.resumeTemplate=e.resumeTemplate,this.startTemplate=e.startTemplate,this.transportFn=e.transport}discover(){return this.provider.discoverSessions()}load(e){return this.provider.loadSession(e)}resolvePath(e){return this.provider.resolveSessionPath(e)}delete(e){return this.provider.deleteSession(e)}getWatchPaths(){return this.provider.getWatchPaths?.()??[]}seedArgsFor(e){let t=e?.prompt;return t===void 0?this.seedArgs:this.seedArgs.map(n=>n===B?t:n)}turnOptsFor(e){return e}seed(e,t){return Ip(e,{recursive:!0}),new Promise(n=>{let s;try{s=cl(this.binary,this.seedArgsFor(t),{cwd:e,env:kt(void 0,e),stdio:["pipe","pipe","pipe"],timeout:6e4})}catch(l){return n({success:!1,error:l instanceof Error?l.message:String(l)})}let i="",o="";s.stdout?.on("data",l=>{i+=l.toString()}),s.stderr?.on("data",l=>{o+=l.toString()});let a=t?.prompt!==void 0&&this.seedStdin!==void 0?`${t.prompt}
1914
1914
  `:this.seedStdin;a&&s.stdin?.write(a),s.stdin?.end(),s.on("exit",l=>{if(l===0||l===null)n({success:!0});else{let c=er(o).trim(),u=er(i).trim();n({success:!1,error:(c||u).slice(0,500)||`exit code ${l}`})}}),s.on("error",l=>{n({success:!1,error:l.message})})})}resumeCommand(e,t){return this.resumeTemplate.replace(/\{\{session_id\}\}/g,e)}startCommand(e){return this.startTemplate}manualSeedHint(e){return{launchCommand:`cd ${e} && ${this.binary}`,postLaunchNote:an,lsCommand:`lmctl ls --provider ${this.name} --sessiondir ${e}`}}static DEFAULT_IDLE_TIMEOUT_MS=8*60*60*1e3;sendTurn(e,t){let n=this.turnOptsFor(t);if(n.userConfig&&il(n.userConfig,this.name)){let i=n.userConfig.tools[this.name];if(i?.agent)return this.runOneShotAgent(e,n,i.agent)}let s=n.timeoutMs??r.DEFAULT_IDLE_TIMEOUT_MS;return s<=0&&!n.signal?this.transportFn(e,{...n,binary:this.binary}):this.withTimeouts(s,e,n)}withTimeouts(e,t,n){let s=new AbortController,i,o,a="",l,c=()=>{e<=0||(clearTimeout(i),i=setTimeout(()=>{n.onIdleWarning?.(e),u(),s.abort(),l&&l({text:a,sessionId:n.sessionId,durationMs:e,status:"stalled",stalledAfterMs:e})},e))},u=()=>{clearTimeout(i)};n.signal&&(n.signal.aborted?(o="external",s.abort()):n.signal.addEventListener("abort",()=>{o="external",s.abort()},{once:!0})),c();let d={...n,binary:this.binary,signal:s.signal,onDelta:h=>{a+=h,c(),n.onDelta?.(h)},onProgress:h=>{h.kind!=="api_retry"&&c(),n.onProgress?.(h)}},p=this.transportFn(t,d).then(h=>(u(),{...h,status:"ok"})).catch(h=>{throw u(),o==="external"?new Ls("Turn cancelled","external"):h}),m=new Promise(h=>{l=h});return Promise.race([p,m])}runOneShotAgent(e,t,n){let s=ol(t.userConfig,this.name,t.sessionId,e,t.profile),i=Date.now();return new Promise((o,a)=>{let l=al(t.env),c=cl(s,{shell:!0,cwd:t.cwd,env:ae(t.env,t.cwd,t.sessionId),stdio:["pipe","pipe","pipe"]}),u=!1,d=!1,p=setTimeout(()=>{d=!0,c.kill()},l),m="",h="";if(c.stdout?.on("data",g=>{let T=g.toString();m+=T,t.onDelta?.(T)}),c.stderr?.on("data",g=>{h+=g.toString()}),t.signal){if(t.signal.aborted)return clearTimeout(p),c.kill(),a(new Error("Aborted"));t.signal.addEventListener("abort",()=>c.kill(),{once:!0})}c.on("exit",g=>{if(u)return;u=!0,clearTimeout(p);let T=Date.now()-i;d?a(new Error(`Agent command timed out after ${l}ms`)):g===0||g===null?o({text:m.trim(),sessionId:t.sessionId,durationMs:T}):a(new Error(h.trim().slice(0,200)||`Agent command exited with code ${g}`))}),c.on("error",g=>{u||(u=!0,clearTimeout(p),a(g))})})}};import{spawn as hl}from"node:child_process";import{existsSync as gl}from"node:fs";var tr=class extends Error{constructor(e,t){super(e,t),this.name=this.constructor.name}},J=class extends tr{};var ln=class extends tr{rpcCode;rpcData;constructor(e,t,n){super(e),t!==void 0&&(this.rpcCode=t),n!==void 0&&(this.rpcData=n)}};function rr(r,e){let t;if(e&&typeof e=="object"){let n=e.code;typeof n=="number"&&(t=n)}return new ln(r,t,e)}import*as Os from"node:child_process";var xp=1e3;function Ap(r){if(typeof Os.spawnSync=="function")try{Os.spawnSync("taskkill",["/T","/F","/PID",String(r)],{windowsHide:!0})}catch{}}function dl(r){return r.exitCode!==null||r.signalCode!==null}function Cs(r,e){return dl(r)?Promise.resolve(!0):new Promise(t=>{let n=!1,s=()=>{n||(n=!0,clearTimeout(i),t(!0))},i=setTimeout(()=>{n||(n=!0,r.removeListener("exit",s),t(!1))},e);r.once("exit",s)})}async function V(r,e={}){let t=Date.now(),n=e.stdinEnd!==!1,s=e.softDelayMs??5e3,i=e.killDelayMs??5e3,o=e.platform??process.platform,a=e.runTaskkill??Ap;if(dl(r))return{signal:"natural",elapsedMs:Date.now()-t};if(n&&r.stdin&&!r.stdin.destroyed)try{r.stdin.end()}catch{}if(await Cs(r,s))return{signal:"stdin",elapsedMs:Date.now()-t};if(o==="win32"&&typeof r.pid=="number")a(r.pid);else try{r.kill("SIGTERM")}catch{}if(await Cs(r,i))return{signal:"SIGTERM",elapsedMs:Date.now()-t};if(o!=="win32")try{r.kill("SIGKILL")}catch{}return await Cs(r,xp)?{signal:"SIGKILL",elapsedMs:Date.now()-t}:{signal:"abandoned",elapsedMs:Date.now()-t}}function ul(r){K()&&he({event:"legacy",msg:`[debug] ${r}`},{always:!0})}var bp={claude:["--dangerously-skip-permissions"],qwen:["--approval-mode","yolo"],gemini:["-y"],copilot:["--yolo"],agy:["--dangerously-skip-permissions"],lmplayer:["--dangerously-skip-permissions"]},Rp={claude:{yolo:["--dangerously-skip-permissions"],plan:["--permission-mode","plan"]},qwen:{yolo:["--approval-mode","yolo"],plan:["--approval-mode","plan"]},gemini:{yolo:["-y"],plan:["--approval-mode","plan"]},copilot:{yolo:["--yolo"],plan:["--yolo"]},agy:{yolo:["--dangerously-skip-permissions"],plan:["--dangerously-skip-permissions"]},lmplayer:{yolo:["--dangerously-skip-permissions"],plan:["--dangerously-skip-permissions"]}};function Ve(r,e){let t=Rp[r];if(t)return t[e]??t.yolo}var Np=new Set(["codex","opencode","kimi","dsh","hermes","pi"]);function kp(r,e){if(e.length===0)return!0;for(let t=0;t+e.length<=r.length;t++){let n=!0;for(let s=0;s<e.length;s++)if(r[t+s]!==e[s]){n=!1;break}if(n)return!0}return!1}function ie(r,e,t="yolo"){if(Np.has(r)){ul(`YOLO ${r} [mode=${t}]: ${r==="codex"?`JSON-RPC params (approvalPolicy=never, sandbox=${t==="plan"?"read-only":"danger-full-access"})`:r==="opencode"?".opencode/opencode.json (permission=allow)":r==="kimi"?`ACP session/set_config_option (configId=mode, value=${t==="plan"?"plan":"auto"})`:r==="dsh"?"DSH_PERMISSION_MODE=danger-full-access env var on the sidecar spawn \u2014 no argv flag":r==="hermes"?"HERMES_YOLO_MODE=1 shell gate + ACP session/set_mode (modeId=dont_ask) edit gate":r==="pi"?"no tool-permission prompts exist in pi by design \u2014 nothing to bypass":"protocol/config (out-of-band)"} \u2014 no argv flag`);return}let n=t==="plan"?Ve(r,"plan"):bp[r];if(!n){let s=`unknown provider "${r}" \u2014 YOLO contract not configured. Add an entry to YOLO_FLAGS in src/providers/yolo-contract.ts before spawning this provider.`;throw b({event:"yolo_assert_failed",provider:r,reason:"unconfigured_provider",args:e.join(" "),message:s}),new J(s)}if(!kp(e,n)){let s=n.join(" "),i=`${r} spawn missing YOLO flag '${s}' \u2014 YOLO is mandatory for every provider; see src/providers/yolo-contract.ts. Got argv: [${e.map(o=>JSON.stringify(o)).join(", ")}]`;throw b({event:"yolo_assert_failed",provider:r,reason:"flag_missing",required_flag:s,mode:t,args:e.join(" "),message:i}),new J(i)}ul(`YOLO ${r} [mode=${t}]: argv flag '${n.join(" ")}'`)}var Lp=2e3,cn=8*60*60*1e3,Cp=5e3,Op=1e3,Dp=50,Ds=Symbol("check-timed-out");async function dn(r,e,t){if(typeof r=="boolean")return r;let n,s;try{return await Promise.race([r,new Promise(i=>{n=setTimeout(()=>i(Ds),e),n.unref?.(),t!==void 0&&(s=()=>i(Ds),t.addEventListener("abort",s,{once:!0}))})])}finally{n!==void 0&&clearTimeout(n),s!==void 0&&t?.removeEventListener("abort",s)}}function Ke(r,e){if(r===void 0){e.closeStdin();return}let t=!1,n=i=>{if(!t){t=!0;try{r.onRelease?.({elapsedMs:Date.now()-i.startedMs,held:i.held,reason:i.reason})}catch{}}e.closeStdin()},s=Date.now();Mp(r,e,s,n).catch(()=>{n({startedMs:s,held:!1,reason:"check-error"})})}async function Mp(r,e,t,n){let s=r.pollMs??Lp,i=r.maxHoldMs??cn,o=r.settleMs??Cp,a=r.backgroundGraceMs??Op,l=!1,c=null,u=d=>n({startedMs:t,held:l,reason:d});for(;;){if(e.isAborted())return u("aborted");if(e.hasChildExited())return u("child-exited");let d=i-(Date.now()-t);if(d<=0)return u("max-hold");let p;try{p=await dn(r.hasOutstandingWork(),d,e.signal)}catch{return u("check-error")}if(p===Ds)return u(e.isAborted()||e.signal?.aborted===!0?"aborted":"max-hold");if(p)c=null;else{if(!l&&e.wasBackgroundJobLaunched?.()===!0&&Date.now()-t<a){let g=a-(Date.now()-t);await new Promise(T=>setTimeout(T,Math.max(0,Math.min(s,Dp,g))).unref?.());continue}if(!l||o<=0)return u("cleared");c===null&&(c=Date.now(),se(`${e.label}: dispatched work cleared \u2014 settling ${o}ms before closing stdin`));let h=Math.max(c,e.lastEventAtMs());if(!e.isTurnInFlight()&&Date.now()-h>=o)return u("cleared")}if(l||(l=!0,r.onHold?.(),se(`${e.label}: deferring stdin close \u2014 outstanding dispatched work (poll ${s}ms)`)),Date.now()-t>=i)return b({event:"transport_hold_open_max_wait",provider:e.label,elapsed_ms:Date.now()-t}),u("max-hold");let m=Math.max(0,Math.min(s,i-(Date.now()-t)));await new Promise(h=>setTimeout(h,m).unref?.())}}function ml(r){if(r.length===0)return"";if(r.length===1)return r[0];let e=[];for(let t=0;t<r.length;t++)t===0?e.push(r[t]):e.push(`
1915
1915
 
1916
1916
  --- additional response (turn ${t+1} of ${r.length}; likely an injected mid-call notification) ---
@@ -24,11 +24,18 @@ export declare function parseMemberSpec(raw: string): {
24
24
  };
25
25
  export declare function renderMemberLine(member: MemberSpec): string;
26
26
  /**
27
- * Render the canonical starter teamfile. The header carries the no-timeout
28
- * rule INLINE (not only as a skill-doc link) so a new Lead's first read
29
- * already has it; the wording is association-first on purpose (a diagnosis
30
- * to reach for after a dispatch dies, not a prohibition stated in advance).
31
- * Session ids are never generated here — that is `lmctl seed`'s job.
27
+ * Render the canonical starter teamfile. Session ids are never generated
28
+ * here — that is `lmctl seed`'s job.
29
+ *
30
+ * Operator, 2026-09-29 (onboarding revamp, queued#21811): the header
31
+ * teaches the loop -- generate, edit, lint, seed -- and points at ONE page
32
+ * covering the teamfile format plus what lint and seed each do, rather
33
+ * than explaining any of that inline. Deliberately ONE link, not two:
34
+ * lmctl-lead.md is dropped (the seed prompt is cut to bare minimum for the
35
+ * same reason -- an arriving Lead isn't front-loaded with an operating
36
+ * guide) and the previously-inline no-`timeout` paragraph is cut entirely
37
+ * (queued#21813/#21814/#21820, operator: a warning that never stopped
38
+ * anyone who hit it is noise for everyone who has not).
32
39
  */
33
40
  export declare function renderTeamfile(opts: {
34
41
  teamName: string;
@@ -1,2 +1,23 @@
1
1
  /** Resolve the package.json version of lmctl-next, with a safe fallback. */
2
- export declare function readLmctlNextVersion(): string;
2
+ export declare function readLmctlNextVersion(root?: string): string;
3
+ /**
4
+ * Real incident, 2026-09-29 (math routing, strengthening queued#21790): a
5
+ * dev-linked lmctl reported `--version 0.2.1` while running code from a much
6
+ * newer, unreleased checkout -- package.json's version is only bumped by the
7
+ * release commit, so any checkout sitting between releases (or a stale one
8
+ * that never rebuilt) silently reports the PREVIOUS release's number while
9
+ * running different code. That produced real false confidence: a flag
10
+ * removed that same morning was about to be published as verified-current
11
+ * documentation.
12
+ *
13
+ * A real npm install has no `.git` directory (pack-release excludes it), so
14
+ * this only ever adds detail for a git checkout, and degrades safely (plain
15
+ * `readLmctlNextVersion()`) whenever git is unavailable, the directory isn't
16
+ * a repo, or any git call fails -- `--version` must never hard-depend on git
17
+ * being installed.
18
+ *
19
+ * `root` is a test seam (defaults to the real package root) so tests can
20
+ * point this at a throwaway fixture repo instead of asserting on whatever
21
+ * commit this repo's own checkout happens to be at when the suite runs.
22
+ */
23
+ export declare function resolveLmctlVersionDisplay(root?: string): string;
@@ -0,0 +1,43 @@
1
+ export interface InitProviderSlot {
2
+ provider: string;
3
+ model1: string;
4
+ model2: string;
5
+ model3: string;
6
+ }
7
+ export interface InitConfig {
8
+ provider1: InitProviderSlot;
9
+ provider2: InitProviderSlot;
10
+ provider3: InitProviderSlot;
11
+ }
12
+ /**
13
+ * The four providers lmctl actively ships defaults for, each with three
14
+ * model tiers (top / mid / lighter). These are real, currently-declared
15
+ * models observed on a live fleet (2026-09-29) -- a useful starting point,
16
+ * not a claim of permanent correctness; lint warns (never errors) if one
17
+ * goes stale, and the whole point of `lmctl init`'s output is that it is
18
+ * meant to be edited.
19
+ */
20
+ export declare const PROVIDER_MODEL_DEFAULTS: Record<string, readonly [string, string, string]>;
21
+ /** Providers lmctl init knows how to fill in, in fixed preference order
22
+ * (used only to pick 3 of 4 when every provider is present; presence
23
+ * detection itself never ranks). */
24
+ export declare const SUPPORTED_INIT_PROVIDERS: readonly ["claude", "codex", "agy", "kimi"];
25
+ export declare function getDefaultInitConfigPath(): string;
26
+ /** Fill rule (operator, 2026-09-29): 3 detected -> use all 3; 2 -> Provider3 = Provider1;
27
+ * 1 (or 0, using a placeholder) -> Provider2 and Provider3 = Provider1. */
28
+ export declare function buildInitConfig(detectedProviders: string[]): InitConfig;
29
+ /** Returns the subset of SUPPORTED_INIT_PROVIDERS present on this machine,
30
+ * in SUPPORTED_INIT_PROVIDERS order (not a usage ranking -- presence is a
31
+ * yes/no question, order here is just deterministic output, not a claim
32
+ * about which is "best"). */
33
+ export declare function detectPresentProviders(): string[];
34
+ export declare function renderInitConfig(config: InitConfig): string;
35
+ export declare function parseInitConfigText(raw: string): InitConfig | null;
36
+ /** Reads the init config, or null if it doesn't exist / doesn't parse into
37
+ * all three complete slots. Never throws. */
38
+ export declare function readInitConfig(filePath?: string): InitConfig | null;
39
+ export declare function writeInitConfig(config: InitConfig, filePath?: string): void;
40
+ /** Substitutes ${Provider1..3} and ${Model1..3} in template text from a
41
+ * resolved InitConfig. Unknown placeholders are left untouched (quickrun
42
+ * surfaces them separately so a lint failure names the real cause). */
43
+ export declare function substituteInitPlaceholders(text: string, config: InitConfig): string;
@@ -1,3 +1,3 @@
1
1
  export declare const SEED_ACK = "ACK: waiting for explicit lmctl task.";
2
2
  export declare const SEED_INITIAL_PROMPT: string;
3
- export declare const MANUAL_SEED_POST_LAUNCH_NOTE = "send this exact lmctl seed instruction: \"lmctl seed initial connection only. Create or pin this provider session, then stop. Do not inspect files, run commands, infer a task, delegate, or edit. A dispatch that dies mid-turn is usually a timeout you set -- use --idle-timeout, not a shell timeout. Reply exactly: ACK: waiting for explicit lmctl task.\"";
3
+ export declare const MANUAL_SEED_POST_LAUNCH_NOTE = "send this exact lmctl seed instruction: \"lmctl seed initial connection only. Create or pin this provider session, then stop. Do not inspect files, run commands, infer a task, delegate, or edit. Reply exactly: ACK: waiting for explicit lmctl task.\"";
@@ -22,4 +22,4 @@ _MEMBER_ alias=Lead provider=claude
22
22
  _MEMBER_ alias=Outliner provider=claude
23
23
  _MEMBER_ alias=Drafter provider=codex
24
24
  _MEMBER_ alias=Editor provider=codex
25
- _MEMBER_ alias=FactChecker provider=qwen
25
+ _MEMBER_ alias=FactChecker provider=agy
@@ -21,5 +21,5 @@
21
21
  _MEMBER_ alias=Lead provider=claude
22
22
  _MEMBER_ alias=Researcher1 provider=codex
23
23
  _MEMBER_ alias=Researcher2 provider=claude
24
- _MEMBER_ alias=Critic provider=qwen
24
+ _MEMBER_ alias=Critic provider=opencode
25
25
  _MEMBER_ alias=Synthesizer provider=codex
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lmctl-ai/lmctl",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
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",