@automagik/genie 4.260429.13 → 4.260429.15

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
@@ -139,7 +139,7 @@ Your role adapts based on workspace maturity:
139
139
  SELECT name FROM _genie_migrations ORDER BY name
140
140
  `,appliedSet=new Set(applied.map((r)=>r.name)),pending=files.filter((f)=>!appliedSet.has(f.name)),results=[];for(let migration of pending)await sql.begin(async(tx)=>{await tx.unsafe(migration.sql),await tx.unsafe("INSERT INTO _genie_migrations (name) VALUES ($1)",[migration.name])}),results.push({name:migration.name,applied_at:new Date().toISOString()});return results}async function getMigrationStatus(sql){await ensureMigrationsTable(sql);let files=await loadMigrationFiles(),applied=await sql`
141
141
  SELECT name, applied_at FROM _genie_migrations ORDER BY name
142
- `,appliedMap=new Map(applied.map((r)=>[r.name,r.applied_at.toISOString()])),appliedRecords=[],pendingRecords=[];for(let file of files){let appliedAt=appliedMap.get(file.name);if(appliedAt)appliedRecords.push({name:file.name,applied_at:appliedAt});else pendingRecords.push({name:file.name,applied_at:null})}return{applied:appliedRecords,pending:pendingRecords}}var init_db_migrations=()=>{};import{readFile,unlink,writeFile}from"fs/promises";function lockPath(filePath){return`${filePath}.lock`}function isPidAlive(pid){try{return process.kill(pid,0),!0}catch{return!1}}async function acquireLock(path){let lock=lockPath(path),deadline=Date.now()+LOCK_TIMEOUT_MS;while(Date.now()<deadline)try{await writeFile(lock,String(process.pid),{flag:"wx"});return}catch{try{let content=await readFile(lock,"utf-8"),holderPid=Number.parseInt(content.trim(),10);if(!Number.isNaN(holderPid)&&!isPidAlive(holderPid)){try{await unlink(lock)}catch{}continue}}catch{continue}let jitter=Math.floor(Math.random()*LOCK_POLL_MS);await new Promise((r)=>setTimeout(r,LOCK_POLL_MS+jitter))}console.warn(`[lockfile] Force-acquiring stale lock: ${lock}`),await writeFile(lock,String(process.pid))}async function releaseLock(path){try{await unlink(lockPath(path))}catch{}}var LOCK_TIMEOUT_MS=5000,LOCK_POLL_MS=50;var init_lockfile=()=>{};function isBlockingEvent(event){return BLOCKING_EVENTS.has(event)}var DISPATCHED_EVENT_MATCHERS,DISPATCHED_EVENTS,BLOCKING_EVENTS;var init_types2=__esm(()=>{DISPATCHED_EVENT_MATCHERS={PreToolUse:"*",PostToolUse:"SendMessage"},DISPATCHED_EVENTS=Object.keys(DISPATCHED_EVENT_MATCHERS),BLOCKING_EVENTS=new Set(["PreToolUse","UserPromptSubmit","TeammateIdle","TaskCompleted","PermissionRequest"])});var exports_inject={};__export(exports_inject,{isTeamHooked:()=>isTeamHooked,injectTeamHooks:()=>injectTeamHooks,buildDispatchCommand:()=>buildDispatchCommand});import{existsSync as existsSync6}from"fs";import{mkdir,readFile as readFile2,writeFile as writeFile2}from"fs/promises";import{homedir as homedir5}from"os";import{join as join8}from"path";import{fileURLToPath}from"url";function escapeShellArg(arg){return`'${arg.replace(/'/g,"'\\''")}'`}function compiledBinaryCandidates(){let candidates=[];if(process.env.GENIE_HOOK_BIN)candidates.push(process.env.GENIE_HOOK_BIN);let home=process.env.GENIE_HOME??join8(homedir5(),".genie");candidates.push(join8(home,"bin","genie-hook"));try{let repoBin=fileURLToPath(new URL("../../dist/genie-hook",import.meta.url));candidates.push(repoBin)}catch{}return candidates}function buildDispatchCommand(){for(let candidate of compiledBinaryCandidates())if(existsSync6(candidate))return escapeShellArg(candidate);let entrypoint=fileURLToPath(new URL("../genie.ts",import.meta.url));if(!existsSync6(entrypoint))return"genie hook dispatch";let bun=process.execPath||"bun";return`${escapeShellArg(bun)} run ${escapeShellArg(entrypoint)} hook dispatch`}function isGenieDispatchCommand(command){return typeof command==="string"&&/(?:^|\s)hook\s+dispatch(?:\s|$)/.test(command)}function claudeConfigDir(){return process.env.CLAUDE_CONFIG_DIR??join8(homedir5(),".claude")}function teamSettingsPath(teamName){let sanitized=teamName.replace(/[^a-zA-Z0-9]/g,"-").toLowerCase();return join8(claudeConfigDir(),"teams",sanitized,"settings.json")}function buildHooksConfig(){let hooks={},dispatchCommand=buildDispatchCommand();for(let[event,matcher]of Object.entries(DISPATCHED_EVENT_MATCHERS))hooks[event]=[{matcher,hooks:[{type:"command",command:dispatchCommand,timeout:DISPATCH_TIMEOUT}]}];return hooks}async function readSettings(settingsPath){if(!existsSync6(settingsPath))return{};try{return JSON.parse(await readFile2(settingsPath,"utf-8"))}catch{return{}}}function allEventsAlreadyInjected(existingHooks,hooksConfig){return DISPATCHED_EVENTS.every((event)=>{let existing=existingHooks[event],desiredCommand=hooksConfig[event][0].hooks[0].command,desiredMatcher=hooksConfig[event][0].matcher;return existing?.some((m)=>m.matcher===desiredMatcher&&m.hooks?.some((h)=>h.command===desiredCommand))})}function hasNoObsoleteGenieEntries(existingHooks){return Object.keys(existingHooks).every((event)=>{if(DISPATCHED_EVENTS.includes(event))return!0;return!existingHooks[event]?.some((m)=>m.hooks?.some((h)=>isGenieDispatchCommand(h.command)))})}function pruneObsoleteGenieEntries(mergedHooks){for(let event of Object.keys(mergedHooks)){if(DISPATCHED_EVENTS.includes(event))continue;let cleaned=(mergedHooks[event]??[]).map((matcher)=>({...matcher,hooks:matcher.hooks?.filter((hook)=>!isGenieDispatchCommand(hook.command))})).filter((matcher)=>(matcher.hooks?.length??0)>0);if(cleaned.length===0)delete mergedHooks[event];else mergedHooks[event]=cleaned}}function refreshMatcherEntries(entries,genieEntry){return entries.map((matcher)=>{let hasGenieHook=matcher.hooks?.some((h)=>isGenieDispatchCommand(h.command));return{...matcher,matcher:hasGenieHook?genieEntry.matcher:matcher.matcher,hooks:matcher.hooks?.map((hook)=>isGenieDispatchCommand(hook.command)?{...hook,command:genieEntry.hooks[0].command,timeout:DISPATCH_TIMEOUT}:hook)}})}function upsertGenieEntry(mergedHooks,event,genieEntry){let existingEntries=refreshMatcherEntries(mergedHooks[event]??[],genieEntry),alreadyPresent=existingEntries.some((m)=>m.hooks?.some((h)=>isGenieDispatchCommand(h.command)));mergedHooks[event]=alreadyPresent?existingEntries:[...existingEntries,genieEntry]}async function injectIntoFile(settingsPath){let settings=await readSettings(settingsPath),hooksConfig=buildHooksConfig(),existingHooks=settings.hooks;if(existingHooks&&allEventsAlreadyInjected(existingHooks,hooksConfig)&&hasNoObsoleteGenieEntries(existingHooks))return!1;let mergedHooks=existingHooks?{...existingHooks}:{};pruneObsoleteGenieEntries(mergedHooks);for(let event of DISPATCHED_EVENTS)upsertGenieEntry(mergedHooks,event,hooksConfig[event][0]);settings.hooks=mergedHooks;let dir=join8(settingsPath,"..");return await mkdir(dir,{recursive:!0}),await writeFile2(settingsPath,JSON.stringify(settings,null,2)),!0}async function injectTeamHooks(teamName){let path=teamSettingsPath(teamName);return injectIntoFile(path)}async function isTeamHooked(teamName){let path=teamSettingsPath(teamName);if(!existsSync6(path))return!1;try{let content=await readFile2(path,"utf-8"),hooks=JSON.parse(content).hooks;if(!hooks)return!1;return DISPATCHED_EVENTS.every((event)=>{return hooks[event]?.some((m)=>m.hooks?.some((h)=>isGenieDispatchCommand(h.command)))})}catch{return!1}}var DISPATCH_TIMEOUT=15;var init_inject=__esm(()=>{init_types2()});var exports_js_yaml={};__export(exports_js_yaml,{types:()=>types2,safeLoadAll:()=>safeLoadAll,safeLoad:()=>safeLoad,safeDump:()=>safeDump,loadAll:()=>loadAll,load:()=>load,dump:()=>dump,default:()=>jsYaml,YAMLException:()=>YAMLException,Type:()=>Type,Schema:()=>Schema,JSON_SCHEMA:()=>JSON_SCHEMA,FAILSAFE_SCHEMA:()=>FAILSAFE_SCHEMA,DEFAULT_SCHEMA:()=>DEFAULT_SCHEMA,CORE_SCHEMA:()=>CORE_SCHEMA});function isNothing(subject){return typeof subject>"u"||subject===null}function isObject(subject){return typeof subject==="object"&&subject!==null}function toArray(sequence){if(Array.isArray(sequence))return sequence;else if(isNothing(sequence))return[];return[sequence]}function extend(target,source){var index,length,key,sourceKeys;if(source){sourceKeys=Object.keys(source);for(index=0,length=sourceKeys.length;index<length;index+=1)key=sourceKeys[index],target[key]=source[key]}return target}function repeat(string,count){var result2="",cycle;for(cycle=0;cycle<count;cycle+=1)result2+=string;return result2}function isNegativeZero(number){return number===0&&Number.NEGATIVE_INFINITY===1/number}function formatError(exception,compact){var where="",message=exception.reason||"(unknown reason)";if(!exception.mark)return message;if(exception.mark.name)where+='in "'+exception.mark.name+'" ';if(where+="("+(exception.mark.line+1)+":"+(exception.mark.column+1)+")",!compact&&exception.mark.snippet)where+=`
142
+ `,appliedMap=new Map(applied.map((r)=>[r.name,r.applied_at.toISOString()])),appliedRecords=[],pendingRecords=[];for(let file of files){let appliedAt=appliedMap.get(file.name);if(appliedAt)appliedRecords.push({name:file.name,applied_at:appliedAt});else pendingRecords.push({name:file.name,applied_at:null})}return{applied:appliedRecords,pending:pendingRecords}}var init_db_migrations=()=>{};import{readFile,unlink,writeFile}from"fs/promises";function lockPath(filePath){return`${filePath}.lock`}function isPidAlive(pid){try{return process.kill(pid,0),!0}catch{return!1}}async function acquireLock(path){let lock=lockPath(path),deadline=Date.now()+LOCK_TIMEOUT_MS;while(Date.now()<deadline)try{await writeFile(lock,String(process.pid),{flag:"wx"});return}catch{try{let content=await readFile(lock,"utf-8"),holderPid=Number.parseInt(content.trim(),10);if(!Number.isNaN(holderPid)&&!isPidAlive(holderPid)){try{await unlink(lock)}catch{}continue}}catch{continue}let jitter=Math.floor(Math.random()*LOCK_POLL_MS);await new Promise((r)=>setTimeout(r,LOCK_POLL_MS+jitter))}console.warn(`[lockfile] Force-acquiring stale lock: ${lock}`),await writeFile(lock,String(process.pid))}async function releaseLock(path){try{await unlink(lockPath(path))}catch{}}var LOCK_TIMEOUT_MS=5000,LOCK_POLL_MS=50;var init_lockfile=()=>{};var exports_types={};__export(exports_types,{isBlockingEvent:()=>isBlockingEvent,DISPATCHED_EVENT_MATCHERS:()=>DISPATCHED_EVENT_MATCHERS,DISPATCHED_EVENTS:()=>DISPATCHED_EVENTS,CODEX_DISPATCHED_EVENT_MATCHERS:()=>CODEX_DISPATCHED_EVENT_MATCHERS});function isBlockingEvent(event){return BLOCKING_EVENTS.has(event)}var DISPATCHED_EVENT_MATCHERS,CODEX_DISPATCHED_EVENT_MATCHERS,DISPATCHED_EVENTS,BLOCKING_EVENTS;var init_types2=__esm(()=>{DISPATCHED_EVENT_MATCHERS={PreToolUse:"*",PostToolUse:"SendMessage"},CODEX_DISPATCHED_EVENT_MATCHERS={PreToolUse:"*",PostToolUse:"SendMessage",UserPromptSubmit:"*",Stop:"*"},DISPATCHED_EVENTS=Object.keys(DISPATCHED_EVENT_MATCHERS),BLOCKING_EVENTS=new Set(["PreToolUse","UserPromptSubmit","TeammateIdle","TaskCompleted","PermissionRequest"])});var exports_inject={};__export(exports_inject,{isTeamHooked:()=>isTeamHooked,injectTeamHooks:()=>injectTeamHooks,buildDispatchCommand:()=>buildDispatchCommand});import{existsSync as existsSync6}from"fs";import{mkdir,readFile as readFile2,writeFile as writeFile2}from"fs/promises";import{homedir as homedir5}from"os";import{join as join8}from"path";import{fileURLToPath}from"url";function escapeShellArg(arg){return`'${arg.replace(/'/g,"'\\''")}'`}function compiledBinaryCandidates(){let candidates=[];if(process.env.GENIE_HOOK_BIN)candidates.push(process.env.GENIE_HOOK_BIN);let home=process.env.GENIE_HOME??join8(homedir5(),".genie");candidates.push(join8(home,"bin","genie-hook"));try{let repoBin=fileURLToPath(new URL("../../dist/genie-hook",import.meta.url));candidates.push(repoBin)}catch{}return candidates}function buildDispatchCommand(){for(let candidate of compiledBinaryCandidates())if(existsSync6(candidate))return escapeShellArg(candidate);let entrypoint=fileURLToPath(new URL("../genie.ts",import.meta.url));if(!existsSync6(entrypoint))return"genie hook dispatch";let bun=process.execPath||"bun";return`${escapeShellArg(bun)} run ${escapeShellArg(entrypoint)} hook dispatch`}function isGenieDispatchCommand(command){return typeof command==="string"&&/(?:^|\s)hook\s+dispatch(?:\s|$)/.test(command)}function claudeConfigDir(){return process.env.CLAUDE_CONFIG_DIR??join8(homedir5(),".claude")}function teamSettingsPath(teamName){let sanitized=teamName.replace(/[^a-zA-Z0-9]/g,"-").toLowerCase();return join8(claudeConfigDir(),"teams",sanitized,"settings.json")}function buildHooksConfig(){let hooks={},dispatchCommand=buildDispatchCommand();for(let[event,matcher]of Object.entries(DISPATCHED_EVENT_MATCHERS))hooks[event]=[{matcher,hooks:[{type:"command",command:dispatchCommand,timeout:DISPATCH_TIMEOUT}]}];return hooks}async function readSettings(settingsPath){if(!existsSync6(settingsPath))return{};try{return JSON.parse(await readFile2(settingsPath,"utf-8"))}catch{return{}}}function allEventsAlreadyInjected(existingHooks,hooksConfig){return DISPATCHED_EVENTS.every((event)=>{let existing=existingHooks[event],desiredCommand=hooksConfig[event][0].hooks[0].command,desiredMatcher=hooksConfig[event][0].matcher;return existing?.some((m)=>m.matcher===desiredMatcher&&m.hooks?.some((h)=>h.command===desiredCommand))})}function hasNoObsoleteGenieEntries(existingHooks){return Object.keys(existingHooks).every((event)=>{if(DISPATCHED_EVENTS.includes(event))return!0;return!existingHooks[event]?.some((m)=>m.hooks?.some((h)=>isGenieDispatchCommand(h.command)))})}function pruneObsoleteGenieEntries(mergedHooks){for(let event of Object.keys(mergedHooks)){if(DISPATCHED_EVENTS.includes(event))continue;let cleaned=(mergedHooks[event]??[]).map((matcher)=>({...matcher,hooks:matcher.hooks?.filter((hook)=>!isGenieDispatchCommand(hook.command))})).filter((matcher)=>(matcher.hooks?.length??0)>0);if(cleaned.length===0)delete mergedHooks[event];else mergedHooks[event]=cleaned}}function refreshMatcherEntries(entries,genieEntry){return entries.map((matcher)=>{let hasGenieHook=matcher.hooks?.some((h)=>isGenieDispatchCommand(h.command));return{...matcher,matcher:hasGenieHook?genieEntry.matcher:matcher.matcher,hooks:matcher.hooks?.map((hook)=>isGenieDispatchCommand(hook.command)?{...hook,command:genieEntry.hooks[0].command,timeout:DISPATCH_TIMEOUT}:hook)}})}function upsertGenieEntry(mergedHooks,event,genieEntry){let existingEntries=refreshMatcherEntries(mergedHooks[event]??[],genieEntry),alreadyPresent=existingEntries.some((m)=>m.hooks?.some((h)=>isGenieDispatchCommand(h.command)));mergedHooks[event]=alreadyPresent?existingEntries:[...existingEntries,genieEntry]}async function injectIntoFile(settingsPath){let settings=await readSettings(settingsPath),hooksConfig=buildHooksConfig(),existingHooks=settings.hooks;if(existingHooks&&allEventsAlreadyInjected(existingHooks,hooksConfig)&&hasNoObsoleteGenieEntries(existingHooks))return!1;let mergedHooks=existingHooks?{...existingHooks}:{};pruneObsoleteGenieEntries(mergedHooks);for(let event of DISPATCHED_EVENTS)upsertGenieEntry(mergedHooks,event,hooksConfig[event][0]);settings.hooks=mergedHooks;let dir=join8(settingsPath,"..");return await mkdir(dir,{recursive:!0}),await writeFile2(settingsPath,JSON.stringify(settings,null,2)),!0}async function injectTeamHooks(teamName){let path=teamSettingsPath(teamName);return injectIntoFile(path)}async function isTeamHooked(teamName){let path=teamSettingsPath(teamName);if(!existsSync6(path))return!1;try{let content=await readFile2(path,"utf-8"),hooks=JSON.parse(content).hooks;if(!hooks)return!1;return DISPATCHED_EVENTS.every((event)=>{return hooks[event]?.some((m)=>m.hooks?.some((h)=>isGenieDispatchCommand(h.command)))})}catch{return!1}}var DISPATCH_TIMEOUT=15;var init_inject=__esm(()=>{init_types2()});var exports_js_yaml={};__export(exports_js_yaml,{types:()=>types2,safeLoadAll:()=>safeLoadAll,safeLoad:()=>safeLoad,safeDump:()=>safeDump,loadAll:()=>loadAll,load:()=>load,dump:()=>dump,default:()=>jsYaml,YAMLException:()=>YAMLException,Type:()=>Type,Schema:()=>Schema,JSON_SCHEMA:()=>JSON_SCHEMA,FAILSAFE_SCHEMA:()=>FAILSAFE_SCHEMA,DEFAULT_SCHEMA:()=>DEFAULT_SCHEMA,CORE_SCHEMA:()=>CORE_SCHEMA});function isNothing(subject){return typeof subject>"u"||subject===null}function isObject(subject){return typeof subject==="object"&&subject!==null}function toArray(sequence){if(Array.isArray(sequence))return sequence;else if(isNothing(sequence))return[];return[sequence]}function extend(target,source){var index,length,key,sourceKeys;if(source){sourceKeys=Object.keys(source);for(index=0,length=sourceKeys.length;index<length;index+=1)key=sourceKeys[index],target[key]=source[key]}return target}function repeat(string,count){var result2="",cycle;for(cycle=0;cycle<count;cycle+=1)result2+=string;return result2}function isNegativeZero(number){return number===0&&Number.NEGATIVE_INFINITY===1/number}function formatError(exception,compact){var where="",message=exception.reason||"(unknown reason)";if(!exception.mark)return message;if(exception.mark.name)where+='in "'+exception.mark.name+'" ';if(where+="("+(exception.mark.line+1)+":"+(exception.mark.column+1)+")",!compact&&exception.mark.snippet)where+=`
143
143
 
144
144
  `+exception.mark.snippet;return message+" "+where}function YAMLException$1(reason,mark){if(Error.call(this),this.name="YAMLException",this.reason=reason,this.mark=mark,this.message=formatError(this,!1),Error.captureStackTrace)Error.captureStackTrace(this,this.constructor);else this.stack=Error().stack||""}function getLine(buffer,lineStart,lineEnd,position,maxLineLength){var head="",tail="",maxHalfLength=Math.floor(maxLineLength/2)-1;if(position-lineStart>maxHalfLength)head=" ... ",lineStart=position-maxHalfLength+head.length;if(lineEnd-position>maxHalfLength)tail=" ...",lineEnd=position+maxHalfLength-tail.length;return{str:head+buffer.slice(lineStart,lineEnd).replace(/\t/g,"\u2192")+tail,pos:position-lineStart+head.length}}function padStart(string,max){return common.repeat(" ",max-string.length)+string}function makeSnippet(mark,options){if(options=Object.create(options||null),!mark.buffer)return null;if(!options.maxLength)options.maxLength=79;if(typeof options.indent!=="number")options.indent=1;if(typeof options.linesBefore!=="number")options.linesBefore=3;if(typeof options.linesAfter!=="number")options.linesAfter=2;var re=/\r?\n|\r|\0/g,lineStarts=[0],lineEnds=[],match,foundLineNo=-1;while(match=re.exec(mark.buffer))if(lineEnds.push(match.index),lineStarts.push(match.index+match[0].length),mark.position<=match.index&&foundLineNo<0)foundLineNo=lineStarts.length-2;if(foundLineNo<0)foundLineNo=lineStarts.length-1;var result2="",i,line,lineNoLength=Math.min(mark.line+options.linesAfter,lineEnds.length).toString().length,maxLineLength=options.maxLength-(options.indent+lineNoLength+3);for(i=1;i<=options.linesBefore;i++){if(foundLineNo-i<0)break;line=getLine(mark.buffer,lineStarts[foundLineNo-i],lineEnds[foundLineNo-i],mark.position-(lineStarts[foundLineNo]-lineStarts[foundLineNo-i]),maxLineLength),result2=common.repeat(" ",options.indent)+padStart((mark.line-i+1).toString(),lineNoLength)+" | "+line.str+`
145
145
  `+result2}line=getLine(mark.buffer,lineStarts[foundLineNo],lineEnds[foundLineNo],mark.position,maxLineLength),result2+=common.repeat(" ",options.indent)+padStart((mark.line+1).toString(),lineNoLength)+" | "+line.str+`
