@automagik/genie 4.260503.8 → 4.260503.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.
package/dist/genie.js CHANGED
@@ -2940,13 +2940,13 @@ Return ONLY a bulleted list of relevant excerpts with their source file paths.
2940
2940
  Keep it under 500 words. If nothing is relevant, say "No relevant prior context."`;try{let result2=execSync15(`rlmx ${shellQuote4(rlmxQuery)} --context ${shellQuote4(brainPath)} --output json --max-iterations ${maxIterations} --max-cost ${maxCost}`,{encoding:"utf-8",timeout,env:{...process.env},stdio:["pipe","pipe","pipe"]}),answer=JSON.parse(result2).answer?.trim();if(!answer||answer==="No relevant prior context."||answer.length<20)return"";return`## Prior Context (from brain vault)
2941
2941
 
2942
2942
  ${answer}
2943
- `}catch{return""}}function shellQuote4(s2){return`'${s2.replace(/'/g,"'\\''")}'`}var init_context_enrichment=()=>{};import{execSync as execSync16}from"child_process";import{existsSync as existsSync64}from"fs";import{mkdir as mkdir9,readFile as readFile13,writeFile as writeFile8}from"fs/promises";import{tmpdir as tmpdir3}from"os";import{join as join76}from"path";async function cliSender(){let origin=await detectSenderIdentity();return origin==="cli"?"cli":`cli:${origin}`}async function writeContextFile(content){let dir=join76(tmpdir3(),"genie-dispatch");await mkdir9(dir,{recursive:!0});let ts3=Date.now().toString(36),rand=Math.random().toString(36).slice(2,8),filePath=join76(dir,`ctx-${ts3}-${rand}.md`);return await writeFile8(filePath,content),filePath}function extractGroup(content,groupName){let pattern=new RegExp(`^### Group ${escapeRegExp(groupName)}:`,"m"),match=content.match(pattern);if(!match||match.index===void 0)return null;let start3=match.index,nextBoundary=content.slice(start3).slice(1).search(/^### Group \d|^---$/m),end=nextBoundary!==-1?start3+1+nextBoundary:content.length;return content.slice(start3,end).trim()}function extractWishContext(content){let execGroupsIdx=content.indexOf("## Execution Groups");if(execGroupsIdx!==-1)return content.slice(0,execGroupsIdx).trim();return content.slice(0,2000).trim()}function validateSlug(slug){if(!SLUG_PATTERN.test(slug))console.error(`\u274C Invalid slug: "${slug}"`),console.error(" Slugs must match [a-zA-Z0-9._-]+ (no slashes, dots-dots, or special characters)"),process.exit(1)}function escapeRegExp(str5){return str5.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function buildContextPrompt(opts){let parts=[`# Dispatch Context (${opts.command})`,"",`**Source file:** \`${opts.filePath}\``,"(Read the full document at the path above for complete context)",""];if(opts.wishContext)parts.push("## Wish Context","",opts.wishContext,"");if(parts.push("## Assigned Section","",opts.sectionContent,""),opts.enrichedContext)parts.push(opts.enrichedContext);if(opts.skill)parts.push("## Initial Command","",`Run \`/${opts.skill}\` to begin.`,"");return parts.join(`
2943
+ `}catch{return""}}function shellQuote4(s2){return`'${s2.replace(/'/g,"'\\''")}'`}var init_context_enrichment=()=>{};import{execSync as execSync16}from"child_process";import{randomUUID as randomUUID14}from"crypto";import{existsSync as existsSync64}from"fs";import{mkdir as mkdir9,readFile as readFile13,writeFile as writeFile8}from"fs/promises";import{tmpdir as tmpdir3}from"os";import{join as join76}from"path";async function cliSender(){let origin=await detectSenderIdentity();return origin==="cli"?"cli":`cli:${origin}`}async function writeContextFile(content){let dir=join76(tmpdir3(),"genie-dispatch");await mkdir9(dir,{recursive:!0});let ts3=Date.now().toString(36),rand=Math.random().toString(36).slice(2,8),filePath=join76(dir,`ctx-${ts3}-${rand}.md`);return await writeFile8(filePath,content),filePath}function extractGroup(content,groupName){let pattern=new RegExp(`^### Group ${escapeRegExp(groupName)}:`,"m"),match=content.match(pattern);if(!match||match.index===void 0)return null;let start3=match.index,nextBoundary=content.slice(start3).slice(1).search(/^### Group \d|^---$/m),end=nextBoundary!==-1?start3+1+nextBoundary:content.length;return content.slice(start3,end).trim()}function extractWishContext(content){let execGroupsIdx=content.indexOf("## Execution Groups");if(execGroupsIdx!==-1)return content.slice(0,execGroupsIdx).trim();return content.slice(0,2000).trim()}function validateSlug(slug){if(!SLUG_PATTERN.test(slug))console.error(`\u274C Invalid slug: "${slug}"`),console.error(" Slugs must match [a-zA-Z0-9._-]+ (no slashes, dots-dots, or special characters)"),process.exit(1)}function escapeRegExp(str5){return str5.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function buildContextPrompt(opts){let parts=[`# Dispatch Context (${opts.command})`,"",`**Source file:** \`${opts.filePath}\``,"(Read the full document at the path above for complete context)",""];if(opts.wishContext)parts.push("## Wish Context","",opts.wishContext,"");if(parts.push("## Assigned Section","",opts.sectionContent,""),opts.enrichedContext)parts.push(opts.enrichedContext);if(opts.skill)parts.push("## Initial Command","",`Run \`/${opts.skill}\` to begin.`,"");return parts.join(`
2944
2944
  `)}function getGitDiff(){try{let diff=execSync16("git diff HEAD",{encoding:"utf-8",maxBuffer:1048576}),staged=execSync16("git diff --cached",{encoding:"utf-8",maxBuffer:1048576}),combined=[diff,staged].filter(Boolean).join(`
2945
2945
  `);if(combined.length>50000)return`${combined.slice(0,50000)}
2946
2946
 
2947
2947
  ... (diff truncated at 50KB)`;return combined}catch{return""}}function parseWishGroups(content){let groups=[],groupPattern=/^### Group ([A-Za-z0-9]+):[ \t]*(.*)$/gim,match=groupPattern.exec(content);while(match!==null){let name=match[1],trimmedTitle=(match[2]??"").trim(),title=trimmedTitle.length>0?trimmedTitle:void 0,start3=match.index,rest=content.slice(start3+match[0].length),nextGroupIdx=rest.search(/^### Group [A-Za-z0-9]+:/m),depsMatch=(nextGroupIdx!==-1?rest.slice(0,nextGroupIdx):rest).match(/\*\*depends-on:\*\*\s*(.+)/i),dependsOn=[];if(depsMatch){let depsNormalized=depsMatch[1].trim().replace(/\s*\([^)]*\)/g,"").trim();if(depsNormalized.toLowerCase()!=="none")dependsOn=depsNormalized.split(",").map((d)=>d.trim().replace(/^groups?\s*/i,"").replace(/^[a-z0-9-]+#/,"").trim()).filter(Boolean)}let groupDef={name,dependsOn};if(title!==void 0)groupDef.title=title;groups.push(groupDef),match=groupPattern.exec(content)}return groups}function parseExecutionStrategy(content){let strategyMatch=content.match(/^## Execution Strategy\s*$/m);if(!strategyMatch||strategyMatch.index===void 0)return buildFallbackWaves(content);let strategyStart=strategyMatch.index+strategyMatch[0].length,nextSectionMatch=content.slice(strategyStart).match(/^## /m),strategyEnd=nextSectionMatch?.index!==void 0?strategyStart+nextSectionMatch.index:content.length,strategyContent=content.slice(strategyStart,strategyEnd),waves=[],wavePattern=/^### (Wave \d+[^\n]*)/gm,waveMatch=wavePattern.exec(strategyContent);while(waveMatch!==null){let waveName=waveMatch[1].trim(),waveStart=waveMatch.index+waveMatch[0].length,nextWaveIdx=strategyContent.slice(waveStart).search(/^### /m),waveEnd=nextWaveIdx!==-1?waveStart+nextWaveIdx:strategyContent.length,waveContent=strategyContent.slice(waveStart,waveEnd),waveGroups=[],tableRowPattern=/^\|\s*([^|]+?)\s*\|\s*([^|]+?)\s*\|\s*[^|]*\s*\|$/gm,rowMatch=tableRowPattern.exec(waveContent);while(rowMatch!==null){let groupVal=rowMatch[1].trim(),agentVal=rowMatch[2].trim();if(groupVal!=="Group"&&!groupVal.startsWith("-"))waveGroups.push({group:groupVal,agent:agentVal});rowMatch=tableRowPattern.exec(waveContent)}if(waveGroups.length>0)waves.push({name:waveName,groups:waveGroups});waveMatch=wavePattern.exec(strategyContent)}if(waves.length===0)return buildFallbackWaves(content);return waves}function buildFallbackWaves(content){let groups=parseWishGroups(content);if(groups.length===0)return[];return[{name:"Wave 1 (sequential fallback)",groups:groups.map((g)=>({group:g.name,agent:"engineer"}))}]}async function resolveLeaderTarget(){let teamName=process.env.GENIE_TEAM;if(!teamName)return"team-lead";try{let{resolveLeaderName:resolveLeaderName2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager));return await resolveLeaderName2(teamName)}catch{return teamName}}function detectWorkMode(ref,agent){if(!agent){if(ref.includes("#"))throw Error("Manual dispatch requires an agent: genie work <slug>#<group> <agent>");return{mode:"auto",slug:ref}}if(ref.includes("#"))return{mode:"manual",ref,agent};if(agent.includes("#"))return{mode:"manual",ref:agent,agent:ref};throw Error('Invalid: ref must contain "#" \u2014 use "genie work <slug>" or "genie work <agent> <slug>#<group>"')}async function autoOrchestrateCommand(slug){let wishPath,actualSlug=slug;if(parseWishRef(slug).namespace){let resolved=await resolveWish(slug);wishPath=resolved.wishPath,actualSlug=resolved.slug;let{handleTeamCreate:handleTeamCreate2}=await Promise.resolve().then(() => (init_team(),exports_team));await handleTeamCreate2(actualSlug,{repo:resolved.repo,branch:"dev",wish:actualSlug,tmuxSession:resolved.session});return}if(validateSlug(slug),wishPath=join76(process.cwd(),".genie","wishes",slug,"WISH.md"),!existsSync64(wishPath))console.error(`\u274C Wish not found: ${wishPath}`),console.error(` Create it first: genie wish <agent> ${slug}`),process.exit(1);Promise.resolve().then(() => (init_wish_sync(),exports_wish_sync)).then((ws)=>ws.syncWishes(process.cwd())).catch(()=>{});let content=await readFile13(wishPath,"utf-8"),groups=parseWishGroups(content),waves=parseExecutionStrategy(content);if(waves.length===0)console.error("\u274C No execution groups found in wish"),process.exit(1);let state=await getOrCreateState(slug,groups),nextWave=waves.find((wave)=>wave.groups.some((g)=>{let gs=state?.groups[g.group];return!gs||gs.status==="ready"}));if(!nextWave){console.log(`\u2705 All waves already dispatched for wish "${slug}"`);return}console.log(`\uD83D\uDE80 Dispatching ${nextWave.name} for wish "${slug}" \u2014 ${nextWave.groups.length} group(s)`);let results=await Promise.allSettled(nextWave.groups.map(({group,agent})=>{let ref=`${slug}#${group}`;return workDispatchCommand(agent,ref)})),succeeded=[],failed=[];if(results.forEach((r,i2)=>{let groupName=nextWave.groups[i2].group,agent=nextWave.groups[i2].agent;if(r.status==="fulfilled")succeeded.push(groupName);else{let reason=r.reason instanceof Error?r.reason.message:String(r.reason),errorClass=r.reason instanceof Error?r.reason.constructor.name:"string";failed.push({group:groupName,agent,reason,errorClass})}}),succeeded.length>0)console.log(`
2948
2948
  \u2705 Agents dispatched for ${nextWave.name} (groups: ${succeeded.join(", ")})`);if(failed.length>0){console.error(`