@@ -177,7 +177,7 @@ ${prompt}`}function extractPromptPreamble(input){let match=input.match(PREAMBLE_
177
177
 
178
178
  ${content}`;if(params.extraArgs){let fileIdx=params.extraArgs.indexOf("--append-system-prompt-file");if(fileIdx!==-1&&params.extraArgs[fileIdx+1])content=`${content}
179
179
 
180
- ${readFileSync6(params.extraArgs[fileIdx+1],"utf-8")}`,params.extraArgs.splice(fileIdx,2)}writeFileSync6(promptFile,content);let flag=params.promptMode==="system"?"--system-prompt-file":"--append-system-prompt-file";parts.push(flag,escapeShellArg2(promptFile))}else if(params.systemPromptFile){let flag=params.promptMode==="system"?"--system-prompt-file":"--append-system-prompt-file";parts.push(flag,escapeShellArg2(params.systemPromptFile))}}function appendOtelEnv(env,params){if(!params.otelPort||process.env.OTEL_EXPORTER_OTLP_ENDPOINT)return;if(env.CLAUDE_CODE_ENABLE_TELEMETRY="1",env.OTEL_LOGS_EXPORTER="otlp",env.OTEL_METRICS_EXPORTER="otlp",env.OTEL_EXPORTER_OTLP_PROTOCOL="http/json",env.OTEL_EXPORTER_OTLP_ENDPOINT=`http://127.0.0.1:${params.otelPort}`,env.OTEL_LOG_TOOL_DETAILS="1",params.otelLogPrompts!==!1)env.OTEL_LOG_USER_PROMPTS="1";let resourceParts=[];if(params.role)resourceParts.push(`agent.name=${params.role}`);if(params.team)resourceParts.push(`team.name=${params.team}`);if(params.otelWishSlug)resourceParts.push(`wish.slug=${params.otelWishSlug}`);if(params.role)resourceParts.push(`agent.role=${params.role}`);if(resourceParts.length>0)env.OTEL_RESOURCE_ATTRIBUTES=resourceParts.join(",")}function appendTraceContext(parts,env,params){let ctx=getAmbient();if(params.initialPrompt){let prompt=ctx?injectPromptPreamble(params.initialPrompt,ctx):params.initialPrompt;parts.push(escapeShellArg2(prompt))}if(ctx)env[TRACE_ENV_VAR]=mintToken(ctx),env[TRACE_ID_ENV_VAR]=ctx.trace_id}function buildClaudeGenieEnv(params){let env={};if(env.GENIE_WORKER="1",params.role)env.GENIE_AGENT_NAME=params.role;if(params.team)env.GENIE_TEAM=params.team;if(params.executorId)env.GENIE_EXECUTOR_ID=params.executorId;if(params.agentId)env.GENIE_AGENT_ID=params.agentId;return env}function appendSessionFlags(parts,params){if(params.resume)parts.push("--resume",escapeShellArg2(params.resume));else if(params.sessionId)parts.push("--session-id",escapeShellArg2(params.sessionId));let claudeAgentFlag=params.agentTemplate??params.role;if(claudeAgentFlag)parts.push("--agent",escapeShellArg2(claudeAgentFlag));if(params.model)parts.push("--model",escapeShellArg2(params.model));if(params.name)parts.push("--name",escapeShellArg2(params.name))}function buildSettingsObject(params){let settingsObj={};if(!params.skipHooks){let hookEntry={type:"command",command:buildDispatchCommand(),timeout:15};settingsObj.hooks={PreToolUse:[{matcher:"*",hooks:[hookEntry]}],PostToolUse:[{matcher:"*",hooks:[hookEntry]}],UserPromptSubmit:[{hooks:[hookEntry]}],Stop:[{hooks:[hookEntry]}]}}if(params.permissions){let perms={};if(params.permissions.allow?.length)perms.allow=params.permissions.allow;if(params.permissions.deny?.length)perms.deny=params.permissions.deny;if(Object.keys(perms).length>0)settingsObj.permissions=perms}return settingsObj}function warnIfAllowRulesAreBypassed(params){if(!params.permissions?.allow?.length)return;if(params.nativeTeam?.permissionMode!=="bypassPermissions")return;let agentName=params.nativeTeam.agentName??params.role??params.name??"unknown";process.stderr.write(`Warning: agent ${agentName} declares permissions.allow but permissionMode is bypassPermissions \u2014 allow rules are advisory under bypass (deny still enforced).
180
+ ${readFileSync6(params.extraArgs[fileIdx+1],"utf-8")}`,params.extraArgs.splice(fileIdx,2)}writeFileSync6(promptFile,content);let flag=params.promptMode==="system"?"--system-prompt-file":"--append-system-prompt-file";parts.push(flag,escapeShellArg2(promptFile))}else if(params.systemPromptFile){let flag=params.promptMode==="system"?"--system-prompt-file":"--append-system-prompt-file";parts.push(flag,escapeShellArg2(params.systemPromptFile))}}function appendOtelEnv(env,params){if(!params.otelPort||process.env.OTEL_EXPORTER_OTLP_ENDPOINT)return;if(env.CLAUDE_CODE_ENABLE_TELEMETRY="1",env.OTEL_LOGS_EXPORTER="otlp",env.OTEL_METRICS_EXPORTER="otlp",env.OTEL_EXPORTER_OTLP_PROTOCOL="http/json",env.OTEL_EXPORTER_OTLP_ENDPOINT=`http://127.0.0.1:${params.otelPort}`,env.OTEL_LOG_TOOL_DETAILS="1",params.otelLogPrompts!==!1)env.OTEL_LOG_USER_PROMPTS="1";let resourceParts=[];if(params.role)resourceParts.push(`agent.name=${params.role}`);if(params.team)resourceParts.push(`team.name=${params.team}`);if(params.otelWishSlug)resourceParts.push(`wish.slug=${params.otelWishSlug}`);if(params.role)resourceParts.push(`agent.role=${params.role}`);if(resourceParts.length>0)env.OTEL_RESOURCE_ATTRIBUTES=resourceParts.join(",")}function appendTraceContext(parts,env,params){let ctx=getAmbient();if(params.initialPrompt){let prompt=ctx?injectPromptPreamble(params.initialPrompt,ctx):params.initialPrompt;parts.push(escapeShellArg2(prompt))}if(ctx)env[TRACE_ENV_VAR]=mintToken(ctx),env[TRACE_ID_ENV_VAR]=ctx.trace_id}function buildClaudeGenieEnv(params){let env={};if(env.GENIE_WORKER="1",params.role)env.GENIE_AGENT_NAME=params.role;if(params.team)env.GENIE_TEAM=params.team;if(params.executorId)env.GENIE_EXECUTOR_ID=params.executorId;if(params.agentId)env.GENIE_AGENT_ID=params.agentId;return env}function appendSessionFlags(parts,params){if(params.resume)parts.push("--resume",escapeShellArg2(params.resume));else if(params.sessionId)parts.push("--session-id",escapeShellArg2(params.sessionId));let claudeAgentFlag=params.agentTemplate??params.role;if(claudeAgentFlag)parts.push("--agent",escapeShellArg2(claudeAgentFlag));if(params.model)parts.push("--model",escapeShellArg2(params.model));if(params.name)parts.push("--name",escapeShellArg2(params.name))}function buildSettingsObject(params){let settingsObj={};if(!params.skipHooks){let hookEntry={type:"command",command:buildDispatchCommand(),timeout:15},{DISPATCHED_EVENT_MATCHERS:DISPATCHED_EVENT_MATCHERS2}=(init_types2(),__toCommonJS(exports_types)),hooks={};for(let[event,matcher]of Object.entries(DISPATCHED_EVENT_MATCHERS2))hooks[event]=[{matcher,hooks:[hookEntry]}];settingsObj.hooks=hooks}if(params.permissions){let perms={};if(params.permissions.allow?.length)perms.allow=params.permissions.allow;if(params.permissions.deny?.length)perms.deny=params.permissions.deny;if(Object.keys(perms).length>0)settingsObj.permissions=perms}return settingsObj}function warnIfAllowRulesAreBypassed(params){if(!params.permissions?.allow?.length)return;if(params.nativeTeam?.permissionMode!=="bypassPermissions")return;let agentName=params.nativeTeam.agentName??params.role??params.name??"unknown";process.stderr.write(`Warning: agent ${agentName} declares permissions.allow but permissionMode is bypassPermissions \u2014 allow rules are advisory under bypass (deny still enforced).
181
181
  `)}function appendDisallowedAndExtraArgs(parts,params){if(params.disallowedTools?.length)for(let tool of params.disallowedTools)parts.push("--disallowedTools",escapeShellArg2(tool));if(params.extraArgs)for(let arg of params.extraArgs)parts.push(escapeShellArg2(arg))}function assertClaudeBuiltinHasIdentity(params){let templateName=params.agentTemplate??params.role;if(!templateName)return;if(params.resume)return;if(!resolveBuiltinAgentPath(templateName))return;if(params.systemPromptFile||params.systemPrompt)return;throw Error(`Refusing to launch built-in agent "${templateName}" without AGENTS.md identity. Resolve systemPromptFile or systemPrompt before building the Claude command.`)}function buildClaudeCommand(params){assertClaudeBuiltinHasIdentity(params),preflightCheck("claude");let parts=[resolveShellBinary("claude")??"claude","--permission-mode",escapeShellArg2("auto")],env=buildClaudeGenieEnv(params);if(appendOtelEnv(env,params),params.nativeTeam?.enabled)appendNativeTeamFlags(parts,env,params.nativeTeam,params);appendSessionFlags(parts,params),appendSystemPromptFlags(parts,params),warnIfAllowRulesAreBypassed(params);let settingsObj=buildSettingsObject(params);if(Object.keys(settingsObj).length>0)parts.push("--settings",escapeShellArg2(JSON.stringify(settingsObj)));return appendDisallowedAndExtraArgs(parts,params),appendTraceContext(parts,env,params),{command:parts.join(" "),provider:"claude",env:Object.keys(env).length>0?env:void 0,meta:{role:params.role,skill:params.skill}}}function buildCodexAutoPrompt(params){let promptParts=[`Genie worker. Team: ${params.team}.`];if(params.role)promptParts.push(`Role: ${params.role}.`);if(params.skill)promptParts.push(`Execute the ${params.skill} skill instructions.`);return promptParts.join(" ")}function sanitizeCodexPromptFileStem(stem){return stem.replace(/[^a-zA-Z0-9._-]/g,"-")||Date.now().toString(36)}function splitCodexExtraArgs(extraArgs){let forwarded=[],promptFiles=[],args=extraArgs??[];for(let i2=0;i2<args.length;i2++){let arg=args[i2],equalsFlag=[...CODEX_PROMPT_FILE_FLAGS].find((flag)=>arg.startsWith(`${flag}=`));if(equalsFlag){let path=arg.slice(equalsFlag.length+1);if(!path)throw Error(`Missing path for ${equalsFlag}`);promptFiles.push(path);continue}if(CODEX_PROMPT_FILE_FLAGS.has(arg)){let path=args[i2+1];if(!path)throw Error(`Missing path after ${arg}`);promptFiles.push(path),i2++;continue}forwarded.push(arg)}return{forwarded,promptFiles}}function buildCodexMergedPrompt(params,extraPromptFiles){let{readFileSync:readFileSync6}=__require("fs"),sections=[];if(params.systemPromptFile!==void 0)sections.push(readFileSync6(params.systemPromptFile,"utf-8"));if(params.systemPrompt!==void 0)sections.push(params.systemPrompt);for(let promptFile of extraPromptFiles)sections.push(readFileSync6(promptFile,"utf-8"));if(params.initialPrompt!==void 0)sections.push(params.initialPrompt);return sections.length>0?sections.join(`
182
182
 
183
183
  `):null}function writeCodexPromptFile(params,content){let{mkdirSync:mkdirSync5,writeFileSync:writeFileSync6}=__require("fs"),{join:join10}=__require("path");mkdirSync5(CODEX_PROMPT_DIR,{recursive:!0});let stem=sanitizeCodexPromptFileStem(params.executorId??Date.now().toString(36)),promptFile=join10(CODEX_PROMPT_DIR,`${stem}.txt`);return writeFileSync6(promptFile,content,"utf-8"),promptFile}function buildCodexCommand(params){preflightCheck("codex");let parts=["codex"],env={};if(params.executorId)env.GENIE_EXECUTOR_ID=params.executorId;if(params.agentId)env.GENIE_AGENT_ID=params.agentId;if(params.role)env.GENIE_AGENT_NAME=params.role;else if(params.name)env.GENIE_AGENT_NAME=params.name;if(params.team)env.GENIE_TEAM=params.team;let{forwarded:extraArgs,promptFiles:extraPromptFiles}=splitCodexExtraArgs(params.extraArgs);parts.push("--yolo"),parts.push("--no-alt-screen");let codexModel=sanitizeModelForProvider("codex",params.model);if(codexModel)parts.push("--model",escapeShellArg2(codexModel));for(let arg of extraArgs)parts.push(escapeShellArg2(arg));let mergedPrompt=buildCodexMergedPrompt(params,extraPromptFiles);if(mergedPrompt!==null){let promptFile=writeCodexPromptFile(params,mergedPrompt);parts.push(`"$(cat ${escapeShellArg2(promptFile)})"`)}else parts.push(escapeShellArg2(buildCodexAutoPrompt(params)));return{command:parts.join(" "),provider:"codex",env:Object.keys(env).length>0?env:void 0,meta:{role:params.role,skill:params.skill}}}function buildLaunchCommand(params){let validated=validateSpawnParams(params);switch(validated.provider){case"claude":return buildClaudeCommand(validated);case"codex":return buildCodexCommand(validated);case"claude-sdk":return{command:"claude-sdk-in-process",provider:"claude-sdk",meta:{role:validated.role,skill:validated.skill}};default:throw Error(`Unknown provider "${validated.provider}". Valid providers: claude, codex, claude-sdk`)}}var CLAUDE_TEAM_COLORS,spawnParamsSchema,CODEX_PROMPT_DIR="/tmp/genie-codex-prompts",CODEX_PROMPT_FILE_FLAGS;var init_provider_adapters=__esm(()=>{init_zod();init_inject();init_builtin_agents();init_provider_models();init_trace_context();CLAUDE_TEAM_COLORS=["red","blue","green","yellow","purple","orange","pink","cyan"],spawnParamsSchema=exports_external.object({provider:exports_external.enum(["claude","codex","claude-sdk","app-pty"]),team:exports_external.string().min(1,"Team name is required"),role:exports_external.string().optional(),agentTemplate:exports_external.string().optional(),skill:exports_external.string().optional(),agentId:exports_external.string().optional(),executorId:exports_external.string().uuid().optional(),extraArgs:exports_external.array(exports_external.string()).optional(),nativeTeam:exports_external.object({enabled:exports_external.boolean(),parentSessionId:exports_external.string().optional(),color:exports_external.string().optional(),agentType:exports_external.string().optional(),planModeRequired:exports_external.boolean().optional(),permissionMode:exports_external.string().optional(),agentName:exports_external.string().optional()}).optional(),sessionId:exports_external.string().uuid().optional(),resume:exports_external.string().optional(),systemPromptFile:exports_external.string().optional(),systemPrompt:exports_external.string().optional(),promptMode:exports_external.enum(["system","append"]).optional(),model:exports_external.string().optional(),initialPrompt:exports_external.string().optional(),name:exports_external.string().optional(),permissions:exports_external.object({allow:exports_external.array(exports_external.string()).optional(),deny:exports_external.array(exports_external.string()).optional()}).optional(),disallowedTools:exports_external.array(exports_external.string()).optional(),otelPort:exports_external.number().optional(),otelLogPrompts:exports_external.boolean().optional(),otelWishSlug:exports_external.string().optional(),newWindow:exports_external.boolean().optional(),windowTarget:exports_external.string().optional()});CODEX_PROMPT_FILE_FLAGS=new Set(["--append-system-prompt-file","--system-prompt-file"])});var exports_audit={};__export(exports_audit,{recordAuditEvent:()=>recordAuditEvent,queryToolUsageDetail:()=>queryToolUsageDetail,queryToolUsage:()=>queryToolUsage,queryTimeline:()=>queryTimeline,querySummary:()=>querySummary,queryErrorPatterns:()=>queryErrorPatterns,queryCostBreakdown:()=>queryCostBreakdown,queryAuditEvents:()=>queryAuditEvents,getActor:()=>getActor,generateTraceId:()=>generateTraceId,followAuditEvents:()=>followAuditEvents});async function recordAuditEvent(entityType,entityId,eventType,actor,details){try{if(!await isAvailable())return;let sql=await getConnection();await sql`
@@ -1032,7 +1032,7 @@ Next steps:`),console.log(" 1. Reload tmux: tmux source ~/.tmux.conf"),console.
1032
1032
  `),await promptUninstallFrom(join27(home,".tmux.conf"),"generated by genie-cli","tmux.conf");for(let shellRc of[join27(home,".zshrc"),join27(home,".bashrc")])await promptUninstallFrom(shellRc,"generated by genie-cli",shellRc);let termuxDir=join27(home,".termux"),isTermux=existsSync22(termuxDir)||process.env.TERMUX_VERSION;if(isTermux){let termuxProps=join27(termuxDir,"termux.properties");if(await promptUninstallFrom(termuxProps,"generated by genie-cli","termux.properties"),!contentExists(termuxProps,"generated by genie-cli"))console.log(" Run: termux-reload-settings")}if(console.log(`
1033
1033
  \u2705 Uninstallation complete!`),console.log(`
1034
1034
  Next steps:`),console.log(" 1. Reload tmux: tmux source ~/.tmux.conf"),console.log(" 2. Restart your shell or run: source ~/.bashrc"),isTermux)console.log(" 3. Reload Termux: termux-reload-settings")}var GENIE_CONTENT_MARKERS;var init_shortcuts=__esm(()=>{GENIE_CONTENT_MARKERS=["genie","Ctrl+","split-window","new-window","stty -ixon","Warp-like","bind-key -n","extra-keys","F1=","bind -x"]});var exports_setup={};__export(exports_setup,{setupCommand:()=>setupCommand});import{homedir as homedir23}from"os";import{join as join28}from"path";function printHeader(){console.log(),console.log(`\x1B[1m\x1B[36m${"=".repeat(64)}\x1B[0m`),console.log("\x1B[1m\x1B[36m Genie Setup Wizard\x1B[0m"),console.log(`\x1B[1m\x1B[36m${"=".repeat(64)}\x1B[0m`),console.log()}function printSection(title,description){if(console.log(),console.log(`\x1B[1m${title}\x1B[0m`),description)console.log(`\x1B[2m${description}\x1B[0m`);console.log()}async function configureSession(config,quick){if(printSection("2. Session Configuration","Configure tmux session settings"),quick)return console.log(` Using defaults: session="${config.session.name}", window="${config.session.defaultWindow}"`),config;let sessionName=await esm_default5({message:"Session name:",default:config.session.name}),defaultWindow=await esm_default5({message:"Default window name:",default:config.session.defaultWindow}),autoCreate=await esm_default4({message:"Auto-create session on connect?",default:config.session.autoCreate});return config.session={name:sessionName,defaultWindow,autoCreate},config}async function configureTerminal(config,quick){if(printSection("3. Terminal Defaults","Configure default values for term commands"),quick)return console.log(` Using defaults: timeout=${config.terminal.execTimeout}ms, lines=${config.terminal.readLines}`),config;let timeoutStr=await esm_default5({message:"Exec timeout (milliseconds):",default:String(config.terminal.execTimeout),validate:(v)=>{let n=Number.parseInt(v,10);return!Number.isNaN(n)&&n>0?!0:"Must be a positive number"}}),linesStr=await esm_default5({message:"Read lines (default for genie agent read):",default:String(config.terminal.readLines),validate:(v)=>{let n=Number.parseInt(v,10);return!Number.isNaN(n)&&n>0?!0:"Must be a positive number"}}),worktreeBase=await esm_default5({message:"Worktree base directory (leave empty for ~/.genie/worktrees/<project>/):",default:config.terminal.worktreeBase??""});return config.terminal={execTimeout:Number.parseInt(timeoutStr,10),readLines:Number.parseInt(linesStr,10),...worktreeBase?{worktreeBase}:{}},config}async function configureShortcuts(config,quick){printSection("4. Keyboard Shortcuts","Warp-like tmux shortcuts for quick navigation");let home=homedir23(),tmuxConf=join28(home,".tmux.conf");if(isShortcutsInstalled(tmuxConf))return console.log(" \x1B[32m\u2713\x1B[0m Tmux shortcuts already installed"),config.shortcuts.tmuxInstalled=!0,config;if(console.log(" Available shortcuts:"),console.log(" \x1B[36mCtrl+T\x1B[0m \u2192 New tab (window)"),console.log(" \x1B[36mCtrl+S\x1B[0m \u2192 Vertical split"),console.log(" \x1B[36mCtrl+H\x1B[0m \u2192 Horizontal split"),console.log(),quick)return console.log(" Skipped in quick mode. Run \x1B[36mgenie setup --shortcuts\x1B[0m to install."),config;if(await esm_default4({message:"Install tmux keyboard shortcuts?",default:!1}))console.log(),await installShortcuts(),config.shortcuts.tmuxInstalled=!0,await updateShortcutsConfig({tmuxInstalled:!0});else console.log(" Skipped. Run \x1B[36mgenie shortcuts install\x1B[0m later.");return config}function printCodexResult(result2){if(result2==="changed")console.log(" \x1B[32m\u2713\x1B[0m Codex config updated");else if(result2==="unchanged")console.log(" \x1B[32m\u2713\x1B[0m Codex config already up to date");else console.log(" \x1B[31m\u2717\x1B[0m Failed to update codex config")}async function configureCodex(config,quick){printSection("5. Codex Integration","Configure OpenAI Codex for genie agents");let codexCheck=await checkCommand("codex");if(!codexCheck.exists)return console.log(" \x1B[33m!\x1B[0m Codex CLI not found. Skipping codex integration."),config;if(console.log(` \x1B[32m\u2713\x1B[0m Codex CLI found (${codexCheck.version??"unknown version"})`),isCodexConfigured())return console.log(" \x1B[32m\u2713\x1B[0m Codex config already configured"),config.codex={configured:!0},config;if(console.log(),console.log(" Genie needs to configure codex for agent communication:"),console.log(" \x1B[36mdisable_paste_burst\x1B[0m \u2192 Reliable tmux command injection"),console.log(" \x1B[36mOTel exporter\x1B[0m \u2192 Telemetry relay for state detection"),console.log(` Config: \x1B[2m${contractPath(getCodexConfigPath())}\x1B[0m`),console.log(),quick){let result2=ensureCodexOtelConfig();return printCodexResult(result2),config.codex={configured:result2!=="error"},config}if(await esm_default4({message:"Configure Codex for genie agent integration?",default:!0})){let result2=ensureCodexOtelConfig();printCodexResult(result2),config.codex={configured:result2!=="error"}}else console.log(" Skipped. Run \x1B[36mgenie setup --codex\x1B[0m later.");return config}async function configureDebug(config,quick){if(printSection("6. Debug Options","Logging and debugging settings"),quick)return console.log(" Using defaults: tmuxDebug=false, verbose=false"),config;let tmuxDebug=await esm_default4({message:"Enable tmux debug logging?",default:config.logging.tmuxDebug}),verbose=await esm_default4({message:"Enable verbose mode?",default:config.logging.verbose});return config.logging={tmuxDebug,verbose},config}async function configurePromptMode(config,quick){if(printSection("7. Prompt Mode","Controls how genie injects system prompts into Claude Code"),quick)return console.log(` Using default: promptMode="${config.promptMode}"`),config;console.log(" append \u2014 Uses --append-system-prompt-file (preserves Claude Code default system prompt)"),console.log(" system \u2014 Uses --system-prompt-file (replaces Claude Code default system prompt)"),console.log();let promptMode=await esm_default11({message:"Prompt mode:",choices:[{name:"append (recommended \u2014 preserves CC default)",value:"append"},{name:"system (replaces CC default)",value:"system"}],default:config.promptMode});return config.promptMode=promptMode,config}async function showSummaryAndSave(config){printSection("Summary",`Configuration will be saved to ${contractPath(getGenieConfigPath())}`),console.log(` Session: \x1B[36m${config.session.name}\x1B[0m (window: ${config.session.defaultWindow})`),console.log(` Terminal: timeout=${config.terminal.execTimeout}ms, lines=${config.terminal.readLines}`),console.log(` Shortcuts: ${config.shortcuts.tmuxInstalled?"\x1B[32minstalled\x1B[0m":"\x1B[2mnot installed\x1B[0m"}`),console.log(` Codex: ${config.codex?.configured?"\x1B[32mconfigured\x1B[0m":"\x1B[2mnot configured\x1B[0m"}`),console.log(` Debug: tmux=${config.logging.tmuxDebug}, verbose=${config.logging.verbose}`),console.log(` Prompt mode: \x1B[36m${config.promptMode}\x1B[0m`),console.log(),config.setupComplete=!0,config.lastSetupAt=new Date().toISOString(),await saveGenieConfig(config),console.log("\x1B[32m\u2713 Configuration saved!\x1B[0m")}async function showCurrentConfig(){let config=await loadGenieConfig();console.log(),console.log("\x1B[1mCurrent Genie Configuration\x1B[0m"),console.log(`\x1B[2m${contractPath(getGenieConfigPath())}\x1B[0m`),console.log(),console.log(JSON.stringify(config,null,2)),console.log()}function printNextSteps(){console.log(),console.log("\x1B[1mNext Steps:\x1B[0m"),console.log(),console.log(" Start a session: \x1B[36mgenie\x1B[0m"),console.log(" Watch AI work: \x1B[36mtmux attach -t genie\x1B[0m"),console.log(" Check health: \x1B[36mgenie doctor\x1B[0m"),console.log()}async function setupCommand(options={}){if(options.show){await showCurrentConfig();return}if(options.reset){await resetConfig(),console.log("\x1B[32m\u2713 Configuration reset to defaults.\x1B[0m"),console.log();return}let config=await loadGenieConfig();if(options.shortcuts){printHeader(),await configureShortcuts(config,!1),await markSetupComplete();return}if(options.terminal){printHeader(),config=await configureTerminal(config,!1),await saveGenieConfig(config),console.log("\x1B[32m\u2713 Terminal configuration saved.\x1B[0m");return}if(options.session){printHeader(),config=await configureSession(config,!1),await saveGenieConfig(config),console.log("\x1B[32m\u2713 Session configuration saved.\x1B[0m");return}if(options.codex){if(printHeader(),config=await configureCodex(config,!1),await saveGenieConfig(config),config.codex?.configured)console.log("\x1B[32m\u2713 Codex configuration saved.\x1B[0m");return}let quick=options.quick??!1;if(printHeader(),quick)console.log("\x1B[2mQuick mode: accepting all defaults\x1B[0m");config=await configureSession(config,quick),config=await configureTerminal(config,quick),config=await configureShortcuts(config,quick),config=await configureCodex(config,quick),config=await configureDebug(config,quick),config=await configurePromptMode(config,quick),await showSummaryAndSave(config),installGenieTmuxConf(),printNextSteps()}function installGenieTmuxConf(){let{existsSync:existsSync23,copyFileSync:copyFileSync3,mkdirSync:mkdirSync13,chmodSync:chmodSync2}=__require("fs"),{resolve:resolve4,dirname:dirname8}=__require("path"),genieHome3=process.env.GENIE_HOME??join28(homedir23(),".genie"),dest=join28(genieHome3,"tmux.conf");if(existsSync23(dest))return;let src=[resolve4(__dirname,"..","..","scripts","tmux","genie.tmux.conf"),resolve4(__dirname,"..","scripts","tmux","genie.tmux.conf")].find((p)=>existsSync23(p));if(!src)return;try{mkdirSync13(genieHome3,{recursive:!0}),copyFileSync3(src,dest),console.log(`\x1B[32m\u2713\x1B[0m Installed genie tmux config to ${dest}`)}catch{}let osc52Src=join28(dirname8(src),"osc52-copy.sh"),osc52Dest=join28(genieHome3,"osc52-copy.sh");if(existsSync23(osc52Src))try{copyFileSync3(osc52Src,osc52Dest),chmodSync2(osc52Dest,493)}catch{}}var __dirname="/home/runner/_work/genie/genie/src/genie-commands";var init_setup=__esm(()=>{init_esm14();init_codex_config();init_genie_config2();init_system_detect();init_shortcuts()});var exports_version={};__export(exports_version,{VERSION:()=>VERSION});import{existsSync as existsSync26,readFileSync as readFileSync18}from"fs";import{dirname as dirname8,resolve as resolve4}from"path";function readPackageJson(path3){try{if(!existsSync26(path3))return null;return JSON.parse(readFileSync18(path3,"utf-8"))}catch{return null}}function readVersionFromPackageJson(){let startDir=dirname8(import.meta.dir??__dirname),current=startDir;for(let depth=0;depth<MAX_WALK_DEPTH;depth++){let candidate=resolve4(current,"package.json"),pkg=readPackageJson(candidate);if(pkg?.name===PACKAGE_NAME&&pkg.version)return pkg.version;let parent=dirname8(current);if(parent===current)break;current=parent}current=startDir;for(let depth=0;depth<MAX_WALK_DEPTH;depth++){let candidate=resolve4(current,"package.json"),pkg=readPackageJson(candidate);if(pkg?.version)return pkg.version;let parent=dirname8(current);if(parent===current)break;current=parent}return FALLBACK_VERSION}var __dirname="/home/runner/_work/genie/genie/src/lib",FALLBACK_VERSION="0.0.0-unknown",PACKAGE_NAME="@automagik/genie",MAX_WALK_DEPTH=10,VERSION;var init_version=__esm(()=>{VERSION=readVersionFromPackageJson()});import{execSync as execSync5}from"child_process";function getRecentGitHistory(filePath,cwd){try{let trimmed=execSync5(`git log --oneline -n ${MAX_COMMITS} -- ${JSON.stringify(filePath)}`,{encoding:"utf-8",timeout:5000,cwd,stdio:["pipe","pipe","pipe"]}).trim();if(!trimmed)return null;return trimmed}catch{return null}}async function auditContext(payload){let input=payload.tool_input;if(!input)return;let filePath=input.file_path;if(!filePath)return;let cwd=payload.cwd??process.cwd(),history=getRecentGitHistory(filePath,cwd);if(!history)return;return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:`[audit-context] Recent git history for ${filePath}:
1035
- ${history}`}}}var MAX_COMMITS=5;var init_audit_context=()=>{};var exports_agent_directory={};__export(exports_agent_directory,{rm:()=>rm3,resolve:()=>resolve5,ls:()=>ls,loadIdentity:()=>loadIdentity,getProjectRoot:()=>getProjectRoot,get:()=>get2,findSessionByRepo:()=>findSessionByRepo,edit:()=>edit,add:()=>add});import{existsSync as existsSync27}from"fs";import{join as join32}from"path";function getProjectRoot(){if(process.env.GENIE_PROJECT_ROOT)return process.env.GENIE_PROJECT_ROOT;try{let{execSync:execSync6}=__require("child_process");return execSync6("git rev-parse --show-toplevel",{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}catch{return process.cwd()}}async function add(entry2,_options){if(!entry2.name||entry2.name.trim()==="")throw Error("Agent name is required.");if(!entry2.dir||entry2.dir.trim()==="")throw Error("Agent directory (--dir) is required.");if(!existsSync27(entry2.dir))throw Error(`Directory does not exist: ${entry2.dir}`);let agentsPath=join32(entry2.dir,"AGENTS.md");if(!existsSync27(agentsPath))throw Error(`AGENTS.md not found in ${entry2.dir}. Each agent directory must contain an AGENTS.md file.`);let full={...entry2,promptMode:entry2.promptMode??"append",registeredAt:new Date().toISOString()},existing=await resolve5(entry2.name);if(existing&&!existing.builtin)throw Error(`Agent "${entry2.name}" already exists. Use "genie dir edit" to update or "genie dir rm" first.`);let metadata=buildMetadata(full),team=entry2.team??entry2.bridgeTmuxSession??null,{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),sql=await getConnection2();return await sql`
1035
+ ${history}`}}}var MAX_COMMITS=5;var init_audit_context=()=>{};var exports_agent_directory={};__export(exports_agent_directory,{rm:()=>rm3,resolve:()=>resolve5,ls:()=>ls,loadIdentity:()=>loadIdentity,getProjectRoot:()=>getProjectRoot,get:()=>get2,findSessionByRepo:()=>findSessionByRepo,edit:()=>edit,add:()=>add});import{existsSync as existsSync27,lstatSync as lstatSync2}from"fs";import{join as join32}from"path";function validateAgentsMd(dir,allowSymlink){let agentsPath=join32(dir,"AGENTS.md");if(!existsSync27(agentsPath))throw Error(`AGENTS.md not found in ${dir}. Each agent directory must contain an AGENTS.md file.`);if(allowSymlink)return;let stat4=lstatSync2(agentsPath);if(!stat4)throw Error(`AGENTS.md in ${dir} disappeared between exists check and stat.`);if(stat4.isSymbolicLink())throw Error(`AGENTS.md in ${dir} is a symlink. Refusing to register: a symlinked AGENTS.md usually means --dir was pointed at a containing folder rather than the agent's real home (the cwd will be wrong and the agent's brain/runbooks won't be visible). Pass --allow-symlink to override if this is intentional.`);if(!stat4.isFile())throw Error(`AGENTS.md in ${dir} is not a regular file (got ${describeFileType(stat4)}).`)}function describeFileType(stat4){if(stat4.isDirectory())return"directory";if(stat4.isBlockDevice())return"block device";if(stat4.isCharacterDevice())return"character device";if(stat4.isFIFO())return"FIFO";if(stat4.isSocket())return"socket";return"unknown special file"}function getProjectRoot(){if(process.env.GENIE_PROJECT_ROOT)return process.env.GENIE_PROJECT_ROOT;try{let{execSync:execSync6}=__require("child_process");return execSync6("git rev-parse --show-toplevel",{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}catch{return process.cwd()}}async function add(entry2,options){if(!entry2.name||entry2.name.trim()==="")throw Error("Agent name is required.");if(!entry2.dir||entry2.dir.trim()==="")throw Error("Agent directory (--dir) is required.");if(!existsSync27(entry2.dir))throw Error(`Directory does not exist: ${entry2.dir}`);validateAgentsMd(entry2.dir,options?.allowSymlink??!1);let full={...entry2,promptMode:entry2.promptMode??"append",registeredAt:new Date().toISOString()},existing=await resolve5(entry2.name);if(existing&&!existing.builtin)throw Error(`Agent "${entry2.name}" already exists. Use "genie dir edit" to update or "genie dir rm" first.`);let metadata=buildMetadata(full),team=entry2.team??entry2.bridgeTmuxSession??null,{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),sql=await getConnection2();return await sql`
1036
1036
  INSERT INTO agents (id, role, custom_name, team, repo_path, started_at, state, metadata)
1037
1037
  VALUES (
1038
1038
  ${`dir:${entry2.name}`},
@@ -1080,7 +1080,7 @@ ${history}`}}}var MAX_COMMITS=5;var init_audit_context=()=>{};var exports_agent_
1080
1080
  LEFT JOIN executors e ON a.current_executor_id = e.id
1081
1081
  WHERE a.role IS NOT NULL
1082
1082
  ORDER BY a.role, (CASE WHEN position('dir:' in a.id) = 1 THEN 0 ELSE 1 END), a.started_at DESC
1083
- `;for(let row of rows){let name=row.role;if(!seen.has(name)){let meta=parseMetadata(row.metadata),createdAt=row.created_at instanceof Date?row.created_at.toISOString():row.created_at,entry2=roleToEntry(name,row.team,meta,createdAt),repoPath=row.repo_path;if(repoPath)entry2.dir=repoPath,entry2.repo=repoPath;result2.push({...entry2,scope:"global"}),seen.add(name)}}}catch{}return result2}async function get2(name,_options){return(await resolve5(name))?.entry??null}async function edit(name,updates,_options){if(updates.dir){if(!existsSync27(updates.dir))throw Error(`Directory does not exist: ${updates.dir}`);let agentsPath=join32(updates.dir,"AGENTS.md");if(!existsSync27(agentsPath))throw Error(`AGENTS.md not found in ${updates.dir}.`)}let existing=await get2(name);if(!existing)throw Error(`Agent "${name}" not found in directory.`);let updated=Object.assign(existing,updates),metadataPatch=buildMetadata(updated);try{let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),sql=await getConnection2();if((await sql`
1083
+ `;for(let row of rows){let name=row.role;if(!seen.has(name)){let meta=parseMetadata(row.metadata),createdAt=row.created_at instanceof Date?row.created_at.toISOString():row.created_at,entry2=roleToEntry(name,row.team,meta,createdAt),repoPath=row.repo_path;if(repoPath)entry2.dir=repoPath,entry2.repo=repoPath;result2.push({...entry2,scope:"global"}),seen.add(name)}}}catch{}return result2}async function get2(name,_options){return(await resolve5(name))?.entry??null}async function edit(name,updates,options){if(updates.dir){if(!existsSync27(updates.dir))throw Error(`Directory does not exist: ${updates.dir}`);validateAgentsMd(updates.dir,options?.allowSymlink??!1)}let existing=await get2(name);if(!existing)throw Error(`Agent "${name}" not found in directory.`);let updated=Object.assign(existing,updates),metadataPatch=buildMetadata(updated);try{let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),sql=await getConnection2();if((await sql`
1084
1084
  UPDATE agents
1085
1085
  SET metadata = metadata || ${sql.json(metadataPatch)}
1086
1086
  WHERE id = ${`dir:${name}`}
@@ -1749,7 +1749,7 @@ ${gitStatus}`:"","","Pick up where you left off. Read the wish file for full con
1749
1749
  --- Error ---
1750
1750
  ${Array.isArray(error2.errors)&&error2.errors.length>0?error2.errors.join("; "):error2.subtype}\x1B[0m
1751
1751
  `}function formatSystem(msg){let rec=msg;if(rec.subtype==="status"&&rec.status)return`[status] ${rec.status}
1752
- `;return null}var exports_codex_inject={};__export(exports_codex_inject,{injectCodexHooks:()=>injectCodexHooks,codexHooksInjected:()=>codexHooksInjected,CODEX_DISPATCHED_EVENTS:()=>CODEX_DISPATCHED_EVENTS});import{existsSync as existsSync36}from"fs";import{mkdir as mkdir6,readFile as readFile10,writeFile as writeFile7}from"fs/promises";import{homedir as homedir29}from"os";import{join as join43}from"path";function codexHomeDir(){return process.env.CODEX_HOME??join43(homedir29(),".codex")}function codexConfigPath(){return join43(codexHomeDir(),"config.toml")}function escapeTomlString(value){return`"${value.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}"`}function buildCodexHookFragment(){let cmd=buildDispatchCommand(),lines=[];lines.push("# === GENIE HOOK BRIDGE BEGIN ==="),lines.push("# Auto-injected by `genie spawn ... --provider codex`. Do not edit by hand."),lines.push("# Removing this block disables codex \u2192 genie hook event delivery."),lines.push("[hooks]"),lines.push("feature_enabled = true"),lines.push("");for(let event of CODEX_DISPATCHED_EVENTS)lines.push(`[[hooks.${event}]]`),lines.push('matcher = "*"'),lines.push(""),lines.push(`[[hooks.${event}.hooks]]`),lines.push('type = "command"'),lines.push(`command = ${escapeTomlString(cmd)}`),lines.push(`timeout = ${DISPATCH_TIMEOUT2}`),lines.push("");return lines.push("# === GENIE HOOK BRIDGE END ==="),lines.join(`
1752
+ `;return null}var exports_codex_inject={};__export(exports_codex_inject,{injectCodexHooks:()=>injectCodexHooks,codexHooksInjected:()=>codexHooksInjected,CODEX_DISPATCHED_EVENTS:()=>CODEX_DISPATCHED_EVENTS});import{existsSync as existsSync36}from"fs";import{mkdir as mkdir6,readFile as readFile10,writeFile as writeFile7}from"fs/promises";import{homedir as homedir29}from"os";import{join as join43}from"path";function codexHomeDir(){return process.env.CODEX_HOME??join43(homedir29(),".codex")}function codexConfigPath(){return join43(codexHomeDir(),"config.toml")}function escapeTomlString(value){return`"${value.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}"`}function buildCodexHookFragment(){let cmd=buildDispatchCommand(),lines=[];lines.push("# === GENIE HOOK BRIDGE BEGIN ==="),lines.push("# Auto-injected by `genie spawn ... --provider codex`. Do not edit by hand."),lines.push("# Removing this block disables codex \u2192 genie hook event delivery."),lines.push("[hooks]"),lines.push("feature_enabled = true"),lines.push("");for(let[event,matcher]of Object.entries(CODEX_DISPATCHED_EVENT_MATCHERS))lines.push(`[[hooks.${event}]]`),lines.push(`matcher = ${escapeTomlString(matcher)}`),lines.push(""),lines.push(`[[hooks.${event}.hooks]]`),lines.push('type = "command"'),lines.push(`command = ${escapeTomlString(cmd)}`),lines.push(`timeout = ${DISPATCH_TIMEOUT2}`),lines.push("");return lines.push("# === GENIE HOOK BRIDGE END ==="),lines.join(`
1753
1753
  `)}function stripExistingBlock(content){let beginIdx=content.indexOf(BEGIN_MARKER),endIdx=content.indexOf(END_MARKER);if(beginIdx===-1||endIdx===-1||endIdx<beginIdx)return{trimmed:content,existed:!1};let before=content.slice(0,beginIdx).replace(/\s+$/,""),after=content.slice(endIdx+END_MARKER.length).replace(/^\s+/,"");return{trimmed:before&&after?`${before}
1754
1754
 
1755
1755
  ${after}
@@ -1758,7 +1758,7 @@ ${after}
1758
1758
 
1759
1759
  ${desired}
1760
1760
  `:`${desired}
1761
- `;if(existing.trim()===candidate.trim())return!1;return await mkdir6(codexHomeDir(),{recursive:!0}),await writeFile7(path3,candidate),!0}async function codexHooksInjected(){let path3=codexConfigPath();if(!existsSync36(path3))return!1;try{let content=await readFile10(path3,"utf-8");return content.includes(BEGIN_MARKER)&&content.includes(END_MARKER)}catch{return!1}}var DISPATCH_TIMEOUT2=15,CODEX_DISPATCHED_EVENTS,BEGIN_MARKER="# === GENIE HOOK BRIDGE BEGIN ===",END_MARKER="# === GENIE HOOK BRIDGE END ===";var init_codex_inject=__esm(()=>{init_inject();CODEX_DISPATCHED_EVENTS=["PreToolUse","PostToolUse","UserPromptSubmit","SessionStart","Stop","PermissionRequest"]});var exports_idle_timeout={};__export(exports_idle_timeout,{suspendWorker:()=>suspendWorker,getIdleTimeoutMs:()=>getIdleTimeoutMs,checkIdleWorkers:()=>checkIdleWorkers,WATCHDOG_POLL_INTERVAL_MS:()=>WATCHDOG_POLL_INTERVAL_MS});function getIdleTimeoutMs(){let env=process.env.GENIE_IDLE_TIMEOUT_MS;if(env!==void 0){if(env==="")return DEFAULT_IDLE_TIMEOUT_MS;let parsed=Number(env);if(!Number.isNaN(parsed)&&parsed>=0)return parsed}return DEFAULT_IDLE_TIMEOUT_MS}async function suspendWorker(executorId,deps=defaultDeps3){let executor=(await deps.listExecutors()).find((e)=>e.id===executorId);if(!executor)return!1;if(executor.state==="terminated")return!0;if(executor.tmuxPaneId)try{await deps.executeTmux(`kill-pane -t '${executor.tmuxPaneId}'`)}catch{}return await deps.terminateExecutor(executorId),!0}async function checkIdleWorkers(deps=defaultDeps3){let timeoutMs=getIdleTimeoutMs();if(timeoutMs===0)return[];let executors=await deps.listExecutors(),suspended=[];for(let e of executors){if(e.state!=="idle")continue;if(Date.now()-new Date(e.updatedAt).getTime()<timeoutMs)continue;if(e.tmuxPaneId){if(!await deps.isPaneAlive(e.tmuxPaneId)){await deps.terminateExecutor(e.id),suspended.push(e.id);continue}}if(await suspendWorker(e.id,deps))suspended.push(e.id)}return suspended}var defaultDeps3,DEFAULT_IDLE_TIMEOUT_MS=1800000,WATCHDOG_POLL_INTERVAL_MS=60000;var init_idle_timeout=__esm(()=>{init_executor_registry();init_tmux();defaultDeps3={listExecutors:()=>listExecutors(),terminateExecutor,updateExecutorState,executeTmux:executeTmux2,isPaneAlive}});var exports_agents={};__export(exports_agents,{tryAutoRegisterAgent:()=>tryAutoRegisterAgent,resolveTeamName:()=>resolveTeamName3,resolveSpawnIdentity:()=>resolveSpawnIdentity,resolveAgentWorkingDir:()=>resolveAgentWorkingDir,resolveAgentForSpawn:()=>resolveAgentForSpawn,rejectDuplicateRole:()=>rejectDuplicateRole,recoverSurgery:()=>recoverSurgery,pickParallelShortId:()=>pickParallelShortId,handleWorkerStop:()=>handleWorkerStop,handleWorkerSpawn:()=>handleWorkerSpawn,handleWorkerResume:()=>handleWorkerResume,handleWorkerRecover:()=>handleWorkerRecover,handleWorkerKill:()=>handleWorkerKill,handleLsCommand:()=>handleLsCommand,findDeadResumable:()=>findDeadResumable,buildWorkerStatusMap:()=>buildWorkerStatusMap,buildResumeContext:()=>buildResumeContext,buildInitialSplitWindowCommand:()=>buildInitialSplitWindowCommand,buildFullResumeParams:()=>buildFullResumeParams,buildDirectoryPermissionSpawnParams:()=>buildDirectoryPermissionSpawnParams,_spawnAutoSyncDeps:()=>_spawnAutoSyncDeps,RecoverAgentNotFoundError:()=>RecoverAgentNotFoundError,OwnerSpawnCollisionError:()=>OwnerSpawnCollisionError});import{existsSync as existsSync37,readFileSync as readFileSync23}from"fs";import{isAbsolute,join as join44,relative,resolve as resolvePath}from"path";async function isPaneAliveOrDead(paneId){try{return await isPaneAlive(paneId)}catch(err){let message=err instanceof Error?err.message:String(err);if(err instanceof TmuxUnreachableError||message.includes("no server running")||message.includes("server exited")||message.includes("error connecting"))return!1;throw err}}async function resolveTeamLeaderName(teamNameOrDefault){return resolveLeaderName(teamNameOrDefault)}function isRelayAlive(pidFile){let{readFileSync:readFileSync24,existsSync:existsSync38}=__require("fs");if(!existsSync38(pidFile))return!1;try{let pid=Number.parseInt(readFileSync24(pidFile,"utf-8").trim());if(pid>0)return process.kill(pid,0),!0}catch{}return!1}async function ensureOtelRelay(team){let{writeFileSync:writeFileSync14,mkdirSync:mkdirSync15}=__require("fs"),{join:join45}=__require("path"),{homedir:homedir30}=__require("os"),relayDir=join45(homedir30(),".genie","relay");mkdirSync15(relayDir,{recursive:!0});let pidFile=join45(relayDir,"otel-relay.pid"),scriptFile=join45(relayDir,"otel-relay.mjs");if(isRelayAlive(pidFile))return!0;let inboxDir=join45(process.env.CLAUDE_CONFIG_DIR??join45(homedir30(),".claude"),"teams",team,"inboxes"),leaderInboxName=sanitizeTeamName(await resolveTeamLeaderName(team)),escapedRelayDir=relayDir.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),escapedInboxDir=inboxDir.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),escapedPidFile=pidFile.replace(/\\/g,"\\\\").replace(/'/g,"\\'");try{writeFileSync14(scriptFile,`import { createServer } from 'http';
1761
+ `;if(existing.trim()===candidate.trim())return!1;return await mkdir6(codexHomeDir(),{recursive:!0}),await writeFile7(path3,candidate),!0}async function codexHooksInjected(){let path3=codexConfigPath();if(!existsSync36(path3))return!1;try{let content=await readFile10(path3,"utf-8");return content.includes(BEGIN_MARKER)&&content.includes(END_MARKER)}catch{return!1}}var DISPATCH_TIMEOUT2=15,CODEX_DISPATCHED_EVENTS,BEGIN_MARKER="# === GENIE HOOK BRIDGE BEGIN ===",END_MARKER="# === GENIE HOOK BRIDGE END ===";var init_codex_inject=__esm(()=>{init_inject();init_types2();CODEX_DISPATCHED_EVENTS=Object.keys(CODEX_DISPATCHED_EVENT_MATCHERS)});var exports_idle_timeout={};__export(exports_idle_timeout,{suspendWorker:()=>suspendWorker,getIdleTimeoutMs:()=>getIdleTimeoutMs,checkIdleWorkers:()=>checkIdleWorkers,WATCHDOG_POLL_INTERVAL_MS:()=>WATCHDOG_POLL_INTERVAL_MS});function getIdleTimeoutMs(){let env=process.env.GENIE_IDLE_TIMEOUT_MS;if(env!==void 0){if(env==="")return DEFAULT_IDLE_TIMEOUT_MS;let parsed=Number(env);if(!Number.isNaN(parsed)&&parsed>=0)return parsed}return DEFAULT_IDLE_TIMEOUT_MS}async function suspendWorker(executorId,deps=defaultDeps3){let executor=(await deps.listExecutors()).find((e)=>e.id===executorId);if(!executor)return!1;if(executor.state==="terminated")return!0;if(executor.tmuxPaneId)try{await deps.executeTmux(`kill-pane -t '${executor.tmuxPaneId}'`)}catch{}return await deps.terminateExecutor(executorId),!0}async function checkIdleWorkers(deps=defaultDeps3){let timeoutMs=getIdleTimeoutMs();if(timeoutMs===0)return[];let executors=await deps.listExecutors(),suspended=[];for(let e of executors){if(e.state!=="idle")continue;if(Date.now()-new Date(e.updatedAt).getTime()<timeoutMs)continue;if(e.tmuxPaneId){if(!await deps.isPaneAlive(e.tmuxPaneId)){await deps.terminateExecutor(e.id),suspended.push(e.id);continue}}if(await suspendWorker(e.id,deps))suspended.push(e.id)}return suspended}var defaultDeps3,DEFAULT_IDLE_TIMEOUT_MS=1800000,WATCHDOG_POLL_INTERVAL_MS=60000;var init_idle_timeout=__esm(()=>{init_executor_registry();init_tmux();defaultDeps3={listExecutors:()=>listExecutors(),terminateExecutor,updateExecutorState,executeTmux:executeTmux2,isPaneAlive}});var exports_agents={};__export(exports_agents,{tryAutoRegisterAgent:()=>tryAutoRegisterAgent,resolveTeamName:()=>resolveTeamName3,resolveSpawnIdentity:()=>resolveSpawnIdentity,resolveAgentWorkingDir:()=>resolveAgentWorkingDir,resolveAgentForSpawn:()=>resolveAgentForSpawn,rejectDuplicateRole:()=>rejectDuplicateRole,recoverSurgery:()=>recoverSurgery,pickParallelShortId:()=>pickParallelShortId,handleWorkerStop:()=>handleWorkerStop,handleWorkerSpawn:()=>handleWorkerSpawn,handleWorkerResume:()=>handleWorkerResume,handleWorkerRecover:()=>handleWorkerRecover,handleWorkerKill:()=>handleWorkerKill,handleLsCommand:()=>handleLsCommand,findDeadResumable:()=>findDeadResumable,buildWorkerStatusMap:()=>buildWorkerStatusMap,buildResumeContext:()=>buildResumeContext,buildInitialSplitWindowCommand:()=>buildInitialSplitWindowCommand,buildFullResumeParams:()=>buildFullResumeParams,buildDirectoryPermissionSpawnParams:()=>buildDirectoryPermissionSpawnParams,_spawnAutoSyncDeps:()=>_spawnAutoSyncDeps,RecoverAgentNotFoundError:()=>RecoverAgentNotFoundError,OwnerSpawnCollisionError:()=>OwnerSpawnCollisionError});import{existsSync as existsSync37,readFileSync as readFileSync23}from"fs";import{isAbsolute,join as join44,relative,resolve as resolvePath}from"path";async function isPaneAliveOrDead(paneId){try{return await isPaneAlive(paneId)}catch(err){let message=err instanceof Error?err.message:String(err);if(err instanceof TmuxUnreachableError||message.includes("no server running")||message.includes("server exited")||message.includes("error connecting"))return!1;throw err}}async function resolveTeamLeaderName(teamNameOrDefault){return resolveLeaderName(teamNameOrDefault)}function isRelayAlive(pidFile){let{readFileSync:readFileSync24,existsSync:existsSync38}=__require("fs");if(!existsSync38(pidFile))return!1;try{let pid=Number.parseInt(readFileSync24(pidFile,"utf-8").trim());if(pid>0)return process.kill(pid,0),!0}catch{}return!1}async function ensureOtelRelay(team){let{writeFileSync:writeFileSync14,mkdirSync:mkdirSync15}=__require("fs"),{join:join45}=__require("path"),{homedir:homedir30}=__require("os"),relayDir=join45(homedir30(),".genie","relay");mkdirSync15(relayDir,{recursive:!0});let pidFile=join45(relayDir,"otel-relay.pid"),scriptFile=join45(relayDir,"otel-relay.mjs");if(isRelayAlive(pidFile))return!0;let inboxDir=join45(process.env.CLAUDE_CONFIG_DIR??join45(homedir30(),".claude"),"teams",team,"inboxes"),leaderInboxName=sanitizeTeamName(await resolveTeamLeaderName(team)),escapedRelayDir=relayDir.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),escapedInboxDir=inboxDir.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),escapedPidFile=pidFile.replace(/\\/g,"\\\\").replace(/'/g,"\\'");try{writeFileSync14(scriptFile,`import { createServer } from 'http';
1762
1762
  import { execSync } from 'child_process';
1763
1763
  import { readFileSync, writeFileSync, mkdirSync, readdirSync, unlinkSync, statSync } from 'fs';
1764
1764
  import { createHash } from 'crypto';
@@ -3469,7 +3469,7 @@ $ bun add react-devtools-core@7 -d
3469
3469
  `).length>0}catch{util4.noop()}return _smartMonToolsInstalled}function isRaspberry(cpuinfo){let PI_MODEL_NO=["BCM2708","BCM2709","BCM2710","BCM2711","BCM2712","BCM2835","BCM2836","BCM2837","BCM2837B0"];if(_rpi_cpuinfo!==null)cpuinfo=_rpi_cpuinfo;else if(cpuinfo===void 0)try{cpuinfo=fs3.readFileSync("/proc/cpuinfo",{encoding:"utf8"}).toString().split(`
3470
3470
  `),_rpi_cpuinfo=cpuinfo}catch{return!1}let hardware=getValue(cpuinfo,"hardware"),model=getValue(cpuinfo,"model");return hardware&&PI_MODEL_NO.indexOf(hardware)>-1||model&&model.indexOf("Raspberry Pi")>-1}function isRaspbian(){let osrelease=[];try{osrelease=fs3.readFileSync("/etc/os-release",{encoding:"utf8"}).toString().split(`
3471
3471
  `)}catch{return!1}let id=getValue(osrelease,"id","=");return id&&id.indexOf("raspbian")>-1}function execWin(cmd,opts,callback){if(!callback)callback=opts,opts=execOptsWin;let newCmd="chcp 65001 > nul && cmd /C "+cmd+" && chcp "+codepage+" > nul";exec3(newCmd,opts,(error2,stdout)=>{callback(error2,stdout)})}function darwinXcodeExists(){let cmdLineToolsExists=fs3.existsSync("/Library/Developer/CommandLineTools/usr/bin/"),xcodeAppExists=fs3.existsSync("/Applications/Xcode.app/Contents/Developer/Tools"),xcodeExists=fs3.existsSync("/Library/Developer/Xcode/");return cmdLineToolsExists||xcodeExists||xcodeAppExists}function nanoSeconds(){let time=process.hrtime();if(!Array.isArray(time)||time.length!==2)return 0;return+time[0]*1e9+ +time[1]}function countUniqueLines(lines,startingWith){startingWith=startingWith||"";let uniqueLines=[];return lines.forEach((line)=>{if(line.startsWith(startingWith)){if(uniqueLines.indexOf(line)===-1)uniqueLines.push(line)}}),uniqueLines.length}function countLines(lines,startingWith){startingWith=startingWith||"";let uniqueLines=[];return lines.forEach((line)=>{if(line.startsWith(startingWith))uniqueLines.push(line)}),uniqueLines.length}function sanitizeShellString(str5,strict){if(typeof strict>"u")strict=!1;let s2=str5||"",result2="",l=mathMin(s2.length,2000);for(let i2=0;i2<=l;i2++)if(!(s2[i2]===void 0||s2[i2]===">"||s2[i2]==="<"||s2[i2]==="*"||s2[i2]==="?"||s2[i2]==="["||s2[i2]==="]"||s2[i2]==="|"||s2[i2]==="\u02DA"||s2[i2]==="$"||s2[i2]===";"||s2[i2]==="&"||s2[i2]==="]"||s2[i2]==="#"||s2[i2]==="\\"||s2[i2]==="\t"||s2[i2]===`
3472
- `||s2[i2]==="\r"||s2[i2]==="'"||s2[i2]==="`"||s2[i2]==='"'||s2[i2].length>1||strict&&s2[i2]==="("||strict&&s2[i2]===")"||strict&&s2[i2]==="@"||strict&&s2[i2]===" "||strict&&s2[i2]==="{"||strict&&s2[i2]===";"||strict&&s2[i2]==="}"))result2=result2+s2[i2];return result2}function isPrototypePolluted(){let notPolluted=!0,st="";try{st.__proto__.replace=stringReplace,st.__proto__.toLowerCase=stringToLower,st.__proto__.toString=stringToString,st.__proto__.substr=stringSubstr,st.__proto__.substring=stringSubstring,st.__proto__.trim=stringTrim,st.__proto__.startsWith=stringStartWith}catch(e){Object.setPrototypeOf(st,stringObj)}notPolluted=notPolluted||!1;let ms=Date.now();if(typeof ms==="number"&&ms>1600000000000){let l=ms%100+15;for(let i2=0;i2<l;i2++){let r=Math.random()*61.99999999+1,rs=parseInt(Math.floor(r).toString(),10),rs2=parseInt(r.toString().split(".")[0],10),q2=Math.random()*61.99999999+1,qs=parseInt(Math.floor(q2).toString(),10),qs2=parseInt(q2.toString().split(".")[0],10);notPolluted=notPolluted&&r!==q2,notPolluted=notPolluted&&rs===rs2&&qs===qs2,st+="1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"[rs-1]}notPolluted=notPolluted&&st.length===l;let p=Math.random()*l*0.9999999999,stm=st.substr(0,p)+" "+st.substr(p,2000);try{stm.__proto__.replace=stringReplace}catch(e){Object.setPrototypeOf(stm,stringObj)}let sto=stm.replace(/ /g,"");notPolluted=notPolluted&&st===sto,p=Math.random()*l*0.9999999999,stm=st.substr(0,p)+"{"+st.substr(p,2000),sto=stm.replace(/{/g,""),notPolluted=notPolluted&&st===sto,p=Math.random()*l*0.9999999999,stm=st.substr(0,p)+"*"+st.substr(p,2000),sto=stm.replace(/\*/g,""),notPolluted=notPolluted&&st===sto,p=Math.random()*l*0.9999999999,stm=st.substr(0,p)+"$"+st.substr(p,2000),sto=stm.replace(/\$/g,""),notPolluted=notPolluted&&st===sto;let stl=st.toLowerCase();notPolluted=notPolluted&&stl.length===l&&stl[l-1]&&!stl[l];for(let i2=0;i2<l;i2++){let s1=st[i2];try{s1.__proto__.toLowerCase=stringToLower}catch{Object.setPrototypeOf(st,stringObj)}let s22=stl?stl[i2]:"",s1l=s1.toLowerCase();notPolluted=notPolluted&&s1l[0]===s22&&s1l[0]&&!s1l[1]}}return!notPolluted}function hex2bin(hex){return("00000000"+parseInt(hex,16).toString(2)).substr(-8)}function getFilesInPath(source){let{lstatSync:lstatSync2,readdirSync:readdirSync14}=fs3,join83=path6.join;function isDirectory2(source2){return lstatSync2(source2).isDirectory()}function isFile2(source2){return lstatSync2(source2).isFile()}function getDirectories(source2){return readdirSync14(source2).map((name)=>{return join83(source2,name)}).filter(isDirectory2)}function getFiles(source2){return readdirSync14(source2).map((name)=>{return join83(source2,name)}).filter(isFile2)}function getFilesRecursively(source2){try{return getDirectories(source2).map((dir)=>{return getFilesRecursively(dir)}).reduce((a,b3)=>{return a.concat(b3)},[]).concat(getFiles(source2))}catch{return[]}}if(fs3.existsSync(source))return getFilesRecursively(source);else return[]}function decodePiCpuinfo(lines){if(_rpi_cpuinfo===null)_rpi_cpuinfo=lines;else if(lines===void 0)lines=_rpi_cpuinfo;let oldRevisionCodes={"0002":{type:"B",revision:"1.0",memory:256,manufacturer:"Egoman",processor:"BCM2835"},"0003":{type:"B",revision:"1.0",memory:256,manufacturer:"Egoman",processor:"BCM2835"},"0004":{type:"B",revision:"2.0",memory:256,manufacturer:"Sony UK",processor:"BCM2835"},"0005":{type:"B",revision:"2.0",memory:256,manufacturer:"Qisda",processor:"BCM2835"},"0006":{type:"B",revision:"2.0",memory:256,manufacturer:"Egoman",processor:"BCM2835"},"0007":{type:"A",revision:"2.0",memory:256,manufacturer:"Egoman",processor:"BCM2835"},"0008":{type:"A",revision:"2.0",memory:256,manufacturer:"Sony UK",processor:"BCM2835"},"0009":{type:"A",revision:"2.0",memory:256,manufacturer:"Qisda",processor:"BCM2835"},"000d":{type:"B",revision:"2.0",memory:512,manufacturer:"Egoman",processor:"BCM2835"},"000e":{type:"B",revision:"2.0",memory:512,manufacturer:"Sony UK",processor:"BCM2835"},"000f":{type:"B",revision:"2.0",memory:512,manufacturer:"Egoman",processor:"BCM2835"},"0010":{type:"B+",revision:"1.2",memory:512,manufacturer:"Sony UK",processor:"BCM2835"},"0011":{type:"CM1",revision:"1.0",memory:512,manufacturer:"Sony UK",processor:"BCM2835"},"0012":{type:"A+",revision:"1.1",memory:256,manufacturer:"Sony UK",processor:"BCM2835"},"0013":{type:"B+",revision:"1.2",memory:512,manufacturer:"Embest",processor:"BCM2835"},"0014":{type:"CM1",revision:"1.0",memory:512,manufacturer:"Embest",processor:"BCM2835"},"0015":{type:"A+",revision:"1.1",memory:256,manufacturer:"512MB\tEmbest",processor:"BCM2835"}},processorList=["BCM2835","BCM2836","BCM2837","BCM2711","BCM2712"],manufacturerList=["Sony UK","Egoman","Embest","Sony Japan","Embest","Stadium"],typeList={"00":"A","01":"B","02":"A+","03":"B+","04":"2B","05":"Alpha (early prototype)","06":"CM1","08":"3B","09":"Zero","0a":"CM3","0c":"Zero W","0d":"3B+","0e":"3A+","0f":"Internal use only",10:"CM3+",11:"4B",12:"Zero 2 W",13:"400",14:"CM4",15:"CM4S",16:"Internal use only",17:"5",18:"CM5",19:"500/500+","1a":"CM5 Lite"},revisionCode=getValue(lines,"revision",":",!0),model=getValue(lines,"model:",":",!0),serial=getValue(lines,"serial",":",!0),result2={};if({}.hasOwnProperty.call(oldRevisionCodes,revisionCode))result2={model,serial,revisionCode,memory:oldRevisionCodes[revisionCode].memory,manufacturer:oldRevisionCodes[revisionCode].manufacturer,processor:oldRevisionCodes[revisionCode].processor,type:oldRevisionCodes[revisionCode].type,revision:oldRevisionCodes[revisionCode].revision};else{let revision=("00000000"+getValue(lines,"revision",":",!0).toLowerCase()).substr(-8),memSizeCode=parseInt(hex2bin(revision.substr(2,1)).substr(5,3),2)||0,manufacturer=manufacturerList[parseInt(revision.substr(3,1),10)],processor=processorList[parseInt(revision.substr(4,1),10)],typeCode=revision.substr(5,2);result2={model,serial,revisionCode,memory:256*Math.pow(2,memSizeCode),manufacturer,processor,type:{}.hasOwnProperty.call(typeList,typeCode)?typeList[typeCode]:"",revision:"1."+revision.substr(7,1)}}return result2}function getRpiGpu(cpuinfo){if(_rpi_cpuinfo===null&&cpuinfo!==void 0)_rpi_cpuinfo=cpuinfo;else if(cpuinfo===void 0&&_rpi_cpuinfo!==null)cpuinfo=_rpi_cpuinfo;else try{cpuinfo=fs3.readFileSync("/proc/cpuinfo",{encoding:"utf8"}).toString().split(`
3472
+ `||s2[i2]==="\r"||s2[i2]==="'"||s2[i2]==="`"||s2[i2]==='"'||s2[i2].length>1||strict&&s2[i2]==="("||strict&&s2[i2]===")"||strict&&s2[i2]==="@"||strict&&s2[i2]===" "||strict&&s2[i2]==="{"||strict&&s2[i2]===";"||strict&&s2[i2]==="}"))result2=result2+s2[i2];return result2}function isPrototypePolluted(){let notPolluted=!0,st="";try{st.__proto__.replace=stringReplace,st.__proto__.toLowerCase=stringToLower,st.__proto__.toString=stringToString,st.__proto__.substr=stringSubstr,st.__proto__.substring=stringSubstring,st.__proto__.trim=stringTrim,st.__proto__.startsWith=stringStartWith}catch(e){Object.setPrototypeOf(st,stringObj)}notPolluted=notPolluted||!1;let ms=Date.now();if(typeof ms==="number"&&ms>1600000000000){let l=ms%100+15;for(let i2=0;i2<l;i2++){let r=Math.random()*61.99999999+1,rs=parseInt(Math.floor(r).toString(),10),rs2=parseInt(r.toString().split(".")[0],10),q2=Math.random()*61.99999999+1,qs=parseInt(Math.floor(q2).toString(),10),qs2=parseInt(q2.toString().split(".")[0],10);notPolluted=notPolluted&&r!==q2,notPolluted=notPolluted&&rs===rs2&&qs===qs2,st+="1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"[rs-1]}notPolluted=notPolluted&&st.length===l;let p=Math.random()*l*0.9999999999,stm=st.substr(0,p)+" "+st.substr(p,2000);try{stm.__proto__.replace=stringReplace}catch(e){Object.setPrototypeOf(stm,stringObj)}let sto=stm.replace(/ /g,"");notPolluted=notPolluted&&st===sto,p=Math.random()*l*0.9999999999,stm=st.substr(0,p)+"{"+st.substr(p,2000),sto=stm.replace(/{/g,""),notPolluted=notPolluted&&st===sto,p=Math.random()*l*0.9999999999,stm=st.substr(0,p)+"*"+st.substr(p,2000),sto=stm.replace(/\*/g,""),notPolluted=notPolluted&&st===sto,p=Math.random()*l*0.9999999999,stm=st.substr(0,p)+"$"+st.substr(p,2000),sto=stm.replace(/\$/g,""),notPolluted=notPolluted&&st===sto;let stl=st.toLowerCase();notPolluted=notPolluted&&stl.length===l&&stl[l-1]&&!stl[l];for(let i2=0;i2<l;i2++){let s1=st[i2];try{s1.__proto__.toLowerCase=stringToLower}catch{Object.setPrototypeOf(st,stringObj)}let s22=stl?stl[i2]:"",s1l=s1.toLowerCase();notPolluted=notPolluted&&s1l[0]===s22&&s1l[0]&&!s1l[1]}}return!notPolluted}function hex2bin(hex){return("00000000"+parseInt(hex,16).toString(2)).substr(-8)}function getFilesInPath(source){let{lstatSync:lstatSync3,readdirSync:readdirSync14}=fs3,join83=path6.join;function isDirectory2(source2){return lstatSync3(source2).isDirectory()}function isFile2(source2){return lstatSync3(source2).isFile()}function getDirectories(source2){return readdirSync14(source2).map((name)=>{return join83(source2,name)}).filter(isDirectory2)}function getFiles(source2){return readdirSync14(source2).map((name)=>{return join83(source2,name)}).filter(isFile2)}function getFilesRecursively(source2){try{return getDirectories(source2).map((dir)=>{return getFilesRecursively(dir)}).reduce((a,b3)=>{return a.concat(b3)},[]).concat(getFiles(source2))}catch{return[]}}if(fs3.existsSync(source))return getFilesRecursively(source);else return[]}function decodePiCpuinfo(lines){if(_rpi_cpuinfo===null)_rpi_cpuinfo=lines;else if(lines===void 0)lines=_rpi_cpuinfo;let oldRevisionCodes={"0002":{type:"B",revision:"1.0",memory:256,manufacturer:"Egoman",processor:"BCM2835"},"0003":{type:"B",revision:"1.0",memory:256,manufacturer:"Egoman",processor:"BCM2835"},"0004":{type:"B",revision:"2.0",memory:256,manufacturer:"Sony UK",processor:"BCM2835"},"0005":{type:"B",revision:"2.0",memory:256,manufacturer:"Qisda",processor:"BCM2835"},"0006":{type:"B",revision:"2.0",memory:256,manufacturer:"Egoman",processor:"BCM2835"},"0007":{type:"A",revision:"2.0",memory:256,manufacturer:"Egoman",processor:"BCM2835"},"0008":{type:"A",revision:"2.0",memory:256,manufacturer:"Sony UK",processor:"BCM2835"},"0009":{type:"A",revision:"2.0",memory:256,manufacturer:"Qisda",processor:"BCM2835"},"000d":{type:"B",revision:"2.0",memory:512,manufacturer:"Egoman",processor:"BCM2835"},"000e":{type:"B",revision:"2.0",memory:512,manufacturer:"Sony UK",processor:"BCM2835"},"000f":{type:"B",revision:"2.0",memory:512,manufacturer:"Egoman",processor:"BCM2835"},"0010":{type:"B+",revision:"1.2",memory:512,manufacturer:"Sony UK",processor:"BCM2835"},"0011":{type:"CM1",revision:"1.0",memory:512,manufacturer:"Sony UK",processor:"BCM2835"},"0012":{type:"A+",revision:"1.1",memory:256,manufacturer:"Sony UK",processor:"BCM2835"},"0013":{type:"B+",revision:"1.2",memory:512,manufacturer:"Embest",processor:"BCM2835"},"0014":{type:"CM1",revision:"1.0",memory:512,manufacturer:"Embest",processor:"BCM2835"},"0015":{type:"A+",revision:"1.1",memory:256,manufacturer:"512MB\tEmbest",processor:"BCM2835"}},processorList=["BCM2835","BCM2836","BCM2837","BCM2711","BCM2712"],manufacturerList=["Sony UK","Egoman","Embest","Sony Japan","Embest","Stadium"],typeList={"00":"A","01":"B","02":"A+","03":"B+","04":"2B","05":"Alpha (early prototype)","06":"CM1","08":"3B","09":"Zero","0a":"CM3","0c":"Zero W","0d":"3B+","0e":"3A+","0f":"Internal use only",10:"CM3+",11:"4B",12:"Zero 2 W",13:"400",14:"CM4",15:"CM4S",16:"Internal use only",17:"5",18:"CM5",19:"500/500+","1a":"CM5 Lite"},revisionCode=getValue(lines,"revision",":",!0),model=getValue(lines,"model:",":",!0),serial=getValue(lines,"serial",":",!0),result2={};if({}.hasOwnProperty.call(oldRevisionCodes,revisionCode))result2={model,serial,revisionCode,memory:oldRevisionCodes[revisionCode].memory,manufacturer:oldRevisionCodes[revisionCode].manufacturer,processor:oldRevisionCodes[revisionCode].processor,type:oldRevisionCodes[revisionCode].type,revision:oldRevisionCodes[revisionCode].revision};else{let revision=("00000000"+getValue(lines,"revision",":",!0).toLowerCase()).substr(-8),memSizeCode=parseInt(hex2bin(revision.substr(2,1)).substr(5,3),2)||0,manufacturer=manufacturerList[parseInt(revision.substr(3,1),10)],processor=processorList[parseInt(revision.substr(4,1),10)],typeCode=revision.substr(5,2);result2={model,serial,revisionCode,memory:256*Math.pow(2,memSizeCode),manufacturer,processor,type:{}.hasOwnProperty.call(typeList,typeCode)?typeList[typeCode]:"",revision:"1."+revision.substr(7,1)}}return result2}function getRpiGpu(cpuinfo){if(_rpi_cpuinfo===null&&cpuinfo!==void 0)_rpi_cpuinfo=cpuinfo;else if(cpuinfo===void 0&&_rpi_cpuinfo!==null)cpuinfo=_rpi_cpuinfo;else try{cpuinfo=fs3.readFileSync("/proc/cpuinfo",{encoding:"utf8"}).toString().split(`
3473
3473
  `),_rpi_cpuinfo=cpuinfo}catch{return!1}let rpi=decodePiCpuinfo(cpuinfo);if(rpi.type==="4B"||rpi.type==="CM4"||rpi.type==="CM4S"||rpi.type==="400")return"VideoCore VI";if(rpi.type==="5"||rpi.type==="500")return"VideoCore VII";return"VideoCore IV"}function promiseAll(promises){let resolvingPromises=promises.map((promise)=>new Promise((resolve20)=>{let payload=[,,];promise.then((result2)=>{payload[0]=result2}).catch((error2)=>{payload[1]=error2}).then(()=>{resolve20(payload)})})),errors3=[],results=[];return Promise.all(resolvingPromises).then((items)=>{return items.forEach((payload)=>{if(payload[1])errors3.push(payload[1]),results.push(null);else errors3.push(null),results.push(payload[0])}),{errors:errors3,results}})}function promisify3(nodeStyleFunction){return()=>{let args=Array.prototype.slice.call(arguments);return new Promise((resolve20,reject)=>{args.push((err,data)=>{if(err)reject(err);else resolve20(data)}),nodeStyleFunction.apply(null,args)})}}function promisifySave(nodeStyleFunction){return()=>{let args=Array.prototype.slice.call(arguments);return new Promise((resolve20)=>{args.push((err,data)=>{resolve20(data)}),nodeStyleFunction.apply(null,args)})}}function linuxVersion(){let result2="";if(_linux)try{result2=execSync18("uname -v",execOptsLinux).toString()}catch{result2=""}return result2}function plistParser(xmlStr){let tags=["array","dict","key","string","integer","date","real","data","boolean","arrayEmpty"],startStr="<plist version",pos=xmlStr.indexOf("<plist version"),len=xmlStr.length;while(xmlStr[pos]!==">"&&pos<len)pos++;let depth=0,inTagStart=!1,inTagContent=!1,inTagEnd=!1,metaData=[{tagStart:"",tagEnd:"",tagContent:"",key:"",data:null}],c="",cn=xmlStr[pos];while(pos<len){if(c=cn,pos+1<len)cn=xmlStr[pos+1];if(c==="<"){if(inTagContent=!1,cn==="/")inTagEnd=!0;else if(metaData[depth].tagStart){if(metaData[depth].tagContent="",!metaData[depth].data)metaData[depth].data=metaData[depth].tagStart==="array"?[]:{};depth++,metaData.push({tagStart:"",tagEnd:"",tagContent:"",key:null,data:null}),inTagStart=!0,inTagContent=!1}else if(!inTagStart)inTagStart=!0}else if(c===">"){if(metaData[depth].tagStart==="true/")inTagStart=!1,inTagEnd=!0,metaData[depth].tagStart="",metaData[depth].tagEnd="/boolean",metaData[depth].data=!0;if(metaData[depth].tagStart==="false/")inTagStart=!1,inTagEnd=!0,metaData[depth].tagStart="",metaData[depth].tagEnd="/boolean",metaData[depth].data=!1;if(metaData[depth].tagStart==="array/")inTagStart=!1,inTagEnd=!0,metaData[depth].tagStart="",metaData[depth].tagEnd="/arrayEmpty",metaData[depth].data=[];if(inTagContent)inTagContent=!1;if(inTagStart){if(inTagStart=!1,inTagContent=!0,metaData[depth].tagStart==="array")metaData[depth].data=[];if(metaData[depth].tagStart==="dict")metaData[depth].data={}}if(inTagEnd){if(inTagEnd=!1,metaData[depth].tagEnd&&tags.indexOf(metaData[depth].tagEnd.substr(1))>=0)if(metaData[depth].tagEnd==="/dict"||metaData[depth].tagEnd==="/array"){if(depth>1&&metaData[depth-2].tagStart==="array")metaData[depth-2].data.push(metaData[depth-1].data);if(depth>1&&metaData[depth-2].tagStart==="dict")metaData[depth-2].data[metaData[depth-1].key]=metaData[depth-1].data;depth--,metaData.pop(),metaData[depth].tagContent="",metaData[depth].tagStart="",metaData[depth].tagEnd=""}else{if(metaData[depth].tagEnd==="/key"&&metaData[depth].tagContent)metaData[depth].key=metaData[depth].tagContent;else{if(metaData[depth].tagEnd==="/real"&&metaData[depth].tagContent)metaData[depth].data=parseFloat(metaData[depth].tagContent)||0;if(metaData[depth].tagEnd==="/integer"&&metaData[depth].tagContent)metaData[depth].data=parseInt(metaData[depth].tagContent)||0;if(metaData[depth].tagEnd==="/string"&&metaData[depth].tagContent)metaData[depth].data=metaData[depth].tagContent||"";if(metaData[depth].tagEnd==="/boolean")metaData[depth].data=metaData[depth].tagContent||!1;if(metaData[depth].tagEnd==="/arrayEmpty")metaData[depth].data=metaData[depth].tagContent||[];if(depth>0&&metaData[depth-1].tagStart==="array")metaData[depth-1].data.push(metaData[depth].data);if(depth>0&&metaData[depth-1].tagStart==="dict")metaData[depth-1].data[metaData[depth].key]=metaData[depth].data}metaData[depth].tagContent="",metaData[depth].tagStart="",metaData[depth].tagEnd=""}metaData[depth].tagEnd="",inTagStart=!1,inTagContent=!1}}else{if(inTagStart)metaData[depth].tagStart+=c;if(inTagEnd)metaData[depth].tagEnd+=c;if(inTagContent)metaData[depth].tagContent+=c}pos++}return metaData[0].data}function strIsNumeric(str5){return typeof str5==="string"&&!isNaN(str5)&&!isNaN(parseFloat(str5))}function plistReader(output){let lines=output.split(`
3474
3474
  `);for(let i2=0;i2<lines.length;i2++){if(lines[i2].indexOf(" = ")>=0){let lineParts=lines[i2].split(" = ");if(lineParts[0]=lineParts[0].trim(),!lineParts[0].startsWith('"'))lineParts[0]='"'+lineParts[0]+'"';if(lineParts[1]=lineParts[1].trim(),lineParts[1].indexOf('"')===-1&&lineParts[1].endsWith(";")){let valueString=lineParts[1].substring(0,lineParts[1].length-1);if(!strIsNumeric(valueString))lineParts[1]=`"${valueString}";`}if(lineParts[1].indexOf('"')>=0&&lineParts[1].endsWith(";")){let valueString=lineParts[1].substring(0,lineParts[1].length-1).replace(/"/g,"");if(strIsNumeric(valueString))lineParts[1]=`${valueString};`}lines[i2]=lineParts.join(" : ")}if(lines[i2]=lines[i2].replace(/\(/g,"[").replace(/\)/g,"]").replace(/;/g,",").trim(),lines[i2].startsWith("}")&&lines[i2-1]&&lines[i2-1].endsWith(","))lines[i2-1]=lines[i2-1].substring(0,lines[i2-1].length-1)}output=lines.join("");let obj={};try{obj=JSON.parse(output)}catch(e){noop4()}return obj}function semverCompare(v1,v2){let res=0,parts1=v1.split("."),parts2=v2.split(".");if(parts1[0]<parts2[0])res=1;else if(parts1[0]>parts2[0])res=-1;else if(parts1[0]===parts2[0]&&parts1.length>=2&&parts2.length>=2){if(parts1[1]<parts2[1])res=1;else if(parts1[1]>parts2[1])res=-1;else if(parts1[1]===parts2[1]){if(parts1.length>=3&&parts2.length>=3){if(parts1[2]<parts2[2])res=1;else if(parts1[2]>parts2[2])res=-1}else if(parts2.length>=3)res=1}}return res}function getAppleModel(key){let list2=[{key:"Mac17,7",name:"MacBook Pro",size:"16-inch",processor:"M5 Max",year:"2026",additional:""},{key:"Mac17,6",name:"MacBook Pro",size:"14-inch",processor:"M5 Max",year:"2026",additional:""},{key:"Mac17,5",name:"MacBook Pro",size:"16-inch",processor:"M5 Pro",year:"2026",additional:""},{key:"Mac17,4",name:"MacBook Pro",size:"14-inch",processor:"M5 Pro",year:"2026",additional:""},{key:"Mac17,1",name:"MacBook Neo",size:"14-inch",processor:"A18 Pro",year:"2026",additional:""},{key:"Mac17,3",name:"MacBook Pro",size:"16-inch",processor:"M5",year:"2025",additional:""},{key:"Mac17,2",name:"MacBook Pro",size:"14-inch",processor:"M5",year:"2025",additional:""},{key:"Mac16,13",name:"MacBook Air",size:"15-inch",processor:"M4",year:"2025",additional:""},{key:"Mac16,12",name:"MacBook Air",size:"13-inch",processor:"M4",year:"2025",additional:""},{key:"Mac15,13",name:"MacBook Air",size:"15-inch",processor:"M3",year:"2024",additional:""},{key:"Mac15,12",name:"MacBook Air",size:"13-inch",processor:"M3",year:"2024",additional:""},{key:"Mac14,15",name:"MacBook Air",size:"15-inch",processor:"M2",year:"2024",additional:""},{key:"Mac14,2",name:"MacBook Air",size:"13-inch",processor:"M2",year:"2022",additional:""},{key:"MacBookAir10,1",name:"MacBook Air",size:"13-inch",processor:"M1",year:"2020",additional:""},{key:"MacBookAir9,1",name:"MacBook Air",size:"13-inch",processor:"",year:"2020",additional:""},{key:"MacBookAir8,2",name:"MacBook Air",size:"13-inch",processor:"",year:"2019",additional:""},{key:"MacBookAir8,1",name:"MacBook Air",size:"13-inch",processor:"",year:"2018",additional:""},{key:"MacBookAir7,2",name:"MacBook Air",size:"13-inch",processor:"",year:"2017",additional:""},{key:"MacBookAir7,2",name:"MacBook Air",size:"13-inch",processor:"",year:"Early 2015",additional:""},{key:"MacBookAir7,1",name:"MacBook Air",size:"11-inch",processor:"",year:"Early 2015",additional:""},{key:"MacBookAir6,2",name:"MacBook Air",size:"13-inch",processor:"",year:"Early 2014",additional:""},{key:"MacBookAir6,1",name:"MacBook Air",size:"11-inch",processor:"",year:"Early 2014",additional:""},{key:"MacBookAir6,2",name:"MacBook Air",size:"13-inch",processor:"",year:"Mid 2013",additional:""},{key:"MacBookAir6,1",name:"MacBook Air",size:"11-inch",processor:"",year:"Mid 2013",additional:""},{key:"MacBookAir5,2",name:"MacBook Air",size:"13-inch",processor:"",year:"Mid 2012",additional:""},{key:"MacBookAir5,1",name:"MacBook Air",size:"11-inch",processor:"",year:"Mid 2012",additional:""},{key:"MacBookAir4,2",name:"MacBook Air",size:"13-inch",processor:"",year:"Mid 2011",additional:""},{key:"MacBookAir4,1",name:"MacBook Air",size:"11-inch",processor:"",year:"Mid 2011",additional:""},{key:"MacBookAir3,2",name:"MacBook Air",size:"13-inch",processor:"",year:"Late 2010",additional:""},{key:"MacBookAir3,1",name:"MacBook Air",size:"11-inch",processor:"",year:"Late 2010",additional:""},{key:"MacBookAir2,1",name:"MacBook Air",size:"13-inch",processor:"",year:"Mid 2009",additional:""},{key:"Mac16,1",name:"MacBook Pro",size:"14-inch",processor:"M4",year:"2024",additional:""},{key:"Mac16,6",name:"MacBook Pro",size:"14-inch",processor:"M4 Pro",year:"2024",additional:""},{key:"Mac16,8",name:"MacBook Pro",size:"14-inch",processor:"M4 Max",year:"2024",additional:""},{key:"Mac16,5",name:"MacBook Pro",size:"16-inch",processor:"M4 Pro",year:"2024",additional:""},{key:"Mac16,6",name:"MacBook Pro",size:"16-inch",processor:"M4 Max",year:"2024",additional:""},{key:"Mac15,3",name:"MacBook Pro",size:"14-inch",processor:"M3",year:"Nov 2023",additional:""},{key:"Mac15,6",name:"MacBook Pro",size:"14-inch",processor:"M3 Pro",year:"Nov 2023",additional:""},{key:"Mac15,8",name:"MacBook Pro",size:"14-inch",processor:"M3 Pro",year:"Nov 2023",additional:""},{key:"Mac15,10",name:"MacBook Pro",size:"14-inch",processor:"M3 Max",year:"Nov 2023",additional:""},{key:"Mac15,7",name:"MacBook Pro",size:"16-inch",processor:"M3 Pro",year:"Nov 2023",additional:""},{key:"Mac15,9",name:"MacBook Pro",size:"16-inch",processor:"M3 Pro",year:"Nov 2023",additional:""},{key:"Mac15,11",name:"MacBook Pro",size:"16-inch",processor:"M3 Max",year:"Nov 2023",additional:""},{key:"Mac14,5",name:"MacBook Pro",size:"14-inch",processor:"M2 Max",year:"2023",additional:""},{key:"Mac14,9",name:"MacBook Pro",size:"14-inch",processor:"M2 Max",year:"2023",additional:""},{key:"Mac14,6",name:"MacBook Pro",size:"16-inch",processor:"M2 Max",year:"2023",additional:""},{key:"Mac14,10",name:"MacBook Pro",size:"16-inch",processor:"M2 Max",year:"2023",additional:""},{key:"Mac14,7",name:"MacBook Pro",size:"13-inch",processor:"M2",year:"2022",additional:""},{key:"MacBookPro18,3",name:"MacBook Pro",size:"14-inch",processor:"M1 Pro",year:"2021",additional:""},{key:"MacBookPro18,4",name:"MacBook Pro",size:"14-inch",processor:"M1 Max",year:"2021",additional:""},{key:"MacBookPro18,1",name:"MacBook Pro",size:"16-inch",processor:"M1 Pro",year:"2021",additional:""},{key:"MacBookPro18,2",name:"MacBook Pro",size:"16-inch",processor:"M1 Max",year:"2021",additional:""},{key:"MacBookPro17,1",name:"MacBook Pro",size:"13-inch",processor:"M1",year:"2020",additional:""},{key:"MacBookPro16,3",name:"MacBook Pro",size:"13-inch",processor:"",year:"2020",additional:"Two Thunderbolt 3 ports"},{key:"MacBookPro16,2",name:"MacBook Pro",size:"13-inch",processor:"",year:"2020",additional:"Four Thunderbolt 3 ports"},{key:"MacBookPro16,1",name:"MacBook Pro",size:"16-inch",processor:"",year:"2019",additional:""},{key:"MacBookPro16,4",name:"MacBook Pro",size:"16-inch",processor:"",year:"2019",additional:""},{key:"MacBookPro15,3",name:"MacBook Pro",size:"15-inch",processor:"",year:"2019",additional:""},{key:"MacBookPro15,2",name:"MacBook Pro",size:"13-inch",processor:"",year:"2019",additional:""},{key:"MacBookPro15,1",name:"MacBook Pro",size:"15-inch",processor:"",year:"2019",additional:""},{key:"MacBookPro15,4",name:"MacBook Pro",size:"13-inch",processor:"",year:"2019",additional:"Two Thunderbolt 3 ports"},{key:"MacBookPro15,1",name:"MacBook Pro",size:"15-inch",processor:"",year:"2018",additional:""},{key:"MacBookPro15,2",name:"MacBook Pro",size:"13-inch",processor:"",year:"2018",additional:"Four Thunderbolt 3 ports"},{key:"MacBookPro14,1",name:"MacBook Pro",size:"13-inch",processor:"",year:"2017",additional:"Two Thunderbolt 3 ports"},{key:"MacBookPro14,2",name:"MacBook Pro",size:"13-inch",processor:"",year:"2017",additional:"Four Thunderbolt 3 ports"},{key:"MacBookPro14,3",name:"MacBook Pro",size:"15-inch",processor:"",year:"2017",additional:""},{key:"MacBookPro13,1",name:"MacBook Pro",size:"13-inch",processor:"",year:"2016",additional:"Two Thunderbolt 3 ports"},{key:"MacBookPro13,2",name:"MacBook Pro",size:"13-inch",processor:"",year:"2016",additional:"Four Thunderbolt 3 ports"},{key:"MacBookPro13,3",name:"MacBook Pro",size:"15-inch",processor:"",year:"2016",additional:""},{key:"MacBookPro11,4",name:"MacBook Pro",size:"15-inch",processor:"",year:"Mid 2015",additional:""},{key:"MacBookPro11,5",name:"MacBook Pro",size:"15-inch",processor:"",year:"Mid 2015",additional:""},{key:"MacBookPro12,1",name:"MacBook Pro",size:"13-inch",processor:"",year:"Early 2015",additional:""},{key:"MacBookPro11,2",name:"MacBook Pro",size:"15-inch",processor:"",year:"Late 2013",additional:""},{key:"MacBookPro11,3",name:"MacBook Pro",size:"15-inch",processor:"",year:"Late 2013",additional:""},{key:"MacBookPro11,1",name:"MacBook Pro",size:"13-inch",processor:"",year:"Late 2013",additional:""},{key:"MacBookPro10,1",name:"MacBook Pro",size:"15-inch",processor:"",year:"Mid 2012",additional:""},{key:"MacBookPro10,2",name:"MacBook Pro",size:"13-inch",processor:"",year:"Late 2012",additional:""},{key:"MacBookPro9,1",name:"MacBook Pro",size:"15-inch",processor:"",year:"Mid 2012",additional:""},{key:"MacBookPro9,2",name:"MacBook Pro",size:"13-inch",processor:"",year:"Mid 2012",additional:""},{key:"MacBookPro8,3",name:"MacBook Pro",size:"17-inch",processor:"",year:"Early 2011",additional:""},{key:"MacBookPro8,2",name:"MacBook Pro",size:"15-inch",processor:"",year:"Early 2011",additional:""},{key:"MacBookPro8,1",name:"MacBook Pro",size:"13-inch",processor:"",year:"Early 2011",additional:""},{key:"MacBookPro6,1",name:"MacBook Pro",size:"17-inch",processor:"",year:"Mid 2010",additional:""},{key:"MacBookPro6,2",name:"MacBook Pro",size:"15-inch",processor:"",year:"Mid 2010",additional:""},{key:"MacBookPro7,1",name:"MacBook Pro",size:"13-inch",processor:"",year:"Mid 2010",additional:""},{key:"MacBookPro5,2",name:"MacBook Pro",size:"17-inch",processor:"",year:"Early 2009",additional:""},{key:"MacBookPro5,3",name:"MacBook Pro",size:"15-inch",processor:"",year:"Mid 2009",additional:""},{key:"MacBookPro5,5",name:"MacBook Pro",size:"13-inch",processor:"",year:"Mid 2009",additional:""},{key:"MacBookPro5,1",name:"MacBook Pro",size:"15-inch",processor:"",year:"Late 2008",additional:""},{key:"MacBookPro4,1",name:"MacBook Pro",size:"15-inch",processor:"",year:"Early 2008",additional:""},{key:"MacBook10,1",name:"MacBook",size:"12-inch",processor:"",year:"2017",additional:""},{key:"MacBook9,1",name:"MacBook",size:"12-inch",processor:"",year:"Early 2016",additional:""},{key:"MacBook8,1",name:"MacBook",size:"12-inch",processor:"",year:"Early 2015",additional:""},{key:"MacBook7,1",name:"MacBook",size:"13-inch",processor:"",year:"Mid 2010",additional:""},{key:"MacBook6,1",name:"MacBook",size:"13-inch",processor:"",year:"Late 2009",additional:""},{key:"MacBook5,2",name:"MacBook",size:"13-inch",processor:"",year:"Early 2009",additional:""},{key:"Mac14,13",name:"Mac Studio",size:"",processor:"M2 Max",year:"2023",additional:""},{key:"Mac14,14",name:"Mac Studio",size:"",processor:"M2 Ultra",year:"2023",additional:""},{key:"Mac15,14",name:"Mac Studio",size:"",processor:"M3 Ultra",year:"2025",additional:""},{key:"Mac16,9",name:"Mac Studio",size:"",processor:"M4 Max",year:"2025",additional:""},{key:"Mac13,1",name:"Mac Studio",size:"",processor:"M1 Max",year:"2022",additional:""},{key:"Mac13,2",name:"Mac Studio",size:"",processor:"M1 Ultra",year:"2022",additional:""},{key:"Mac16,11",name:"Mac mini",size:"",processor:"M4 Pro",year:"2024",additional:""},{key:"Mac16,10",name:"Mac mini",size:"",processor:"M4",year:"2024",additional:""},{key:"Mac14,3",name:"Mac mini",size:"",processor:"M2",year:"2023",additional:""},{key:"Mac14,12",name:"Mac mini",size:"",processor:"M2 Pro",year:"2023",additional:""},{key:"Macmini9,1",name:"Mac mini",size:"",processor:"M1",year:"2020",additional:""},{key:"Macmini8,1",name:"Mac mini",size:"",processor:"",year:"Late 2018",additional:""},{key:"Macmini7,1",name:"Mac mini",size:"",processor:"",year:"Late 2014",additional:""},{key:"Macmini6,1",name:"Mac mini",size:"",processor:"",year:"Late 2012",additional:""},{key:"Macmini6,2",name:"Mac mini",size:"",processor:"",year:"Late 2012",additional:""},{key:"Macmini5,1",name:"Mac mini",size:"",processor:"",year:"Mid 2011",additional:""},{key:"Macmini5,2",name:"Mac mini",size:"",processor:"",year:"Mid 2011",additional:""},{key:"Macmini4,1",name:"Mac mini",size:"",processor:"",year:"Mid 2010",additional:""},{key:"Macmini3,1",name:"Mac mini",size:"",processor:"",year:"Early 2009",additional:""},{key:"Mac16,3",name:"iMac",size:"24-inch",processor:"M4",year:"2024",additional:"Four ports"},{key:"Mac16,2",name:"iMac",size:"24-inch",processor:"M4",year:"2024",additional:"Two ports"},{key:"Mac15,5",name:"iMac",size:"24-inch",processor:"M3",year:"2023",additional:"Four ports"},{key:"Mac15,4",name:"iMac",size:"24-inch",processor:"M3",year:"2023",additional:"Two ports"},{key:"iMac21,1",name:"iMac",size:"24-inch",processor:"M1",year:"2021",additional:""},{key:"iMac21,2",name:"iMac",size:"24-inch",processor:"M1",year:"2021",additional:""},{key:"iMac20,1",name:"iMac",size:"27-inch",processor:"",year:"2020",additional:"Retina 5K"},{key:"iMac20,2",name:"iMac",size:"27-inch",processor:"",year:"2020",additional:"Retina 5K"},{key:"iMac19,1",name:"iMac",size:"27-inch",processor:"",year:"2019",additional:"Retina 5K"},{key:"iMac19,2",name:"iMac",size:"21.5-inch",processor:"",year:"2019",additional:"Retina 4K"},{key:"iMacPro1,1",name:"iMac Pro",size:"",processor:"",year:"2017",additional:""},{key:"iMac18,3",name:"iMac",size:"27-inch",processor:"",year:"2017",additional:"Retina 5K"},{key:"iMac18,2",name:"iMac",size:"21.5-inch",processor:"",year:"2017",additional:"Retina 4K"},{key:"iMac18,1",name:"iMac",size:"21.5-inch",processor:"",year:"2017",additional:""},{key:"iMac17,1",name:"iMac",size:"27-inch",processor:"",year:"Late 2015",additional:"Retina 5K"},{key:"iMac16,2",name:"iMac",size:"21.5-inch",processor:"",year:"Late 2015",additional:"Retina 4K"},{key:"iMac16,1",name:"iMac",size:"21.5-inch",processor:"",year:"Late 2015",additional:""},{key:"iMac15,1",name:"iMac",size:"27-inch",processor:"",year:"Late 2014",additional:"Retina 5K"},{key:"iMac14,4",name:"iMac",size:"21.5-inch",processor:"",year:"Mid 2014",additional:""},{key:"iMac14,2",name:"iMac",size:"27-inch",processor:"",year:"Late 2013",additional:""},{key:"iMac14,1",name:"iMac",size:"21.5-inch",processor:"",year:"Late 2013",additional:""},{key:"iMac13,2",name:"iMac",size:"27-inch",processor:"",year:"Late 2012",additional:""},{key:"iMac13,1",name:"iMac",size:"21.5-inch",processor:"",year:"Late 2012",additional:""},{key:"iMac12,2",name:"iMac",size:"27-inch",processor:"",year:"Mid 2011",additional:""},{key:"iMac12,1",name:"iMac",size:"21.5-inch",processor:"",year:"Mid 2011",additional:""},{key:"iMac11,3",name:"iMac",size:"27-inch",processor:"",year:"Mid 2010",additional:""},{key:"iMac11,2",name:"iMac",size:"21.5-inch",processor:"",year:"Mid 2010",additional:""},{key:"iMac10,1",name:"iMac",size:"21.5-inch",processor:"",year:"Late 2009",additional:""},{key:"iMac9,1",name:"iMac",size:"20-inch",processor:"",year:"Early 2009",additional:""},{key:"Mac14,8",name:"Mac Pro",size:"",processor:"",year:"2023",additional:""},{key:"Mac14,8",name:"Mac Pro",size:"",processor:"",year:"2023",additional:"Rack"},{key:"MacPro7,1",name:"Mac Pro",size:"",processor:"",year:"2019",additional:""},{key:"MacPro7,1",name:"Mac Pro",size:"",processor:"",year:"2019",additional:"Rack"},{key:"MacPro6,1",name:"Mac Pro",size:"",processor:"",year:"Late 2013",additional:""},{key:"MacPro5,1",name:"Mac Pro",size:"",processor:"",year:"Mid 2012",additional:""},{key:"MacPro5,1",name:"Mac Pro Server",size:"",processor:"",year:"Mid 2012",additional:"Server"},{key:"MacPro5,1",name:"Mac Pro",size:"",processor:"",year:"Mid 2010",additional:""},{key:"MacPro5,1",name:"Mac Pro Server",size:"",processor:"",year:"Mid 2010",additional:"Server"},{key:"MacPro4,1",name:"Mac Pro",size:"",processor:"",year:"Early 2009",additional:""}].filter((model)=>model.key===key);if(list2.length===0)return{key,model:"Apple",version:"Unknown"};let features=[];if(list2[0].size)features.push(list2[0].size);if(list2[0].processor)features.push(list2[0].processor);if(list2[0].year)features.push(list2[0].year);if(list2[0].additional)features.push(list2[0].additional);return{key,model:list2[0].name,version:list2[0].name+" ("+features.join(", ")+")"}}function checkWebsite(url,timeout=5000){let http=url.startsWith("https:")||url.indexOf(":443/")>0||url.indexOf(":8443/")>0?__require("https"):__require("http"),t2=Date.now();return new Promise((resolve20)=>{let request=http.get(url,(res)=>{res.on("data",()=>{}),res.on("end",()=>{resolve20({url,statusCode:res.statusCode,message:res.statusMessage,time:Date.now()-t2})})}).on("error",(e)=>{resolve20({url,statusCode:404,message:e.message,time:Date.now()-t2})}).setTimeout(timeout,()=>{request.destroy(),resolve20({url,statusCode:408,message:"Request Timeout",time:Date.now()-t2})})})}function cleanString(str5){return str5.replace(/To Be Filled By O.E.M./g,"")}function noop4(){}exports.toInt=toInt;exports.splitByNumber=splitByNumber;exports.execOptsWin=execOptsWin;exports.execOptsLinux=execOptsLinux;exports.getCodepage=getCodepage;exports.execWin=execWin;exports.isFunction=isFunction;exports.unique=unique;exports.sortByKey=sortByKey;exports.cores=cores;exports.getValue=getValue;exports.decodeEscapeSequence=decodeEscapeSequence;exports.parseDateTime=parseDateTime;exports.parseHead=parseHead;exports.findObjectByKey=findObjectByKey;exports.darwinXcodeExists=darwinXcodeExists;exports.getVboxmanage=getVboxmanage;exports.powerShell=powerShell;exports.powerShellStart=powerShellStart;exports.powerShellRelease=powerShellRelease;exports.execSafe=execSafe;exports.nanoSeconds=nanoSeconds;exports.countUniqueLines=countUniqueLines;exports.countLines=countLines;exports.noop=noop4;exports.isRaspberry=isRaspberry;exports.isRaspbian=isRaspbian;exports.sanitizeShellString=sanitizeShellString;exports.isPrototypePolluted=isPrototypePolluted;exports.decodePiCpuinfo=decodePiCpuinfo;exports.getRpiGpu=getRpiGpu;exports.promiseAll=promiseAll;exports.promisify=promisify3;exports.promisifySave=promisifySave;exports.smartMonToolsInstalled=smartMonToolsInstalled;exports.linuxVersion=linuxVersion;exports.plistParser=plistParser;exports.plistReader=plistReader;exports.stringObj=stringObj;exports.stringReplace=stringReplace;exports.stringToLower=stringToLower;exports.stringToString=stringToString;exports.stringSubstr=stringSubstr;exports.stringSubstring=stringSubstring;exports.stringTrim=stringTrim;exports.stringStartWith=stringStartWith;exports.mathMin=mathMin;exports.WINDIR=WINDIR;exports.getFilesInPath=getFilesInPath;exports.semverCompare=semverCompare;exports.getAppleModel=getAppleModel;exports.checkWebsite=checkWebsite;exports.cleanString=cleanString;exports.getPowershell=getPowershell});var require_osinfo=__commonJS((exports)=>{var os4=__require("os"),fs3=__require("fs"),util4=require_util3(),exec3=__require("child_process").exec,execSync18=__require("child_process").execSync,_platform=process.platform,_linux=_platform==="linux"||_platform==="android",_darwin=_platform==="darwin",_windows=_platform==="win32",_freebsd=_platform==="freebsd",_openbsd=_platform==="openbsd",_netbsd=_platform==="netbsd",_sunos=_platform==="sunos";function time(){let t2=new Date().toString().split(" "),timezoneName="";try{timezoneName=Intl.DateTimeFormat().resolvedOptions().timeZone}catch{timezoneName=t2.length>=7?t2.slice(6).join(" ").replace(/\(/g,"").replace(/\)/g,""):""}let result2={current:Date.now(),uptime:os4.uptime(),timezone:t2.length>=7?t2[5]:"",timezoneName};if(_darwin||_linux)try{let lines=execSync18("date +%Z && date +%z && ls -l /etc/localtime 2>/dev/null",util4.execOptsLinux).toString().split(os4.EOL);if(lines.length>3&&!lines[0])lines.shift();let timezone=lines[0]||"";if(timezone.startsWith("+")||timezone.startsWith("-"))timezone="GMT";return{current:Date.now(),uptime:os4.uptime(),timezone:lines[1]?timezone+lines[1]:timezone,timezoneName:lines[2]&&lines[2].indexOf("/zoneinfo/")>0?lines[2].split("/zoneinfo/")[1]||"":""}}catch{util4.noop()}return result2}exports.time=time;function getLogoFile(distro){distro=distro||"",distro=distro.toLowerCase();let result2=_platform;if(_windows)result2="windows";else if(distro.indexOf("mac os")!==-1||distro.indexOf("macos")!==-1)result2="apple";else if(distro.indexOf("arch")!==-1)result2="arch";else if(distro.indexOf("cachy")!==-1)result2="cachy";else if(distro.indexOf("centos")!==-1)result2="centos";else if(distro.indexOf("coreos")!==-1)result2="coreos";else if(distro.indexOf("debian")!==-1)result2="debian";else if(distro.indexOf("deepin")!==-1)result2="deepin";else if(distro.indexOf("elementary")!==-1)result2="elementary";else if(distro.indexOf("endeavour")!==-1)result2="endeavour";else if(distro.indexOf("fedora")!==-1)result2="fedora";else if(distro.indexOf("gentoo")!==-1)result2="gentoo";else if(distro.indexOf("mageia")!==-1)result2="mageia";else if(distro.indexOf("mandriva")!==-1)result2="mandriva";else if(distro.indexOf("manjaro")!==-1)result2="manjaro";else if(distro.indexOf("mint")!==-1)result2="mint";else if(distro.indexOf("mx")!==-1)result2="mx";else if(distro.indexOf("openbsd")!==-1)result2="openbsd";else if(distro.indexOf("freebsd")!==-1)result2="freebsd";else if(distro.indexOf("opensuse")!==-1)result2="opensuse";else if(distro.indexOf("pclinuxos")!==-1)result2="pclinuxos";else if(distro.indexOf("puppy")!==-1)result2="puppy";else if(distro.indexOf("popos")!==-1)result2="popos";else if(distro.indexOf("raspbian")!==-1)result2="raspbian";else if(distro.indexOf("reactos")!==-1)result2="reactos";else if(distro.indexOf("redhat")!==-1)result2="redhat";else if(distro.indexOf("slackware")!==-1)result2="slackware";else if(distro.indexOf("sugar")!==-1)result2="sugar";else if(distro.indexOf("steam")!==-1)result2="steam";else if(distro.indexOf("suse")!==-1)result2="suse";else if(distro.indexOf("mate")!==-1)result2="ubuntu-mate";else if(distro.indexOf("lubuntu")!==-1)result2="lubuntu";else if(distro.indexOf("xubuntu")!==-1)result2="xubuntu";else if(distro.indexOf("ubuntu")!==-1)result2="ubuntu";else if(distro.indexOf("solaris")!==-1)result2="solaris";else if(distro.indexOf("tails")!==-1)result2="tails";else if(distro.indexOf("feren")!==-1)result2="ferenos";else if(distro.indexOf("robolinux")!==-1)result2="robolinux";else if(_linux&&distro)result2=distro.toLowerCase().trim().replace(/\s+/g,"-");return result2}var WINDOWS_RELEASES=[[26200,"25H2"],[26100,"24H2"],[22631,"23H2"],[22621,"22H2"],[19045,"22H2"],[22000,"21H2"],[19044,"21H2"],[19043,"21H1"],[19042,"20H2"],[19041,"2004"],[18363,"1909"],[18362,"1903"],[17763,"1809"],[17134,"1803"]];function getWindowsRelease(build){for(let[minBuild,label]of WINDOWS_RELEASES)if(build>=minBuild)return label;return""}function getFQDN(){let fqdn=os4.hostname;if(_linux||_darwin)try{fqdn=execSync18("hostname -f 2>/dev/null",util4.execOptsLinux).toString().split(os4.EOL)[0]}catch{util4.noop()}if(_freebsd||_openbsd||_netbsd)try{fqdn=execSync18("hostname 2>/dev/null").toString().split(os4.EOL)[0]}catch{util4.noop()}if(_windows)try{fqdn=execSync18("echo %COMPUTERNAME%.%USERDNSDOMAIN%",util4.execOptsWin).toString().replace(".%USERDNSDOMAIN%","").split(os4.EOL)[0]}catch{util4.noop()}return fqdn}function osInfo(callback){return new Promise((resolve20)=>{process.nextTick(()=>{let result2={platform:_platform==="win32"?"Windows":_platform,distro:"unknown",release:"unknown",codename:"",kernel:os4.release(),arch:os4.arch(),hostname:os4.hostname(),fqdn:getFQDN(),codepage:"",logofile:"",serial:"",build:"",servicepack:"",uefi:!1};if(_linux)exec3("cat /etc/*-release; cat /usr/lib/os-release; cat /etc/openwrt_release",(error2,stdout)=>{let release={};stdout.toString().split(`
3475
3475
  `).forEach((line)=>{if(line.indexOf("=")!==-1)release[line.split("=")[0].trim().toUpperCase()]=line.split("=")[1].trim()}),result2.distro=(release.DISTRIB_ID||release.NAME||"unknown").replace(/"/g,""),result2.logofile=getLogoFile(result2.distro);let releaseVersion=(release.VERSION||"").replace(/"/g,""),codename=(release.DISTRIB_CODENAME||release.VERSION_CODENAME||"").replace(/"/g,""),prettyName=(release.PRETTY_NAME||"").replace(/"/g,"");if(prettyName.indexOf(result2.distro+" ")===0)releaseVersion=prettyName.replace(result2.distro+" ","").trim();if(releaseVersion.indexOf("(")>=0)codename=releaseVersion.split("(")[1].replace(/[()]/g,"").trim(),releaseVersion=releaseVersion.split("(")[0].trim();result2.release=(releaseVersion||release.DISTRIB_RELEASE||release.VERSION_ID||"unknown").replace(/"/g,""),result2.codename=codename,result2.codepage=util4.getCodepage(),result2.build=(release.BUILD_ID||"").replace(/"/g,"").trim(),isUefiLinux().then((uefi)=>{result2.uefi=uefi,uuid().then((data)=>{if(result2.serial=data.os,callback)callback(result2);resolve20(result2)})})});if(_freebsd||_openbsd||_netbsd)exec3("sysctl kern.ostype kern.osrelease kern.osrevision kern.hostuuid machdep.bootmethod kern.geom.confxml",(error2,stdout)=>{let lines=stdout.toString().split(`
@@ -3924,7 +3924,18 @@ ${yamlStr}---`)}function buildDirResolveContext(agentName){let ctx={};try{let ws
3924
3924
  No agents registered. Add one with: genie dir add <name> --dir <path>`),console.log(`Use --builtins to also see built-in roles and council members.
3925
3925
  `);return}if(entries.length>0)printRegisteredTable(entries),printResolvedTable(entries);if(includeBuiltins)printBuiltinsTable()}function listEntriesJson(entries,includeBuiltins){let result2=entries.map((e)=>({...e,builtin:!1}));if(includeBuiltins)for(let b2 of ALL_BUILTINS)result2.push({name:b2.name,description:b2.description,model:b2.model,category:b2.category,scope:"built-in",builtin:!0});let{writeSync}=__require("fs"),data=`${JSON.stringify(result2,null,2)}
3926
3926
  `,CHUNK=4096;for(let i2=0;i2<data.length;i2+=CHUNK)writeSync(1,data.slice(i2,i2+CHUNK))}function registerSdkFlags(cmd){cmd.option("--sdk-permission-mode <mode>","SDK permission mode: default|acceptEdits|bypassPermissions|plan|dontAsk|auto").option("--sdk-tools <list>","SDK tools: comma-separated tool names").option("--sdk-allowed-tools <list>","SDK auto-approved tools: comma-separated").option("--sdk-disallowed-tools <list>","SDK blacklisted tools: comma-separated").option("--sdk-max-turns <n>","SDK max conversation turns").option("--sdk-max-budget <usd>","SDK max budget in USD").option("--sdk-effort <level>","SDK effort: low|medium|high|max").option("--sdk-thinking <config>","SDK thinking: adaptive|disabled|enabled[:budgetTokens]").option("--sdk-persist-session","SDK: enable session persistence").option("--no-sdk-persist-session","SDK: disable session persistence").option("--sdk-file-checkpointing","SDK: enable file checkpointing").option("--sdk-output-format <path>","SDK: path to JSON schema file for output format").option("--sdk-stream-partial","SDK: include partial messages in stream").option("--sdk-hook-events","SDK: include hook events in stream").option("--sdk-prompt-suggestions","SDK: enable prompt suggestions").option("--sdk-progress-summaries","SDK: enable agent progress summaries").option("--sdk-sandbox","SDK: enable sandbox").option("--sdk-betas <list>","SDK beta flags: comma-separated").option("--sdk-system-prompt <string>","SDK system prompt text").option("--sdk-mcp-server <spec>","SDK MCP server: name:command:args (repeatable)",collectRepeat,[]).option("--sdk-plugin <path>","SDK plugin path (repeatable)",collectRepeat,[]).option("--sdk-agent <name>","SDK main agent name").option("--sdk-subagent <spec>","SDK subagent: name:json (repeatable)",collectRepeat,[])}function collectRepeat(value,previous){return previous.concat([value])}function buildSdkConfig(options){let config={};return applyScalarSdkOptions(config,options),applyBooleanSdkOptions(config,options),applyRepeatableSdkOptions(config,options),Object.keys(config).length>0?config:void 0}function toSafeNumber(value,flagName){let n=Number(value);if(Number.isNaN(n))throw Error(`${flagName} must be a number, got: ${value}`);return n}function applyScalarSdkOptions(config,options){if(options.sdkPermissionMode!==void 0)config.permissionMode=options.sdkPermissionMode;if(options.sdkTools!==void 0)config.tools=splitComma(options.sdkTools);if(options.sdkAllowedTools!==void 0)config.allowedTools=splitComma(options.sdkAllowedTools);if(options.sdkDisallowedTools!==void 0)config.disallowedTools=splitComma(options.sdkDisallowedTools);if(options.sdkMaxTurns!==void 0)config.maxTurns=toSafeNumber(options.sdkMaxTurns,"--sdk-max-turns");if(options.sdkMaxBudget!==void 0)config.maxBudgetUsd=toSafeNumber(options.sdkMaxBudget,"--sdk-max-budget");if(options.sdkEffort!==void 0)config.effort=options.sdkEffort;if(options.sdkThinking!==void 0)config.thinking=parseThinkingConfig(options.sdkThinking);if(options.sdkBetas!==void 0)config.betas=splitComma(options.sdkBetas);if(options.sdkSystemPrompt!==void 0)config.systemPrompt=options.sdkSystemPrompt;if(options.sdkAgent!==void 0)config.agent=options.sdkAgent;if(options.sdkOutputFormat!==void 0)config.outputFormat={type:"json_schema",schema:{$ref:options.sdkOutputFormat}}}function applyBooleanSdkOptions(config,options){if(options.sdkPersistSession!==void 0)config.persistSession=options.sdkPersistSession;if(options.sdkFileCheckpointing===!0)config.enableFileCheckpointing=!0;if(options.sdkStreamPartial===!0)config.includePartialMessages=!0;if(options.sdkHookEvents===!0)config.includeHookEvents=!0;if(options.sdkPromptSuggestions===!0)config.promptSuggestions=!0;if(options.sdkProgressSummaries===!0)config.agentProgressSummaries=!0;if(options.sdkSandbox===!0)config.sandbox={enabled:!0}}function applyRepeatableSdkOptions(config,options){if(options.sdkMcpServer&&options.sdkMcpServer.length>0){config.mcpServers={};for(let spec of options.sdkMcpServer){let parsed=parseMcpServer(spec);config.mcpServers[parsed.name]=parsed.config}}if(options.sdkPlugin&&options.sdkPlugin.length>0)config.plugins=options.sdkPlugin.map((p)=>({type:"local",path:p}));if(options.sdkSubagent&&options.sdkSubagent.length>0)config.agents=parseSubagents(options.sdkSubagent)}function parseSubagents(specs){let agents={};for(let spec of specs){let colonIdx=spec.indexOf(":");if(colonIdx===-1)throw Error(`Invalid --sdk-subagent format: "${spec}". Expected "name:json".`);let agentName=spec.slice(0,colonIdx),jsonStr=spec.slice(colonIdx+1);try{agents[agentName]=JSON.parse(jsonStr)}catch{throw Error(`Invalid JSON in --sdk-subagent "${agentName}": ${jsonStr}`)}}return agents}function parseThinkingConfig(value){if(value==="adaptive")return{type:"adaptive"};if(value==="disabled")return{type:"disabled"};if(value==="enabled")return{type:"enabled"};if(value.startsWith("enabled:"))return{type:"enabled",budgetTokens:toSafeNumber(value.slice(8),"--sdk-thinking budgetTokens")};throw Error(`Invalid --sdk-thinking value: "${value}". Expected adaptive|disabled|enabled[:budgetTokens].`)}function parseMcpServer(spec){let firstColon=spec.indexOf(":");if(firstColon===-1)throw Error(`Invalid --sdk-mcp-server format: "${spec}". Expected "name:command:args".`);let name=spec.slice(0,firstColon),rest=spec.slice(firstColon+1),secondColon=rest.indexOf(":");if(secondColon===-1)throw Error(`Invalid --sdk-mcp-server format: "${spec}". Expected "name:command:args".`);let command=rest.slice(0,secondColon),argsStr=rest.slice(secondColon+1),args=argsStr?argsStr.split(",").map((s)=>s.trim()).filter(Boolean):[];return{name,config:{type:"stdio",command,args}}}function splitComma(value){return value.split(",").map((s)=>s.trim()).filter(Boolean)}function printSdkConfig(sdk){console.log(" SDK Config:");let lines=collectSdkDisplayLines(sdk);for(let line of lines)console.log(` ${line}`)}function collectSdkDisplayLines(sdk){let lines=[];if(sdk.permissionMode)lines.push(`Permission Mode: ${sdk.permissionMode}`);if(sdk.tools)lines.push(`Tools: ${Array.isArray(sdk.tools)?sdk.tools.join(", "):`preset:${sdk.tools.preset}`}`);if(sdk.allowedTools?.length)lines.push(`Allowed Tools: ${sdk.allowedTools.join(", ")}`);if(sdk.disallowedTools?.length)lines.push(`Disallowed Tools: ${sdk.disallowedTools.join(", ")}`);if(sdk.maxTurns!==void 0)lines.push(`Max Turns: ${sdk.maxTurns}`);if(sdk.maxBudgetUsd!==void 0)lines.push(`Max Budget: $${sdk.maxBudgetUsd.toFixed(2)}`);if(sdk.effort)lines.push(`Effort: ${sdk.effort}`);if(sdk.thinking)lines.push(`Thinking: ${formatThinking(sdk.thinking)}`);if(sdk.agent)lines.push(`Agent: ${sdk.agent}`);if(sdk.persistSession!==void 0)lines.push(`Persist Session: ${sdk.persistSession}`);if(sdk.enableFileCheckpointing)lines.push("File Checkpointing: enabled");if(sdk.outputFormat)lines.push(`Output Format: ${JSON.stringify(sdk.outputFormat.schema)}`);return collectSdkBooleanLines(sdk,lines),collectSdkComplexLines(sdk,lines),lines}function collectSdkBooleanLines(sdk,lines){if(sdk.includePartialMessages)lines.push("Stream Partial: enabled");if(sdk.includeHookEvents)lines.push("Hook Events: enabled");if(sdk.promptSuggestions)lines.push("Prompt Suggestions: enabled");if(sdk.agentProgressSummaries)lines.push("Progress Summaries: enabled");if(sdk.sandbox?.enabled)lines.push("Sandbox: enabled");if(sdk.betas?.length)lines.push(`Betas: ${sdk.betas.join(", ")}`)}function collectSdkComplexLines(sdk,lines){if(sdk.systemPrompt){let prompt2=typeof sdk.systemPrompt==="string"?sdk.systemPrompt:`preset:${sdk.systemPrompt.preset}`;lines.push(`System Prompt: ${prompt2.length>60?`${prompt2.slice(0,60)}...`:prompt2}`)}if(sdk.mcpServers)lines.push(`MCP Servers: ${Object.keys(sdk.mcpServers).join(", ")}`);if(sdk.plugins?.length)lines.push(`Plugins: ${sdk.plugins.map((p)=>p.path).join(", ")}`);if(sdk.agents)lines.push(`Subagents: ${Object.keys(sdk.agents).join(", ")}`)}function formatThinking(thinking){if(thinking.type==="enabled"&&thinking.budgetTokens)return`enabled:${thinking.budgetTokens}`;return thinking.type}function buildPermissions(permissionPreset,allow,bashAllow){if(!permissionPreset&&!allow&&!bashAllow)return;if(permissionPreset)return{preset:permissionPreset};return{...allow&&{allow:allow.split(",").map((s)=>s.trim()).filter(Boolean)},...bashAllow&&{bashAllowPatterns:bashAllow.split(",").map((s)=>s.trim()).filter(Boolean)}}}function normalizeRoles(roles){if(!roles)return;return roles.flatMap((r)=>r.split(",")).map((r)=>r.trim()).filter(Boolean)}function printRegisteredTable(entries){let repoValues=[],roleValues=[];for(let entry2 of entries)repoValues.push(entry2.repo?contractPath(entry2.repo):contractPath(entry2.dir)),roleValues.push(entry2.roles?.join(", ")||"-");let termW=process.stdout.columns||120,fixedW=54,maxRepoLen=Math.max(4,...repoValues.map((v)=>v.length)),repoW=Math.min(maxRepoLen+2,Math.max(30,termW-fixedW-20)),totalW=fixedW+repoW+20;console.log(""),console.log("REGISTERED AGENTS"),console.log("-".repeat(Math.max(90,totalW))),console.log(` ${"NAME".padEnd(22)}${"SCOPE".padEnd(10)}${"REPO".padEnd(repoW)}${"MODEL".padEnd(10)}${"PROVIDER".padEnd(10)}ROLES`),console.log(` ${"-".repeat(20)} ${"-".repeat(8)} ${"-".repeat(repoW-2)} ${"-".repeat(8)} ${"-".repeat(8)} ${"-".repeat(20)}`);for(let i2=0;i2<entries.length;i2++){let entry2=entries[i2],repo=repoValues[i2],roles=roleValues[i2];console.log(` ${entry2.name.padEnd(22)}${entry2.scope.padEnd(10)}${repo.padEnd(repoW)}${(entry2.model||"-").padEnd(10)}${(entry2.provider||"-").padEnd(10)}${roles}`)}console.log("")}function printResolvedTable(entries){if(entries.length===0)return;let nameW=22,declW=14,resolvedW=14;console.log("RESOLVED DEFAULTS"),console.log("-".repeat(70));for(let field of RESOLVED_FIELDS){let fieldUpper=field.toUpperCase();console.log(` ${"AGENT".padEnd(nameW)}${`${fieldUpper} (declared)`.padEnd(declW)}${`${fieldUpper} (resolved)`.padEnd(resolvedW)}SOURCE`),console.log(` ${"-".repeat(nameW-2)} ${"-".repeat(declW-2)} ${"-".repeat(resolvedW-2)} ${"-".repeat(16)}`);for(let entry2 of entries){let ctx=buildDirResolveContext(entry2.name),result2=resolveFieldWithSource(entry2,field,ctx),declared=entry2[field]||"-";console.log(` ${entry2.name.padEnd(nameW)}${declared.padEnd(declW)}${result2.value.padEnd(resolvedW)}${result2.source}`)}}console.log("")}function printBuiltinsTable(){console.log("BUILT-IN AGENTS"),console.log("-".repeat(80)),console.log(` ${"NAME".padEnd(22)}${"TYPE".padEnd(10)}${"MODEL".padEnd(8)}DESCRIPTION`),console.log(` ${"-".repeat(20)} ${"-".repeat(8)} ${"-".repeat(6)} ${"-".repeat(30)}`);for(let agent of ALL_BUILTINS)console.log(` ${agent.name.padEnd(22)}${agent.category.padEnd(10)}${(agent.model||"-").padEnd(8)}${agent.description}`);console.log("")}function validatePromptMode2(mode){if(mode!=="system"&&mode!=="append")throw Error(`Invalid prompt mode "${mode}". Must be "append" or "system".`);return mode}function normalizeRoles2(roles){if(!roles)return;return roles.flatMap((r)=>r.split(",")).map((r)=>r.trim()).filter(Boolean)}function printEntry2(entry2){if(console.log(` Name: ${entry2.name}`),console.log(` Dir: ${contractPath(entry2.dir)}`),entry2.repo)console.log(` Repo: ${contractPath(entry2.repo)}`);if(console.log(` Prompt mode: ${entry2.promptMode}`),entry2.model)console.log(` Model: ${entry2.model}`);if(entry2.roles?.length)console.log(` Roles: ${entry2.roles.join(", ")}`);console.log(` Registered: ${entry2.registeredAt}`)}async function handleOmniRegistration(name,options){let omniUrl=await resolveOmniApiUrl();if(!omniUrl)return;console.log(`
3927
- Registering in Omni (${omniUrl})...`);let existingId=await findOmniAgent(name);if(existingId){console.log(` Agent already exists in Omni: ${existingId}`),await edit(name,{omniAgentId:existingId},{global:options.global}),console.log(" Linked existing Omni agent to directory entry.");return}let omniAgentId=await registerAgentInOmni(name,{model:options.model,roles:options.roles});if(omniAgentId)await edit(name,{omniAgentId},{global:options.global}),console.log(` Omni agent created: ${omniAgentId}`),console.log(" Session isolation: per-person + per-channel")}async function handleAgentRegister(name,options){let promptMode=validatePromptMode2(options.promptMode);if(options.repo)validateRepoPath(options.repo);let roles=normalizeRoles2(options.roles),entry2=await add({name,dir:resolvePath3(options.dir),repo:options.repo?resolvePath3(options.repo):void 0,promptMode,model:options.model,roles},{global:options.global}),scope=options.global?"global":"project";if(console.log(`Agent "${entry2.name}" registered (${scope}).`),printEntry2(entry2),!options.skipOmni)await handleOmniRegistration(name,{...options,roles})}function registerAgentRegister(parent){parent.command("register <name>").description("Register an agent locally and auto-register in Omni when configured").requiredOption("--dir <path>","Agent folder (CWD + AGENTS.md)").option("--repo <path>","Default git repo (overridden by team)").option("--prompt-mode <mode>","Prompt mode: append or system","append").option("--model <model>","Default model (sonnet, opus, codex)").option("--roles <roles...>","Built-in roles this agent can orchestrate").option("--global","Write to global directory instead of project").option("--skip-omni","Skip Omni auto-registration").action(async(name,options)=>{try{await handleAgentRegister(name,options)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}init_agents();function registerAgentResume(parent){parent.command("resume [name]").description("Resume a suspended/failed agent with its Claude session").option("--all","Resume all eligible agents").option("--no-reset-attempts","Preserve resumeAttempts counter (scheduler auto-resume use)").action(async(name,options)=>{try{await handleWorkerResume(name,{all:options.all,noResetAttempts:options.resetAttempts===!1})}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}init_msg();function registerAgentSend(parent){parent.command("send <body>").description("Send a direct message to an agent (hierarchy-enforced)").option("--to <agent>","Recipient agent name (default: team leader)","team-lead").option("--from <sender>","Sender ID (auto-detected from context)").option("--team <name>","Explicit team context for sender/recipient resolution").option("--broadcast","Send to all direct reports").action(async(body,options)=>{try{let from=options.from??await detectSenderIdentity(options.team);if(options.broadcast){await handleBroadcast2(from,body,options.team);return}await handleDirectMessage(from,options.to,body,options.team)}catch(error2){console.error(`Error: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}})}async function isTeamLeader(agentName,teamName){try{let{resolveLeaderName:resolveLeaderName2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),leaderName=await resolveLeaderName2(teamName);return agentName===leaderName}catch{return!1}}async function checkHierarchy(from,to){if(isCliSender(from))return{allowed:!0};if(from===to)return{allowed:!0};try{let agents=await(await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry))).listAgents({}),sender=agents.find((a)=>a.customName===from||a.role===from||a.id===from),recipient=agents.find((a)=>a.customName===to||a.role===to||a.id===to);if(!sender||!recipient)return{allowed:!0};if(recipient.reportsTo===from||recipient.reportsTo===sender.id)return{allowed:!0};if(sender.reportsTo===to||sender.reportsTo===recipient.id)return{allowed:!0};if(sender.reportsTo&&sender.reportsTo===recipient.reportsTo)return{allowed:!0};if(sender.team&&sender.team===recipient.team&&await isTeamLeader(from,sender.team))return{allowed:!0};let manager=sender.reportsTo??"your manager";return{allowed:!1,reason:`Cannot reach "${to}". Escalate to ${manager}.`}}catch{return{allowed:!0}}}async function handleDirectMessage(from,to,body,team){let{allowed,reason}=await checkHierarchy(from,to);if(!allowed)console.error(`Error: ${reason}`),process.exit(1);let{checkSendScope:checkSendScope2}=await Promise.resolve().then(() => (init_msg(),exports_msg)),repoPath=process.cwd(),scopeError=await checkSendScope2(repoPath,from,to);if(scopeError)console.error(`Error: ${scopeError}`),process.exit(1);let taskService=await Promise.resolve().then(() => (init_task_service(),exports_task_service)),mailbox=await Promise.resolve().then(() => (init_mailbox(),exports_mailbox)),senderActor={actorType:"local",actorId:from},recipientActor={actorType:"local",actorId:to},conv=await taskService.findOrCreateConversation({type:"dm",members:[senderActor,recipientActor],createdBy:senderActor});await taskService.addMember(conv.id,senderActor),await taskService.addMember(conv.id,recipientActor),await mailbox.send(repoPath,from,to,body);let msg=await taskService.sendMessage(conv.id,senderActor,body);try{let{publishSubjectEvent:publishSubjectEvent2}=await Promise.resolve().then(() => (init_runtime_events(),exports_runtime_events));await publishSubjectEvent2(repoPath,`genie.msg.${to}`,{kind:"message",agent:from,direction:"out",peer:to,text:body,data:{messageId:msg.id,conversationId:conv.id,from,to},source:"mailbox"})}catch{}try{let nativeTeams=await Promise.resolve().then(() => (init_claude_native_teams(),exports_claude_native_teams)),nativeMsg={from,text:body,summary:body.length>50?`${body.substring(0,50)}...`:body,timestamp:new Date().toISOString(),color:"blue",read:!1},currentTeam=team??process.env.GENIE_TEAM;if(currentTeam){let nativeName=await nativeTeams.resolveNativeMemberName(currentTeam,to);if(nativeName)await nativeTeams.writeNativeInbox(currentTeam,nativeName,nativeMsg)}}catch{}console.log(`Message sent to "${to}".`),console.log(` ID: ${msg.id}`),console.log(` Conversation: ${conv.id}`)}async function deliverBroadcastToMembers(deps,repoPath,from,teamName,body){let members=await deps.listMembers(teamName)??[],results=[];for(let member of members){if(member===from)continue;try{let r=await deps.sendMessage(repoPath,from,member,body,teamName);results.push({member,delivered:r.delivered,reason:r.reason})}catch(err){results.push({member,delivered:!1,reason:err instanceof Error?err.message:String(err)})}}return results}async function handleBroadcast2(from,body,team){let taskService=await Promise.resolve().then(() => (init_task_service(),exports_task_service)),repoPath=process.cwd(),teamName=team??process.env.GENIE_TEAM;if(!teamName)console.error("Error: Could not detect team. Use --team <name>."),process.exit(1);let senderActor={actorType:"local",actorId:from},conv=await taskService.findOrCreateConversation({type:"group",name:`Team: ${teamName}`,linkedEntity:"team",linkedEntityId:teamName,createdBy:senderActor,members:[senderActor]});await taskService.addMember(conv.id,senderActor);let msg=await taskService.sendMessage(conv.id,senderActor,body);try{let{publishSubjectEvent:publishSubjectEvent2}=await Promise.resolve().then(() => (init_runtime_events(),exports_runtime_events));await publishSubjectEvent2(repoPath,"genie.msg.broadcast",{kind:"message",agent:from,direction:"out",peer:teamName,text:body,data:{messageId:msg.id,conversationId:conv.id,from,team:teamName},source:"mailbox"})}catch{}let{listMembers:listMembers2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),protocolRouter=await Promise.resolve().then(() => (init_protocol_router(),exports_protocol_router)),fanoutResults=await deliverBroadcastToMembers({listMembers:listMembers2,sendMessage:protocolRouter.sendMessage},repoPath,from,teamName,body);console.log(`Broadcast sent to team "${teamName}".`),console.log(` Message ID: ${msg.id}`),console.log(` Conversation: ${conv.id}`);let deliveredCount=fanoutResults.filter((r)=>r.delivered).length;console.log(` Fan-out: ${deliveredCount}/${fanoutResults.length} members reached`);for(let r of fanoutResults)if(!r.delivered)console.log(` \u26A0 ${r.member}: ${r.reason??"delivery failed"}`)}init_term_format();function printAgentFields(agent){if(console.log(""),console.log(`AGENT: ${agent.customName??agent.role??agent.id}`),console.log("\u2500".repeat(60)),console.log(` ${padRight("ID:",20)} ${agent.id}`),agent.role)console.log(` ${padRight("Role:",20)} ${agent.role}`);if(agent.customName)console.log(` ${padRight("Name:",20)} ${agent.customName}`);if(agent.team)console.log(` ${padRight("Team:",20)} ${agent.team}`);console.log(` ${padRight("Started:",20)} ${agent.startedAt}`)}function printExecutorFields(executor){if(console.log(""),console.log("Current Executor:"),console.log("\u2500".repeat(60)),console.log(` ${padRight("Executor ID:",20)} ${executor.id}`),console.log(` ${padRight("Provider:",20)} ${executor.provider}`),console.log(` ${padRight("Transport:",20)} ${executor.transport}`),console.log(` ${padRight("State:",20)} ${executor.state}`),executor.pid)console.log(` ${padRight("PID:",20)} ${executor.pid}`);if(executor.tmuxSession)console.log(` ${padRight("Tmux Session:",20)} ${executor.tmuxSession}`);if(executor.tmuxPaneId)console.log(` ${padRight("Tmux Pane:",20)} ${executor.tmuxPaneId}`);if(executor.worktree)console.log(` ${padRight("Worktree:",20)} ${executor.worktree}`);if(console.log(` ${padRight("Started:",20)} ${executor.startedAt}`),executor.endedAt)console.log(` ${padRight("Ended:",20)} ${executor.endedAt}`)}async function showAgent(name,json2){let registry=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry)),executorRegistry=await Promise.resolve().then(() => (init_executor_registry(),exports_executor_registry)),matches=(await registry.listAgents()).filter((a)=>a.customName===name||a.role===name||a.id===name),preferredTeam=process.env.GENIE_TEAM,agent=(preferredTeam&&matches.find((a)=>a.team===preferredTeam))??matches[0];if(!agent)console.error(`Agent "${name}" not found.`),process.exit(1);if(json2){let executor=agent.currentExecutorId?await executorRegistry.getExecutor(agent.currentExecutorId):null;console.log(JSON.stringify({agent,executor},null,2));return}if(printAgentFields(agent),agent.currentExecutorId){let executor=await executorRegistry.getExecutor(agent.currentExecutorId);if(executor)printExecutorFields(executor)}else console.log(`
3927
+ Registering in Omni (${omniUrl})...`);let existingId=await findOmniAgent(name);if(existingId){console.log(` Agent already exists in Omni: ${existingId}`),await edit(name,{omniAgentId:existingId},{global:options.global}),console.log(" Linked existing Omni agent to directory entry.");return}let omniAgentId=await registerAgentInOmni(name,{model:options.model,roles:options.roles});if(omniAgentId)await edit(name,{omniAgentId},{global:options.global}),console.log(` Omni agent created: ${omniAgentId}`),console.log(" Session isolation: per-person + per-channel")}async function handleAgentRegister(name,options){let promptMode=validatePromptMode2(options.promptMode);if(options.repo)validateRepoPath(options.repo);let roles=normalizeRoles2(options.roles),entry2=await add({name,dir:resolvePath3(options.dir),repo:options.repo?resolvePath3(options.repo):void 0,promptMode,model:options.model,roles},{global:options.global,allowSymlink:options.allowSymlink}),scope=options.global?"global":"project";if(console.log(`Agent "${entry2.name}" registered (${scope}).`),printEntry2(entry2),options.skipOmni){process.stderr.write(`
3928
+ \u26A0 Skipped Omni auto-registration. The genie directory entry exists, but no Omni agent
3929
+ record, no nats-genie provider, and no instance binding were created. Until you wire
3930
+ the Omni side, this agent will not receive messages from any channel.
3931
+
3932
+ To complete the wire when ready:
3933
+ omni connect <instance-id> ${entry2.name}
3934
+
3935
+ Or run the canonical wizard from a Claude session:
3936
+ /genie:omni
3937
+
3938
+ `);return}await handleOmniRegistration(name,{...options,roles})}function registerAgentRegister(parent){parent.command("register <name>").description("Register an agent locally and auto-register in Omni when configured").requiredOption("--dir <path>","Agent folder (CWD + AGENTS.md)").option("--repo <path>","Default git repo (overridden by team)").option("--prompt-mode <mode>","Prompt mode: append or system","append").option("--model <model>","Default model (sonnet, opus, codex)").option("--roles <roles...>","Built-in roles this agent can orchestrate").option("--global","Write to global directory instead of project").option("--skip-omni","Skip Omni auto-registration (prints a stderr warning explaining the cost)").option("--allow-symlink","Accept a symlinked AGENTS.md (default: rejected \u2014 usually indicates --dir was pointed at the wrong folder)").action(async(name,options)=>{try{await handleAgentRegister(name,options)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}init_agents();function registerAgentResume(parent){parent.command("resume [name]").description("Resume a suspended/failed agent with its Claude session").option("--all","Resume all eligible agents").option("--no-reset-attempts","Preserve resumeAttempts counter (scheduler auto-resume use)").action(async(name,options)=>{try{await handleWorkerResume(name,{all:options.all,noResetAttempts:options.resetAttempts===!1})}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}init_msg();function registerAgentSend(parent){parent.command("send <body>").description("Send a direct message to an agent (hierarchy-enforced)").option("--to <agent>","Recipient agent name (default: team leader)","team-lead").option("--from <sender>","Sender ID (auto-detected from context)").option("--team <name>","Explicit team context for sender/recipient resolution").option("--broadcast","Send to all direct reports").action(async(body,options)=>{try{let from=options.from??await detectSenderIdentity(options.team);if(options.broadcast){await handleBroadcast2(from,body,options.team);return}await handleDirectMessage(from,options.to,body,options.team)}catch(error2){console.error(`Error: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}})}async function isTeamLeader(agentName,teamName){try{let{resolveLeaderName:resolveLeaderName2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),leaderName=await resolveLeaderName2(teamName);return agentName===leaderName}catch{return!1}}async function checkHierarchy(from,to){if(isCliSender(from))return{allowed:!0};if(from===to)return{allowed:!0};try{let agents=await(await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry))).listAgents({}),sender=agents.find((a)=>a.customName===from||a.role===from||a.id===from),recipient=agents.find((a)=>a.customName===to||a.role===to||a.id===to);if(!sender||!recipient)return{allowed:!0};if(recipient.reportsTo===from||recipient.reportsTo===sender.id)return{allowed:!0};if(sender.reportsTo===to||sender.reportsTo===recipient.id)return{allowed:!0};if(sender.reportsTo&&sender.reportsTo===recipient.reportsTo)return{allowed:!0};if(sender.team&&sender.team===recipient.team&&await isTeamLeader(from,sender.team))return{allowed:!0};let manager=sender.reportsTo??"your manager";return{allowed:!1,reason:`Cannot reach "${to}". Escalate to ${manager}.`}}catch{return{allowed:!0}}}async function handleDirectMessage(from,to,body,team){let{allowed,reason}=await checkHierarchy(from,to);if(!allowed)console.error(`Error: ${reason}`),process.exit(1);let{checkSendScope:checkSendScope2}=await Promise.resolve().then(() => (init_msg(),exports_msg)),repoPath=process.cwd(),scopeError=await checkSendScope2(repoPath,from,to);if(scopeError)console.error(`Error: ${scopeError}`),process.exit(1);let taskService=await Promise.resolve().then(() => (init_task_service(),exports_task_service)),mailbox=await Promise.resolve().then(() => (init_mailbox(),exports_mailbox)),senderActor={actorType:"local",actorId:from},recipientActor={actorType:"local",actorId:to},conv=await taskService.findOrCreateConversation({type:"dm",members:[senderActor,recipientActor],createdBy:senderActor});await taskService.addMember(conv.id,senderActor),await taskService.addMember(conv.id,recipientActor),await mailbox.send(repoPath,from,to,body);let msg=await taskService.sendMessage(conv.id,senderActor,body);try{let{publishSubjectEvent:publishSubjectEvent2}=await Promise.resolve().then(() => (init_runtime_events(),exports_runtime_events));await publishSubjectEvent2(repoPath,`genie.msg.${to}`,{kind:"message",agent:from,direction:"out",peer:to,text:body,data:{messageId:msg.id,conversationId:conv.id,from,to},source:"mailbox"})}catch{}try{let nativeTeams=await Promise.resolve().then(() => (init_claude_native_teams(),exports_claude_native_teams)),nativeMsg={from,text:body,summary:body.length>50?`${body.substring(0,50)}...`:body,timestamp:new Date().toISOString(),color:"blue",read:!1},currentTeam=team??process.env.GENIE_TEAM;if(currentTeam){let nativeName=await nativeTeams.resolveNativeMemberName(currentTeam,to);if(nativeName)await nativeTeams.writeNativeInbox(currentTeam,nativeName,nativeMsg)}}catch{}console.log(`Message sent to "${to}".`),console.log(` ID: ${msg.id}`),console.log(` Conversation: ${conv.id}`)}async function deliverBroadcastToMembers(deps,repoPath,from,teamName,body){let members=await deps.listMembers(teamName)??[],results=[];for(let member of members){if(member===from)continue;try{let r=await deps.sendMessage(repoPath,from,member,body,teamName);results.push({member,delivered:r.delivered,reason:r.reason})}catch(err){results.push({member,delivered:!1,reason:err instanceof Error?err.message:String(err)})}}return results}async function handleBroadcast2(from,body,team){let taskService=await Promise.resolve().then(() => (init_task_service(),exports_task_service)),repoPath=process.cwd(),teamName=team??process.env.GENIE_TEAM;if(!teamName)console.error("Error: Could not detect team. Use --team <name>."),process.exit(1);let senderActor={actorType:"local",actorId:from},conv=await taskService.findOrCreateConversation({type:"group",name:`Team: ${teamName}`,linkedEntity:"team",linkedEntityId:teamName,createdBy:senderActor,members:[senderActor]});await taskService.addMember(conv.id,senderActor);let msg=await taskService.sendMessage(conv.id,senderActor,body);try{let{publishSubjectEvent:publishSubjectEvent2}=await Promise.resolve().then(() => (init_runtime_events(),exports_runtime_events));await publishSubjectEvent2(repoPath,"genie.msg.broadcast",{kind:"message",agent:from,direction:"out",peer:teamName,text:body,data:{messageId:msg.id,conversationId:conv.id,from,team:teamName},source:"mailbox"})}catch{}let{listMembers:listMembers2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),protocolRouter=await Promise.resolve().then(() => (init_protocol_router(),exports_protocol_router)),fanoutResults=await deliverBroadcastToMembers({listMembers:listMembers2,sendMessage:protocolRouter.sendMessage},repoPath,from,teamName,body);console.log(`Broadcast sent to team "${teamName}".`),console.log(` Message ID: ${msg.id}`),console.log(` Conversation: ${conv.id}`);let deliveredCount=fanoutResults.filter((r)=>r.delivered).length;console.log(` Fan-out: ${deliveredCount}/${fanoutResults.length} members reached`);for(let r of fanoutResults)if(!r.delivered)console.log(` \u26A0 ${r.member}: ${r.reason??"delivery failed"}`)}init_term_format();function printAgentFields(agent){if(console.log(""),console.log(`AGENT: ${agent.customName??agent.role??agent.id}`),console.log("\u2500".repeat(60)),console.log(` ${padRight("ID:",20)} ${agent.id}`),agent.role)console.log(` ${padRight("Role:",20)} ${agent.role}`);if(agent.customName)console.log(` ${padRight("Name:",20)} ${agent.customName}`);if(agent.team)console.log(` ${padRight("Team:",20)} ${agent.team}`);console.log(` ${padRight("Started:",20)} ${agent.startedAt}`)}function printExecutorFields(executor){if(console.log(""),console.log("Current Executor:"),console.log("\u2500".repeat(60)),console.log(` ${padRight("Executor ID:",20)} ${executor.id}`),console.log(` ${padRight("Provider:",20)} ${executor.provider}`),console.log(` ${padRight("Transport:",20)} ${executor.transport}`),console.log(` ${padRight("State:",20)} ${executor.state}`),executor.pid)console.log(` ${padRight("PID:",20)} ${executor.pid}`);if(executor.tmuxSession)console.log(` ${padRight("Tmux Session:",20)} ${executor.tmuxSession}`);if(executor.tmuxPaneId)console.log(` ${padRight("Tmux Pane:",20)} ${executor.tmuxPaneId}`);if(executor.worktree)console.log(` ${padRight("Worktree:",20)} ${executor.worktree}`);if(console.log(` ${padRight("Started:",20)} ${executor.startedAt}`),executor.endedAt)console.log(` ${padRight("Ended:",20)} ${executor.endedAt}`)}async function showAgent(name,json2){let registry=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry)),executorRegistry=await Promise.resolve().then(() => (init_executor_registry(),exports_executor_registry)),matches=(await registry.listAgents()).filter((a)=>a.customName===name||a.role===name||a.id===name),preferredTeam=process.env.GENIE_TEAM,agent=(preferredTeam&&matches.find((a)=>a.team===preferredTeam))??matches[0];if(!agent)console.error(`Agent "${name}" not found.`),process.exit(1);if(json2){let executor=agent.currentExecutorId?await executorRegistry.getExecutor(agent.currentExecutorId):null;console.log(JSON.stringify({agent,executor},null,2));return}if(printAgentFields(agent),agent.currentExecutorId){let executor=await executorRegistry.getExecutor(agent.currentExecutorId);if(executor)printExecutorFields(executor)}else console.log(`
3928
3939
  No active executor.`);console.log("")}function registerAgentShow(parent){parent.command("show <name>").description("Show agent identity and current executor detail").option("--json","Output as JSON").action(async(name,options)=>{try{await showAgent(name,options.json)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}init_provider_models();init_agents();function parseNumericFlag(flagName){return(value)=>{let n=Number(value);if(Number.isNaN(n))throw Error(`${flagName} must be a number, got: ${value}`);return n}}function registerAgentSpawn(parent){parent.command("spawn <name>").description("Spawn a new agent by name (resolves from directory or built-ins)").option("--provider <provider>","Provider: claude, codex, or claude-sdk").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("--prompt <prompt>","Initial prompt (first user message)").option("--sdk-max-turns <n>","SDK: max conversation turns",parseNumericFlag("--sdk-max-turns")).option("--sdk-max-budget <usd>","SDK: max budget in USD",parseNumericFlag("--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").action(async(name,options)=>{if(options.prompt)options.initialPrompt=options.prompt;if(options.autoSync===!1)options.noAutoSync=!0;try{validateProviderModel({provider:options.provider??null,model:options.model??null})}catch(error2){if(error2 instanceof CrossProviderModelError)console.error(`Error: ${error2.message}`),process.exit(1);throw error2}try{await handleWorkerSpawn(name,options)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}init_agents();function registerAgentStop(parent){parent.command("stop <name>").description("Stop an agent (preserves session for resume)").action(async(name)=>{try{await handleWorkerStop(name)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}function registerAgentCommands(program2){let agent=program2.command("agent").description("Agent lifecycle management");registerAgentSpawn(agent),registerAgentStop(agent),registerAgentResume(agent),registerAgentRecover(agent),registerAgentKill(agent),registerAgentList(agent),registerAgentShow(agent),registerAgentAnswer(agent),registerAgentRegister(agent),registerAgentDirectory(agent),registerAgentInbox(agent),registerAgentBrief(agent),registerAgentLog(agent),registerAgentSend(agent),agent.on("command:*",(operands)=>{let cmd=operands[0],available=agent.commands.map((c)=>c.name()).join(", ");agent.error(`Unknown agent command '${cmd}'. Available: ${available}`)})}init_agents();async function handleTuiMode(){let{isServeRunning:isServeRunning2,autoStartServe:autoStartServe2}=await Promise.resolve().then(() => (init_serve(),exports_serve));if(!isServeRunning2())console.log("Starting genie serve..."),await autoStartServe2();let{attachTuiSession:attachTuiSession2}=await Promise.resolve().then(() => (init_tmux2(),exports_tmux2));attachTuiSession2()}async function findTauriBinary(){let{existsSync:existsSync46}=await import("fs"),{join:join57,dirname:dirname14}=await import("path"),{execSync:execSync11}=await import("child_process"),appName="genie-desktop",rootDir=join57(dirname14(new URL(import.meta.url).pathname),"..",".."),localBin=[join57(rootDir,"packages","genie-app","src-tauri","target","release","genie-desktop"),join57(rootDir,"packages","genie-app","src-tauri","target","debug","genie-desktop"),join57(rootDir,"dist","app","genie-desktop"),"/usr/local/bin/genie-desktop"].find((p)=>existsSync46(p));if(localBin)return localBin;try{return execSync11("which genie-desktop",{stdio:"ignore"}),"genie-desktop"}catch{return}}function registerAppCommand(program2){program2.command("app").description("Launch Genie desktop app (backend sidecar + views)").option("--backend-only","Start only the backend sidecar (IPC on stdin/stdout)").option("--tui","Fall back to terminal UI mode").option("--dev","Development mode").action(async(options)=>{if(options.tui){await handleTuiMode();return}if(options.backendOnly){await Promise.resolve().then(() => (init_src_backend(),exports_src_backend));return}let tauriBin=await findTauriBinary();if(tauriBin){console.log("\x1B[35m\u25C6 Genie App\x1B[0m Launching desktop...");let{execFileSync}=await import("child_process");try{execFileSync(tauriBin,[],{stdio:"inherit"})}catch{}return}console.log("\x1B[35m\u25C6 Genie App\x1B[0m Starting backend sidecar..."),console.log("\x1B[2mDesktop binary not found \u2014 running in sidecar mode.\x1B[0m"),console.log("\x1B[2mPG bridge + PTY manager + IPC on stdin/stdout\x1B[0m"),console.log(`\x1B[2mUse --tui for terminal UI, or pipe to a frontend shell.\x1B[0m
3929
3940
  `),await Promise.resolve().then(() => (init_src_backend(),exports_src_backend))})}init_claude_sdk_remote_approval();init_workspace();async function handleRequest(options){let ws=findWorkspace(),permissions=ws?getWorkspaceConfig(ws.root).permissions:void 0,timeoutSec=options.timeout?Number(options.timeout):permissions?.timeout??300,defaultAction=permissions?.defaultAction??"deny",timeoutAt=new Date(Date.now()+timeoutSec*1000),approvalId=await insertApproval(`cli-${process.pid}`,options.agent,options.tool,options.input,timeoutAt);if(console.log(`Approval created: ${approvalId}`),options.wait){console.log(`Waiting for resolution (timeout: ${timeoutSec}s, default: ${defaultAction})...`);let decision=await waitForResolution(approvalId,timeoutAt,defaultAction);if(console.log(`Decision: ${decision}`),decision==="deny")process.exit(1)}}async function handleResolve(id,options){if(options.decision!=="allow"&&options.decision!=="deny")console.error('Error: --decision must be "allow" or "deny"'),process.exit(1);let actor=process.env.GENIE_AGENT_NAME||options.by;if(await resolveApproval(id,options.decision,actor))console.log(`Approval ${id} resolved: ${options.decision} by ${options.by}`);else console.error(`Error: Approval ${id} not found or already resolved`),process.exit(1)}async function handleList(options){let rows=await listPendingApprovals(options.agent);if(options.json){console.log(JSON.stringify(rows,null,2));return}if(rows.length===0){console.log("No pending approvals.");return}console.log(` ${"ID".padEnd(38)} ${"AGENT".padEnd(20)} ${"TOOL".padEnd(15)} TIMEOUT`),console.log(` ${"\u2500".repeat(85)}`);for(let row of rows){let timeout=new Date(row.timeout_at).toLocaleTimeString();console.log(` ${String(row.id).padEnd(38)} ${String(row.agent_name).padEnd(20)} ${String(row.tool_name).padEnd(15)} ${timeout}`)}console.log(`
3930
3941
  ${rows.length} pending approval${rows.length===1?"":"s"}`)}function registerApprovalCommands(program2){let approval=program2.command("approval").description("Remote approval queue management");approval.command("request").description("Create an approval request (for tmux-path agents)").requiredOption("--tool <name>","Tool name requiring approval").requiredOption("--input <preview>","Tool input preview text").requiredOption("--agent <name>","Agent name requesting approval").option("--wait","Block until the approval is resolved").option("--timeout <seconds>","Timeout in seconds (overrides workspace config)").action(async(options)=>{try{await handleRequest(options)}catch(error2){console.error(`Error: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}}),approval.command("resolve <id>").description("Resolve a pending approval").requiredOption("--decision <decision>","Decision: allow or deny").option("--by <actor>",'Display label for decision maker (defaults to GENIE_AGENT_NAME or "cli")',"cli").action(async(id,options)=>{try{await handleResolve(id,options)}catch(error2){console.error(`Error: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}}),approval.command("list").description("List pending approvals").option("--agent <name>","Filter by agent name").option("--json","Output as JSON").action(async(options)=>{try{await handleList(options)}catch(error2){console.error(`Error: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}})}init_audit();init_db();var V2_SELECT=`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/genie",
3
- "version": "4.260429.13",
3
+ "version": "4.260429.15",
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.260429.13",
3
+ "version": "4.260429.15",
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.260429.13",
3
+ "version": "4.260429.15",
4
4
  "private": true,
5
5
  "description": "Runtime dependencies for genie bundled CLIs",
6
6
  "type": "module",
@@ -0,0 +1,152 @@
1
+ ---
2
+ name: omni
3
+ description: "Wire a Genie agent to an Omni channel in one canonical flow — register the agent, bind to an instance, verify the round-trip. Replaces the 5+ command legacy chain."
4
+ allowed-tools: Bash(omni *), Bash(genie *)
5
+ ---
6
+
7
+ # /genie:omni — Canonical Genie ↔ Omni Wiring
8
+
9
+ Single-command wizard that takes an operator from "no agent yet" (or "an existing genie agent") to "agent answering messages on a channel". Wraps `genie agent register` + `omni connect` + verification into one conversational flow so operators don't have to remember two systems' command surfaces.
10
+
11
+ ## When to Use
12
+
13
+ - Adding a new agent to a connected Omni channel.
14
+ - Wiring an existing genie agent dir to a fresh Omni instance.
15
+ - Verifying that an existing wire still works end-to-end.
16
+ - Operator types `/genie:omni` and expects the assistant to drive.
17
+
18
+ If the legacy multi-command chain (`omni providers create` + `omni agents create` + `omni instances update --agent` + `omni routes create`) is what you reach for first — stop and use this skill instead. The legacy chain still works for power users / CI but emits stderr deprecation nudges pointing here.
19
+
20
+ ## Pre-conditions (verify before driving)
21
+
22
+ These checks are quick and tell you which Phase to start in. Always run them up front:
23
+
24
+ ```bash
25
+ omni auth status # Phase 1 needed if missing or invalid
26
+ genie serve status # Phase 4 verification needs this green
27
+ omni instances list # at least one connected instance needed for Phase 3
28
+ ```
29
+
30
+ ## Flow
31
+
32
+ ### Phase 1 — Omni installed and authenticated?
33
+
34
+ **Entry:** Always (first thing to check).
35
+
36
+ **Steps:**
37
+
38
+ 1. Run `omni auth status`. If it reports a valid connection, **skip to Phase 2**.
39
+ 2. If not authenticated or omni is not installed:
40
+ - Tell the operator that omni needs a one-time bootstrap and instruct them to run `omni install` **in a separate terminal** (do NOT nest two interactive flows from inside this skill — the omni installer is itself a wizard).
41
+ - Wait for the operator to confirm `omni install` completed.
42
+ - Re-run `omni auth status` to verify, then continue to Phase 2.
43
+
44
+ **Exit:** `omni auth status` succeeds.
45
+
46
+ ### Phase 2 — Pick or scaffold the genie agent dir
47
+
48
+ **Entry:** Phase 1 passed.
49
+
50
+ **Steps:**
51
+
52
+ 1. Ask the operator: *"Which genie agent are we wiring? Existing one, or do we scaffold a new dir?"*
53
+ 2. If existing:
54
+ - Ask for the agent name.
55
+ - Run `genie dir ls <name>` to confirm it's already registered. If yes, skip to Phase 3.
56
+ - If not registered, ask for the agent's home directory — the path that contains a real `AGENTS.md`. Validate up front:
57
+ - The path must exist.
58
+ - `<dir>/AGENTS.md` must be a real file, **not** a symlink. If it's a symlink, ask whether the operator wants to register the dir the symlink points to instead (almost always the right answer), or pass `--allow-symlink` (only if intentional template-sharing layout).
59
+ - Run `genie agent register <name> --dir <validated-path>`. The default flow auto-registers the agent in Omni (creates the agent record). Do **NOT** pass `--skip-omni` here — Phase 3 uses `omni connect` which expects the agent record to exist.
60
+ 3. If scaffolding new:
61
+ - Direct the operator to `/genie:wizard` (which scaffolds an agent identity and AGENTS.md), then come back to this Phase 2 with the freshly-scaffolded dir.
62
+
63
+ **Exit:** `genie dir ls <name>` returns a clean entry with the correct `Dir:` field.
64
+
65
+ ### Phase 3 — Bind to an Omni instance
66
+
67
+ **Entry:** Phase 2 passed.
68
+
69
+ **Steps:**
70
+
71
+ 1. Run `omni instances list` and show the operator the connected instances (those with `ACTIVE=yes`). Highlight the channel and profile name so the operator picks the right one.
72
+ 2. If there are no connected instances, point the operator at `/omni:omni-setup` (the omni plugin's connect-channel wizard) and pause this flow until an instance is connected.
73
+ 3. Once the operator picks an instance:
74
+ - Run `omni connect <instance-id> <agent-name>` — this is the canonical command. It:
75
+ - reads `genie dir ls <name> --json` (so the agent must have been registered in Phase 2),
76
+ - creates (or reuses) a `nats-genie` provider,
77
+ - creates (or reuses) the omni agent record bound to that provider,
78
+ - updates the instance with `agentId`, `agentProviderId`, `agentReplyFilter`, and `triggerMode`.
79
+ - The operator can pass `--mode turn-based` (default, recommended for chat) or `--mode fire-and-forget` if they have a reason. Default `--reply-filter all` is fine for KHAL-V1-LAUNCH-style group bots.
80
+ 4. Confirm the success summary printed by `omni connect` — note the agent ID, provider ID, and the NATS subjects (`omni.message.<inst>.*` inbound, `omni.reply.<inst>.*` outbound).
81
+
82
+ **Exit:** `omni connect` exits 0 with the configuration summary.
83
+
84
+ ### Phase 4 — Verify the round-trip
85
+
86
+ **Entry:** Phase 3 passed.
87
+
88
+ **Steps:**
89
+
90
+ 1. Confirm the bridge daemon is running:
91
+ ```bash
92
+ genie serve status
93
+ ```
94
+ If not running, start it:
95
+ ```bash
96
+ genie serve start --headless
97
+ ```
98
+ 2. Confirm the bridge is subscribed to the right NATS subjects:
99
+ ```bash
100
+ nats --server localhost:4222 server report connections | grep genie-omni-bridge
101
+ ```
102
+ Should show 7+ subscriptions with non-zero uptime.
103
+ 3. Run a synthetic round-trip:
104
+ - Tell the operator to send a real test message in the chat that's now wired (e.g. a WhatsApp group).
105
+ - Watch the omni-api log: `tail -f ~/.pm2/logs/omni-api-out.log | grep <chat-id>` — expect `Received → Dispatching → Published to NATS → Agent response` within a few seconds.
106
+ - On the genie side: `genie agent ls` should show a new per-chat agent (e.g. `<name>:<chat-id>` in `idle` state).
107
+ 4. Print the final topology:
108
+
109
+ ```
110
+ 📨 WhatsApp/Telegram
111
+
112
+
113
+ 🌐 Omni instance <instance-id> channel=<channel>
114
+
115
+
116
+ 🔌 nats-genie provider <provider-id> agentName=<name>
117
+
118
+ ▼ NATS subject: omni.message.<inst>.*
119
+
120
+ 🤖 genie-omni-bridge → spawns claude in <agent.dir> with --resume <session>
121
+
122
+
123
+ 📝 Claude (TUI) responds via `omni say "..."`
124
+ ```
125
+
126
+ **Exit:** A real test message gets a real reply in the chat. Done.
127
+
128
+ ## Recovery
129
+
130
+ If any Phase fails, point the operator at `Runbooks/wire-new-omni-agent.md` (lives in their genie-configure brain) for the fallback two-command path:
131
+
132
+ ```bash
133
+ genie agent register <name> --dir <validated-path>
134
+ omni connect <instance-id> <name>
135
+ ```
136
+
137
+ …plus the troubleshooting table for common symptoms (wrong cwd, bridge not subscribing, multiple agents with same role).
138
+
139
+ ## Rules
140
+
141
+ - **Never nest interactive flows.** If `omni install` or `/genie:wizard` is needed, hand off to the operator and pause this skill.
142
+ - **Never use `--skip-omni` in this flow.** It defeats Phase 3.
143
+ - **Always validate `--dir` is real (not a symlink).** As of v4.260429.14+, `genie agent register` rejects symlinked AGENTS.md by default; this skill should not pass `--allow-symlink` unless the operator explicitly says so.
144
+ - **Always run `omni connect`, not the legacy chain.** If the operator is mid-way through manually creating providers/agents/routes, ask them to stop and run `omni connect` instead — it's idempotent and reuses anything already created.
145
+ - **Never commit secrets.** The `omni_sk_…` API key in `~/.omni/config.json` is read by `genie agent register` automatically; never echo it back to the operator or include it in commit messages.
146
+
147
+ ## See also
148
+
149
+ - Genie defect fixes that this skill relies on: namastexlabs/genie-configure#10 (brain map + ADR), automagik-dev/genie#1514 (symlink validation + `--skip-omni` warning).
150
+ - Omni-side cleanups: automagik-dev/omni#552 (drop stale `genie omni start` hint), automagik-dev/omni#553 (deprecation nudges scaffolding).
151
+ - Wish: `canonical-genie-omni-wiring` — `.genie/wishes/canonical-genie-omni-wiring/WISH.md`.
152
+ - Sibling omni-side skill: `/omni:omni-setup` (covers omni install + channel connect; this skill picks up where that one ends).