2949
- \u274C ${failed.length} group(s) failed to dispatch in ${nextWave.name}:`);for(let{group,agent,reason,errorClass}of failed)console.error(` \u2022 Group ${group} (${agent}): [${errorClass}] ${reason}`),recordAuditEvent("wish",actualSlug,"wish.dispatch.failed",getActor(),{wish_slug:actualSlug,wave_name:nextWave.name,group_name:group,agent_name:agent,error_class:errorClass,reason}).catch(()=>{});console.error(` Check state with: genie status ${slug}`),console.error(" Some groups may have mutated state before failing \u2014 rerun genie work to retry.")}if(console.log(` Monitor: genie status ${slug}`),console.log(" Logs: genie read <agent>"),failed.length>0)process.exitCode=1}async function brainstormCommand(agentName,slug){validateSlug(slug);let draftPath=join76(process.cwd(),".genie","brainstorms",slug,"DRAFT.md");if(!existsSync64(draftPath))console.error(`\u274C Draft not found: ${draftPath}`),console.error(` Create it first: mkdir -p .genie/brainstorms/${slug} && touch .genie/brainstorms/${slug}/DRAFT.md`),process.exit(1);let content=await readFile13(draftPath,"utf-8"),context=buildContextPrompt({filePath:draftPath,sectionContent:content,command:"brainstorm",skill:"brainstorm"}),contextFile=await writeContextFile(context);console.log(`\uD83D\uDCDD Dispatching brainstorm to ${agentName} for "${slug}"`),console.log(` Draft: ${draftPath}`);let brainstormPrompt=`Brainstorm "${slug}". Your context is in the system prompt. Explore the idea, ask clarifying questions, and build toward a design.`;await handleWorkerSpawn(agentName,{provider:"claude",cwd:process.cwd(),extraArgs:["--append-system-prompt-file",contextFile],initialPrompt:brainstormPrompt});let repoPath=process.cwd(),result2=await sendMessage2(repoPath,await cliSender(),agentName,brainstormPrompt);if(!result2.delivered)console.warn(`\u26A0 Backup delivery to ${agentName} failed: ${result2.reason??"unknown"}`)}async function wishCommand(agentName,slug){validateSlug(slug);let designPath=join76(process.cwd(),".genie","brainstorms",slug,"DESIGN.md");if(!existsSync64(designPath))console.error(`\u274C Design not found: ${designPath}`),console.error(` Run brainstorm first: genie brainstorm <agent> ${slug}`),process.exit(1);let content=await readFile13(designPath,"utf-8"),context=buildContextPrompt({filePath:designPath,sectionContent:content,command:"wish",skill:"wish"}),contextFile=await writeContextFile(context);console.log(`\uD83D\uDCDD Dispatching wish to ${agentName} for "${slug}"`),console.log(` Design: ${designPath}`);let wishPrompt=`Create a wish from the design for "${slug}". Your context is in the system prompt. Write the WISH.md with execution groups, acceptance criteria, and validation commands.`;await handleWorkerSpawn(agentName,{provider:"claude",cwd:process.cwd(),extraArgs:["--append-system-prompt-file",contextFile],initialPrompt:wishPrompt});let repoPath=process.cwd(),result2=await sendMessage2(repoPath,await cliSender(),agentName,wishPrompt);if(!result2.delivered)console.warn(`\u26A0 Backup delivery to ${agentName} failed: ${result2.reason??"unknown"}`)}async function workDispatchCommand(agentName,ref){let{slug,group}=parseRef(ref);validateSlug(slug);let wishPath=join76(process.cwd(),".genie","wishes",slug,"WISH.md"),dispatchSpan=isWideEmitEnabled()?startSpan("wish.dispatch",{wish_slug:slug,group_name:group},{source_subsystem:"dispatch",ctx:getAmbient()??void 0,agent:agentName}):null;try{if(await runWorkDispatch(slug,group,agentName,wishPath,ref),dispatchSpan)endSpan(dispatchSpan,{outcome:"completed"},{source_subsystem:"dispatch",agent:agentName})}catch(err){if(dispatchSpan)endSpan(dispatchSpan,{outcome:"failed"},{source_subsystem:"dispatch",agent:agentName});throw err}}async function runWorkDispatch(slug,group,agentName,wishPath,ref){if(!existsSync64(wishPath))throw Error(`Wish not found: ${wishPath}. Create it first: genie wish <agent> ${slug}`);let content=await readFile13(wishPath,"utf-8"),groupSection=extractGroup(content,group);if(!groupSection){let availableGroups=content.match(/^### Group [A-Za-z0-9]+:.*$/gm),availableList=availableGroups?availableGroups.join(", "):"(none)";throw Error(`Group "${group}" not found in ${wishPath}. Available: ${availableList}`)}let groups=parseWishGroups(content);await getOrCreateState(slug,groups);try{await startGroup(slug,group,agentName),console.log(`\u2705 Group "${group}" set to in_progress (assigned to ${agentName})`)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);throw Error(message)}let wishContext=extractWishContext(content),enrichedContext;try{let{enrichContext:enrichContext2}=await Promise.resolve().then(() => (init_context_enrichment(),exports_context_enrichment));enrichedContext=enrichContext2({query:`${slug} ${group}: ${groupSection.slice(0,500)}`})||void 0}catch{}let context=buildContextPrompt({filePath:wishPath,sectionContent:groupSection,wishContext,command:`work ${ref}`,skill:"work",enrichedContext}),contextFile=await writeContextFile(context);console.log(`\uD83D\uDD27 Dispatching work to ${agentName} for "${ref}"`),console.log(` Wish: ${wishPath}`),console.log(` Group: ${group}`);let effectiveRole=`${agentName}-${group}`,leaderTarget=await resolveLeaderTarget(),workPrompt=`Execute Group ${group} of wish "${slug}". Your full context is in the system prompt. Read the wish at ${wishPath} if needed. Implement all deliverables, run validation, and report completion.
2949
+ \u274C ${failed.length} group(s) failed to dispatch in ${nextWave.name}:`);for(let{group,agent,reason,errorClass}of failed)console.error(` \u2022 Group ${group} (${agent}): [${errorClass}] ${reason}`),recordAuditEvent("wish",actualSlug,"wish.dispatch.failed",getActor(),{wish_slug:actualSlug,wave_name:nextWave.name,group_name:group,agent_name:agent,error_class:errorClass,reason}).catch(()=>{});console.error(` Check state with: genie status ${slug}`),console.error(" Some groups may have mutated state before failing \u2014 rerun genie work to retry.")}if(console.log(` Monitor: genie status ${slug}`),console.log(" Logs: genie read <agent>"),failed.length>0)process.exitCode=1}async function brainstormCommand(agentName,slug){validateSlug(slug);let draftPath=join76(process.cwd(),".genie","brainstorms",slug,"DRAFT.md");if(!existsSync64(draftPath))console.error(`\u274C Draft not found: ${draftPath}`),console.error(` Create it first: mkdir -p .genie/brainstorms/${slug} && touch .genie/brainstorms/${slug}/DRAFT.md`),process.exit(1);let content=await readFile13(draftPath,"utf-8"),context=buildContextPrompt({filePath:draftPath,sectionContent:content,command:"brainstorm",skill:"brainstorm"}),contextFile=await writeContextFile(context);console.log(`\uD83D\uDCDD Dispatching brainstorm to ${agentName} for "${slug}"`),console.log(` Draft: ${draftPath}`);let brainstormPrompt=`Brainstorm "${slug}". Your context is in the system prompt. Explore the idea, ask clarifying questions, and build toward a design.`;await handleWorkerSpawn(agentName,{provider:"claude",cwd:process.cwd(),extraArgs:["--append-system-prompt-file",contextFile],initialPrompt:brainstormPrompt});let repoPath=process.cwd(),result2=await sendMessage2(repoPath,await cliSender(),agentName,brainstormPrompt);if(!result2.delivered)console.warn(`\u26A0 Backup delivery to ${agentName} failed: ${result2.reason??"unknown"}`)}async function wishCommand(agentName,slug){validateSlug(slug);let designPath=join76(process.cwd(),".genie","brainstorms",slug,"DESIGN.md");if(!existsSync64(designPath))console.error(`\u274C Design not found: ${designPath}`),console.error(` Run brainstorm first: genie brainstorm <agent> ${slug}`),process.exit(1);let content=await readFile13(designPath,"utf-8"),context=buildContextPrompt({filePath:designPath,sectionContent:content,command:"wish",skill:"wish"}),contextFile=await writeContextFile(context);console.log(`\uD83D\uDCDD Dispatching wish to ${agentName} for "${slug}"`),console.log(` Design: ${designPath}`);let wishPrompt=`Create a wish from the design for "${slug}". Your context is in the system prompt. Write the WISH.md with execution groups, acceptance criteria, and validation commands.`;await handleWorkerSpawn(agentName,{provider:"claude",cwd:process.cwd(),extraArgs:["--append-system-prompt-file",contextFile],initialPrompt:wishPrompt});let repoPath=process.cwd(),result2=await sendMessage2(repoPath,await cliSender(),agentName,wishPrompt);if(!result2.delivered)console.warn(`\u26A0 Backup delivery to ${agentName} failed: ${result2.reason??"unknown"}`)}async function workDispatchCommand(agentName,ref){let{slug,group}=parseRef(ref);validateSlug(slug);let wishPath=join76(process.cwd(),".genie","wishes",slug,"WISH.md"),dispatchSpan=isWideEmitEnabled()?startSpan("wish.dispatch",{wish_slug:slug,group_name:group},{source_subsystem:"dispatch",ctx:getAmbient()??void 0,agent:agentName}):null;try{if(await runWorkDispatch(slug,group,agentName,wishPath,ref),dispatchSpan)endSpan(dispatchSpan,{outcome:"completed"},{source_subsystem:"dispatch",agent:agentName})}catch(err){if(dispatchSpan)endSpan(dispatchSpan,{outcome:"failed"},{source_subsystem:"dispatch",agent:agentName});throw err}}async function runWorkDispatch(slug,group,agentName,wishPath,ref){if(!existsSync64(wishPath))throw Error(`Wish not found: ${wishPath}. Create it first: genie wish <agent> ${slug}`);let content=await readFile13(wishPath,"utf-8"),groupSection=extractGroup(content,group);if(!groupSection){let availableGroups=content.match(/^### Group [A-Za-z0-9]+:.*$/gm),availableList=availableGroups?availableGroups.join(", "):"(none)";throw Error(`Group "${group}" not found in ${wishPath}. Available: ${availableList}`)}let groups=parseWishGroups(content);await getOrCreateState(slug,groups);try{await startGroup(slug,group,agentName),console.log(`\u2705 Group "${group}" set to in_progress (assigned to ${agentName})`)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);throw Error(message)}let wishContext=extractWishContext(content),enrichedContext;try{let{enrichContext:enrichContext2}=await Promise.resolve().then(() => (init_context_enrichment(),exports_context_enrichment));enrichedContext=enrichContext2({query:`${slug} ${group}: ${groupSection.slice(0,500)}`})||void 0}catch{}let context=buildContextPrompt({filePath:wishPath,sectionContent:groupSection,wishContext,command:`work ${ref}`,skill:"work",enrichedContext}),contextFile=await writeContextFile(context);console.log(`\uD83D\uDD27 Dispatching work to ${agentName} for "${ref}"`),console.log(` Wish: ${wishPath}`),console.log(` Group: ${group}`);let effectiveRole=`${agentName}-${group}-${randomUUID14().slice(0,4)}`,leaderTarget=await resolveLeaderTarget(),workPrompt=`Execute Group ${group} of wish "${slug}". Your full context is in the system prompt. Read the wish at ${wishPath} if needed. Implement all deliverables, run validation, and report completion.
2950
2950
 
2951
2951
  When done:
2952
2952
  1. Run: genie done ${slug}#${group}
@@ -4843,7 +4843,7 @@ Stage Pipeline:`);let stages=t.stages;for(let i2=0;i2<stages.length;i2++){let s2
4843
4843
  No fixable violations to apply.`);process.exit(report2.summary.total>0?1:0)}function handleDryRunFix(report2,markdown,fixed,wishPath,jsonMode){if(jsonMode)console.log(JSON.stringify({...report2,dryRun:!0,diff:renderDiff(markdown,fixed)}));else console.log(formatLintReport(report2,{color:process.stdout.isTTY??!1,path:wishPath})),console.log(`
4844
4844
  --- Dry-run diff (${wishPath}) ---`),console.log(renderDiff(markdown,fixed)),console.log(`
4845
4845
  File not modified (--dry-run).`);process.exit(report2.summary.total>0?1:0)}async function applyAndReportFix(report2,fixed,wishPath,slug,lintOpts,jsonMode){await writeFile11(wishPath,fixed,"utf-8");let docOrError2=parseWishOrError(fixed),report22={...lintWish(docOrError2,fixed,lintOpts),wish:slug,file:wishPath},fixedCount=report2.summary.fixable;if(jsonMode)console.log(JSON.stringify({...report22,fixedViolations:fixedCount}));else console.log(`\u2705 Applied ${fixedCount} fix(es) to ${wishPath}`),console.log(""),console.log(formatLintReport(report22,{color:process.stdout.isTTY??!1,path:wishPath}));let remainingErrors=report22.violations.filter((v)=>v.severity==="error").length;process.exit(remainingErrors>0?1:0)}async function runLintFix(report2,markdown,wishPath,slug,lintOpts,options){let{applyFixes:applyFixes2}=await Promise.resolve().then(() => (init_wish_lint(),exports_wish_lint)),fixed=applyFixes2(markdown,report2),jsonMode=options.json??!1;if(fixed===markdown)handleNoFixableViolations(report2,wishPath,jsonMode);if(options.dryRun)handleDryRunFix(report2,markdown,fixed,wishPath,jsonMode);return applyAndReportFix(report2,fixed,wishPath,slug,lintOpts,jsonMode)}async function wishLintCommand(slug,options){let wishPath=join88(process.cwd(),".genie","wishes",slug,"WISH.md"),jsonMode=options.json??!1;if(!existsSync73(wishPath))reportWishFileMissing(slug,wishPath,jsonMode);let markdown=await readFile17(wishPath,"utf-8"),lintOpts={allowTodoPlaceholders:options.allowTodoPlaceholders},docOrError=parseWishOrError(markdown),report2={...lintWish(docOrError,markdown,lintOpts),wish:slug,file:wishPath};if(options.fix){await runLintFix(report2,markdown,wishPath,slug,lintOpts,options);return}emitLintReport(report2,wishPath,jsonMode),exitWithErrorCount(report2)}function reportWishParseError(error2,jsonMode){let payload={error:error2.message,rule:error2.rule,line:error2.line,column:error2.column??null,file:error2.file??null};if(jsonMode){console.log(JSON.stringify(payload));return}if(console.error(`\u274C Parse failed (${payload.rule}): ${payload.error}`),payload.file)console.error(` File: ${payload.file}`);if(payload.line)console.error(` Line: ${payload.line}`)}async function wishParseCommand(slug,options){try{let doc=parseWishFile(slug);console.log(options.json?JSON.stringify(doc):JSON.stringify(doc,null,2));return}catch(error2){if(error2 instanceof WishParseError)reportWishParseError(error2,options.json??!1),process.exit(1);let message=error2 instanceof Error?error2.message:String(error2);console.error(`\u274C ${message}`),process.exit(1)}}async function isWishFile(wishPath){try{return(await stat11(wishPath)).isFile()}catch{return!1}}function parseWishSummary(slug){try{let doc=parseWishFile(slug);return{status:doc.metadata.status??"-",groupCount:String(doc.executionGroups.length)}}catch(error2){return{status:error2 instanceof WishParseError?"malformed":"error",groupCount:"-"}}}async function loadStateCounts(slug){try{let state=await(await Promise.resolve().then(() => (init_wish_state(),exports_wish_state))).getState(slug);if(!state)return{ready:0,inProgress:0,done:0};let ready=0,inProgress=0,done=0;for(let g of Object.values(state.groups))if(g.status==="ready")ready++;else if(g.status==="in_progress")inProgress++;else if(g.status==="done")done++;return{ready,inProgress,done}}catch{return{ready:0,inProgress:0,done:0}}}async function wishListCommand(){let wishesRoot=join88(process.cwd(),".genie","wishes");if(!existsSync73(wishesRoot))console.error(`\u274C Wishes directory not found: ${wishesRoot}`),process.exit(1);let entries=await readdir11(wishesRoot),rows=[];for(let entry2 of entries.sort()){if(entry2.startsWith("_")||entry2.startsWith("."))continue;if(!await isWishFile(join88(wishesRoot,entry2,"WISH.md")))continue;let{status:status2,groupCount}=parseWishSummary(entry2),{ready,inProgress,done}=await loadStateCounts(entry2);rows.push({slug:entry2,status:status2,groupCount,ready,inProgress,done})}if(rows.length===0){console.log("No wishes found under .genie/wishes/");return}let slugW=Math.max(4,...rows.map((r)=>r.slug.length)),statusW=Math.max(6,...rows.map((r)=>r.status.length)),pad=(s2,n)=>s2+" ".repeat(Math.max(0,n-s2.length));console.log(` ${pad("SLUG",slugW)} ${pad("STATUS",statusW)} GROUPS READY IN-PROG DONE`),console.log(` ${"\u2500".repeat(slugW+statusW+32)}`);for(let r of rows)console.log(` ${pad(r.slug,slugW)} ${pad(r.status,statusW)} ${pad(r.groupCount,6)} ${pad(String(r.ready),5)} ${pad(String(r.inProgress),7)} ${r.done}`);console.log(""),console.log(` Total: ${rows.length} wishes`)}function registerWishCommands(program2){let wish=program2.command("wish").description("Wish lifecycle management");wish.command("new <slug>").description("Scaffold a new WISH.md from templates/wish-template.md").option("--force","Overwrite an existing wish directory").action(async(slug,options)=>{await wishNewCommand(slug,options)}),wish.command("lint <slug>").description("Structural health check (stub \u2014 full implementation in Group 3)").option("--json","Emit machine-readable JSON output").option("--fix","Auto-repair deterministic violations").option("--dry-run","With --fix: print diff without writing").option("--allow-todo-placeholders","Pass <TODO> placeholders without emitting todo-placeholder-remaining").action(async(slug,options)=>{await wishLintCommand(slug,options)}),wish.command("parse <slug>").description("Parse WISH.md and emit the WishDocument as JSON").option("--json","One-line JSON output (default: pretty-printed)").action(async(slug,options)=>{await wishParseCommand(slug,options)}),wish.command("status <slug>").description("Show wish state overview for all groups").action(async(slug)=>{await statusCommand(slug)}),wish.command("done <ref>").description("Mark a wish group as done (format: <slug>#<group>)").action(async(ref)=>{await doneCommand(ref)}),wish.command("reset <ref>").option("-y, --yes","Skip confirmation prompt (required in non-interactive mode)").description("Reset wish state. <slug>#<group> resets one in-progress group; bare <slug> wipes the wish and recreates from current WISH.md").action(async(ref,options)=>{await resetAction(ref,options)}),wish.command("list").description("Enumerate all wishes with status, group counts, and progress").action(async()=>{await wishListCommand()})}var _T_BOOT=Date.now();try{let{execSync:execSyncStartup}=__require("child_process");if(execSyncStartup("git config core.bare",{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()==="true")execSyncStartup("git config core.bare false",{stdio:["pipe","pipe","pipe"]})}catch{}function parseNumericFlag2(flagName){return(value)=>{let n=Number(value);if(Number.isNaN(n))throw Error(`${flagName} must be a number, got: ${value}`);return n}}if(process.env.GENIE_PROFILE_DB)console.error(`[profile] imports=${Date.now()-_T_BOOT}ms`);var program2=new Command;program2.name("genie").description("Genie CLI - AI-assisted development").version(VERSION);program2.option("--no-interactive","Disable interactive prompts (exit 2 instead of prompting)");program2.option("--no-tui","Skip TUI bootstrap (or set GENIE_TUI_DISABLE=1)");program2.configureHelp({sortSubcommands:!0,showGlobalOptions:!0});program2.configureOutput({outputError:(str5,write)=>{let cmd=program2.commands.find((c)=>process.argv.slice(2,6).includes(c.name())),prefix=cmd?`genie ${cmd.name()}`:"genie";write(`\x1B[31mError (${prefix}): ${str5}\x1B[0m
4846
- `)}});async function startNamedSession(name){let{randomUUID:randomUUID14}=await import("crypto"),{buildTeamLeadCommand:buildTeamLeadCommand2}=await Promise.resolve().then(() => (init_team_lead_command(),exports_team_lead_command)),{getAgentsFilePath:getAgentsFilePath2}=await Promise.resolve().then(() => (init_session(),exports_session)),systemPromptFile=getAgentsFilePath2(),sessionId=randomUUID14(),cmd=buildTeamLeadCommand2(name,{systemPromptFile:systemPromptFile??void 0,sessionId});console.log(`Starting new session: ${name}`);let{spawnSync:spawnSync11}=await import("child_process"),result2=spawnSync11("sh",["-c",cmd],{stdio:"inherit"});if(result2.status)process.exit(result2.status)}program2.command("setup").description("Configure genie settings").option("--quick","Accept all defaults").option("--shortcuts","Only configure keyboard shortcuts").option("--codex","Only configure Codex integration").option("--terminal","Only configure terminal defaults").option("--session","Only configure session settings").option("--reset","Reset configuration to defaults").option("--show","Show current configuration").action(async(options)=>{await setupCommand(options)});program2.command("install").description("Register genie-serve under pm2 with hardened defaults (canonical-pgserve-pm2-supervision wave 2)").option("--skip-pgserve","Don't run `pgserve install` first (operators who manage pgserve themselves)").action(async(options)=>{await installCommand(options)});program2.command("doctor").description("Run diagnostic checks on genie installation").option("--fix","Auto-fix: kill zombie postgres, clean shared memory, restart daemon").option("--observability","Report partition health + GENIE_WIDE_EMIT flag state").option("--perf","Report rolling per-handler P50/P99 from hook_perf_baseline + flag P99 regressions and recent fallback-log entries").option("--fix-team-orphans","Archive stale Claude-team config dirs missing config.json (paired with invincible-genie wish migration 050)").option("--dry-run","Pair with --fix-team-orphans to preview archive moves without mutating").option("--json","Emit JSON instead of human output (pairs with --observability)").action(doctorCommand);program2.command("update").description("Update Genie CLI to the latest version").option("--next","Switch to dev builds (npm @next tag)").option("--stable","Switch to stable releases (npm @latest tag)").option("--skip-maintenance","Skip post-update maintenance (or set GENIE_UPDATE_SKIP_MAINTENANCE=1)").action(updateCommand);program2.command("migrate").description("Apply pending genie host-migrations (auto-runs on install)").option("--dry-run","List pending migrations without executing").option("--quiet","Suppress per-step OK lines (used by postinstall)").option("--status","Show applied / pending / failed table").action(async(opts)=>{await migrateCommand({dryRun:opts.dryRun,quiet:opts.quiet,status:opts.status})});program2.command("uninstall").description("Remove Genie CLI and clean up hooks").action(uninstallCommand);var shortcuts=program2.command("shortcuts").description("Manage tmux keyboard shortcuts");shortcuts.action(shortcutsShowCommand);shortcuts.command("show").description("Show available shortcuts and installation status").action(shortcutsShowCommand);shortcuts.command("install").description("Install shortcuts to config files (~/.tmux.conf, shell rc)").action(shortcutsInstallCommand);shortcuts.command("uninstall").description("Remove shortcuts from config files").action(shortcutsUninstallCommand);registerServeCommands(program2);registerAppCommand(program2);registerInitCommands(program2);registerTeamNamespace(program2);registerDirNamespace(program2);registerAgentCommands(program2);registerObserveCommands(program2);registerOmniNamespace(program2);registerSendInboxCommands(program2);registerStateCommands(program2);registerDispatchCommands(program2);registerDispatchGroupCommands(program2);registerWishCommands(program2);registerHookNamespace(program2);registerDbCommands(program2);registerScheduleCommands(program2);registerDaemonCommands(program2);registerTaskCommands(program2);registerTypeCommands(program2);registerBoardCommands(program2);registerTagCommands(program2);registerReleaseCommands(program2);registerSecCommands(program2);registerProjectCommands(program2);registerPruneCommands(program2);registerNotifyCommands(program2);registerEventsCommands(program2);registerSessionsCommands(program2);registerMetricsCommands(program2);registerExportCommands(program2);registerImportCommands(program2);registerTemplateCommands(program2);registerBrainCommands(program2);registerBriefCommands(program2);registerApprovalCommands(program2);program2.command("done [ref]").description("Close the current turn (inside an agent session) or mark a wish group done (team-lead, <slug>#<group>)").action(async(ref)=>{let{doneAction:doneAction2}=await Promise.resolve().then(() => (init_done(),exports_done));await doneAction2(ref)});program2.command("blocked").description("Close the current turn with outcome=blocked").requiredOption("--reason <message>","Why the turn is blocked").action(async(options)=>{let{blockedAction:blockedAction2}=await Promise.resolve().then(() => (init_blocked(),exports_blocked));await blockedAction2(options)});program2.command("failed").description("Close the current turn with outcome=failed").requiredOption("--reason <message>","Why the turn failed").action(async(options)=>{let{failedAction:failedAction2}=await Promise.resolve().then(() => (init_failed(),exports_failed));await failedAction2(options)});program2.command("pane-trap").description("Internal: write clean_exit_unverified outcome for a dying pane/shell. Invoked by the tmux pane-died hook and the inline shell EXIT trap.").option("--pane-id <id>","tmux pane id (%N) \u2014 resolved to executor via executors.tmux_pane_id").option("--executor-id <id>","explicit executor UUID (preferred when available)").option("--reason <reason>","trap source: pane_died or shell_exit","pane_died").action(async(options)=>{let{paneTrapAction:paneTrapAction2}=await Promise.resolve().then(() => (init_pane_trap2(),exports_pane_trap));await paneTrapAction2(options)});installWorkspaceCheck(program2);var auditTimers=new Map,auditSpans=new Map;program2.hook("preAction",(_thisCommand,actionCommand)=>{let name=actionCommand.name();auditTimers.set(name,Date.now()),Promise.resolve().then(() => (init_db(),exports_db)).then(({isConnected:isConnected2})=>{if(!isConnected2())return;recordAuditEvent("command",name,"command_start",getActor(),{args:actionCommand.args}).catch(()=>{})}).catch(()=>{}),(async()=>{try{let{isWideEmitEnabled:isWideEmitEnabled2}=await Promise.resolve().then(() => exports_observability_flag);if(!isWideEmitEnabled2())return;let{startSpan:startSpan2}=await Promise.resolve().then(() => (init_emit(),exports_emit)),{getAmbient:getAmbient2}=await Promise.resolve().then(() => (init_trace_context(),exports_trace_context)),handle=startSpan2("cli.command",{command:name,args:actionCommand.args??[],cwd:process.cwd()},{severity:"debug",source_subsystem:"cli",ctx:getAmbient2()??void 0,agent:getActor()});auditSpans.set(name,handle)}catch{}})()});program2.hook("postAction",async(_thisCommand,actionCommand)=>{let name=actionCommand.name(),startMs=auditTimers.get(name),durationMs=startMs?Date.now()-startMs:void 0;auditTimers.delete(name);try{let{isConnected:isConnected2}=await Promise.resolve().then(() => (init_db(),exports_db));if(!isConnected2())return;await recordAuditEvent("command",name,"command_success",getActor(),{args:actionCommand.args,duration_ms:durationMs})}catch{}let handle=auditSpans.get(name);auditSpans.delete(name);try{if(handle){let{isWideEmitEnabled:isWideEmitEnabled2}=await Promise.resolve().then(() => exports_observability_flag);if(isWideEmitEnabled2()){let{endSpan:endSpan2}=await Promise.resolve().then(() => (init_emit(),exports_emit));endSpan2(handle,{exit_code:0,duration_ms:durationMs??0},{severity:"debug",source_subsystem:"cli",agent:getActor()})}}}catch{}try{let{flushNow:flushNow2}=await Promise.resolve().then(() => (init_emit(),exports_emit));await flushNow2()}catch{}});program2.command("spawn <name>").description("Spawn a new agent by name (resolves from directory or built-ins)").option("--provider <provider>","Provider: claude or codex","claude").option("--team <team>","Team name").option("--model <model>","Model override (e.g., sonnet, opus)").option("--skill <skill>","Skill to load (optional)").option("--layout <layout>","Layout mode: mosaic (default) or vertical").option("--color <color>","Teammate pane border color").option("--plan-mode","Start teammate in plan mode").option("--permission-mode <mode>","Permission mode (e.g., acceptEdits)").option("--extra-args <args...>","Extra CLI args forwarded to provider").option("--cwd <path>","Working directory for the agent (overrides directory entry)").option("--session <session>","Tmux session name to spawn into").option("--role <role>","Override role name for registration (avoids duplicate guard)").option("--new-window","Create a new tmux window instead of splitting").option("--window <target>","Tmux window to split into (e.g., genie:3)").option("--no-auto-resume","Disable auto-resume on pane death").option("--no-auto-sync","Disable auto-registration from workspace agents directory").option("--stream","Stream SDK messages to stdout in real-time (claude-sdk provider)").option("--stream-format <format>","Streaming output format: text, json, ndjson (default: text)","text").option("--sdk-max-turns <n>","SDK: max conversation turns",parseNumericFlag2("--sdk-max-turns")).option("--sdk-max-budget <usd>","SDK: max budget in USD",parseNumericFlag2("--sdk-max-budget")).option("--sdk-stream","SDK: enable streaming output (shortcut for --stream)").option("--sdk-effort <level>","SDK: reasoning effort level (low, medium, high, max)").option("--sdk-resume <session-id>","SDK: resume a previous session by ID").option("--prompt <text>","Initial prompt to send as the first user message").addHelpText("after",`
4846
+ `)}});async function startNamedSession(name){let{randomUUID:randomUUID15}=await import("crypto"),{buildTeamLeadCommand:buildTeamLeadCommand2}=await Promise.resolve().then(() => (init_team_lead_command(),exports_team_lead_command)),{getAgentsFilePath:getAgentsFilePath2}=await Promise.resolve().then(() => (init_session(),exports_session)),systemPromptFile=getAgentsFilePath2(),sessionId=randomUUID15(),cmd=buildTeamLeadCommand2(name,{systemPromptFile:systemPromptFile??void 0,sessionId});console.log(`Starting new session: ${name}`);let{spawnSync:spawnSync11}=await import("child_process"),result2=spawnSync11("sh",["-c",cmd],{stdio:"inherit"});if(result2.status)process.exit(result2.status)}program2.command("setup").description("Configure genie settings").option("--quick","Accept all defaults").option("--shortcuts","Only configure keyboard shortcuts").option("--codex","Only configure Codex integration").option("--terminal","Only configure terminal defaults").option("--session","Only configure session settings").option("--reset","Reset configuration to defaults").option("--show","Show current configuration").action(async(options)=>{await setupCommand(options)});program2.command("install").description("Register genie-serve under pm2 with hardened defaults (canonical-pgserve-pm2-supervision wave 2)").option("--skip-pgserve","Don't run `pgserve install` first (operators who manage pgserve themselves)").action(async(options)=>{await installCommand(options)});program2.command("doctor").description("Run diagnostic checks on genie installation").option("--fix","Auto-fix: kill zombie postgres, clean shared memory, restart daemon").option("--observability","Report partition health + GENIE_WIDE_EMIT flag state").option("--perf","Report rolling per-handler P50/P99 from hook_perf_baseline + flag P99 regressions and recent fallback-log entries").option("--fix-team-orphans","Archive stale Claude-team config dirs missing config.json (paired with invincible-genie wish migration 050)").option("--dry-run","Pair with --fix-team-orphans to preview archive moves without mutating").option("--json","Emit JSON instead of human output (pairs with --observability)").action(doctorCommand);program2.command("update").description("Update Genie CLI to the latest version").option("--next","Switch to dev builds (npm @next tag)").option("--stable","Switch to stable releases (npm @latest tag)").option("--skip-maintenance","Skip post-update maintenance (or set GENIE_UPDATE_SKIP_MAINTENANCE=1)").action(updateCommand);program2.command("migrate").description("Apply pending genie host-migrations (auto-runs on install)").option("--dry-run","List pending migrations without executing").option("--quiet","Suppress per-step OK lines (used by postinstall)").option("--status","Show applied / pending / failed table").action(async(opts)=>{await migrateCommand({dryRun:opts.dryRun,quiet:opts.quiet,status:opts.status})});program2.command("uninstall").description("Remove Genie CLI and clean up hooks").action(uninstallCommand);var shortcuts=program2.command("shortcuts").description("Manage tmux keyboard shortcuts");shortcuts.action(shortcutsShowCommand);shortcuts.command("show").description("Show available shortcuts and installation status").action(shortcutsShowCommand);shortcuts.command("install").description("Install shortcuts to config files (~/.tmux.conf, shell rc)").action(shortcutsInstallCommand);shortcuts.command("uninstall").description("Remove shortcuts from config files").action(shortcutsUninstallCommand);registerServeCommands(program2);registerAppCommand(program2);registerInitCommands(program2);registerTeamNamespace(program2);registerDirNamespace(program2);registerAgentCommands(program2);registerObserveCommands(program2);registerOmniNamespace(program2);registerSendInboxCommands(program2);registerStateCommands(program2);registerDispatchCommands(program2);registerDispatchGroupCommands(program2);registerWishCommands(program2);registerHookNamespace(program2);registerDbCommands(program2);registerScheduleCommands(program2);registerDaemonCommands(program2);registerTaskCommands(program2);registerTypeCommands(program2);registerBoardCommands(program2);registerTagCommands(program2);registerReleaseCommands(program2);registerSecCommands(program2);registerProjectCommands(program2);registerPruneCommands(program2);registerNotifyCommands(program2);registerEventsCommands(program2);registerSessionsCommands(program2);registerMetricsCommands(program2);registerExportCommands(program2);registerImportCommands(program2);registerTemplateCommands(program2);registerBrainCommands(program2);registerBriefCommands(program2);registerApprovalCommands(program2);program2.command("done [ref]").description("Close the current turn (inside an agent session) or mark a wish group done (team-lead, <slug>#<group>)").action(async(ref)=>{let{doneAction:doneAction2}=await Promise.resolve().then(() => (init_done(),exports_done));await doneAction2(ref)});program2.command("blocked").description("Close the current turn with outcome=blocked").requiredOption("--reason <message>","Why the turn is blocked").action(async(options)=>{let{blockedAction:blockedAction2}=await Promise.resolve().then(() => (init_blocked(),exports_blocked));await blockedAction2(options)});program2.command("failed").description("Close the current turn with outcome=failed").requiredOption("--reason <message>","Why the turn failed").action(async(options)=>{let{failedAction:failedAction2}=await Promise.resolve().then(() => (init_failed(),exports_failed));await failedAction2(options)});program2.command("pane-trap").description("Internal: write clean_exit_unverified outcome for a dying pane/shell. Invoked by the tmux pane-died hook and the inline shell EXIT trap.").option("--pane-id <id>","tmux pane id (%N) \u2014 resolved to executor via executors.tmux_pane_id").option("--executor-id <id>","explicit executor UUID (preferred when available)").option("--reason <reason>","trap source: pane_died or shell_exit","pane_died").action(async(options)=>{let{paneTrapAction:paneTrapAction2}=await Promise.resolve().then(() => (init_pane_trap2(),exports_pane_trap));await paneTrapAction2(options)});installWorkspaceCheck(program2);var auditTimers=new Map,auditSpans=new Map;program2.hook("preAction",(_thisCommand,actionCommand)=>{let name=actionCommand.name();auditTimers.set(name,Date.now()),Promise.resolve().then(() => (init_db(),exports_db)).then(({isConnected:isConnected2})=>{if(!isConnected2())return;recordAuditEvent("command",name,"command_start",getActor(),{args:actionCommand.args}).catch(()=>{})}).catch(()=>{}),(async()=>{try{let{isWideEmitEnabled:isWideEmitEnabled2}=await Promise.resolve().then(() => exports_observability_flag);if(!isWideEmitEnabled2())return;let{startSpan:startSpan2}=await Promise.resolve().then(() => (init_emit(),exports_emit)),{getAmbient:getAmbient2}=await Promise.resolve().then(() => (init_trace_context(),exports_trace_context)),handle=startSpan2("cli.command",{command:name,args:actionCommand.args??[],cwd:process.cwd()},{severity:"debug",source_subsystem:"cli",ctx:getAmbient2()??void 0,agent:getActor()});auditSpans.set(name,handle)}catch{}})()});program2.hook("postAction",async(_thisCommand,actionCommand)=>{let name=actionCommand.name(),startMs=auditTimers.get(name),durationMs=startMs?Date.now()-startMs:void 0;auditTimers.delete(name);try{let{isConnected:isConnected2}=await Promise.resolve().then(() => (init_db(),exports_db));if(!isConnected2())return;await recordAuditEvent("command",name,"command_success",getActor(),{args:actionCommand.args,duration_ms:durationMs})}catch{}let handle=auditSpans.get(name);auditSpans.delete(name);try{if(handle){let{isWideEmitEnabled:isWideEmitEnabled2}=await Promise.resolve().then(() => exports_observability_flag);if(isWideEmitEnabled2()){let{endSpan:endSpan2}=await Promise.resolve().then(() => (init_emit(),exports_emit));endSpan2(handle,{exit_code:0,duration_ms:durationMs??0},{severity:"debug",source_subsystem:"cli",agent:getActor()})}}}catch{}try{let{flushNow:flushNow2}=await Promise.resolve().then(() => (init_emit(),exports_emit));await flushNow2()}catch{}});program2.command("spawn <name>").description("Spawn a new agent by name (resolves from directory or built-ins)").option("--provider <provider>","Provider: claude or codex","claude").option("--team <team>","Team name").option("--model <model>","Model override (e.g., sonnet, opus)").option("--skill <skill>","Skill to load (optional)").option("--layout <layout>","Layout mode: mosaic (default) or vertical").option("--color <color>","Teammate pane border color").option("--plan-mode","Start teammate in plan mode").option("--permission-mode <mode>","Permission mode (e.g., acceptEdits)").option("--extra-args <args...>","Extra CLI args forwarded to provider").option("--cwd <path>","Working directory for the agent (overrides directory entry)").option("--session <session>","Tmux session name to spawn into").option("--role <role>","Override role name for registration (avoids duplicate guard)").option("--new-window","Create a new tmux window instead of splitting").option("--window <target>","Tmux window to split into (e.g., genie:3)").option("--no-auto-resume","Disable auto-resume on pane death").option("--no-auto-sync","Disable auto-registration from workspace agents directory").option("--stream","Stream SDK messages to stdout in real-time (claude-sdk provider)").option("--stream-format <format>","Streaming output format: text, json, ndjson (default: text)","text").option("--sdk-max-turns <n>","SDK: max conversation turns",parseNumericFlag2("--sdk-max-turns")).option("--sdk-max-budget <usd>","SDK: max budget in USD",parseNumericFlag2("--sdk-max-budget")).option("--sdk-stream","SDK: enable streaming output (shortcut for --stream)").option("--sdk-effort <level>","SDK: reasoning effort level (low, medium, high, max)").option("--sdk-resume <session-id>","SDK: resume a previous session by ID").option("--prompt <text>","Initial prompt to send as the first user message").addHelpText("after",`
4847
4847
  Examples:
4848
4848
  genie spawn engineer # Spawn built-in engineer role
4849
4849
  genie spawn researcher --model sonnet # Spawn with model override
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/genie",
3
- "version": "4.260503.8",
3
+ "version": "4.260503.9",
4
4
  "description": "Collaborative terminal toolkit for human + AI workflows. NOTE: the npm distribution is being soft-deprecated — the canonical install is `curl -fsSL https://get.automagik.dev/genie | bash` (cosign + SLSA verified). See https://automagik.dev/genie/security/distribution-sovereignty",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genie",
3
- "version": "4.260503.8",
3
+ "version": "4.260503.9",
4
4
  "description": "Human-AI partnership for Claude Code. Share a terminal, orchestrate workers, evolve together. Brainstorm ideas, turn them into wishes, execute with /work, validate with /review, and ship as one team.",
5
5
  "author": {
6
6
  "name": "Namastex Labs"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genie-plugin",
3
- "version": "4.260503.8",
3
+ "version": "4.260503.9",
4
4
  "private": true,
5
5
  "description": "Runtime dependencies for genie bundled CLIs",
6
6
  "type": "module",