@automagik/genie 4.260507.4 → 4.260507.6
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
|
@@ -21,8 +21,8 @@ Expecting one of '${allowedValues.join("', '")}'`);if(this._lifeCycleHooks[event
|
|
|
21
21
|
`),this.outputHelp({error:!0});let config=errorOptions||{},exitCode=config.exitCode||1,code=config.code||"commander.error";this._exit(exitCode,code,message)}_parseOptionsEnv(){this.options.forEach((option)=>{if(option.envVar&&option.envVar in process2.env){let optionKey=option.attributeName();if(this.getOptionValue(optionKey)===void 0||["default","config","env"].includes(this.getOptionValueSource(optionKey)))if(option.required||option.optional)this.emit(`optionEnv:${option.name()}`,process2.env[option.envVar]);else this.emit(`optionEnv:${option.name()}`)}})}_parseOptionsImplied(){let dualHelper=new DualOptions(this.options),hasCustomOptionValue=(optionKey)=>{return this.getOptionValue(optionKey)!==void 0&&!["default","implied"].includes(this.getOptionValueSource(optionKey))};this.options.filter((option)=>option.implied!==void 0&&hasCustomOptionValue(option.attributeName())&&dualHelper.valueFromOption(this.getOptionValue(option.attributeName()),option)).forEach((option)=>{Object.keys(option.implied).filter((impliedKey)=>!hasCustomOptionValue(impliedKey)).forEach((impliedKey)=>{this.setOptionValueWithSource(impliedKey,option.implied[impliedKey],"implied")})})}missingArgument(name){let message=`error: missing required argument '${name}'`;this.error(message,{code:"commander.missingArgument"})}optionMissingArgument(option){let message=`error: option '${option.flags}' argument missing`;this.error(message,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue(option){let message=`error: required option '${option.flags}' not specified`;this.error(message,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption(option,conflictingOption){let findBestOptionFromValue=(option2)=>{let optionKey=option2.attributeName(),optionValue=this.getOptionValue(optionKey),negativeOption=this.options.find((target)=>target.negate&&optionKey===target.attributeName()),positiveOption=this.options.find((target)=>!target.negate&&optionKey===target.attributeName());if(negativeOption&&(negativeOption.presetArg===void 0&&optionValue===!1||negativeOption.presetArg!==void 0&&optionValue===negativeOption.presetArg))return negativeOption;return positiveOption||option2},getErrorMessage=(option2)=>{let bestOption=findBestOptionFromValue(option2),optionKey=bestOption.attributeName();if(this.getOptionValueSource(optionKey)==="env")return`environment variable '${bestOption.envVar}'`;return`option '${bestOption.flags}'`},message=`error: ${getErrorMessage(option)} cannot be used with ${getErrorMessage(conflictingOption)}`;this.error(message,{code:"commander.conflictingOption"})}unknownOption(flag){if(this._allowUnknownOption)return;let suggestion="";if(flag.startsWith("--")&&this._showSuggestionAfterError){let candidateFlags=[],command=this;do{let moreFlags=command.createHelp().visibleOptions(command).filter((option)=>option.long).map((option)=>option.long);candidateFlags=candidateFlags.concat(moreFlags),command=command.parent}while(command&&!command._enablePositionalOptions);suggestion=suggestSimilar(flag,candidateFlags)}let message=`error: unknown option '${flag}'${suggestion}`;this.error(message,{code:"commander.unknownOption"})}_excessArguments(receivedArgs){if(this._allowExcessArguments)return;let expected=this.registeredArguments.length,s=expected===1?"":"s",message=`error: too many arguments${this.parent?` for '${this.name()}'`:""}. Expected ${expected} argument${s} but got ${receivedArgs.length}.`;this.error(message,{code:"commander.excessArguments"})}unknownCommand(){let unknownName=this.args[0],suggestion="";if(this._showSuggestionAfterError){let candidateNames=[];this.createHelp().visibleCommands(this).forEach((command)=>{if(candidateNames.push(command.name()),command.alias())candidateNames.push(command.alias())}),suggestion=suggestSimilar(unknownName,candidateNames)}let message=`error: unknown command '${unknownName}'${suggestion}`;this.error(message,{code:"commander.unknownCommand"})}version(str,flags,description){if(str===void 0)return this._version;this._version=str,flags=flags||"-V, --version",description=description||"output the version number";let versionOption=this.createOption(flags,description);return this._versionOptionName=versionOption.attributeName(),this._registerOption(versionOption),this.on("option:"+versionOption.name(),()=>{this._outputConfiguration.writeOut(`${str}
|
|
22
22
|
`),this._exit(0,"commander.version",str)}),this}description(str,argsDescription){if(str===void 0&&argsDescription===void 0)return this._description;if(this._description=str,argsDescription)this._argsDescription=argsDescription;return this}summary(str){if(str===void 0)return this._summary;return this._summary=str,this}alias(alias){if(alias===void 0)return this._aliases[0];let command=this;if(this.commands.length!==0&&this.commands[this.commands.length-1]._executableHandler)command=this.commands[this.commands.length-1];if(alias===command._name)throw Error("Command alias can't be the same as its name");let matchingCommand=this.parent?._findCommand(alias);if(matchingCommand){let existingCmd=[matchingCommand.name()].concat(matchingCommand.aliases()).join("|");throw Error(`cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`)}return command._aliases.push(alias),this}aliases(aliases){if(aliases===void 0)return this._aliases;return aliases.forEach((alias)=>this.alias(alias)),this}usage(str){if(str===void 0){if(this._usage)return this._usage;let args=this.registeredArguments.map((arg)=>{return humanReadableArgName(arg)});return[].concat(this.options.length||this._helpOption!==null?"[options]":[],this.commands.length?"[command]":[],this.registeredArguments.length?args:[]).join(" ")}return this._usage=str,this}name(str){if(str===void 0)return this._name;return this._name=str,this}nameFromFilename(filename){return this._name=path.basename(filename,path.extname(filename)),this}executableDir(path2){if(path2===void 0)return this._executableDir;return this._executableDir=path2,this}helpInformation(contextOptions){let helper=this.createHelp();if(helper.helpWidth===void 0)helper.helpWidth=contextOptions&&contextOptions.error?this._outputConfiguration.getErrHelpWidth():this._outputConfiguration.getOutHelpWidth();return helper.formatHelp(this,helper)}_getHelpContext(contextOptions){contextOptions=contextOptions||{};let context={error:!!contextOptions.error},write;if(context.error)write=(arg)=>this._outputConfiguration.writeErr(arg);else write=(arg)=>this._outputConfiguration.writeOut(arg);return context.write=contextOptions.write||write,context.command=this,context}outputHelp(contextOptions){let deprecatedCallback;if(typeof contextOptions==="function")deprecatedCallback=contextOptions,contextOptions=void 0;let context=this._getHelpContext(contextOptions);this._getCommandAndAncestors().reverse().forEach((command)=>command.emit("beforeAllHelp",context)),this.emit("beforeHelp",context);let helpInformation=this.helpInformation(context);if(deprecatedCallback){if(helpInformation=deprecatedCallback(helpInformation),typeof helpInformation!=="string"&&!Buffer.isBuffer(helpInformation))throw Error("outputHelp callback must return a string or a Buffer")}if(context.write(helpInformation),this._getHelpOption()?.long)this.emit(this._getHelpOption().long);this.emit("afterHelp",context),this._getCommandAndAncestors().forEach((command)=>command.emit("afterAllHelp",context))}helpOption(flags,description){if(typeof flags==="boolean"){if(flags)this._helpOption=this._helpOption??void 0;else this._helpOption=null;return this}return flags=flags??"-h, --help",description=description??"display help for command",this._helpOption=this.createOption(flags,description),this}_getHelpOption(){if(this._helpOption===void 0)this.helpOption(void 0,void 0);return this._helpOption}addHelpOption(option){return this._helpOption=option,this}help(contextOptions){this.outputHelp(contextOptions);let exitCode=process2.exitCode||0;if(exitCode===0&&contextOptions&&typeof contextOptions!=="function"&&contextOptions.error)exitCode=1;this._exit(exitCode,"commander.help","(outputHelp)")}addHelpText(position,text){let allowedValues=["beforeAll","before","after","afterAll"];if(!allowedValues.includes(position))throw Error(`Unexpected value for position to addHelpText.
|
|
23
23
|
Expecting one of '${allowedValues.join("', '")}'`);let helpEvent=`${position}Help`;return this.on(helpEvent,(context)=>{let helpStr;if(typeof text==="function")helpStr=text({error:context.error,command:context.command});else helpStr=text;if(helpStr)context.write(`${helpStr}
|
|
24
|
-
`)}),this}_outputHelpIfRequested(args){let helpOption=this._getHelpOption();if(helpOption&&args.find((arg)=>helpOption.is(arg)))this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)")}}function incrementNodeInspectorPort(args){return args.map((arg)=>{if(!arg.startsWith("--inspect"))return arg;let debugOption,debugHost="127.0.0.1",debugPort="9229",match;if((match=arg.match(/^(--inspect(-brk)?)$/))!==null)debugOption=match[1];else if((match=arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null)if(debugOption=match[1],/^\d+$/.test(match[3]))debugPort=match[3];else debugHost=match[3];else if((match=arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null)debugOption=match[1],debugHost=match[3],debugPort=match[4];if(debugOption&&debugPort!=="0")return`${debugOption}=${debugHost}:${parseInt(debugPort)+1}`;return arg})}exports.Command=Command});var require_commander=__commonJS((exports)=>{var{Argument}=require_argument(),{Command}=require_command(),{CommanderError,InvalidArgumentError}=require_error(),{Help}=require_help(),{Option}=require_option();exports.program=new Command;exports.createCommand=(name)=>new Command(name);exports.createOption=(flags,description)=>new Option(flags,description);exports.createArgument=(name,description)=>new Argument(name,description);exports.Command=Command;exports.Option=Option;exports.Argument=Argument;exports.Help=Help;exports.CommanderError=CommanderError;exports.InvalidArgumentError=InvalidArgumentError;exports.InvalidOptionArgumentError=InvalidArgumentError});import{existsSync,mkdirSync,readFileSync,unlinkSync,writeFileSync}from"fs";import{homedir}from"os";import{join}from"path";function getClaudeSettingsPath(){return CLAUDE_SETTINGS_FILE}function getGenieHookScriptPath(){return join(CLAUDE_HOOKS_DIR,GENIE_HOOK_SCRIPT_NAME)}function hookScriptExists(){return existsSync(getGenieHookScriptPath())}function removeHookScript(){let scriptPath=getGenieHookScriptPath();if(existsSync(scriptPath))unlinkSync(scriptPath)}function ensureClaudeSettingsSafe(){let dir=join(homedir(),".claude");if(!existsSync(dir))mkdirSync(dir,{recursive:!0});let settings={};if(existsSync(CLAUDE_SETTINGS_FILE))try{settings=JSON.parse(readFileSync(CLAUDE_SETTINGS_FILE,"utf-8"))}catch{}let validTopologyValues=new Set(["auto","tmux","in-process"]),changed=!1;if("teammateMode"in settings&&!validTopologyValues.has(settings.teammateMode)){let{teammateMode:_removed,...rest}=settings;settings=rest,changed=!0}if(settings.skipDangerousModePermissionPrompt!==!0)settings.skipDangerousModePermissionPrompt=!0,changed=!0;if(changed)writeFileSync(CLAUDE_SETTINGS_FILE,`${JSON.stringify(settings,null,2)}
|
|
25
|
-
`,"utf-8")}function contractClaudePath(path){let home=homedir();if(path.startsWith(`${home}/`))return`~${path.slice(home.length)}`;if(path===home)return"~";return path}var CLAUDE_DIR,CLAUDE_HOOKS_DIR,CLAUDE_SETTINGS_FILE,GENIE_HOOK_SCRIPT_NAME="genie-bash-hook.sh";var init_claude_settings=__esm(()=>{CLAUDE_DIR=join(homedir(),".claude"),CLAUDE_HOOKS_DIR=join(CLAUDE_DIR,"hooks"),CLAUDE_SETTINGS_FILE=join(CLAUDE_DIR,"settings.json")});import{readdirSync}from"fs";import{dirname,join as join2}from"path";function getMigrationsDir(){return join2(import.meta.dir,"..","db","migrations")}function getPackageRootMigrationsDir(){return join2(dirname(import.meta.dir),"src","db","migrations")}async function loadMigrationFiles(){let candidates=[getMigrationsDir(),getPackageRootMigrationsDir()];for(let dir of candidates)try{let files=readdirSync(dir).filter((f)=>f.endsWith(".sql")).sort();if(files.length===0)continue;let migrations=[];for(let file of files){let content=await Bun.file(join2(dir,file)).text();migrations.push({name:file.replace(/\.sql$/,""),sql:content})}return migrations}catch{}return[]}async function ensureMigrationsTable(sql){await sql`
|
|
24
|
+
`)}),this}_outputHelpIfRequested(args){let helpOption=this._getHelpOption();if(helpOption&&args.find((arg)=>helpOption.is(arg)))this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)")}}function incrementNodeInspectorPort(args){return args.map((arg)=>{if(!arg.startsWith("--inspect"))return arg;let debugOption,debugHost="127.0.0.1",debugPort="9229",match;if((match=arg.match(/^(--inspect(-brk)?)$/))!==null)debugOption=match[1];else if((match=arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null)if(debugOption=match[1],/^\d+$/.test(match[3]))debugPort=match[3];else debugHost=match[3];else if((match=arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null)debugOption=match[1],debugHost=match[3],debugPort=match[4];if(debugOption&&debugPort!=="0")return`${debugOption}=${debugHost}:${parseInt(debugPort)+1}`;return arg})}exports.Command=Command});var require_commander=__commonJS((exports)=>{var{Argument}=require_argument(),{Command}=require_command(),{CommanderError,InvalidArgumentError}=require_error(),{Help}=require_help(),{Option}=require_option();exports.program=new Command;exports.createCommand=(name)=>new Command(name);exports.createOption=(flags,description)=>new Option(flags,description);exports.createArgument=(name,description)=>new Argument(name,description);exports.Command=Command;exports.Option=Option;exports.Argument=Argument;exports.Help=Help;exports.CommanderError=CommanderError;exports.InvalidArgumentError=InvalidArgumentError;exports.InvalidOptionArgumentError=InvalidArgumentError});import{existsSync,mkdirSync,readFileSync,unlinkSync,writeFileSync}from"fs";import{homedir}from"os";import{join}from"path";function getClaudeSettingsPath(){return CLAUDE_SETTINGS_FILE}function getGenieHookScriptPath(){return join(CLAUDE_HOOKS_DIR,GENIE_HOOK_SCRIPT_NAME)}function hookScriptExists(){return existsSync(getGenieHookScriptPath())}function removeHookScript(){let scriptPath=getGenieHookScriptPath();if(existsSync(scriptPath))unlinkSync(scriptPath)}function ensureClaudeSettingsSafe(){let dir=join(homedir(),".claude");if(!existsSync(dir))mkdirSync(dir,{recursive:!0});let settings={};if(existsSync(CLAUDE_SETTINGS_FILE))try{settings=JSON.parse(readFileSync(CLAUDE_SETTINGS_FILE,"utf-8"))}catch{}let validTopologyValues=new Set(["auto","tmux","in-process"]),changed=!1;if("teammateMode"in settings&&!validTopologyValues.has(settings.teammateMode)){let{teammateMode:_removed,...rest}=settings;settings=rest,changed=!0}if(settings.skipDangerousModePermissionPrompt!==!0)settings.skipDangerousModePermissionPrompt=!0,changed=!0;if(ensureBaselineAllowedTools(settings))changed=!0;if(changed)writeFileSync(CLAUDE_SETTINGS_FILE,`${JSON.stringify(settings,null,2)}
|
|
25
|
+
`,"utf-8")}function ensureBaselineAllowedTools(settings){let permissions=settings.permissions??{},allowStrings=(Array.isArray(permissions.allow)?permissions.allow:[]).filter((entry)=>typeof entry==="string"),missing=GENIE_BASELINE_ALLOWED_TOOLS.filter((tool)=>!allowStrings.includes(tool));if(missing.length===0)return!1;return permissions.allow=[...allowStrings,...missing],settings.permissions=permissions,!0}function contractClaudePath(path){let home=homedir();if(path.startsWith(`${home}/`))return`~${path.slice(home.length)}`;if(path===home)return"~";return path}var CLAUDE_DIR,CLAUDE_HOOKS_DIR,CLAUDE_SETTINGS_FILE,GENIE_HOOK_SCRIPT_NAME="genie-bash-hook.sh",GENIE_BASELINE_ALLOWED_TOOLS;var init_claude_settings=__esm(()=>{CLAUDE_DIR=join(homedir(),".claude"),CLAUDE_HOOKS_DIR=join(CLAUDE_DIR,"hooks"),CLAUDE_SETTINGS_FILE=join(CLAUDE_DIR,"settings.json");GENIE_BASELINE_ALLOWED_TOOLS=["AskUserQuestion"]});import{readdirSync}from"fs";import{dirname,join as join2}from"path";function getMigrationsDir(){return join2(import.meta.dir,"..","db","migrations")}function getPackageRootMigrationsDir(){return join2(dirname(import.meta.dir),"src","db","migrations")}async function loadMigrationFiles(){let candidates=[getMigrationsDir(),getPackageRootMigrationsDir()];for(let dir of candidates)try{let files=readdirSync(dir).filter((f)=>f.endsWith(".sql")).sort();if(files.length===0)continue;let migrations=[];for(let file of files){let content=await Bun.file(join2(dir,file)).text();migrations.push({name:file.replace(/\.sql$/,""),sql:content})}return migrations}catch{}return[]}async function ensureMigrationsTable(sql){await sql`
|
|
26
26
|
CREATE TABLE IF NOT EXISTS _genie_migrations (
|
|
27
27
|
id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
28
28
|
name TEXT UNIQUE NOT NULL,
|
|
@@ -186,16 +186,16 @@ ${prompt}`}function extractPromptPreamble(input){let match=input.match(PREAMBLE_
|
|
|
186
186
|
|
|
187
187
|
${content}`;if(params.extraArgs){let fileIdx=params.extraArgs.indexOf("--append-system-prompt-file");if(fileIdx!==-1&¶ms.extraArgs[fileIdx+1])content=`${content}
|
|
188
188
|
|
|
189
|
-
${readFileSync3(params.extraArgs[fileIdx+1],"utf-8")}`,params.extraArgs.splice(fileIdx,2)}writeFileSync2(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}
|
|
189
|
+
${readFileSync3(params.extraArgs[fileIdx+1],"utf-8")}`,params.extraArgs.splice(fileIdx,2)}writeFileSync2(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}let explicitAllow=params.permissions?.allow??[],explicitDeny=params.permissions?.deny??[],missingBaseline=GENIE_BASELINE_ALLOWED_TOOLS.filter((tool)=>!explicitAllow.includes(tool)),perms={allow:[...explicitAllow,...missingBaseline]};if(explicitDeny.length>0)perms.deny=explicitDeny;return settingsObj.permissions=perms,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).
|
|
190
190
|
`)}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:readFileSync3}=__require("fs"),sections=[];if(params.systemPromptFile!==void 0)sections.push(readFileSync3(params.systemPromptFile,"utf-8"));if(params.systemPrompt!==void 0)sections.push(params.systemPrompt);for(let promptFile of extraPromptFiles)sections.push(readFileSync3(promptFile,"utf-8"));if(params.initialPrompt!==void 0)sections.push(params.initialPrompt);return sections.length>0?sections.join(`
|
|
191
191
|
|
|
192
|
-
`):null}function writeCodexPromptFile(params,content){let{mkdirSync:mkdirSync2,writeFileSync:writeFileSync2}=__require("fs"),{join:join5}=__require("path");mkdirSync2(CODEX_PROMPT_DIR,{recursive:!0});let stem=sanitizeCodexPromptFileStem(params.executorId??Date.now().toString(36)),promptFile=join5(CODEX_PROMPT_DIR,`${stem}.txt`);return writeFileSync2(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(),allowedTools:exports_external.array(exports_external.string()).optional(),permissionMode:exports_external.enum(["default","acceptEdits","bypassPermissions","plan","dontAsk","auto","remoteApproval"]).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 palette;var init_palette=__esm(()=>{palette={bg:"#0a1d2a",bgRaised:"#0f2638",bgHover:"#143049",bgOverlay:"rgba(10, 29, 42, 0.92)",text:"#c9cfd4",textDim:"#8a9499",textMuted:"#5e6e74",border:"#2a3f4f",borderActive:"#7fc8a9",accent:"#7fc8a9",accentDim:"#5a9d82",accentBright:"#9eddc1",success:"#7fc8a9",warning:"#d4a574",error:"#a83838",errorBright:"#c44a4a",info:"#5a8ca8",beige:"#d4c5a9",innieGrey:"#5e6e74",outieAmber:"#d4a574",scrollTrack:"#2a3f4f",scrollThumb:"#5e6e74"}});var tokens;var init_tokens=__esm(()=>{init_palette();tokens={accent:palette.accent,accentDim:palette.accentDim,accentBright:palette.accentBright,surface:palette.bg,surfaceRaised:palette.bgRaised,surfaceHover:palette.bgHover,surfaceOverlay:palette.bgOverlay,text:palette.text,textDim:palette.textDim,textMuted:palette.textMuted,border:palette.border,borderActive:palette.borderActive,danger:palette.error,dangerStrong:palette.errorBright,attention:palette.warning,info:palette.info,success:palette.success,severed:palette.innieGrey,outieWarm:palette.outieAmber,lumonBeige:palette.beige}});function hexToRgb(hex){let m=hex.trim().match(/^#?([0-9a-fA-F]{6})$/);if(!m)throw Error(`Invalid hex: ${hex}`);let n=Number.parseInt(m[1],16);return[n>>16&255,n>>8&255,n&255]}function rgbToHex([r,g,b]){let c=(v)=>Math.max(0,Math.min(255,Math.round(v))).toString(16).padStart(2,"0");return`#${c(r)}${c(g)}${c(b)}`}function rgbToHsl([r,g,b]){let rn=r/255,gn=g/255,bn=b/255,max=Math.max(rn,gn,bn),min=Math.min(rn,gn,bn),l=(max+min)/2;if(max===min)return[0,0,l];let d=max-min,s=l>0.5?d/(2-max-min):d/(max+min),h;switch(max){case rn:h=((gn-bn)/d+(gn<bn?6:0))*60;break;case gn:h=((bn-rn)/d+2)*60;break;default:h=((rn-gn)/d+4)*60}return[h,s,l]}function hslToRgb([h,s,l]){if(s===0){let v=l*255;return[v,v,v]}let q=l<0.5?l*(1+s):l+s-l*s,p=2*l-q,hk=(h%360+360)%360/360,f=(t)=>{let tt=t;if(tt<0)tt+=1;if(tt>1)tt-=1;if(tt<0.16666666666666666)return p+(q-p)*6*tt;if(tt<0.5)return q;if(tt<0.6666666666666666)return p+(q-p)*(0.6666666666666666-tt)*6;return p};return[f(hk+0.3333333333333333)*255,f(hk)*255,f(hk-0.3333333333333333)*255]}function rotateHue(hex,deg){let[h,s,l]=rgbToHsl(hexToRgb(hex));return rgbToHex(hslToRgb([h+deg,s,l]))}var init_genie_tokens=__esm(()=>{init_palette();init_tokens()});var exports_ensure_tmux={};__export(exports_ensure_tmux,{tmuxBin:()=>tmuxBin,ensureTmux:()=>ensureTmux});import{execSync}from"child_process";import{chmodSync,copyFileSync,existsSync as existsSync4,mkdirSync as mkdirSync2,rmSync,unlinkSync as unlinkSync2,writeFileSync as writeFileSync2}from"fs";import{arch,homedir as homedir3,platform,tmpdir}from"os";import{join as join5}from"path";function getPlatformAsset(){let os=platform(),cpu=arch(),key=`${os}-${cpu}`,asset={"linux-x64":`tmux-${TMUX_VERSION}-linux-x86_64.tar.gz`,"linux-arm64":`tmux-${TMUX_VERSION}-linux-arm64.tar.gz`,"darwin-arm64":`tmux-${TMUX_VERSION}-macos-arm64.tar.gz`,"darwin-x64":`tmux-${TMUX_VERSION}-macos-x86_64.tar.gz`}[key];if(!asset)throw Error(`Unsupported platform: ${key}
|
|
192
|
+
`):null}function writeCodexPromptFile(params,content){let{mkdirSync:mkdirSync2,writeFileSync:writeFileSync2}=__require("fs"),{join:join5}=__require("path");mkdirSync2(CODEX_PROMPT_DIR,{recursive:!0});let stem=sanitizeCodexPromptFileStem(params.executorId??Date.now().toString(36)),promptFile=join5(CODEX_PROMPT_DIR,`${stem}.txt`);return writeFileSync2(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_claude_settings();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(),allowedTools:exports_external.array(exports_external.string()).optional(),permissionMode:exports_external.enum(["default","acceptEdits","bypassPermissions","plan","dontAsk","auto","remoteApproval"]).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 palette;var init_palette=__esm(()=>{palette={bg:"#0a1d2a",bgRaised:"#0f2638",bgHover:"#143049",bgOverlay:"rgba(10, 29, 42, 0.92)",text:"#c9cfd4",textDim:"#8a9499",textMuted:"#5e6e74",border:"#2a3f4f",borderActive:"#7fc8a9",accent:"#7fc8a9",accentDim:"#5a9d82",accentBright:"#9eddc1",success:"#7fc8a9",warning:"#d4a574",error:"#a83838",errorBright:"#c44a4a",info:"#5a8ca8",beige:"#d4c5a9",innieGrey:"#5e6e74",outieAmber:"#d4a574",scrollTrack:"#2a3f4f",scrollThumb:"#5e6e74"}});var tokens;var init_tokens=__esm(()=>{init_palette();tokens={accent:palette.accent,accentDim:palette.accentDim,accentBright:palette.accentBright,surface:palette.bg,surfaceRaised:palette.bgRaised,surfaceHover:palette.bgHover,surfaceOverlay:palette.bgOverlay,text:palette.text,textDim:palette.textDim,textMuted:palette.textMuted,border:palette.border,borderActive:palette.borderActive,danger:palette.error,dangerStrong:palette.errorBright,attention:palette.warning,info:palette.info,success:palette.success,severed:palette.innieGrey,outieWarm:palette.outieAmber,lumonBeige:palette.beige}});function hexToRgb(hex){let m=hex.trim().match(/^#?([0-9a-fA-F]{6})$/);if(!m)throw Error(`Invalid hex: ${hex}`);let n=Number.parseInt(m[1],16);return[n>>16&255,n>>8&255,n&255]}function rgbToHex([r,g,b]){let c=(v)=>Math.max(0,Math.min(255,Math.round(v))).toString(16).padStart(2,"0");return`#${c(r)}${c(g)}${c(b)}`}function rgbToHsl([r,g,b]){let rn=r/255,gn=g/255,bn=b/255,max=Math.max(rn,gn,bn),min=Math.min(rn,gn,bn),l=(max+min)/2;if(max===min)return[0,0,l];let d=max-min,s=l>0.5?d/(2-max-min):d/(max+min),h;switch(max){case rn:h=((gn-bn)/d+(gn<bn?6:0))*60;break;case gn:h=((bn-rn)/d+2)*60;break;default:h=((rn-gn)/d+4)*60}return[h,s,l]}function hslToRgb([h,s,l]){if(s===0){let v=l*255;return[v,v,v]}let q=l<0.5?l*(1+s):l+s-l*s,p=2*l-q,hk=(h%360+360)%360/360,f=(t)=>{let tt=t;if(tt<0)tt+=1;if(tt>1)tt-=1;if(tt<0.16666666666666666)return p+(q-p)*6*tt;if(tt<0.5)return q;if(tt<0.6666666666666666)return p+(q-p)*(0.6666666666666666-tt)*6;return p};return[f(hk+0.3333333333333333)*255,f(hk)*255,f(hk-0.3333333333333333)*255]}function rotateHue(hex,deg){let[h,s,l]=rgbToHsl(hexToRgb(hex));return rgbToHex(hslToRgb([h+deg,s,l]))}var init_genie_tokens=__esm(()=>{init_palette();init_tokens()});var exports_ensure_tmux={};__export(exports_ensure_tmux,{tmuxBin:()=>tmuxBin,ensureTmux:()=>ensureTmux});import{execSync}from"child_process";import{chmodSync,copyFileSync,existsSync as existsSync4,mkdirSync as mkdirSync2,rmSync,unlinkSync as unlinkSync2,writeFileSync as writeFileSync2}from"fs";import{arch,homedir as homedir3,platform,tmpdir}from"os";import{join as join5}from"path";function getPlatformAsset(){let os=platform(),cpu=arch(),key=`${os}-${cpu}`,asset={"linux-x64":`tmux-${TMUX_VERSION}-linux-x86_64.tar.gz`,"linux-arm64":`tmux-${TMUX_VERSION}-linux-arm64.tar.gz`,"darwin-arm64":`tmux-${TMUX_VERSION}-macos-arm64.tar.gz`,"darwin-x64":`tmux-${TMUX_VERSION}-macos-x86_64.tar.gz`}[key];if(!asset)throw Error(`Unsupported platform: ${key}
|
|
193
193
|
tmux auto-download supports: linux-x64, linux-arm64, macos-arm64, macos-x64.
|
|
194
194
|
Install tmux manually: https://github.com/tmux/tmux/wiki/Installing`);return asset}function genieHome(){return process.env.GENIE_HOME??join5(homedir3(),".genie")}function genieBinDir(){return join5(genieHome(),"bin")}function cachedTmuxPath(){return join5(genieBinDir(),"tmux")}function tmuxBin(){if(_resolved)return _resolved;try{let p=execSync("which tmux",{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}).trim();if(p)return _resolved=p,p}catch{}let cached=cachedTmuxPath();if(existsSync4(cached))return _resolved=cached,cached;return"tmux"}async function ensureTmux(){let bin=tmuxBin();if(bin!=="tmux")return bin;return downloadTmux()}async function downloadTmux(){let asset=getPlatformAsset(),url=process.env.GENIE_TMUX_URL??`https://github.com/tmux/tmux-builds/releases/download/v${TMUX_VERSION}/${asset}`,dest=cachedTmuxPath(),tempDir=join5(tmpdir(),`genie-tmux-download-${Date.now()}`);console.log(" tmux not found \u2014 downloading static binary..."),console.log(` ${url}`);try{let response=await fetch(url);if(!response.ok)throw Error(`HTTP ${response.status} ${response.statusText}`);let buffer=Buffer.from(await response.arrayBuffer()),sizeMB=(buffer.byteLength/1024/1024).toFixed(1);console.log(` Downloaded ${sizeMB} MB`),mkdirSync2(tempDir,{recursive:!0});let tarballPath=join5(tempDir,asset);writeFileSync2(tarballPath,buffer),execSync(`tar -xzf '${tarballPath}' -C '${tempDir}'`,{stdio:"ignore"});let extractedBin=join5(tempDir,"tmux");if(!existsSync4(extractedBin))throw Error("Tarball did not contain a tmux binary");mkdirSync2(genieBinDir(),{recursive:!0}),copyFileSync(extractedBin,dest),chmodSync(dest,493);let version=execSync(`'${dest}' -V`,{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}).trim();return _resolved=dest,console.log(` ${version} installed to ${dest}`),dest}catch(err){try{if(existsSync4(dest))unlinkSync2(dest)}catch{}let msg=err instanceof Error?err.message:String(err);throw Error(`Failed to download tmux: ${msg}
|
|
195
195
|
Install manually:
|
|
196
196
|
Linux: sudo apt install tmux
|
|
197
|
-
macOS: brew install tmux`)}finally{try{rmSync(tempDir,{recursive:!0,force:!0})}catch{}}}var TMUX_VERSION="3.6a",_resolved=null;var init_ensure_tmux=()=>{};var SessionConfigSchema,TerminalConfigSchema,LoggingConfigSchema,ShellConfigSchema,ShortcutsConfigSchema,CodexConfigSchema,WorkerProfileSchema,OtelConfigSchema,OmniConfigSchema,BrainConfigSchema,CouncilPresetSchema,GenieConfigSchema;var init_genie_config=__esm(()=>{init_zod();SessionConfigSchema=exports_external.object({name:exports_external.string().default("genie"),defaultWindow:exports_external.string().default("shell"),autoCreate:exports_external.boolean().default(!0)}),TerminalConfigSchema=exports_external.object({execTimeout:exports_external.number().default(120000),readLines:exports_external.number().default(100),worktreeBase:exports_external.string().optional()}),LoggingConfigSchema=exports_external.object({tmuxDebug:exports_external.boolean().default(!1),verbose:exports_external.boolean().default(!1)}),ShellConfigSchema=exports_external.object({preference:exports_external.enum(["auto","zsh","bash","fish"]).default("auto")}),ShortcutsConfigSchema=exports_external.object({tmuxInstalled:exports_external.boolean().default(!1),shellInstalled:exports_external.boolean().default(!1)}),CodexConfigSchema=exports_external.object({configured:exports_external.boolean().default(!1)}),WorkerProfileSchema=exports_external.object({launcher:exports_external.preprocess((val)=>val==="claudio"?"claude":val,exports_external.literal("claude")),claudeArgs:exports_external.array(exports_external.string())}).passthrough(),OtelConfigSchema=exports_external.object({enabled:exports_external.boolean().default(!0),port:exports_external.number().optional(),logPrompts:exports_external.boolean().default(!0)}),OmniConfigSchema=exports_external.object({apiUrl:exports_external.string(),apiKey:exports_external.string().optional(),defaultInstanceId:exports_external.string().optional(),executor:exports_external.enum(["tmux","sdk"]).optional()}),BrainConfigSchema=exports_external.object({embedded:exports_external.boolean().default(!0),paths:exports_external.array(exports_external.string()).optional()}),CouncilPresetSchema=exports_external.object({left:exports_external.string(),right:exports_external.string(),skill:exports_external.string().default("council")}),GenieConfigSchema=exports_external.object({version:exports_external.number().default(2),session:SessionConfigSchema.default({}),terminal:TerminalConfigSchema.default({}),logging:LoggingConfigSchema.default({}),shell:ShellConfigSchema.default({}),shortcuts:ShortcutsConfigSchema.default({}),codex:CodexConfigSchema.optional(),installMethod:exports_external.enum(["source","npm","bun"]).optional(),updateChannel:exports_external.enum(["latest","next"]).default("latest"),setupComplete:exports_external.boolean().default(!1),lastSetupAt:exports_external.string().optional(),sourcePath:exports_external.string().optional(),workerProfiles:exports_external.record(exports_external.string(),WorkerProfileSchema).optional(),defaultWorkerProfile:exports_external.string().optional(),councilPresets:exports_external.record(exports_external.string(),CouncilPresetSchema).optional(),defaultCouncilPreset:exports_external.string().optional(),promptMode:exports_external.enum(["append","system"]).default("append"),autoMergeDev:exports_external.boolean().default(!1),defaultProject:exports_external.string().optional(),otel:OtelConfigSchema.optional(),omni:OmniConfigSchema.optional(),brain:BrainConfigSchema.default({})})});var exports_genie_config={};__export(exports_genie_config,{updateShortcutsConfig:()=>updateShortcutsConfig,saveGenieConfig:()=>saveGenieConfig,resetConfig:()=>resetConfig,markSetupComplete:()=>markSetupComplete,loadGenieConfigSync:()=>loadGenieConfigSync,loadGenieConfig:()=>loadGenieConfig,isSetupComplete:()=>isSetupComplete,getTerminalConfig:()=>getTerminalConfig,getGenieDir:()=>getGenieDir,getGenieConfigPath:()=>getGenieConfigPath,genieConfigExists:()=>genieConfigExists,contractPath:()=>contractPath});import{existsSync as existsSync5,mkdirSync as mkdirSync3,readFileSync as readFileSync3,writeFileSync as writeFileSync3}from"fs";import{homedir as homedir4}from"os";import{join as join6}from"path";function getGenieDir(){return GENIE_DIR}function getGenieConfigPath(){return GENIE_CONFIG_FILE}function genieConfigExists(){return existsSync5(GENIE_CONFIG_FILE)}function ensureGenieDir(){if(!existsSync5(GENIE_DIR))mkdirSync3(GENIE_DIR,{recursive:!0})}async function loadGenieConfig(){if(!existsSync5(GENIE_CONFIG_FILE))return GenieConfigSchema.parse({});try{let content=readFileSync3(GENIE_CONFIG_FILE,"utf-8"),data=JSON.parse(content);return GenieConfigSchema.parse(data)}catch(error){let message=error instanceof Error?error.message:String(error);return console.warn(`Warning: Invalid genie config, using defaults: ${message}`),GenieConfigSchema.parse({})}}async function saveGenieConfig(config){ensureGenieDir();try{let validated=GenieConfigSchema.parse(config),content=JSON.stringify(validated,null,2);writeFileSync3(GENIE_CONFIG_FILE,content,"utf-8")}catch(error){let message=error instanceof Error?error.message:String(error);throw Error(`Failed to save genie config: ${message}`)}}function getDefaultGenieConfig(){return GenieConfigSchema.parse({})}function loadGenieConfigSync(){if(!existsSync5(GENIE_CONFIG_FILE))return GenieConfigSchema.parse({});try{let content=readFileSync3(GENIE_CONFIG_FILE,"utf-8"),data=JSON.parse(content);return GenieConfigSchema.parse(data)}catch{return GenieConfigSchema.parse({})}}function contractPath(path){let home=homedir4();if(path.startsWith(`${home}/`))return`~${path.slice(home.length)}`;if(path===home)return"~";return path}function getTerminalConfig(){return loadGenieConfigSync().terminal}function isSetupComplete(){if(!genieConfigExists())return!1;return loadGenieConfigSync().setupComplete??!1}async function markSetupComplete(){let config=await loadGenieConfig();config.setupComplete=!0,config.lastSetupAt=new Date().toISOString(),await saveGenieConfig(config)}async function resetConfig(){let defaultConfig=getDefaultGenieConfig();await saveGenieConfig(defaultConfig)}async function updateShortcutsConfig(partial){let config=await loadGenieConfig();config.shortcuts={...config.shortcuts,...partial},await saveGenieConfig(config)}var GENIE_DIR,GENIE_CONFIG_FILE;var init_genie_config2=__esm(()=>{init_genie_config();GENIE_DIR=join6(homedir4(),".genie"),GENIE_CONFIG_FILE=join6(GENIE_DIR,"config.json")});var exports_team_lead_command={};__export(exports_team_lead_command,{shellQuote:()=>shellQuote,sessionExists:()=>sessionExists,ccProjectDirName:()=>ccProjectDirName,buildTeamLeadCommand:()=>buildTeamLeadCommand});import{readFileSync as readFileSync4,readdirSync as readdirSync3}from"fs";import{join as join7}from"path";function shellQuote(s){return`'${s.replace(/'/g,"'\\''")}'`}function buildTeamLeadCommand(teamName,options){let sanitized=sanitizeTeamName(teamName),qTeam=shellQuote(sanitized),resolvedLeader=options?.leaderName??teamName,sanitizedLeader=sanitizeTeamName(resolvedLeader),parts=["GENIE_WORKER=1","CLAUDECODE=1","CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1",`GENIE_TEAM=${qTeam}`,`GENIE_AGENT_NAME=${shellQuote(sanitizedLeader)}`,"claude",`--agent-id ${shellQuote(`${sanitizedLeader}@${sanitized}`)}`,`--agent-name ${shellQuote(sanitizedLeader)}`,`--team-name ${qTeam}`,"--agent-type team-lead","--permission-mode auto"];if(parts.push(`--name ${shellQuote(sanitized)}`),options?.sessionId){let flag=options.resume?"--resume":"--session-id";parts.push(`${flag} ${shellQuote(options.sessionId)}`)}if(options?.systemPromptFile){let promptFlag=(options?.promptMode??loadGenieConfigSync().promptMode)==="system"?"--system-prompt-file":"--append-system-prompt-file";parts.push(`${promptFlag} ${shellQuote(options.systemPromptFile)}`)}return parts.join(" ")}function ccProjectDirName(dir){return dir.replace(/\//g,"-")}function fileHasSessionName(filePath,needle){try{let lines=readFileSync4(filePath,"utf-8").split(`
|
|
198
|
-
`).slice(0,10);for(let line of lines){if(!line.includes("custom-title"))continue;let entry=JSON.parse(line);if(entry.type==="custom-title"&&entry.customTitle?.toLowerCase()===needle)return!0}}catch{}return!1}function sessionExists(name,cwd){try{let home=process.env.HOME??"/root",projectDir=ccProjectDirName(cwd??process.cwd()),projectPath=join7(home,".claude","projects",projectDir),files;try{files=readdirSync3(projectPath).filter((f)=>f.endsWith(".jsonl"))}catch{return!1}let needle=name.toLowerCase();return files.some((file)=>{let full=join7(projectPath,file);return fileHasSessionName(full,needle)||fileHasSessionName(full,`${needle}-${needle}`)})}catch{return!1}}var init_team_lead_command=__esm(()=>{init_claude_native_teams();init_genie_config2()});var exports_tmux_wrapper={};__export(exports_tmux_wrapper,{prependEnvVars:()=>prependEnvVars,genieTmuxPrefix:()=>genieTmuxPrefix,genieTmuxCmd:()=>genieTmuxCmd,executeTmux:()=>executeTmux});import{exec as execCallback}from"child_process";import{existsSync as existsSync6,mkdirSync as mkdirSync4}from"fs";import{homedir as homedir5}from"os";import{join as join8}from"path";import{promisify}from"util";function resolveGenieTmuxConf(){let home=homedir5(),genieHome2=process.env.GENIE_HOME??join8(home,".genie");return[join8(genieHome2,"tmux.conf"),join8(__dirname,"..","..","scripts","tmux","genie.tmux.conf"),join8(home,".bun","install","global","node_modules","@automagik","genie","scripts","tmux","genie.tmux.conf")].find((p)=>existsSync6(p))??"/dev/null"}function genieTmuxPrefix(){return["-L",GENIE_TMUX_SOCKET,"-f",resolveGenieTmuxConf()]}function genieTmuxCmd(subcommand){return`${tmuxBin()} ${genieTmuxPrefix().join(" ")} ${subcommand}`}function prependEnvVars(command,env){if(!env||Object.keys(env).length===0)return command;return`env ${Object.entries(env).map(([k,v])=>`${k}=${v}`).join(" ")} ${command}`}function getLogDir(){let logDir=join8(homedir5(),".genie","logs","tmux");if(!existsSync6(logDir))mkdirSync4(logDir,{recursive:!0});return logDir}function stripVerboseFlags(args){return args.filter((arg)=>!/^-v+$/.test(arg))}function isTmuxDebugEnabled(){return process.env.GENIE_TMUX_DEBUG==="1"}async function executeTmux(args){let argList=typeof args==="string"?args.split(/\s+/).filter(Boolean):args,finalArgs=stripVerboseFlags(argList),debugMode=isTmuxDebugEnabled(),options={};if(debugMode)finalArgs=["-v",...finalArgs],options.cwd=getLogDir();finalArgs=[...genieTmuxPrefix(),...finalArgs];let command=`${tmuxBin()} ${finalArgs.join(" ")}`,{stdout}=await exec(command,options);return stdout.trim()}var __dirname="/home/runner/_work/genie/genie/src/lib",exec,GENIE_TMUX_SOCKET;var init_tmux_wrapper=__esm(()=>{init_ensure_tmux();exec=promisify(execCallback),GENIE_TMUX_SOCKET=process.env.GENIE_TMUX_SOCKET||"genie"});var exports_tmux={};__export(exports_tmux,{setWindowEnv:()=>setWindowEnv,resolveRepoSession:()=>resolveRepoSession,listWindows:()=>listWindows,listPanes:()=>listPanes,killWindow:()=>killWindow,killSession:()=>killSession,isTmuxServerReachable:()=>isTmuxServerReachable,isPaneProcessRunning:()=>isPaneProcessRunning,isPaneAlive:()=>isPaneAlive,getWindowEnv:()=>getWindowEnv,getCurrentSessionName:()=>getCurrentSessionName,findWindowByName:()=>findWindowByName,findSessionByName:()=>findSessionByName,executeTmux:()=>executeTmux2,ensureTeamWindow:()=>ensureTeamWindow,createSession:()=>createSession,capturePaneContent:()=>capturePaneContent,applyPaneColor:()=>applyPaneColor,TmuxUnreachableError:()=>TmuxUnreachableError});import{existsSync as existsSync7}from"fs";import{basename,join as join9}from"path";async function executeTmux2(tmuxCommand){let{executeTmux:wrapperExec}=await Promise.resolve().then(() => (init_tmux_wrapper(),exports_tmux_wrapper));try{return await wrapperExec(tmuxCommand)}catch(error){let message=error instanceof Error?error.message:String(error);throw Error(`Failed to execute tmux command: ${message}`)}}async function getCurrentSessionName(hint){if(process.env.TMUX)try{return(await executeTmux2("display-message -p '#{session_name}'")).trim()||null}catch{return null}try{let sessions=await listSessions();if(sessions.length===0)return null;if(hint){let match=sessions.find((s)=>s.name.includes(hint));if(match)return match.name}return sessions[0].name}catch{return null}}async function listSessions(){try{let output=await executeTmux2("list-sessions -F '#{session_id}:#{session_name}:#{?session_attached,1,0}:#{session_windows}'");if(!output)return[];return output.split(`
|
|
197
|
+
macOS: brew install tmux`)}finally{try{rmSync(tempDir,{recursive:!0,force:!0})}catch{}}}var TMUX_VERSION="3.6a",_resolved=null;var init_ensure_tmux=()=>{};var SessionConfigSchema,TerminalConfigSchema,LoggingConfigSchema,ShellConfigSchema,ShortcutsConfigSchema,CodexConfigSchema,WorkerProfileSchema,OtelConfigSchema,OmniConfigSchema,BrainConfigSchema,CouncilPresetSchema,GenieConfigSchema;var init_genie_config=__esm(()=>{init_zod();SessionConfigSchema=exports_external.object({name:exports_external.string().default("genie"),defaultWindow:exports_external.string().default("shell"),autoCreate:exports_external.boolean().default(!0)}),TerminalConfigSchema=exports_external.object({execTimeout:exports_external.number().default(120000),readLines:exports_external.number().default(100),worktreeBase:exports_external.string().optional()}),LoggingConfigSchema=exports_external.object({tmuxDebug:exports_external.boolean().default(!1),verbose:exports_external.boolean().default(!1)}),ShellConfigSchema=exports_external.object({preference:exports_external.enum(["auto","zsh","bash","fish"]).default("auto")}),ShortcutsConfigSchema=exports_external.object({tmuxInstalled:exports_external.boolean().default(!1),shellInstalled:exports_external.boolean().default(!1)}),CodexConfigSchema=exports_external.object({configured:exports_external.boolean().default(!1)}),WorkerProfileSchema=exports_external.object({launcher:exports_external.preprocess((val)=>val==="claudio"?"claude":val,exports_external.literal("claude")),claudeArgs:exports_external.array(exports_external.string())}).passthrough(),OtelConfigSchema=exports_external.object({enabled:exports_external.boolean().default(!0),port:exports_external.number().optional(),logPrompts:exports_external.boolean().default(!0)}),OmniConfigSchema=exports_external.object({apiUrl:exports_external.string(),apiKey:exports_external.string().optional(),defaultInstanceId:exports_external.string().optional(),executor:exports_external.enum(["tmux","sdk"]).optional()}),BrainConfigSchema=exports_external.object({embedded:exports_external.boolean().default(!0),paths:exports_external.array(exports_external.string()).optional()}),CouncilPresetSchema=exports_external.object({left:exports_external.string(),right:exports_external.string(),skill:exports_external.string().default("council")}),GenieConfigSchema=exports_external.object({version:exports_external.number().default(2),session:SessionConfigSchema.default({}),terminal:TerminalConfigSchema.default({}),logging:LoggingConfigSchema.default({}),shell:ShellConfigSchema.default({}),shortcuts:ShortcutsConfigSchema.default({}),codex:CodexConfigSchema.optional(),installMethod:exports_external.enum(["source","npm","bun"]).optional(),updateChannel:exports_external.enum(["latest","next"]).default("latest"),setupComplete:exports_external.boolean().default(!1),lastSetupAt:exports_external.string().optional(),sourcePath:exports_external.string().optional(),workerProfiles:exports_external.record(exports_external.string(),WorkerProfileSchema).optional(),defaultWorkerProfile:exports_external.string().optional(),councilPresets:exports_external.record(exports_external.string(),CouncilPresetSchema).optional(),defaultCouncilPreset:exports_external.string().optional(),promptMode:exports_external.enum(["append","system"]).default("append"),autoMergeDev:exports_external.boolean().default(!1),defaultProject:exports_external.string().optional(),otel:OtelConfigSchema.optional(),omni:OmniConfigSchema.optional(),brain:BrainConfigSchema.default({})})});var exports_genie_config={};__export(exports_genie_config,{updateShortcutsConfig:()=>updateShortcutsConfig,saveGenieConfig:()=>saveGenieConfig,resetConfig:()=>resetConfig,markSetupComplete:()=>markSetupComplete,loadGenieConfigSync:()=>loadGenieConfigSync,loadGenieConfig:()=>loadGenieConfig,isSetupComplete:()=>isSetupComplete,getTerminalConfig:()=>getTerminalConfig,getGenieDir:()=>getGenieDir,getGenieConfigPath:()=>getGenieConfigPath,genieConfigExists:()=>genieConfigExists,contractPath:()=>contractPath});import{existsSync as existsSync5,mkdirSync as mkdirSync3,readFileSync as readFileSync3,writeFileSync as writeFileSync3}from"fs";import{homedir as homedir4}from"os";import{join as join6}from"path";function getGenieDir(){return GENIE_DIR}function getGenieConfigPath(){return GENIE_CONFIG_FILE}function genieConfigExists(){return existsSync5(GENIE_CONFIG_FILE)}function ensureGenieDir(){if(!existsSync5(GENIE_DIR))mkdirSync3(GENIE_DIR,{recursive:!0})}async function loadGenieConfig(){if(!existsSync5(GENIE_CONFIG_FILE))return GenieConfigSchema.parse({});try{let content=readFileSync3(GENIE_CONFIG_FILE,"utf-8"),data=JSON.parse(content);return GenieConfigSchema.parse(data)}catch(error){let message=error instanceof Error?error.message:String(error);return console.warn(`Warning: Invalid genie config, using defaults: ${message}`),GenieConfigSchema.parse({})}}async function saveGenieConfig(config){ensureGenieDir();try{let validated=GenieConfigSchema.parse(config),content=JSON.stringify(validated,null,2);writeFileSync3(GENIE_CONFIG_FILE,content,"utf-8")}catch(error){let message=error instanceof Error?error.message:String(error);throw Error(`Failed to save genie config: ${message}`)}}function getDefaultGenieConfig(){return GenieConfigSchema.parse({})}function loadGenieConfigSync(){if(!existsSync5(GENIE_CONFIG_FILE))return GenieConfigSchema.parse({});try{let content=readFileSync3(GENIE_CONFIG_FILE,"utf-8"),data=JSON.parse(content);return GenieConfigSchema.parse(data)}catch{return GenieConfigSchema.parse({})}}function contractPath(path){let home=homedir4();if(path.startsWith(`${home}/`))return`~${path.slice(home.length)}`;if(path===home)return"~";return path}function getTerminalConfig(){return loadGenieConfigSync().terminal}function isSetupComplete(){if(!genieConfigExists())return!1;return loadGenieConfigSync().setupComplete??!1}async function markSetupComplete(){let config=await loadGenieConfig();config.setupComplete=!0,config.lastSetupAt=new Date().toISOString(),await saveGenieConfig(config)}async function resetConfig(){let defaultConfig=getDefaultGenieConfig();await saveGenieConfig(defaultConfig)}async function updateShortcutsConfig(partial){let config=await loadGenieConfig();config.shortcuts={...config.shortcuts,...partial},await saveGenieConfig(config)}var GENIE_DIR,GENIE_CONFIG_FILE;var init_genie_config2=__esm(()=>{init_genie_config();GENIE_DIR=join6(homedir4(),".genie"),GENIE_CONFIG_FILE=join6(GENIE_DIR,"config.json")});var exports_team_lead_command={};__export(exports_team_lead_command,{shellQuote:()=>shellQuote,sessionExists:()=>sessionExists,ccProjectDirName:()=>ccProjectDirName,buildTeamLeadCommand:()=>buildTeamLeadCommand});import{readFileSync as readFileSync4,readdirSync as readdirSync3}from"fs";import{join as join7}from"path";function shellQuote(s){return`'${s.replace(/'/g,"'\\''")}'`}function buildTeamLeadCommand(teamName,options){let sanitized=sanitizeTeamName(teamName),qTeam=shellQuote(sanitized),resolvedLeader=options?.leaderName??teamName,sanitizedLeader=sanitizeTeamName(resolvedLeader),parts=["GENIE_WORKER=1","CLAUDECODE=1","CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1",`GENIE_TEAM=${qTeam}`,`GENIE_AGENT_NAME=${shellQuote(sanitizedLeader)}`,"claude",`--agent-id ${shellQuote(`${sanitizedLeader}@${sanitized}`)}`,`--agent-name ${shellQuote(sanitizedLeader)}`,`--team-name ${qTeam}`,"--agent-type team-lead","--permission-mode auto"];if(parts.push(`--name ${shellQuote(sanitized)}`),options?.sessionId){let flag=options.resume?"--resume":"--session-id";parts.push(`${flag} ${shellQuote(options.sessionId)}`)}if(options?.systemPromptFile){let promptFlag=(options?.promptMode??loadGenieConfigSync().promptMode)==="system"?"--system-prompt-file":"--append-system-prompt-file";parts.push(`${promptFlag} ${shellQuote(options.systemPromptFile)}`)}let baselineSettings=JSON.stringify({permissions:{allow:[...GENIE_BASELINE_ALLOWED_TOOLS]}});return parts.push(`--settings ${shellQuote(baselineSettings)}`),parts.join(" ")}function ccProjectDirName(dir){return dir.replace(/\//g,"-")}function fileHasSessionName(filePath,needle){try{let lines=readFileSync4(filePath,"utf-8").split(`
|
|
198
|
+
`).slice(0,10);for(let line of lines){if(!line.includes("custom-title"))continue;let entry=JSON.parse(line);if(entry.type==="custom-title"&&entry.customTitle?.toLowerCase()===needle)return!0}}catch{}return!1}function sessionExists(name,cwd){try{let home=process.env.HOME??"/root",projectDir=ccProjectDirName(cwd??process.cwd()),projectPath=join7(home,".claude","projects",projectDir),files;try{files=readdirSync3(projectPath).filter((f)=>f.endsWith(".jsonl"))}catch{return!1}let needle=name.toLowerCase();return files.some((file)=>{let full=join7(projectPath,file);return fileHasSessionName(full,needle)||fileHasSessionName(full,`${needle}-${needle}`)})}catch{return!1}}var init_team_lead_command=__esm(()=>{init_claude_native_teams();init_claude_settings();init_genie_config2()});var exports_tmux_wrapper={};__export(exports_tmux_wrapper,{prependEnvVars:()=>prependEnvVars,genieTmuxPrefix:()=>genieTmuxPrefix,genieTmuxCmd:()=>genieTmuxCmd,executeTmux:()=>executeTmux});import{exec as execCallback}from"child_process";import{existsSync as existsSync6,mkdirSync as mkdirSync4}from"fs";import{homedir as homedir5}from"os";import{join as join8}from"path";import{promisify}from"util";function resolveGenieTmuxConf(){let home=homedir5(),genieHome2=process.env.GENIE_HOME??join8(home,".genie");return[join8(genieHome2,"tmux.conf"),join8(__dirname,"..","..","scripts","tmux","genie.tmux.conf"),join8(home,".bun","install","global","node_modules","@automagik","genie","scripts","tmux","genie.tmux.conf")].find((p)=>existsSync6(p))??"/dev/null"}function genieTmuxPrefix(){return["-L",GENIE_TMUX_SOCKET,"-f",resolveGenieTmuxConf()]}function genieTmuxCmd(subcommand){return`${tmuxBin()} ${genieTmuxPrefix().join(" ")} ${subcommand}`}function prependEnvVars(command,env){if(!env||Object.keys(env).length===0)return command;return`env ${Object.entries(env).map(([k,v])=>`${k}=${v}`).join(" ")} ${command}`}function getLogDir(){let logDir=join8(homedir5(),".genie","logs","tmux");if(!existsSync6(logDir))mkdirSync4(logDir,{recursive:!0});return logDir}function stripVerboseFlags(args){return args.filter((arg)=>!/^-v+$/.test(arg))}function isTmuxDebugEnabled(){return process.env.GENIE_TMUX_DEBUG==="1"}async function executeTmux(args){let argList=typeof args==="string"?args.split(/\s+/).filter(Boolean):args,finalArgs=stripVerboseFlags(argList),debugMode=isTmuxDebugEnabled(),options={};if(debugMode)finalArgs=["-v",...finalArgs],options.cwd=getLogDir();finalArgs=[...genieTmuxPrefix(),...finalArgs];let command=`${tmuxBin()} ${finalArgs.join(" ")}`,{stdout}=await exec(command,options);return stdout.trim()}var __dirname="/home/runner/_work/genie/genie/src/lib",exec,GENIE_TMUX_SOCKET;var init_tmux_wrapper=__esm(()=>{init_ensure_tmux();exec=promisify(execCallback),GENIE_TMUX_SOCKET=process.env.GENIE_TMUX_SOCKET||"genie"});var exports_tmux={};__export(exports_tmux,{setWindowEnv:()=>setWindowEnv,resolveRepoSession:()=>resolveRepoSession,listWindows:()=>listWindows,listPanes:()=>listPanes,killWindow:()=>killWindow,killSession:()=>killSession,isTmuxServerReachable:()=>isTmuxServerReachable,isPaneProcessRunning:()=>isPaneProcessRunning,isPaneAlive:()=>isPaneAlive,getWindowEnv:()=>getWindowEnv,getCurrentSessionName:()=>getCurrentSessionName,findWindowByName:()=>findWindowByName,findSessionByName:()=>findSessionByName,executeTmux:()=>executeTmux2,ensureTeamWindow:()=>ensureTeamWindow,createSession:()=>createSession,capturePaneContent:()=>capturePaneContent,applyPaneColor:()=>applyPaneColor,TmuxUnreachableError:()=>TmuxUnreachableError});import{existsSync as existsSync7}from"fs";import{basename,join as join9}from"path";async function executeTmux2(tmuxCommand){let{executeTmux:wrapperExec}=await Promise.resolve().then(() => (init_tmux_wrapper(),exports_tmux_wrapper));try{return await wrapperExec(tmuxCommand)}catch(error){let message=error instanceof Error?error.message:String(error);throw Error(`Failed to execute tmux command: ${message}`)}}async function getCurrentSessionName(hint){if(process.env.TMUX)try{return(await executeTmux2("display-message -p '#{session_name}'")).trim()||null}catch{return null}try{let sessions=await listSessions();if(sessions.length===0)return null;if(hint){let match=sessions.find((s)=>s.name.includes(hint));if(match)return match.name}return sessions[0].name}catch{return null}}async function listSessions(){try{let output=await executeTmux2("list-sessions -F '#{session_id}:#{session_name}:#{?session_attached,1,0}:#{session_windows}'");if(!output)return[];return output.split(`
|
|
199
199
|
`).map((line)=>{let[id,name,attached,windows]=line.split(":");return{id,name,attached:attached==="1",windows:Number.parseInt(windows,10)}})}catch(error){if((error instanceof Error?error.message:String(error)).includes("no server running"))return[];throw error}}async function findSessionByName(name){try{return(await listSessions()).find((session)=>session.name===name)||null}catch(_error){return null}}async function getWindowEnv(target,varName){try{let output=await executeTmux2(`show-environment -t ${shellQuote(target)} ${shellQuote(varName)}`),prefix=`${varName}=`;if(output?.startsWith(prefix))return output.slice(prefix.length).trim();return null}catch{return null}}async function setWindowEnv(target,varName,value){await executeTmux2(`set-environment -t ${shellQuote(target)} ${shellQuote(varName)} ${shellQuote(value)}`)}async function killSession(sessionId){await executeTmux2(`kill-session -t '${sessionId}'`)}async function listWindows(sessionId){try{let output=await executeTmux2(`list-windows -t '=${sessionId}' -F '#{window_id}:#{window_name}:#{window_index}:#{?window_active,1,0}'`);if(!output)return[];return output.split(`
|
|
200
200
|
`).map((line)=>{let[id,name,indexStr,active]=line.split(":");return{id,name,index:Number.parseInt(indexStr,10),active:active==="1",sessionId}})}catch(error){let message=error instanceof Error?error.message:String(error);if(message.includes("no server running")||message.includes("session not found"))return[];throw error}}async function listPanes(windowId){try{let output=await executeTmux2(`list-panes -t '${windowId}' -F '#{pane_id}:#{pane_title}:#{?pane_active,1,0}'`);if(!output)return[];return output.split(`
|
|
201
201
|
`).map((line)=>{let[id,title,active]=line.split(":");return{id,windowId,title,active:active==="1"}})}catch(error){let message=error instanceof Error?error.message:String(error);if(message.includes("no server running")||message.includes("window not found"))return[];throw error}}async function capturePaneContent(paneId,lines=200,includeColors=!1){try{return await executeTmux2(`capture-pane -p ${includeColors?"-e":""} -t '${paneId}' -S -${lines} -E -`)}catch(error){let message=error instanceof Error?error.message:String(error);if(message.includes("no server running")||message.includes("pane not found"))return"";throw error}}async function createSession(name){return await executeTmux2(`new-session -d -s "${name}" -e LC_ALL=C.UTF-8 -e LANG=C.UTF-8`),findSessionByName(name)}async function createWindow(sessionId,name,workingDir){let cdFlag=workingDir?` -c '${workingDir.replace(/'/g,"'\\''")}'`:"",output=await executeTmux2(`new-window -d -P -F '#{window_id}:#{window_index}' -t '${sessionId}:' -n '${name}'${cdFlag}`),[windowId,indexStr]=output.trim().split(":");if(!windowId)return null;try{await executeTmux2(`set-window-option -t '${windowId}' automatic-rename off`)}catch{}return{id:windowId,name,index:Number.parseInt(indexStr,10)||0,active:!1,sessionId}}async function findWindowByName(sessionId,name){return(await listWindows(sessionId)).find((w)=>w.name===name)||null}async function ensureMasterWindow(session,masterName){try{let windows=await listWindows(session);if(windows.length<2)return;let masterWindow=windows.find((w)=>w.name===masterName);if(!masterWindow)return;let minIndex=Math.min(...windows.map((w)=>w.index));if(masterWindow.index===minIndex)return;await executeTmux2(`swap-window -s '${session}:${masterWindow.index}' -t '${session}:${minIndex}'`)}catch{}}async function ensureSessionExists(name){if(/^[@$]\d+$/.test(name))throw Error(`Refused to create tmux session with id-shaped name "${name}". Names matching /^[@$]\\d+$/ collide with tmux's window-id (@N) and session-id ($N) notation, producing ghost sessions that cannot be safely targeted. Pass a human-readable session name (e.g. the team or agent name) instead.`);try{await executeTmux2(`new-session -d -s "${name}" -e LC_ALL=C.UTF-8 -e LANG=C.UTF-8`)}catch(error){if((error instanceof Error?error.message:String(error)).includes("duplicate session"))return;throw error}}async function ensureTeamWindow(session,teamName,workingDir){for(let attempt=0;attempt<3;attempt++)try{return await ensureTeamWindowOnce(session,teamName,workingDir)}catch(error){let message=error instanceof Error?error.message:String(error);if(message.includes("no server running")||message.includes("server exited")||message.includes("error connecting")){if(attempt<2){let delay=250*2**attempt;console.warn(`[genie-tmux] tmux server unreachable (attempt ${attempt+1}/3), retrying in ${delay}ms...`),await new Promise((resolve2)=>setTimeout(resolve2,delay));continue}}throw error}throw Error("Failed to ensure team window after 3 attempts")}async function ensureTeamWindowOnce(session,teamName,workingDir){await ensureSessionExists(session);let existing=await findWindowByName(session,teamName);if(existing){try{await executeTmux2(`set-window-option -t '${existing.id}' automatic-rename off`)}catch{}await rehydratePaneColorHook(existing.id);let panes2=await listPanes(existing.id),paneId2=panes2.length>0?panes2[0].id:`${session}:${teamName}.0`;return{windowId:existing.id,windowName:teamName,sessionName:session,paneId:paneId2,created:!1}}let windowsBefore=await listWindows(session),masterBefore=windowsBefore.length>0?windowsBefore.reduce((a,b)=>a.index<=b.index?a:b):null,newWindow=await createWindow(session,teamName,workingDir);if(!newWindow)throw Error(`Failed to create team window "${teamName}" in session "${session}"`);if(masterBefore)await ensureMasterWindow(session,masterBefore.name);await rehydratePaneColorHook(newWindow.id);let panes=await listPanes(newWindow.id),paneId=panes.length>0?panes[0].id:`${session}:${teamName}.0`;return{windowId:newWindow.id,windowName:teamName,sessionName:session,paneId,created:!0}}function ensurePaneColorScript(){let{existsSync:existsSync8,writeFileSync:writeFileSync4,mkdirSync:mkdirSync5,chmodSync:chmodSync2}=__require("fs"),{dirname:dirname3}=__require("path");if(existsSync8(PANE_COLOR_SCRIPT))return;mkdirSync5(dirname3(PANE_COLOR_SCRIPT),{recursive:!0});let bin=tmuxBin();writeFileSync4(PANE_COLOR_SCRIPT,`#!/bin/bash
|
|
@@ -1667,7 +1667,7 @@ Stopping inbox watcher...`),stopInboxWatcher2(handle),process.exit(0)};process.o
|
|
|
1667
1667
|
JOIN agents a ON e.agent_id = a.id
|
|
1668
1668
|
WHERE e.id = ${executorId}
|
|
1669
1669
|
LIMIT 1
|
|
1670
|
-
`;if(rows.length===0)return;let{custom_name:agentName,team:teamName}=rows[0];if(!agentName||!teamName)return;let{writeNativeInbox:writeNativeInbox2}=await Promise.resolve().then(() => (init_claude_native_teams(),exports_claude_native_teams));await writeNativeInbox2(teamName,agentName,{from:"system",text:message.text,summary:message.text.slice(0,120),timestamp:new Date().toISOString(),color:"red",read:!1})}}function spawnContextToParams2(ctx){return{provider:"claude",team:ctx.team,role:ctx.role,skill:ctx.skill,agentId:ctx.agentId,executorId:ctx.executorId,extraArgs:ctx.extraArgs,model:ctx.model,sessionId:ctx.sessionId,systemPromptFile:ctx.systemPromptFile,systemPrompt:ctx.systemPrompt,promptMode:ctx.promptMode,initialPrompt:ctx.initialPrompt,name:ctx.name,nativeTeam:ctx.nativeTeam,otelPort:ctx.otelPort,otelLogPrompts:ctx.otelLogPrompts,otelWishSlug:ctx.otelWishSlug}}function resumeContextToParams2(ctx){return{provider:"claude",team:ctx.team,role:ctx.role,agentId:ctx.agentId,executorId:ctx.executorId,extraArgs:ctx.extraArgs,model:ctx.model,resume:ctx.claudeSessionId,nativeTeam:ctx.nativeTeam,otelPort:ctx.otelPort,otelLogPrompts:ctx.otelLogPrompts,otelWishSlug:ctx.otelWishSlug}}async function findSessionLogPath(sessionId,projectPath){let{access:access2,readdir:readdir6}=await import("fs/promises"),{join:join48}=await import("path"),claudeDir=join48(process.env.HOME||"",".claude","projects");try{await access2(claudeDir)}catch{return null}let jsonlName=`${sessionId}.jsonl`;if(projectPath){let{projectPathToHash:projectPathToHash2}=await Promise.resolve().then(() => (init_claude_logs(),exports_claude_logs)),hash=projectPathToHash2(projectPath),candidate=join48(claudeDir,hash,jsonlName);try{return await access2(candidate),candidate}catch{}}try{let dirs=await readdir6(claudeDir);for(let dir of dirs){let candidate=join48(claudeDir,dir,jsonlName);try{return await access2(candidate),candidate}catch{}}}catch{}return null}function mapDetectedState(detectedType){switch(detectedType){case"idle":return"idle";case"working":case"tool_use":return"working";case"permission":return"permission";case"question":return"question";case"error":return"error";case"complete":return"done";case"unknown":return"running"}}var init_claude_code=__esm(()=>{init_provider_adapters()});function getEventType(msg){if(msg.type==="result"){let sub=msg.subtype??"";return RESULT_SUBTYPE_MAP[sub]??"sdk.result.error"}if(msg.type==="system"){let sub=msg.subtype??"";return SYSTEM_SUBTYPE_MAP[sub]??null}return TOP_LEVEL_MAP[msg.type]??null}function truncate3(s,max=200){return s.slice(0,max)}function assistantDetails(msg){let details={},content=msg.message?.content;if(Array.isArray(content)){let textBlock=content.find((b2)=>b2.type==="text");if(textBlock?.text)details.textPreview=truncate3(textBlock.text);let toolBlocks=content.filter((b2)=>b2.type==="tool_use");if(toolBlocks.length>0)details.toolCalls=toolBlocks.map((t)=>{let call={name:t.name};if(t.name==="Bash"&&t.input&&typeof t.input.command==="string")call.command=truncate3(t.input.command,150);if(t.name==="Read"&&t.input&&typeof t.input.file_path==="string")call.path=t.input.file_path;return call})}if(msg.error)details.error=msg.error;if(msg.parent_tool_use_id)details.parentToolUseId=msg.parent_tool_use_id;return details}function resultDetails(msg){let details={subtype:msg.subtype,isError:msg.is_error,durationMs:msg.duration_ms,durationApiMs:msg.duration_api_ms,numTurns:msg.num_turns,totalCostUsd:msg.total_cost_usd};if(msg.terminal_reason!==void 0)details.terminalReason=msg.terminal_reason;if(msg.usage)details.usage=msg.usage;if(msg.subtype==="success"&&typeof msg.result==="string")details.resultPreview=truncate3(msg.result);if(Array.isArray(msg.errors)&&msg.errors.length>0)details.errors=msg.errors;return details}function systemDetails(msg){let details={subtype:msg.subtype},subtype=msg.subtype;return{init:()=>{if(details.model=msg.model,details.cwd=msg.cwd,details.version=msg.claude_code_version,details.tools=Array.isArray(msg.tools)?msg.tools.length:0,msg.session_id)details.sessionId=msg.session_id},api_retry:()=>{details.attempt=msg.attempt,details.maxRetries=msg.max_retries,details.retryDelayMs=msg.retry_delay_ms,details.errorStatus=msg.error_status,details.error=msg.error},compact_boundary:()=>{let meta=msg.compact_metadata;if(meta)details.trigger=meta.trigger,details.preTokens=meta.pre_tokens},hook_started:()=>assignHookDetails(msg,details),hook_progress:()=>assignHookDetails(msg,details),hook_response:()=>{assignHookDetails(msg,details),details.outcome=msg.outcome,details.exitCode=msg.exit_code},task_notification:()=>{if(details.taskId=msg.task_id,details.status=msg.status,details.summary=typeof msg.summary==="string"?truncate3(msg.summary):void 0,msg.usage)details.usage=msg.usage},task_started:()=>{details.taskId=msg.task_id,details.description=typeof msg.description==="string"?truncate3(msg.description):void 0,details.taskType=msg.task_type},task_progress:()=>{if(details.taskId=msg.task_id,details.description=typeof msg.description==="string"?truncate3(msg.description):void 0,details.lastToolName=msg.last_tool_name,msg.usage)details.usage=msg.usage},session_state_changed:()=>{details.state=msg.state},status:()=>{details.status=msg.status},files_persisted:()=>{let files=msg.files;details.fileCount=Array.isArray(files)?files.length:0;let failed=msg.failed;details.failedCount=Array.isArray(failed)?failed.length:0},elicitation_complete:()=>{details.mcpServerName=msg.mcp_server_name,details.elicitationId=msg.elicitation_id},local_command_output:()=>{details.contentPreview=typeof msg.content==="string"?truncate3(msg.content):void 0}}[subtype]?.(),details}function assignHookDetails(msg,details){details.hookId=msg.hook_id,details.hookName=msg.hook_name,details.hookEvent=msg.hook_event}function buildEventDetails(msg){let base={sdkType:msg.type},extra=DETAIL_BUILDERS[msg.type]?.(msg)??{};return{...base,...extra}}async function routeSdkMessage(msg,executorId,agentId){let eventType=getEventType(msg);if(!eventType)return null;if(eventType==="sdk.stream.partial")return eventType;let details=buildEventDetails(msg);return details.executorId=executorId,await recordAuditEvent("sdk_message",executorId,eventType,agentId,details),eventType}var SYSTEM_SUBTYPE_MAP,RESULT_SUBTYPE_MAP,TOP_LEVEL_MAP,DETAIL_BUILDERS;var init_claude_sdk_events=__esm(()=>{init_audit();SYSTEM_SUBTYPE_MAP={init:"sdk.system",api_retry:"sdk.api.retry",compact_boundary:"sdk.context.compacted",elicitation_complete:"sdk.elicitation.complete",files_persisted:"sdk.files.persisted",hook_progress:"sdk.hook.progress",hook_response:"sdk.hook.response",hook_started:"sdk.hook.started",local_command_output:"sdk.command.output",session_state_changed:"sdk.session.state",status:"sdk.status",task_notification:"sdk.task.notification",task_progress:"sdk.task.progress",task_started:"sdk.task.started"},RESULT_SUBTYPE_MAP={success:"sdk.result.success",error_max_turns:"sdk.result.max_turns",error_max_budget_usd:"sdk.result.max_budget"},TOP_LEVEL_MAP={assistant:"sdk.assistant.message",stream_event:"sdk.stream.partial",tool_progress:"sdk.tool.progress",tool_use_summary:"sdk.tool.summary",rate_limit_event:"sdk.rate_limit",auth_status:"sdk.auth.status",prompt_suggestion:"sdk.prompt.suggestion",user:"sdk.user.message"};DETAIL_BUILDERS={assistant:(msg)=>assistantDetails(msg),result:(msg)=>resultDetails(msg),system:(msg)=>systemDetails(msg),stream_event:(msg)=>msg.parent_tool_use_id?{parentToolUseId:msg.parent_tool_use_id}:{},tool_progress:(msg)=>{let d={toolName:msg.tool_name,toolUseId:msg.tool_use_id,elapsedSeconds:msg.elapsed_time_seconds};if(msg.task_id)d.taskId=msg.task_id;return d},tool_use_summary:(msg)=>({summaryPreview:truncate3(msg.summary),toolUseIds:msg.preceding_tool_use_ids}),rate_limit_event:(msg)=>{let d={status:msg.rate_limit_info.status};if(msg.rate_limit_info.resetsAt)d.resetsAt=msg.rate_limit_info.resetsAt;if(msg.rate_limit_info.utilization!=null)d.utilization=msg.rate_limit_info.utilization;return d},auth_status:(msg)=>{let d={isAuthenticating:msg.isAuthenticating};if(msg.error)d.error=msg.error;return d},prompt_suggestion:(msg)=>({suggestion:truncate3(msg.suggestion)}),user:(msg)=>{let d={isReplay:msg.isReplay===!0,isSynthetic:msg.isSynthetic===!0};if(msg.parent_tool_use_id)d.parentToolUseId=msg.parent_tool_use_id;let content=msg.message?.content;if(typeof content==="string")d.textPreview=truncate3(content);else if(Array.isArray(content)){let textBlock=content.find((b2)=>b2.type==="text");if(textBlock?.text)d.textPreview=truncate3(textBlock.text)}return d}}});function normalizeCommand(command){let normalized=command.trim().replace(/\s+/g," ");if(normalized==="")return"";return normalized=normalized.replace(/^\/[\w./-]*\/(\w)/,"$1"),normalized}function hasShellMetacharacters(command){return/(&&|\||;|`|\$\()/.test(command)}var ToolName,RepoConfigSchema,DefaultsConfigSchema,AutoApproveConfigSchema;var init_auto_approve=__esm(()=>{init_js_yaml();init_zod();ToolName=exports_external.string(),RepoConfigSchema=exports_external.object({inherit:exports_external.enum(["global","none"]).optional(),allow:exports_external.array(ToolName).default([]),deny:exports_external.array(ToolName).default([]),bash_allow_patterns:exports_external.array(exports_external.string()).optional(),bash_deny_patterns:exports_external.array(exports_external.string()).optional()}),DefaultsConfigSchema=exports_external.object({allow:exports_external.array(ToolName).default([]),deny:exports_external.array(ToolName).default([]),bash_allow_patterns:exports_external.array(exports_external.string()).optional(),bash_deny_patterns:exports_external.array(exports_external.string()).optional()}),AutoApproveConfigSchema=exports_external.object({defaults:DefaultsConfigSchema.default({}),repos:exports_external.record(exports_external.string(),RepoConfigSchema).optional()})});var exports_claude_sdk_permissions={};__export(exports_claude_sdk_permissions,{translateClaudeCodePermissions:()=>translateClaudeCodePermissions,resolvePreset:()=>resolvePreset,resolvePermissionConfig:()=>resolvePermissionConfig,createPermissionGate:()=>createPermissionGate,PRESET_READ_ONLY:()=>PRESET_READ_ONLY,PRESET_FULL:()=>PRESET_FULL,PRESET_CHAT_ONLY:()=>PRESET_CHAT_ONLY});function resolvePreset(name){let preset=PRESETS[name];if(!preset)throw Error(`Unknown permission preset "${name}". Valid: ${Object.keys(PRESETS).join(", ")}`);return preset}function translateClaudeCodePermissions(ccPerms){let toolAllow=[],bashPatterns=[];for(let entry2 of ccPerms.allow??[]){let bashMatch=entry2.match(/^Bash\((.+)\)$/);if(bashMatch){let regex=`^${bashMatch[1].replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*")}$`;if(bashPatterns.push(regex),!toolAllow.includes("Bash"))toolAllow.push("Bash")}else toolAllow.push(entry2)}return{allow:toolAllow.length>0?toolAllow:["*"],bashAllowPatterns:bashPatterns.length>0?bashPatterns:void 0}}function isClaudeCodeFormat(permissions){if(Array.isArray(permissions.allow))return permissions.allow.some((entry2)=>typeof entry2==="string"&&/^Bash\(.+\)$/.test(entry2));return"deny"in permissions&&!("preset"in permissions)&&!("bashAllowPatterns"in permissions)}function resolvePermissionConfig(permissions){if(permissions?.preset)return resolvePreset(permissions.preset);if(permissions&&isClaudeCodeFormat(permissions))return translateClaudeCodePermissions(permissions);if(permissions?.allow)return{allow:permissions.allow,bashAllowPatterns:permissions.bashAllowPatterns};return PRESET_FULL}function matchesCompoundPattern(normalized,patterns2){for(let pattern of patterns2)try{let match=normalized.match(new RegExp(pattern));if(match&&match[0]===normalized)return!0}catch{}return!1}function matchesSimplePattern(normalized,patterns2){for(let pattern of patterns2)try{if(new RegExp(pattern).test(normalized))return!0}catch{if(normalized.includes(pattern))return!0}return!1}function matchesBashAllow(command,patterns2){let normalized=normalizeCommand(command);if(hasShellMetacharacters(normalized))return matchesCompoundPattern(normalized,patterns2);return matchesSimplePattern(normalized,patterns2)}function createPermissionGate(config){let{allow,bashAllowPatterns=[]}=config,allowAll=allow.includes("*"),allowSet=new Set(allow);return async(input)=>{let hookInput=input,toolName=hookInput.tool_name;if(!allowAll&&!allowSet.has(toolName))return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`Tool "${toolName}" is not allowed. Allowed: ${allow.join(", ")}`}};if(toolName==="Bash"&&bashAllowPatterns.length>0){let toolInput=hookInput.tool_input??{},command=typeof toolInput.command==="string"?toolInput.command:"";if(!command||!matchesBashAllow(command,bashAllowPatterns))return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`Bash command not in allow patterns: ${command||"(empty)"}`}}}return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}}var PRESET_FULL,PRESET_READ_ONLY,PRESET_CHAT_ONLY,PRESETS;var init_claude_sdk_permissions=__esm(()=>{init_auto_approve();PRESET_FULL={allow:["*"]},PRESET_READ_ONLY={allow:["Read","Glob","Grep","WebFetch"]},PRESET_CHAT_ONLY={allow:["SendMessage","Read"]},PRESETS={full:PRESET_FULL,"read-only":PRESET_READ_ONLY,"chat-only":PRESET_CHAT_ONLY}});function pruneRecentSends(){let cutoff=Date.now()-BATCH_WINDOW_MS;while(recentOmniSends.length>0&&recentOmniSends[0]<cutoff)recentOmniSends.shift()}function formatApprovalMessage(approvalId,agentName,toolName,preview){let shortPreview=preview.length>200?`${preview.slice(0,197)}...`:preview;return["\uD83D\uDD14 *Approval Required*","",`Agent: *${agentName}*`,`Tool: \`${toolName}\``,`Preview: ${shortPreview}`,"","Reply *y* to approve or *n* to deny","Or react \uD83D\uDC4D / \uD83D\uDC4E","",`_ID: ${approvalId}_`].join(`
|
|
1670
|
+
`;if(rows.length===0)return;let{custom_name:agentName,team:teamName}=rows[0];if(!agentName||!teamName)return;let{writeNativeInbox:writeNativeInbox2}=await Promise.resolve().then(() => (init_claude_native_teams(),exports_claude_native_teams));await writeNativeInbox2(teamName,agentName,{from:"system",text:message.text,summary:message.text.slice(0,120),timestamp:new Date().toISOString(),color:"red",read:!1})}}function spawnContextToParams2(ctx){return{provider:"claude",team:ctx.team,role:ctx.role,skill:ctx.skill,agentId:ctx.agentId,executorId:ctx.executorId,extraArgs:ctx.extraArgs,model:ctx.model,sessionId:ctx.sessionId,systemPromptFile:ctx.systemPromptFile,systemPrompt:ctx.systemPrompt,promptMode:ctx.promptMode,initialPrompt:ctx.initialPrompt,name:ctx.name,nativeTeam:ctx.nativeTeam,otelPort:ctx.otelPort,otelLogPrompts:ctx.otelLogPrompts,otelWishSlug:ctx.otelWishSlug}}function resumeContextToParams2(ctx){return{provider:"claude",team:ctx.team,role:ctx.role,agentId:ctx.agentId,executorId:ctx.executorId,extraArgs:ctx.extraArgs,model:ctx.model,resume:ctx.claudeSessionId,nativeTeam:ctx.nativeTeam,otelPort:ctx.otelPort,otelLogPrompts:ctx.otelLogPrompts,otelWishSlug:ctx.otelWishSlug}}async function findSessionLogPath(sessionId,projectPath){let{access:access2,readdir:readdir6}=await import("fs/promises"),{join:join48}=await import("path"),claudeDir=join48(process.env.HOME||"",".claude","projects");try{await access2(claudeDir)}catch{return null}let jsonlName=`${sessionId}.jsonl`;if(projectPath){let{projectPathToHash:projectPathToHash2}=await Promise.resolve().then(() => (init_claude_logs(),exports_claude_logs)),hash=projectPathToHash2(projectPath),candidate=join48(claudeDir,hash,jsonlName);try{return await access2(candidate),candidate}catch{}}try{let dirs=await readdir6(claudeDir);for(let dir of dirs){let candidate=join48(claudeDir,dir,jsonlName);try{return await access2(candidate),candidate}catch{}}}catch{}return null}function mapDetectedState(detectedType){switch(detectedType){case"idle":return"idle";case"working":case"tool_use":return"working";case"permission":return"permission";case"question":return"question";case"error":return"error";case"complete":return"done";case"unknown":return"running"}}var init_claude_code=__esm(()=>{init_provider_adapters()});function getEventType(msg){if(msg.type==="result"){let sub=msg.subtype??"";return RESULT_SUBTYPE_MAP[sub]??"sdk.result.error"}if(msg.type==="system"){let sub=msg.subtype??"";return SYSTEM_SUBTYPE_MAP[sub]??null}return TOP_LEVEL_MAP[msg.type]??null}function truncate3(s,max=200){return s.slice(0,max)}function assistantDetails(msg){let details={},content=msg.message?.content;if(Array.isArray(content)){let textBlock=content.find((b2)=>b2.type==="text");if(textBlock?.text)details.textPreview=truncate3(textBlock.text);let toolBlocks=content.filter((b2)=>b2.type==="tool_use");if(toolBlocks.length>0)details.toolCalls=toolBlocks.map((t)=>{let call={name:t.name};if(t.name==="Bash"&&t.input&&typeof t.input.command==="string")call.command=truncate3(t.input.command,150);if(t.name==="Read"&&t.input&&typeof t.input.file_path==="string")call.path=t.input.file_path;return call})}if(msg.error)details.error=msg.error;if(msg.parent_tool_use_id)details.parentToolUseId=msg.parent_tool_use_id;return details}function resultDetails(msg){let details={subtype:msg.subtype,isError:msg.is_error,durationMs:msg.duration_ms,durationApiMs:msg.duration_api_ms,numTurns:msg.num_turns,totalCostUsd:msg.total_cost_usd};if(msg.terminal_reason!==void 0)details.terminalReason=msg.terminal_reason;if(msg.usage)details.usage=msg.usage;if(msg.subtype==="success"&&typeof msg.result==="string")details.resultPreview=truncate3(msg.result);if(Array.isArray(msg.errors)&&msg.errors.length>0)details.errors=msg.errors;return details}function systemDetails(msg){let details={subtype:msg.subtype},subtype=msg.subtype;return{init:()=>{if(details.model=msg.model,details.cwd=msg.cwd,details.version=msg.claude_code_version,details.tools=Array.isArray(msg.tools)?msg.tools.length:0,msg.session_id)details.sessionId=msg.session_id},api_retry:()=>{details.attempt=msg.attempt,details.maxRetries=msg.max_retries,details.retryDelayMs=msg.retry_delay_ms,details.errorStatus=msg.error_status,details.error=msg.error},compact_boundary:()=>{let meta=msg.compact_metadata;if(meta)details.trigger=meta.trigger,details.preTokens=meta.pre_tokens},hook_started:()=>assignHookDetails(msg,details),hook_progress:()=>assignHookDetails(msg,details),hook_response:()=>{assignHookDetails(msg,details),details.outcome=msg.outcome,details.exitCode=msg.exit_code},task_notification:()=>{if(details.taskId=msg.task_id,details.status=msg.status,details.summary=typeof msg.summary==="string"?truncate3(msg.summary):void 0,msg.usage)details.usage=msg.usage},task_started:()=>{details.taskId=msg.task_id,details.description=typeof msg.description==="string"?truncate3(msg.description):void 0,details.taskType=msg.task_type},task_progress:()=>{if(details.taskId=msg.task_id,details.description=typeof msg.description==="string"?truncate3(msg.description):void 0,details.lastToolName=msg.last_tool_name,msg.usage)details.usage=msg.usage},session_state_changed:()=>{details.state=msg.state},status:()=>{details.status=msg.status},files_persisted:()=>{let files=msg.files;details.fileCount=Array.isArray(files)?files.length:0;let failed=msg.failed;details.failedCount=Array.isArray(failed)?failed.length:0},elicitation_complete:()=>{details.mcpServerName=msg.mcp_server_name,details.elicitationId=msg.elicitation_id},local_command_output:()=>{details.contentPreview=typeof msg.content==="string"?truncate3(msg.content):void 0}}[subtype]?.(),details}function assignHookDetails(msg,details){details.hookId=msg.hook_id,details.hookName=msg.hook_name,details.hookEvent=msg.hook_event}function buildEventDetails(msg){let base={sdkType:msg.type},extra=DETAIL_BUILDERS[msg.type]?.(msg)??{};return{...base,...extra}}async function routeSdkMessage(msg,executorId,agentId){let eventType=getEventType(msg);if(!eventType)return null;if(eventType==="sdk.stream.partial")return eventType;let details=buildEventDetails(msg);return details.executorId=executorId,await recordAuditEvent("sdk_message",executorId,eventType,agentId,details),eventType}var SYSTEM_SUBTYPE_MAP,RESULT_SUBTYPE_MAP,TOP_LEVEL_MAP,DETAIL_BUILDERS;var init_claude_sdk_events=__esm(()=>{init_audit();SYSTEM_SUBTYPE_MAP={init:"sdk.system",api_retry:"sdk.api.retry",compact_boundary:"sdk.context.compacted",elicitation_complete:"sdk.elicitation.complete",files_persisted:"sdk.files.persisted",hook_progress:"sdk.hook.progress",hook_response:"sdk.hook.response",hook_started:"sdk.hook.started",local_command_output:"sdk.command.output",session_state_changed:"sdk.session.state",status:"sdk.status",task_notification:"sdk.task.notification",task_progress:"sdk.task.progress",task_started:"sdk.task.started"},RESULT_SUBTYPE_MAP={success:"sdk.result.success",error_max_turns:"sdk.result.max_turns",error_max_budget_usd:"sdk.result.max_budget"},TOP_LEVEL_MAP={assistant:"sdk.assistant.message",stream_event:"sdk.stream.partial",tool_progress:"sdk.tool.progress",tool_use_summary:"sdk.tool.summary",rate_limit_event:"sdk.rate_limit",auth_status:"sdk.auth.status",prompt_suggestion:"sdk.prompt.suggestion",user:"sdk.user.message"};DETAIL_BUILDERS={assistant:(msg)=>assistantDetails(msg),result:(msg)=>resultDetails(msg),system:(msg)=>systemDetails(msg),stream_event:(msg)=>msg.parent_tool_use_id?{parentToolUseId:msg.parent_tool_use_id}:{},tool_progress:(msg)=>{let d={toolName:msg.tool_name,toolUseId:msg.tool_use_id,elapsedSeconds:msg.elapsed_time_seconds};if(msg.task_id)d.taskId=msg.task_id;return d},tool_use_summary:(msg)=>({summaryPreview:truncate3(msg.summary),toolUseIds:msg.preceding_tool_use_ids}),rate_limit_event:(msg)=>{let d={status:msg.rate_limit_info.status};if(msg.rate_limit_info.resetsAt)d.resetsAt=msg.rate_limit_info.resetsAt;if(msg.rate_limit_info.utilization!=null)d.utilization=msg.rate_limit_info.utilization;return d},auth_status:(msg)=>{let d={isAuthenticating:msg.isAuthenticating};if(msg.error)d.error=msg.error;return d},prompt_suggestion:(msg)=>({suggestion:truncate3(msg.suggestion)}),user:(msg)=>{let d={isReplay:msg.isReplay===!0,isSynthetic:msg.isSynthetic===!0};if(msg.parent_tool_use_id)d.parentToolUseId=msg.parent_tool_use_id;let content=msg.message?.content;if(typeof content==="string")d.textPreview=truncate3(content);else if(Array.isArray(content)){let textBlock=content.find((b2)=>b2.type==="text");if(textBlock?.text)d.textPreview=truncate3(textBlock.text)}return d}}});function normalizeCommand(command){let normalized=command.trim().replace(/\s+/g," ");if(normalized==="")return"";return normalized=normalized.replace(/^\/[\w./-]*\/(\w)/,"$1"),normalized}function hasShellMetacharacters(command){return/(&&|\||;|`|\$\()/.test(command)}var ToolName,RepoConfigSchema,DefaultsConfigSchema,AutoApproveConfigSchema;var init_auto_approve=__esm(()=>{init_js_yaml();init_zod();ToolName=exports_external.string(),RepoConfigSchema=exports_external.object({inherit:exports_external.enum(["global","none"]).optional(),allow:exports_external.array(ToolName).default([]),deny:exports_external.array(ToolName).default([]),bash_allow_patterns:exports_external.array(exports_external.string()).optional(),bash_deny_patterns:exports_external.array(exports_external.string()).optional()}),DefaultsConfigSchema=exports_external.object({allow:exports_external.array(ToolName).default([]),deny:exports_external.array(ToolName).default([]),bash_allow_patterns:exports_external.array(exports_external.string()).optional(),bash_deny_patterns:exports_external.array(exports_external.string()).optional()}),AutoApproveConfigSchema=exports_external.object({defaults:DefaultsConfigSchema.default({}),repos:exports_external.record(exports_external.string(),RepoConfigSchema).optional()})});var exports_claude_sdk_permissions={};__export(exports_claude_sdk_permissions,{translateClaudeCodePermissions:()=>translateClaudeCodePermissions,resolvePreset:()=>resolvePreset,resolvePermissionConfig:()=>resolvePermissionConfig,createPermissionGate:()=>createPermissionGate,PRESET_READ_ONLY:()=>PRESET_READ_ONLY,PRESET_FULL:()=>PRESET_FULL,PRESET_CHAT_ONLY:()=>PRESET_CHAT_ONLY});function resolvePreset(name){let preset=PRESETS[name];if(!preset)throw Error(`Unknown permission preset "${name}". Valid: ${Object.keys(PRESETS).join(", ")}`);return preset}function translateClaudeCodePermissions(ccPerms){let toolAllow=[],bashPatterns=[];for(let entry2 of ccPerms.allow??[]){let bashMatch=entry2.match(/^Bash\((.+)\)$/);if(bashMatch){let regex=`^${bashMatch[1].replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*")}$`;if(bashPatterns.push(regex),!toolAllow.includes("Bash"))toolAllow.push("Bash")}else toolAllow.push(entry2)}return{allow:toolAllow.length>0?toolAllow:["*"],bashAllowPatterns:bashPatterns.length>0?bashPatterns:void 0}}function isClaudeCodeFormat(permissions){if(Array.isArray(permissions.allow))return permissions.allow.some((entry2)=>typeof entry2==="string"&&/^Bash\(.+\)$/.test(entry2));return"deny"in permissions&&!("preset"in permissions)&&!("bashAllowPatterns"in permissions)}function resolvePermissionConfig(permissions){if(permissions?.preset)return resolvePreset(permissions.preset);if(permissions&&isClaudeCodeFormat(permissions))return translateClaudeCodePermissions(permissions);if(permissions?.allow)return{allow:permissions.allow,bashAllowPatterns:permissions.bashAllowPatterns};return PRESET_FULL}function matchesCompoundPattern(normalized,patterns2){for(let pattern of patterns2)try{let match=normalized.match(new RegExp(pattern));if(match&&match[0]===normalized)return!0}catch{}return!1}function matchesSimplePattern(normalized,patterns2){for(let pattern of patterns2)try{if(new RegExp(pattern).test(normalized))return!0}catch{if(normalized.includes(pattern))return!0}return!1}function matchesBashAllow(command,patterns2){let normalized=normalizeCommand(command);if(hasShellMetacharacters(normalized))return matchesCompoundPattern(normalized,patterns2);return matchesSimplePattern(normalized,patterns2)}function createPermissionGate(config){let{allow,bashAllowPatterns=[]}=config,allowAll=allow.includes("*"),allowSet=new Set(allow);return async(input)=>{let hookInput=input,toolName=hookInput.tool_name;if(!allowAll&&!allowSet.has(toolName))return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`Tool "${toolName}" is not allowed. Allowed: ${allow.join(", ")}`}};if(toolName==="Bash"&&bashAllowPatterns.length>0){let toolInput=hookInput.tool_input??{},command=typeof toolInput.command==="string"?toolInput.command:"";if(!command||!matchesBashAllow(command,bashAllowPatterns))return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`Bash command not in allow patterns: ${command||"(empty)"}`}}}return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}}var PRESET_FULL,PRESET_READ_ONLY,PRESET_CHAT_ONLY,PRESETS;var init_claude_sdk_permissions=__esm(()=>{init_auto_approve();PRESET_FULL={allow:["*"]},PRESET_READ_ONLY={allow:["Read","Glob","Grep","WebFetch","AskUserQuestion"]},PRESET_CHAT_ONLY={allow:["SendMessage","Read","AskUserQuestion"]},PRESETS={full:PRESET_FULL,"read-only":PRESET_READ_ONLY,"chat-only":PRESET_CHAT_ONLY}});function pruneRecentSends(){let cutoff=Date.now()-BATCH_WINDOW_MS;while(recentOmniSends.length>0&&recentOmniSends[0]<cutoff)recentOmniSends.shift()}function formatApprovalMessage(approvalId,agentName,toolName,preview){let shortPreview=preview.length>200?`${preview.slice(0,197)}...`:preview;return["\uD83D\uDD14 *Approval Required*","",`Agent: *${agentName}*`,`Tool: \`${toolName}\``,`Preview: ${shortPreview}`,"","Reply *y* to approve or *n* to deny","Or react \uD83D\uDC4D / \uD83D\uDC4E","",`_ID: ${approvalId}_`].join(`
|
|
1671
1671
|
`)}function formatBatchMessage(pendingCount){return[`\uD83D\uDD14 *${pendingCount} Approvals Pending*`,"","Multiple tool approvals are queued.","Reply *y* to approve next or *n* to deny.","Use `genie approval list` for details."].join(`
|
|
1672
1672
|
`)}async function updateOmniMessageId(approvalId,omniMessageId){try{await(await getConnection())`UPDATE approvals SET omni_message_id = ${omniMessageId} WHERE id = ${approvalId}`}catch{}}async function sendApprovalToOmni(approvalId,agentName,toolName,preview,permissions){let{omniChat,omniInstance}=permissions;if(!omniChat||!omniInstance)return;pruneRecentSends();let text;if(recentOmniSends.length>=BATCH_THRESHOLD){let sql=await getConnection(),[row]=await sql`SELECT count(*)::int AS count FROM approvals WHERE decision = 'pending'`;text=formatBatchMessage(row.count)}else text=formatApprovalMessage(approvalId,agentName,toolName,preview);recentOmniSends.push(Date.now());try{let proc=Bun.spawn(["omni","send","--instance",omniInstance,"--to",omniChat,"--text",text,"--json"],{stdout:"pipe",stderr:"ignore"}),stdout=await new Response(proc.stdout).text();await proc.exited;try{let result2=JSON.parse(stdout),messageId=result2.messageId??result2.message_id??result2.id;if(messageId)await updateOmniMessageId(approvalId,String(messageId))}catch{}}catch(err){console.warn(`[remote-approval] Omni notification failed: ${err instanceof Error?err.message:String(err)}`)}}async function insertApproval(executorId,agentName,toolName,toolInputPreview,timeoutAt){let sql=await getConnection(),[row]=await sql`
|
|
1673
1673
|
INSERT INTO approvals (executor_id, agent_name, tool_name, tool_input_preview, timeout_at)
|
|
@@ -2954,7 +2954,14 @@ Genie Serve`),console.log("\u2500".repeat(50)),console.log(` Status: ${runn
|
|
|
2954
2954
|
WHERE team = ${slug}
|
|
2955
2955
|
AND state IS DISTINCT FROM 'archived'
|
|
2956
2956
|
RETURNING id
|
|
2957
|
-
`;if(rows.length>0)console.log(` \uD83D\uDCE6 Archived ${rows.length} wish-named agent row${rows.length===1?"":"s"} (team="${slug}")`);return rows.length}catch(err){let detail=err instanceof Error?err.message:String(err);return console.warn(` \u26A0\uFE0F Could not archive wish-named agent rows: ${detail}`),0}}function autoKillPane(){let paneId=process.env.TMUX_PANE;if(paneId)setTimeout(()=>{try{let{genieTmuxCmd:genieTmuxCmd2}=(init_tmux_wrapper(),__toCommonJS(exports_tmux_wrapper));execSync13(genieTmuxCmd2(`kill-pane -t '${paneId}'`),{encoding:"utf-8"})}catch{process.exit(0)}},1000);else process.exit(0)}async function resolveNotificationTargets(){let teamName=process.env.GENIE_TEAM;if(!teamName)return{leader:"team-lead"};try{let teamManager=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),leader=await teamManager.resolveLeaderName(teamName),config=await teamManager.getTeam(teamName);return{leader,spawner:config?.spawner}}catch{return{leader:teamName}}}async function notifyWaveCompletion(waveResult,wishComplete){console.log(` \uD83C\uDF0A ${waveResult.waveName} complete! All groups done: ${waveResult.waveGroups.join(", ")}`);try{let protocolRouter=await Promise.resolve().then(() => (init_protocol_router(),exports_protocol_router)),repoPath=process.cwd(),{leader,spawner}=await resolveNotificationTargets(),
|
|
2957
|
+
`;if(rows.length>0)console.log(` \uD83D\uDCE6 Archived ${rows.length} wish-named agent row${rows.length===1?"":"s"} (team="${slug}")`);return rows.length}catch(err){let detail=err instanceof Error?err.message:String(err);return console.warn(` \u26A0\uFE0F Could not archive wish-named agent rows: ${detail}`),0}}function autoKillPane(){let paneId=process.env.TMUX_PANE;if(paneId)setTimeout(()=>{try{let{genieTmuxCmd:genieTmuxCmd2}=(init_tmux_wrapper(),__toCommonJS(exports_tmux_wrapper));execSync13(genieTmuxCmd2(`kill-pane -t '${paneId}'`),{encoding:"utf-8"})}catch{process.exit(0)}},1000);else process.exit(0)}async function resolveNotificationTargets(){let teamName=process.env.GENIE_TEAM;if(!teamName)return{leader:"team-lead"};try{let teamManager=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),leader=await teamManager.resolveLeaderName(teamName),config=await teamManager.getTeam(teamName);return{leader,spawner:config?.spawner}}catch{return{leader:teamName}}}async function notifyWaveCompletion(waveResult,wishComplete,report2){console.log(` \uD83C\uDF0A ${waveResult.waveName} complete! All groups done: ${waveResult.waveGroups.join(", ")}`);try{let protocolRouter=await Promise.resolve().then(() => (init_protocol_router(),exports_protocol_router)),repoPath=process.cwd(),{leader,spawner}=await resolveNotificationTargets(),reportBlock=`
|
|
2958
|
+
|
|
2959
|
+
--- Handoff ---
|
|
2960
|
+
${report2.trimEnd()}
|
|
2961
|
+
--- End handoff ---
|
|
2962
|
+
`,message=wishComplete?`WISH COMPLETE \u2014 all groups done: [${waveResult.waveGroups.join(", ")}].${reportBlock}
|
|
2963
|
+
Team will be auto-cleaned. Run \`genie team done\` to confirm or override.`:`${waveResult.waveName} complete. All groups done: [${waveResult.waveGroups.join(", ")}].${reportBlock}
|
|
2964
|
+
Run /review or advance to next wave.`,result2=await protocolRouter.sendMessage(repoPath,"cli",leader,message);if(result2&&typeof result2==="object"&&"delivered"in result2&&!result2.delivered)console.warn(` \u26A0\uFE0F Wave-complete notification to ${leader} may not have been delivered.`);else console.log(` Notified ${leader} of wave completion.`);if(spawner&&spawner!==leader&&spawner!=="cli")await protocolRouter.sendMessage(repoPath,"cli",spawner,message).catch(()=>{}),console.log(` Notified spawner (${spawner}) of wave completion.`)}catch{console.warn(" \u26A0\uFE0F Could not notify leader (messaging unavailable).")}}async function doneCommand(ref,report2){if(!report2?.trim())throw Error("doneCommand: report is required \u2014 full group handoff (what shipped, verified, left, surprises). Not a one-liner.");try{let{slug,group}=parseRef(ref),result2=await completeGroup(slug,group);if(console.log(`\u2705 Group "${group}" marked as done in wish "${slug}"`),console.log("--- Handoff ---"),console.log(report2.trimEnd()),console.log("--- End handoff ---"),result2.completedAt)console.log(` Completed at: ${formatTimestamp(result2.completedAt)}`);let state=await getState(slug);if(state){let nowReady=Object.entries(state.groups).filter(([,g])=>g.status==="ready"&&g.dependsOn.includes(group)).map(([name])=>name);if(nowReady.length>0)console.log(` Unblocked: ${nowReady.join(", ")}`)}await ensureWorkPushed(slug,group);let wishComplete=await isWishComplete(slug),waveResult=await detectWaveCompletion(slug,group);if(waveResult)await notifyWaveCompletion(waveResult,wishComplete,report2);if(wishComplete)console.log(" \uD83C\uDF89 Wish fully complete \u2014 all groups done."),await autoCleanupTeam(),await archiveWishNamedAgents(slug);autoKillPane()}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`\u274C ${message}`),process.exit(1)}}async function autoInitWishState(slug){let wishPath=resolveWishPath(slug);if(!wishPath)console.error(`\u274C No state found for wish "${slug}" and no WISH.md found in cwd or repo root`),console.error(` Create it first: genie wish <agent> ${slug}`),process.exit(1);let content=await readFile12(wishPath,"utf-8"),groups=parseWishGroups(content);if(groups.length===0)console.error(`\u274C No execution groups found in ${wishPath}`),process.exit(1);let state=await createState(slug,groups);return console.log(`\uD83D\uDCDD Auto-initialized state for wish "${slug}" (${groups.length} groups)`),state}function parseWishLifecycleStatus(content){let patterns2=[/^\|\s*\*\*Status\*\*\s*\|\s*([^|]+?)\s*\|/im,/^\*\*Status:\*\*\s*([A-Za-z][A-Za-z_-]*)/im,/^Status:\s*([A-Za-z][A-Za-z_-]*)/im];for(let pattern of patterns2){let token=content.match(pattern)?.[1]?.trim().match(/^[A-Za-z][A-Za-z_-]*/)?.[0];if(token)return token.toUpperCase()}return null}async function getTerminalWishLifecycleStatus(slug){let wishPath=resolveWishPath(slug);if(!wishPath)return null;let content=await readFile12(wishPath,"utf-8"),status2=parseWishLifecycleStatus(content);if(!status2||!TERMINAL_WISH_STATUSES.has(status2.toLowerCase()))return null;return{status:status2,wishPath}}function printTerminalWishLifecycleStatus(slug,terminal){console.log(`
|
|
2958
2965
|
Wish: ${slug}`),console.log("\u2500".repeat(60)),console.log(` Status: ${terminal.status}`),console.log(` Source: ${terminal.wishPath}`),console.log(""),console.log(" No active execution state initialized for terminal wish status."),console.log("")}async function printWishExecutors(slug){try{let{registry:registry3,executorRegistry,assignmentRegistry}=await loadExecutorInfo(),agents=await registry3.listAgents({team:process.env.GENIE_TEAM}),executorInfoLines=[];for(let agent of agents){if(!agent.currentExecutorId)continue;let executor=await executorRegistry.getExecutor(agent.currentExecutorId);if(!executor||executor.state==="terminated"||executor.state==="done")continue;let assignment=await assignmentRegistry.getActiveAssignment(executor.id);if(assignment?.wishSlug!==slug)continue;let taskLabel=`Group ${assignment.groupNumber??"?"}`,name=agent.customName??agent.role??agent.id.slice(0,12);executorInfoLines.push(` Agent: ${padRight(name,16)} | Executor: ${executor.id.slice(0,12)} (${executor.provider}) | State: ${padRight(executor.state,10)} | Task: ${taskLabel}`)}if(executorInfoLines.length>0){console.log(`
|
|
2959
2966
|
Active Executors:`),console.log("\u2500".repeat(60));for(let line of executorInfoLines)console.log(line)}}catch{}}async function statusCommand(slug){try{let terminal=await getTerminalWishLifecycleStatus(slug);if(terminal){printTerminalWishLifecycleStatus(slug,terminal);return}let state=await getState(slug)??await autoInitWishState(slug);console.log(`
|
|
2960
2967
|
Wish: ${state.wish}`),console.log("\u2500".repeat(60));let entries=Object.entries(state.groups),maxNameLen=Math.max(...entries.map(([name])=>name.length),5);console.log(` ${padRight("GROUP",maxNameLen)} STATUS ASSIGNEE STARTED COMPLETED`),console.log(` ${"\u2500".repeat(maxNameLen+62)}`);for(let[name,group]of entries){let icon=STATUS_ICONS[group.status]??"\u2753",status2=padRight(`${icon} ${group.status}`,13),assignee=padRight(group.assignee??"-",13),started=padRight(formatTimestamp(group.startedAt)||"-",14),completed=formatTimestamp(group.completedAt)||"-";console.log(` ${padRight(name,maxNameLen)} ${status2} ${assignee} ${started} ${completed}`)}let total=entries.length,done=entries.filter(([,g])=>g.status==="done").length,inProgress=entries.filter(([,g])=>g.status==="in_progress").length,ready=entries.filter(([,g])=>g.status==="ready").length,blocked=entries.filter(([,g])=>g.status==="blocked").length;console.log(""),console.log(` Progress: ${done}/${total} done | ${inProgress} in progress | ${ready} ready | ${blocked} blocked`),await printWishExecutors(slug),console.log("")}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`\u274C ${message}`),process.exit(1)}}async function resetAction(ref,options){try{if(ref.includes("#")){let{slug,group}=parseRef(ref),result2=await resetGroup(slug,group);if(console.log(`\uD83D\uDD04 Group "${group}" reset to ready in wish "${slug}"`),result2.status==="ready")console.log(" Status: ready (assignee cleared)");return}await resetWishCommand(ref,options?.yes??!1)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`\u274C ${message}`),process.exit(1)}}function registerStateCommands(_program){}async function confirmWipe(slug,existing,confirmed){let groupCount=Object.keys(existing.groups).length,inProgress=Object.values(existing.groups).filter((g)=>g.status==="in_progress").length,summary=`Wipe all state for "${slug}" (${groupCount} groups, ${inProgress} in-progress)?`;if(!isInteractive()){if(confirmed)return!0;console.error(`\u274C ${summary}`),console.error(" Refusing to wipe in non-interactive mode. Pass --yes to confirm."),process.exit(2)}let{confirm:confirm3}=await Promise.resolve().then(() => (init_esm14(),exports_esm));return confirm3({message:summary,default:!1})}function printResetState(state){console.log(""),console.log(`Wish: ${state.wish}`),console.log("\u2500".repeat(60));for(let[name,group]of Object.entries(state.groups)){let icon=STATUS_ICONS[group.status]??"\u2753";console.log(` ${name} ${icon} ${group.status}`)}}async function resetWishCommand(slug,confirmed){let wishPath=resolveWishPath(slug);if(!wishPath)throw Error(`No WISH.md found for "${slug}" \u2014 searched cwd and repo root`);let content=await readFile12(wishPath,"utf-8"),groups=parseWishGroups(content);if(groups.length===0)throw Error(`No execution groups found in ${wishPath}`);let existing=await getState(slug);if(existing){if(!await confirmWipe(slug,existing,confirmed)){console.log("Aborted.");return}console.log(`\uD83D\uDDD1\uFE0F Replacing existing state for wish "${slug}"`)}else console.log(`\u2139\uFE0F No existing state for wish "${slug}" \u2014 creating fresh`);let state=await createState(slug,groups);console.log(`\uD83D\uDCDD Recreated state from ${wishPath} (${groups.length} groups)`),printResetState(state)}var STATUS_ICONS,TERMINAL_WISH_STATUSES;var init_state=__esm(()=>{init_interactivity();init_term_format();init_wish_state();init_dispatch();STATUS_ICONS={blocked:"\uD83D\uDD12",ready:"\uD83D\uDFE2",in_progress:"\uD83D\uDD04",done:"\u2705"};TERMINAL_WISH_STATUSES=new Set(["shipped","done","complete","completed","archived"])});var exports_team={};__export(exports_team,{registerTeamNamespace:()=>registerTeamNamespace,handleTeamRepair:()=>handleTeamRepair,handleTeamCreate:()=>handleTeamCreate});import{existsSync as existsSync61,mkdirSync as mkdirSync29,renameSync as renameSync11,statSync as statSync14}from"fs";import{copyFile as copyFile3,cp,mkdir as mkdir8}from"fs/promises";import{homedir as homedir47}from"os";import{join as join73,resolve as resolve15}from"path";function registerTeamNamespace(program2){let team=program2.command("team").description("Team lifecycle management");team.command("create <name>").description("Create a new team with a git worktree").requiredOption("--repo <path>","Path to the git repository").option("--branch <branch>","Base branch to create from","dev").option("--wish <slug>","Wish slug \u2014 auto-spawns a task leader with wish context").option("--tmux-session <name>","Tmux session to place team window in (default: derived from repo path)").option("--session <name>","Alias for --tmux-session (deprecated)").option("--no-spawn","Create team and copy wish without spawning the leader (useful for testing)").addHelpText("after",`
|
|
@@ -3100,7 +3107,8 @@ ${label} <TODO>
|
|
|
3100
3107
|
JOIN executors e ON e.agent_id = a.id
|
|
3101
3108
|
WHERE e.id = ${executorId}
|
|
3102
3109
|
LIMIT 1
|
|
3103
|
-
`)[0]??null}async function rejectIfPermanent(deps){let result2=await(deps.lookupCallingAgent??defaultLookupCallingAgent)();if(result2?.kind==="permanent")throw new PermanentAgentDoneRejected({agentId:result2.id})}async function runAgentSessionPath(deps){await rejectIfPermanent(deps);let result2=await(deps.turnCloseFn??turnClose)({outcome:"done"});if(result2.noop)console.log(`\u2139\uFE0F Executor ${result2.executorId} already closed \u2014 no-op.`);else console.log(`\u2705 Turn closed: outcome=done, executor=${result2.executorId}`)}async function doneAction(ref,deps={}){let agentName=process.env.GENIE_AGENT_NAME;try{if(!ref&&agentName){await runAgentSessionPath(deps);return}if(ref){await(deps.wishDone??(async(r)=>{let{doneCommand:doneCommand2}=await Promise.resolve().then(() => (init_state(),exports_state));await doneCommand2(r)}))(ref);return}console.error("\u274C genie done requires either a <slug>#<group> ref (team-lead) or GENIE_AGENT_NAME (inside agent session)."),process.exit(2)}catch(err){if(err instanceof PermanentAgentDoneRejected)console.error(`\u274C ${err.message}`),process.exit(4);throw err}}var PermanentAgentDoneRejected;var init_done=__esm(()=>{init_db();init_turn_close();PermanentAgentDoneRejected=class PermanentAgentDoneRejected extends Error{agentId;reason;constructor(opts){super(`Permanent agent "${opts.agentId}" cannot call \`genie done\`. Permanent identities (team-leads, dir-row placeholders, root agents) do not have task lifecycles. Use \`genie agent stop ${opts.agentId}\` to halt the executor without marking the identity as done.`);this.name="PermanentAgentDoneRejected",this.agentId=opts.agentId,this.reason=opts.reason??"permanent_agents_never_call_done"}}
|
|
3110
|
+
`)[0]??null}async function rejectIfPermanent(deps){let result2=await(deps.lookupCallingAgent??defaultLookupCallingAgent)();if(result2?.kind==="permanent")throw new PermanentAgentDoneRejected({agentId:result2.id})}async function runAgentSessionPath(deps,report2){await rejectIfPermanent(deps);let result2=await(deps.turnCloseFn??turnClose)({outcome:"done",reason:report2});if(result2.noop)console.log(`\u2139\uFE0F Executor ${result2.executorId} already closed \u2014 no-op.`);else console.log(`\u2705 Turn closed: outcome=done, executor=${result2.executorId}`),console.log("--- Handoff ---"),console.log(report2.trimEnd()),console.log("--- End handoff ---")}async function doneAction(ref,options,deps={}){let agentName=process.env.GENIE_AGENT_NAME,report2=options.report?.trim();if(!report2)console.error(REPORT_MISSING_HINT),process.exit(2);try{if(!ref&&agentName){await runAgentSessionPath(deps,report2);return}if(ref){await(deps.wishDone??(async(r,rpt)=>{let{doneCommand:doneCommand2}=await Promise.resolve().then(() => (init_state(),exports_state));await doneCommand2(r,rpt)}))(ref,report2);return}console.error("\u274C genie done requires either a <slug>#<group> ref (team-lead) or GENIE_AGENT_NAME (inside agent session)."),process.exit(2)}catch(err){if(err instanceof PermanentAgentDoneRejected)console.error(`\u274C ${err.message}`),process.exit(4);throw err}}var PermanentAgentDoneRejected,REPORT_MISSING_HINT;var init_done=__esm(()=>{init_db();init_turn_close();PermanentAgentDoneRejected=class PermanentAgentDoneRejected extends Error{agentId;reason;constructor(opts){super(`Permanent agent "${opts.agentId}" cannot call \`genie done\`. Permanent identities (team-leads, dir-row placeholders, root agents) do not have task lifecycles. Use \`genie agent stop ${opts.agentId}\` to halt the executor without marking the identity as done.`);this.name="PermanentAgentDoneRejected",this.agentId=opts.agentId,this.reason=opts.reason??"permanent_agents_never_call_done"}};REPORT_MISSING_HINT=['\u274C genie done requires --report "<session handoff>".',""," This is your handoff to the orchestrator. It lands in the audit trail and the"," wave/wish-complete notification, and is the ONLY summary anyone reading later"," will see without replaying your transcript. Write it like you are briefing the"," next person on call.",""," Cover:"," \u2022 What you attempted (the actual goal of this turn / group)"," \u2022 What shipped \u2014 files changed, PRs opened, migrations run, services touched"," \u2022 What is verified vs unverified (tests passed? smoke run? CI green?)"," \u2022 What is left, blocked, or deferred \u2014 and why"," \u2022 Surprises or decisions a future agent needs to know (data losses, infra"," quirks, hooks fired, anything non-obvious)",""," Length: as long as it needs to be. A one-liner is almost never enough."," Multi-line is fine \u2014 pass via heredoc or a file:",` genie done --report "$(cat <<'EOF'`," Goal: wire dev-local auth bridge for hv tenant."," Shipped: PR #143 (fixtures), PR #144 (smoke). Both green on CI."," Verified: 'make smoke' passed locally; tenant-A login round-trip OK."," Left: CSRF rotation deferred to followup (issue #1245)."," Notes: had to bump core@1.260507.5 \u2014 desktop shell rebuild required."," EOF",' )"'].join(`
|
|
3111
|
+
`)});var exports_blocked={};__export(exports_blocked,{blockedAction:()=>blockedAction});async function blockedAction(options,deps={}){let reason=options.reason?.trim();if(!reason)console.error('\u274C genie blocked requires --reason "<message>"'),process.exit(2);let result2=await(deps.turnCloseFn??turnClose)({outcome:"blocked",reason});if(result2.noop)console.log(`\u2139\uFE0F Executor ${result2.executorId} already closed \u2014 no-op.`);else console.log(`\uD83D\uDD12 Turn closed: outcome=blocked, executor=${result2.executorId}`),console.log(` Reason: ${reason}`)}var init_blocked=__esm(()=>{init_turn_close()});var exports_failed={};__export(exports_failed,{failedAction:()=>failedAction});async function failedAction(options,deps={}){let reason=options.reason?.trim();if(!reason)console.error('\u274C genie failed requires --reason "<message>"'),process.exit(2);let result2=await(deps.turnCloseFn??turnClose)({outcome:"failed",reason});if(result2.noop)console.log(`\u2139\uFE0F Executor ${result2.executorId} already closed \u2014 no-op.`);else console.log(`\uD83D\uDED1 Turn closed: outcome=failed, executor=${result2.executorId}`),console.log(` Reason: ${reason}`)}var init_failed=__esm(()=>{init_turn_close()});async function resolveExecutorId2(sql,opts){if(opts.executorId)return{id:opts.executorId,source:"executorId"};if(opts.paneId){let rows=await sql`
|
|
3104
3112
|
SELECT id FROM executors
|
|
3105
3113
|
WHERE tmux_pane_id = ${opts.paneId}
|
|
3106
3114
|
ORDER BY started_at DESC
|
|
@@ -4904,8 +4912,26 @@ Stage Pipeline:`);let stages=t.stages;for(let i2=0;i2<stages.length;i2++){let s2
|
|
|
4904
4912
|
`)}function parseWishOrError(markdown){try{return parseWish(markdown)}catch(err){if(err instanceof WishParseError)return err;throw err}}function reportWishFileMissing(slug,wishPath,jsonMode){if(jsonMode)console.log(JSON.stringify({error:`Wish file not found: ${wishPath}`,rule:"missing-title",wish:slug,file:wishPath}));else console.error(`\u274C Wish file not found: ${wishPath}`);process.exit(1)}function emitLintReport(report2,wishPath,jsonMode){if(jsonMode)console.log(JSON.stringify(report2));else console.log(formatLintReport(report2,{color:process.stdout.isTTY??!1,path:wishPath}))}function exitWithErrorCount(report2){let errors3=report2.violations.filter((v)=>v.severity==="error").length;process.exit(errors3>0?1:0)}function handleNoFixableViolations(report2,wishPath,jsonMode){if(jsonMode)console.log(JSON.stringify({...report2,fixedViolations:0}));else console.log(formatLintReport(report2,{color:process.stdout.isTTY??!1,path:wishPath})),console.log(`
|
|
4905
4913
|
No fixable violations to apply.`);process.exit(report2.summary.total>0?1:0)}function handleDryRunFix(report2,markdown,fixed,wishPath,jsonMode){if(jsonMode)console.log(JSON.stringify({...report2,dryRun:!0,diff:renderDiff(markdown,fixed)}));else console.log(formatLintReport(report2,{color:process.stdout.isTTY??!1,path:wishPath})),console.log(`
|
|
4906
4914
|
--- Dry-run diff (${wishPath}) ---`),console.log(renderDiff(markdown,fixed)),console.log(`
|
|
4907
|
-
File not modified (--dry-run).`);process.exit(report2.summary.total>0?1:0)}async function applyAndReportFix(report2,fixed,wishPath,slug,lintOpts,jsonMode){await writeFile11(wishPath,fixed,"utf-8");let docOrError2=parseWishOrError(fixed),report22={...lintWish(docOrError2,fixed,lintOpts),wish:slug,file:wishPath},fixedCount=report2.summary.fixable;if(jsonMode)console.log(JSON.stringify({...report22,fixedViolations:fixedCount}));else console.log(`\u2705 Applied ${fixedCount} fix(es) to ${wishPath}`),console.log(""),console.log(formatLintReport(report22,{color:process.stdout.isTTY??!1,path:wishPath}));let remainingErrors=report22.violations.filter((v)=>v.severity==="error").length;process.exit(remainingErrors>0?1:0)}async function runLintFix(report2,markdown,wishPath,slug,lintOpts,options){let{applyFixes:applyFixes2}=await Promise.resolve().then(() => (init_wish_lint(),exports_wish_lint)),fixed=applyFixes2(markdown,report2),jsonMode=options.json??!1;if(fixed===markdown)handleNoFixableViolations(report2,wishPath,jsonMode);if(options.dryRun)handleDryRunFix(report2,markdown,fixed,wishPath,jsonMode);return applyAndReportFix(report2,fixed,wishPath,slug,lintOpts,jsonMode)}async function wishLintCommand(slug,options){let wishPath=join88(process.cwd(),".genie","wishes",slug,"WISH.md"),jsonMode=options.json??!1;if(!existsSync73(wishPath))reportWishFileMissing(slug,wishPath,jsonMode);let markdown=await readFile17(wishPath,"utf-8"),lintOpts={allowTodoPlaceholders:options.allowTodoPlaceholders},docOrError=parseWishOrError(markdown),report2={...lintWish(docOrError,markdown,lintOpts),wish:slug,file:wishPath};if(options.fix){await runLintFix(report2,markdown,wishPath,slug,lintOpts,options);return}emitLintReport(report2,wishPath,jsonMode),exitWithErrorCount(report2)}function reportWishParseError(error2,jsonMode){let payload={error:error2.message,rule:error2.rule,line:error2.line,column:error2.column??null,file:error2.file??null};if(jsonMode){console.log(JSON.stringify(payload));return}if(console.error(`\u274C Parse failed (${payload.rule}): ${payload.error}`),payload.file)console.error(` File: ${payload.file}`);if(payload.line)console.error(` Line: ${payload.line}`)}async function wishParseCommand(slug,options){try{let doc=parseWishFile(slug);console.log(options.json?JSON.stringify(doc):JSON.stringify(doc,null,2));return}catch(error2){if(error2 instanceof WishParseError)reportWishParseError(error2,options.json??!1),process.exit(1);let message=error2 instanceof Error?error2.message:String(error2);console.error(`\u274C ${message}`),process.exit(1)}}async function isWishFile(wishPath){try{return(await stat11(wishPath)).isFile()}catch{return!1}}function parseWishSummary(slug){try{let doc=parseWishFile(slug);return{status:doc.metadata.status??"-",groupCount:String(doc.executionGroups.length)}}catch(error2){return{status:error2 instanceof WishParseError?"malformed":"error",groupCount:"-"}}}async function loadStateCounts(slug){try{let state=await(await Promise.resolve().then(() => (init_wish_state(),exports_wish_state))).getState(slug);if(!state)return{ready:0,inProgress:0,done:0};let ready=0,inProgress=0,done=0;for(let g of Object.values(state.groups))if(g.status==="ready")ready++;else if(g.status==="in_progress")inProgress++;else if(g.status==="done")done++;return{ready,inProgress,done}}catch{return{ready:0,inProgress:0,done:0}}}async function wishListCommand(){let wishesRoot=join88(process.cwd(),".genie","wishes");if(!existsSync73(wishesRoot))console.error(`\u274C Wishes directory not found: ${wishesRoot}`),process.exit(1);let entries=await readdir11(wishesRoot),rows=[];for(let entry2 of entries.sort()){if(entry2.startsWith("_")||entry2.startsWith("."))continue;if(!await isWishFile(join88(wishesRoot,entry2,"WISH.md")))continue;let{status:status2,groupCount}=parseWishSummary(entry2),{ready,inProgress,done}=await loadStateCounts(entry2);rows.push({slug:entry2,status:status2,groupCount,ready,inProgress,done})}if(rows.length===0){console.log("No wishes found under .genie/wishes/");return}let slugW=Math.max(4,...rows.map((r)=>r.slug.length)),statusW=Math.max(6,...rows.map((r)=>r.status.length)),pad=(s2,n)=>s2+" ".repeat(Math.max(0,n-s2.length));console.log(` ${pad("SLUG",slugW)} ${pad("STATUS",statusW)} GROUPS READY IN-PROG DONE`),console.log(` ${"\u2500".repeat(slugW+statusW+32)}`);for(let r of rows)console.log(` ${pad(r.slug,slugW)} ${pad(r.status,statusW)} ${pad(r.groupCount,6)} ${pad(String(r.ready),5)} ${pad(String(r.inProgress),7)} ${r.done}`);console.log(""),console.log(` Total: ${rows.length} wishes`)}function registerWishCommands(program2){let wish=program2.command("wish").description("Wish lifecycle management");wish.command("new <slug>").description("Scaffold a new WISH.md from templates/wish-template.md").option("--force","Overwrite an existing wish directory").action(async(slug,options)=>{await wishNewCommand(slug,options)}),wish.command("lint <slug>").description("Structural health check (stub \u2014 full implementation in Group 3)").option("--json","Emit machine-readable JSON output").option("--fix","Auto-repair deterministic violations").option("--dry-run","With --fix: print diff without writing").option("--allow-todo-placeholders","Pass <TODO> placeholders without emitting todo-placeholder-remaining").action(async(slug,options)=>{await wishLintCommand(slug,options)}),wish.command("parse <slug>").description("Parse WISH.md and emit the WishDocument as JSON").option("--json","One-line JSON output (default: pretty-printed)").action(async(slug,options)=>{await wishParseCommand(slug,options)}),wish.command("status <slug>").description("Show wish state overview for all groups").action(async(slug)=>{await statusCommand(slug)}),wish.command("done <ref>").description("Mark a wish group as done (format: <slug>#<group>)").
|
|
4908
|
-
`)}});async function startNamedSession(name){let{randomUUID:randomUUID15}=await import("crypto"),{buildTeamLeadCommand:buildTeamLeadCommand2}=await Promise.resolve().then(() => (init_team_lead_command(),exports_team_lead_command)),{getAgentsFilePath:getAgentsFilePath2}=await Promise.resolve().then(() => (init_session(),exports_session)),systemPromptFile=getAgentsFilePath2(),sessionId=randomUUID15(),cmd=buildTeamLeadCommand2(name,{systemPromptFile:systemPromptFile??void 0,sessionId});console.log(`Starting new session: ${name}`);let{spawnSync:spawnSync11}=await import("child_process"),result2=spawnSync11("sh",["-c",cmd],{stdio:"inherit"});if(result2.status)process.exit(result2.status)}program2.command("setup").description("Configure genie settings").option("--quick","Accept all defaults").option("--shortcuts","Only configure keyboard shortcuts").option("--codex","Only configure Codex integration").option("--terminal","Only configure terminal defaults").option("--session","Only configure session settings").option("--reset","Reset configuration to defaults").option("--show","Show current configuration").action(async(options)=>{await setupCommand(options)});program2.command("install").description("Register genie-serve under pm2 with hardened defaults (canonical-pgserve-pm2-supervision wave 2)").option("--skip-pgserve","Don't run `pgserve install` first (operators who manage pgserve themselves)").action(async(options)=>{await installCommand(options)});program2.command("doctor").description("Run diagnostic checks on genie installation").option("--fix","Auto-fix: kill zombie postgres, clean shared memory, restart daemon").option("--observability","Report partition health + GENIE_WIDE_EMIT flag state").option("--perf","Report rolling per-handler P50/P99 from hook_perf_baseline + flag P99 regressions and recent fallback-log entries").option("--fix-team-orphans","Archive stale Claude-team config dirs missing config.json (paired with invincible-genie wish migration 050)").option("--dry-run","Pair with --fix-team-orphans to preview archive moves without mutating").option("--json","Emit JSON instead of human output (pairs with --observability)").action(doctorCommand);program2.command("update").description("Update Genie CLI to the latest version").option("--next","Switch to dev builds (npm @next tag)").option("--stable","Switch to stable releases (npm @latest tag)").option("-y, --yes","Skip the TTY confirmation prompt (or set GENIE_UPDATE_YES=1)").option("--no-restart","Skip post-update maintenance AND the verify probe").option("--no-verify","Run maintenance but skip the post-restart verify probe").option("--skip-maintenance","Skip post-update maintenance (or set GENIE_UPDATE_SKIP_MAINTENANCE=1)").option("--skip-cleanup <names>","Comma-separated legacy-artifact cleanup names to skip").option("--no-sidecar-cleanup","Accepted for cross-CLI portability with omni (no-op for genie)").action(updateCommand);program2.command("migrate").description("Apply pending genie host-migrations (auto-runs on install)").option("--dry-run","List pending migrations without executing").option("--quiet","Suppress per-step OK lines (used by postinstall)").option("--status","Show applied / pending / failed table").action(async(opts)=>{await migrateCommand({dryRun:opts.dryRun,quiet:opts.quiet,status:opts.status})});program2.command("uninstall").description("Remove Genie CLI and clean up hooks").action(uninstallCommand);var shortcuts=program2.command("shortcuts").description("Manage tmux keyboard shortcuts");shortcuts.action(shortcutsShowCommand);shortcuts.command("show").description("Show available shortcuts and installation status").action(shortcutsShowCommand);shortcuts.command("install").description("Install shortcuts to config files (~/.tmux.conf, shell rc)").action(shortcutsInstallCommand);shortcuts.command("uninstall").description("Remove shortcuts from config files").action(shortcutsUninstallCommand);registerServeCommands(program2);registerAppCommand(program2);registerInitCommands(program2);registerTeamNamespace(program2);registerDirNamespace(program2);registerAgentCommands(program2);registerObserveCommands(program2);registerOmniNamespace(program2);registerSendInboxCommands(program2);registerStateCommands(program2);registerDispatchCommands(program2);registerDispatchGroupCommands(program2);registerWishCommands(program2);registerHookNamespace(program2);registerDbCommands(program2);registerScheduleCommands(program2);registerDaemonCommands(program2);registerTaskCommands(program2);registerTypeCommands(program2);registerBoardCommands(program2);registerTagCommands(program2);registerReleaseCommands(program2);registerSecCommands(program2);registerProjectCommands(program2);registerPruneCommands(program2);registerNotifyCommands(program2);registerEventsCommands(program2);registerSessionsCommands(program2);registerMetricsCommands(program2);registerExportCommands(program2);registerImportCommands(program2);registerTemplateCommands(program2);registerBrainCommands(program2);registerBriefCommands(program2);registerApprovalCommands(program2);program2.command("done [ref]").description("Close the current turn (inside an agent session) or mark a wish group done (team-lead, <slug>#<group>)").action(async(ref)=>{let{doneAction:doneAction2}=await Promise.resolve().then(() => (init_done(),exports_done));await doneAction2(ref)});program2.command("blocked").description("Close the current turn with outcome=blocked").requiredOption("--reason <message>","Why the turn is blocked").action(async(options)=>{let{blockedAction:blockedAction2}=await Promise.resolve().then(() => (init_blocked(),exports_blocked));await blockedAction2(options)});program2.command("failed").description("Close the current turn with outcome=failed").requiredOption("--reason <message>","Why the turn failed").action(async(options)=>{let{failedAction:failedAction2}=await Promise.resolve().then(() => (init_failed(),exports_failed));await failedAction2(options)});program2.command("pane-trap").description("Internal: write clean_exit_unverified outcome for a dying pane/shell. Invoked by the tmux pane-died hook and the inline shell EXIT trap.").option("--pane-id <id>","tmux pane id (%N) \u2014 resolved to executor via executors.tmux_pane_id").option("--executor-id <id>","explicit executor UUID (preferred when available)").option("--reason <reason>","trap source: pane_died or shell_exit","pane_died").action(async(options)=>{let{paneTrapAction:paneTrapAction2}=await Promise.resolve().then(() => (init_pane_trap2(),exports_pane_trap));await paneTrapAction2(options)});installWorkspaceCheck(program2);var auditTimers=new Map,auditSpans=new Map;program2.hook("preAction",(_thisCommand,actionCommand)=>{let name=actionCommand.name();auditTimers.set(name,Date.now()),Promise.resolve().then(() => (init_db(),exports_db)).then(({isConnected:isConnected2})=>{if(!isConnected2())return;recordAuditEvent("command",name,"command_start",getActor(),{args:actionCommand.args}).catch(()=>{})}).catch(()=>{}),(async()=>{try{let{isWideEmitEnabled:isWideEmitEnabled2}=await Promise.resolve().then(() => exports_observability_flag);if(!isWideEmitEnabled2())return;let{startSpan:startSpan2}=await Promise.resolve().then(() => (init_emit(),exports_emit)),{getAmbient:getAmbient2}=await Promise.resolve().then(() => (init_trace_context(),exports_trace_context)),handle=startSpan2("cli.command",{command:name,args:actionCommand.args??[],cwd:process.cwd()},{severity:"debug",source_subsystem:"cli",ctx:getAmbient2()??void 0,agent:getActor()});auditSpans.set(name,handle)}catch{}})()});program2.hook("postAction",async(_thisCommand,actionCommand)=>{let name=actionCommand.name(),startMs=auditTimers.get(name),durationMs=startMs?Date.now()-startMs:void 0;auditTimers.delete(name);try{let{isConnected:isConnected2}=await Promise.resolve().then(() => (init_db(),exports_db));if(!isConnected2())return;await recordAuditEvent("command",name,"command_success",getActor(),{args:actionCommand.args,duration_ms:durationMs})}catch{}let handle=auditSpans.get(name);auditSpans.delete(name);try{if(handle){let{isWideEmitEnabled:isWideEmitEnabled2}=await Promise.resolve().then(() => exports_observability_flag);if(isWideEmitEnabled2()){let{endSpan:endSpan2}=await Promise.resolve().then(() => (init_emit(),exports_emit));endSpan2(handle,{exit_code:0,duration_ms:durationMs??0},{severity:"debug",source_subsystem:"cli",agent:getActor()})}}}catch{}try{let{flushNow:flushNow2}=await Promise.resolve().then(() => (init_emit(),exports_emit));await flushNow2()}catch{}});program2.command("spawn <name>").description("Spawn a new agent by name (resolves from directory or built-ins)").option("--provider <provider>","Provider: claude or codex","claude").option("--team <team>","Team name").option("--model <model>","Model override (e.g., sonnet, opus)").option("--skill <skill>","Skill to load (optional)").option("--layout <layout>","Layout mode: mosaic (default) or vertical").option("--color <color>","Teammate pane border color").option("--plan-mode","Start teammate in plan mode").option("--permission-mode <mode>","Permission mode (e.g., acceptEdits)").option("--extra-args <args...>","Extra CLI args forwarded to provider").option("--cwd <path>","Working directory for the agent (overrides directory entry)").option("--session <session>","Tmux session name to spawn into").option("--role <role>","Override role name for registration (avoids duplicate guard)").option("--new-window","Create a new tmux window instead of splitting").option("--window <target>","Tmux window to split into (e.g., genie:3)").option("--no-auto-resume","Disable auto-resume on pane death").option("--no-auto-sync","Disable auto-registration from workspace agents directory").option("--stream","Stream SDK messages to stdout in real-time (claude-sdk provider)").option("--stream-format <format>","Streaming output format: text, json, ndjson (default: text)","text").option("--sdk-max-turns <n>","SDK: max conversation turns",parseNumericFlag2("--sdk-max-turns")).option("--sdk-max-budget <usd>","SDK: max budget in USD",parseNumericFlag2("--sdk-max-budget")).option("--sdk-stream","SDK: enable streaming output (shortcut for --stream)").option("--sdk-effort <level>","SDK: reasoning effort level (low, medium, high, max)").option("--sdk-resume <session-id>","SDK: resume a previous session by ID").option("--prompt <text>","Initial prompt to send as the first user message").addHelpText("after",`
|
|
4915
|
+
File not modified (--dry-run).`);process.exit(report2.summary.total>0?1:0)}async function applyAndReportFix(report2,fixed,wishPath,slug,lintOpts,jsonMode){await writeFile11(wishPath,fixed,"utf-8");let docOrError2=parseWishOrError(fixed),report22={...lintWish(docOrError2,fixed,lintOpts),wish:slug,file:wishPath},fixedCount=report2.summary.fixable;if(jsonMode)console.log(JSON.stringify({...report22,fixedViolations:fixedCount}));else console.log(`\u2705 Applied ${fixedCount} fix(es) to ${wishPath}`),console.log(""),console.log(formatLintReport(report22,{color:process.stdout.isTTY??!1,path:wishPath}));let remainingErrors=report22.violations.filter((v)=>v.severity==="error").length;process.exit(remainingErrors>0?1:0)}async function runLintFix(report2,markdown,wishPath,slug,lintOpts,options){let{applyFixes:applyFixes2}=await Promise.resolve().then(() => (init_wish_lint(),exports_wish_lint)),fixed=applyFixes2(markdown,report2),jsonMode=options.json??!1;if(fixed===markdown)handleNoFixableViolations(report2,wishPath,jsonMode);if(options.dryRun)handleDryRunFix(report2,markdown,fixed,wishPath,jsonMode);return applyAndReportFix(report2,fixed,wishPath,slug,lintOpts,jsonMode)}async function wishLintCommand(slug,options){let wishPath=join88(process.cwd(),".genie","wishes",slug,"WISH.md"),jsonMode=options.json??!1;if(!existsSync73(wishPath))reportWishFileMissing(slug,wishPath,jsonMode);let markdown=await readFile17(wishPath,"utf-8"),lintOpts={allowTodoPlaceholders:options.allowTodoPlaceholders},docOrError=parseWishOrError(markdown),report2={...lintWish(docOrError,markdown,lintOpts),wish:slug,file:wishPath};if(options.fix){await runLintFix(report2,markdown,wishPath,slug,lintOpts,options);return}emitLintReport(report2,wishPath,jsonMode),exitWithErrorCount(report2)}function reportWishParseError(error2,jsonMode){let payload={error:error2.message,rule:error2.rule,line:error2.line,column:error2.column??null,file:error2.file??null};if(jsonMode){console.log(JSON.stringify(payload));return}if(console.error(`\u274C Parse failed (${payload.rule}): ${payload.error}`),payload.file)console.error(` File: ${payload.file}`);if(payload.line)console.error(` Line: ${payload.line}`)}async function wishParseCommand(slug,options){try{let doc=parseWishFile(slug);console.log(options.json?JSON.stringify(doc):JSON.stringify(doc,null,2));return}catch(error2){if(error2 instanceof WishParseError)reportWishParseError(error2,options.json??!1),process.exit(1);let message=error2 instanceof Error?error2.message:String(error2);console.error(`\u274C ${message}`),process.exit(1)}}async function isWishFile(wishPath){try{return(await stat11(wishPath)).isFile()}catch{return!1}}function parseWishSummary(slug){try{let doc=parseWishFile(slug);return{status:doc.metadata.status??"-",groupCount:String(doc.executionGroups.length)}}catch(error2){return{status:error2 instanceof WishParseError?"malformed":"error",groupCount:"-"}}}async function loadStateCounts(slug){try{let state=await(await Promise.resolve().then(() => (init_wish_state(),exports_wish_state))).getState(slug);if(!state)return{ready:0,inProgress:0,done:0};let ready=0,inProgress=0,done=0;for(let g of Object.values(state.groups))if(g.status==="ready")ready++;else if(g.status==="in_progress")inProgress++;else if(g.status==="done")done++;return{ready,inProgress,done}}catch{return{ready:0,inProgress:0,done:0}}}async function wishListCommand(){let wishesRoot=join88(process.cwd(),".genie","wishes");if(!existsSync73(wishesRoot))console.error(`\u274C Wishes directory not found: ${wishesRoot}`),process.exit(1);let entries=await readdir11(wishesRoot),rows=[];for(let entry2 of entries.sort()){if(entry2.startsWith("_")||entry2.startsWith("."))continue;if(!await isWishFile(join88(wishesRoot,entry2,"WISH.md")))continue;let{status:status2,groupCount}=parseWishSummary(entry2),{ready,inProgress,done}=await loadStateCounts(entry2);rows.push({slug:entry2,status:status2,groupCount,ready,inProgress,done})}if(rows.length===0){console.log("No wishes found under .genie/wishes/");return}let slugW=Math.max(4,...rows.map((r)=>r.slug.length)),statusW=Math.max(6,...rows.map((r)=>r.status.length)),pad=(s2,n)=>s2+" ".repeat(Math.max(0,n-s2.length));console.log(` ${pad("SLUG",slugW)} ${pad("STATUS",statusW)} GROUPS READY IN-PROG DONE`),console.log(` ${"\u2500".repeat(slugW+statusW+32)}`);for(let r of rows)console.log(` ${pad(r.slug,slugW)} ${pad(r.status,statusW)} ${pad(r.groupCount,6)} ${pad(String(r.ready),5)} ${pad(String(r.inProgress),7)} ${r.done}`);console.log(""),console.log(` Total: ${rows.length} wishes`)}function registerWishCommands(program2){let wish=program2.command("wish").description("Wish lifecycle management");wish.command("new <slug>").description("Scaffold a new WISH.md from templates/wish-template.md").option("--force","Overwrite an existing wish directory").action(async(slug,options)=>{await wishNewCommand(slug,options)}),wish.command("lint <slug>").description("Structural health check (stub \u2014 full implementation in Group 3)").option("--json","Emit machine-readable JSON output").option("--fix","Auto-repair deterministic violations").option("--dry-run","With --fix: print diff without writing").option("--allow-todo-placeholders","Pass <TODO> placeholders without emitting todo-placeholder-remaining").action(async(slug,options)=>{await wishLintCommand(slug,options)}),wish.command("parse <slug>").description("Parse WISH.md and emit the WishDocument as JSON").option("--json","One-line JSON output (default: pretty-printed)").action(async(slug,options)=>{await wishParseCommand(slug,options)}),wish.command("status <slug>").description("Show wish state overview for all groups").action(async(slug)=>{await statusCommand(slug)}),wish.command("done <ref>").description("Mark a wish group as done (format: <slug>#<group>)").option("-r, --report <message>","Full group handoff \u2014 what shipped, what is verified, what is left, surprises, decisions. REQUIRED. Multi-line OK (pass via heredoc).").action(async(ref,options)=>{let report2=options.report?.trim();if(!report2)console.error(`\u274C genie wish done requires --report "<group handoff>".
|
|
4916
|
+
`+`
|
|
4917
|
+
This is the orchestrator's handoff. It lands in the audit trail and the
|
|
4918
|
+
`+` wave/wish-complete notification \u2014 the ONLY summary anyone reading later
|
|
4919
|
+
`+` will see without replaying your transcript.
|
|
4920
|
+
|
|
4921
|
+
Cover: what was attempted, what shipped, what is verified vs unverified,
|
|
4922
|
+
what is left or deferred, and any surprises or decisions a future agent
|
|
4923
|
+
needs to know. Length: as long as it needs to be. Multi-line is fine.
|
|
4924
|
+
|
|
4925
|
+
Example (heredoc):
|
|
4926
|
+
genie wish done my-wish#3 --report "$(cat <<'EOF'
|
|
4927
|
+
Goal: wire dev-local fixtures + smoke for group 3.
|
|
4928
|
+
Shipped: PR #143 + PR #144, both merged to dev.
|
|
4929
|
+
Verified: make smoke passed; tenant-A login round-trip OK.
|
|
4930
|
+
Left: CSRF rotation deferred to issue #1245.
|
|
4931
|
+
`+` Notes: bumped core@1.260507.5 \u2014 desktop rebuild required.
|
|
4932
|
+
`+` EOF
|
|
4933
|
+
)"`),process.exit(2);await doneCommand(ref,report2)}),wish.command("reset <ref>").option("-y, --yes","Skip confirmation prompt (required in non-interactive mode)").description("Reset wish state. <slug>#<group> resets one in-progress group; bare <slug> wipes the wish and recreates from current WISH.md").action(async(ref,options)=>{await resetAction(ref,options)}),wish.command("list").description("Enumerate all wishes with status, group counts, and progress").action(async()=>{await wishListCommand()})}var _T_BOOT=Date.now();try{let{execSync:execSyncStartup}=__require("child_process");if(execSyncStartup("git config core.bare",{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()==="true")execSyncStartup("git config core.bare false",{stdio:["pipe","pipe","pipe"]})}catch{}function parseNumericFlag2(flagName){return(value)=>{let n=Number(value);if(Number.isNaN(n))throw Error(`${flagName} must be a number, got: ${value}`);return n}}if(process.env.GENIE_PROFILE_DB)console.error(`[profile] imports=${Date.now()-_T_BOOT}ms`);var program2=new Command;program2.name("genie").description("Genie CLI - AI-assisted development").version(VERSION);program2.option("--no-interactive","Disable interactive prompts (exit 2 instead of prompting)");program2.option("--no-tui","Skip TUI bootstrap (or set GENIE_TUI_DISABLE=1)");program2.configureHelp({sortSubcommands:!0,showGlobalOptions:!0});program2.configureOutput({outputError:(str5,write)=>{let cmd=program2.commands.find((c)=>process.argv.slice(2,6).includes(c.name())),prefix=cmd?`genie ${cmd.name()}`:"genie";write(`\x1B[31mError (${prefix}): ${str5}\x1B[0m
|
|
4934
|
+
`)}});async function startNamedSession(name){let{randomUUID:randomUUID15}=await import("crypto"),{buildTeamLeadCommand:buildTeamLeadCommand2}=await Promise.resolve().then(() => (init_team_lead_command(),exports_team_lead_command)),{getAgentsFilePath:getAgentsFilePath2}=await Promise.resolve().then(() => (init_session(),exports_session)),systemPromptFile=getAgentsFilePath2(),sessionId=randomUUID15(),cmd=buildTeamLeadCommand2(name,{systemPromptFile:systemPromptFile??void 0,sessionId});console.log(`Starting new session: ${name}`);let{spawnSync:spawnSync11}=await import("child_process"),result2=spawnSync11("sh",["-c",cmd],{stdio:"inherit"});if(result2.status)process.exit(result2.status)}program2.command("setup").description("Configure genie settings").option("--quick","Accept all defaults").option("--shortcuts","Only configure keyboard shortcuts").option("--codex","Only configure Codex integration").option("--terminal","Only configure terminal defaults").option("--session","Only configure session settings").option("--reset","Reset configuration to defaults").option("--show","Show current configuration").action(async(options)=>{await setupCommand(options)});program2.command("install").description("Register genie-serve under pm2 with hardened defaults (canonical-pgserve-pm2-supervision wave 2)").option("--skip-pgserve","Don't run `pgserve install` first (operators who manage pgserve themselves)").action(async(options)=>{await installCommand(options)});program2.command("doctor").description("Run diagnostic checks on genie installation").option("--fix","Auto-fix: kill zombie postgres, clean shared memory, restart daemon").option("--observability","Report partition health + GENIE_WIDE_EMIT flag state").option("--perf","Report rolling per-handler P50/P99 from hook_perf_baseline + flag P99 regressions and recent fallback-log entries").option("--fix-team-orphans","Archive stale Claude-team config dirs missing config.json (paired with invincible-genie wish migration 050)").option("--dry-run","Pair with --fix-team-orphans to preview archive moves without mutating").option("--json","Emit JSON instead of human output (pairs with --observability)").action(doctorCommand);program2.command("update").description("Update Genie CLI to the latest version").option("--next","Switch to dev builds (npm @next tag)").option("--stable","Switch to stable releases (npm @latest tag)").option("-y, --yes","Skip the TTY confirmation prompt (or set GENIE_UPDATE_YES=1)").option("--no-restart","Skip post-update maintenance AND the verify probe").option("--no-verify","Run maintenance but skip the post-restart verify probe").option("--skip-maintenance","Skip post-update maintenance (or set GENIE_UPDATE_SKIP_MAINTENANCE=1)").option("--skip-cleanup <names>","Comma-separated legacy-artifact cleanup names to skip").option("--no-sidecar-cleanup","Accepted for cross-CLI portability with omni (no-op for genie)").action(updateCommand);program2.command("migrate").description("Apply pending genie host-migrations (auto-runs on install)").option("--dry-run","List pending migrations without executing").option("--quiet","Suppress per-step OK lines (used by postinstall)").option("--status","Show applied / pending / failed table").action(async(opts)=>{await migrateCommand({dryRun:opts.dryRun,quiet:opts.quiet,status:opts.status})});program2.command("uninstall").description("Remove Genie CLI and clean up hooks").action(uninstallCommand);var shortcuts=program2.command("shortcuts").description("Manage tmux keyboard shortcuts");shortcuts.action(shortcutsShowCommand);shortcuts.command("show").description("Show available shortcuts and installation status").action(shortcutsShowCommand);shortcuts.command("install").description("Install shortcuts to config files (~/.tmux.conf, shell rc)").action(shortcutsInstallCommand);shortcuts.command("uninstall").description("Remove shortcuts from config files").action(shortcutsUninstallCommand);registerServeCommands(program2);registerAppCommand(program2);registerInitCommands(program2);registerTeamNamespace(program2);registerDirNamespace(program2);registerAgentCommands(program2);registerObserveCommands(program2);registerOmniNamespace(program2);registerSendInboxCommands(program2);registerStateCommands(program2);registerDispatchCommands(program2);registerDispatchGroupCommands(program2);registerWishCommands(program2);registerHookNamespace(program2);registerDbCommands(program2);registerScheduleCommands(program2);registerDaemonCommands(program2);registerTaskCommands(program2);registerTypeCommands(program2);registerBoardCommands(program2);registerTagCommands(program2);registerReleaseCommands(program2);registerSecCommands(program2);registerProjectCommands(program2);registerPruneCommands(program2);registerNotifyCommands(program2);registerEventsCommands(program2);registerSessionsCommands(program2);registerMetricsCommands(program2);registerExportCommands(program2);registerImportCommands(program2);registerTemplateCommands(program2);registerBrainCommands(program2);registerBriefCommands(program2);registerApprovalCommands(program2);program2.command("done [ref]").description("Close the current turn (inside an agent session) or mark a wish group done (team-lead, <slug>#<group>)").option("-r, --report <message>","Full session handoff \u2014 what shipped, what is verified, what is left, surprises, decisions. REQUIRED. As long as it needs to be (multi-line OK; pass via heredoc).").action(async(ref,options)=>{let{doneAction:doneAction2}=await Promise.resolve().then(() => (init_done(),exports_done));await doneAction2(ref,options)});program2.command("blocked").description("Close the current turn with outcome=blocked").requiredOption("--reason <message>","Why the turn is blocked").action(async(options)=>{let{blockedAction:blockedAction2}=await Promise.resolve().then(() => (init_blocked(),exports_blocked));await blockedAction2(options)});program2.command("failed").description("Close the current turn with outcome=failed").requiredOption("--reason <message>","Why the turn failed").action(async(options)=>{let{failedAction:failedAction2}=await Promise.resolve().then(() => (init_failed(),exports_failed));await failedAction2(options)});program2.command("pane-trap").description("Internal: write clean_exit_unverified outcome for a dying pane/shell. Invoked by the tmux pane-died hook and the inline shell EXIT trap.").option("--pane-id <id>","tmux pane id (%N) \u2014 resolved to executor via executors.tmux_pane_id").option("--executor-id <id>","explicit executor UUID (preferred when available)").option("--reason <reason>","trap source: pane_died or shell_exit","pane_died").action(async(options)=>{let{paneTrapAction:paneTrapAction2}=await Promise.resolve().then(() => (init_pane_trap2(),exports_pane_trap));await paneTrapAction2(options)});installWorkspaceCheck(program2);var auditTimers=new Map,auditSpans=new Map;program2.hook("preAction",(_thisCommand,actionCommand)=>{let name=actionCommand.name();auditTimers.set(name,Date.now()),Promise.resolve().then(() => (init_db(),exports_db)).then(({isConnected:isConnected2})=>{if(!isConnected2())return;recordAuditEvent("command",name,"command_start",getActor(),{args:actionCommand.args}).catch(()=>{})}).catch(()=>{}),(async()=>{try{let{isWideEmitEnabled:isWideEmitEnabled2}=await Promise.resolve().then(() => exports_observability_flag);if(!isWideEmitEnabled2())return;let{startSpan:startSpan2}=await Promise.resolve().then(() => (init_emit(),exports_emit)),{getAmbient:getAmbient2}=await Promise.resolve().then(() => (init_trace_context(),exports_trace_context)),handle=startSpan2("cli.command",{command:name,args:actionCommand.args??[],cwd:process.cwd()},{severity:"debug",source_subsystem:"cli",ctx:getAmbient2()??void 0,agent:getActor()});auditSpans.set(name,handle)}catch{}})()});program2.hook("postAction",async(_thisCommand,actionCommand)=>{let name=actionCommand.name(),startMs=auditTimers.get(name),durationMs=startMs?Date.now()-startMs:void 0;auditTimers.delete(name);try{let{isConnected:isConnected2}=await Promise.resolve().then(() => (init_db(),exports_db));if(!isConnected2())return;await recordAuditEvent("command",name,"command_success",getActor(),{args:actionCommand.args,duration_ms:durationMs})}catch{}let handle=auditSpans.get(name);auditSpans.delete(name);try{if(handle){let{isWideEmitEnabled:isWideEmitEnabled2}=await Promise.resolve().then(() => exports_observability_flag);if(isWideEmitEnabled2()){let{endSpan:endSpan2}=await Promise.resolve().then(() => (init_emit(),exports_emit));endSpan2(handle,{exit_code:0,duration_ms:durationMs??0},{severity:"debug",source_subsystem:"cli",agent:getActor()})}}}catch{}try{let{flushNow:flushNow2}=await Promise.resolve().then(() => (init_emit(),exports_emit));await flushNow2()}catch{}});program2.command("spawn <name>").description("Spawn a new agent by name (resolves from directory or built-ins)").option("--provider <provider>","Provider: claude or codex","claude").option("--team <team>","Team name").option("--model <model>","Model override (e.g., sonnet, opus)").option("--skill <skill>","Skill to load (optional)").option("--layout <layout>","Layout mode: mosaic (default) or vertical").option("--color <color>","Teammate pane border color").option("--plan-mode","Start teammate in plan mode").option("--permission-mode <mode>","Permission mode (e.g., acceptEdits)").option("--extra-args <args...>","Extra CLI args forwarded to provider").option("--cwd <path>","Working directory for the agent (overrides directory entry)").option("--session <session>","Tmux session name to spawn into").option("--role <role>","Override role name for registration (avoids duplicate guard)").option("--new-window","Create a new tmux window instead of splitting").option("--window <target>","Tmux window to split into (e.g., genie:3)").option("--no-auto-resume","Disable auto-resume on pane death").option("--no-auto-sync","Disable auto-registration from workspace agents directory").option("--stream","Stream SDK messages to stdout in real-time (claude-sdk provider)").option("--stream-format <format>","Streaming output format: text, json, ndjson (default: text)","text").option("--sdk-max-turns <n>","SDK: max conversation turns",parseNumericFlag2("--sdk-max-turns")).option("--sdk-max-budget <usd>","SDK: max budget in USD",parseNumericFlag2("--sdk-max-budget")).option("--sdk-stream","SDK: enable streaming output (shortcut for --stream)").option("--sdk-effort <level>","SDK: reasoning effort level (low, medium, high, max)").option("--sdk-resume <session-id>","SDK: resume a previous session by ID").option("--prompt <text>","Initial prompt to send as the first user message").addHelpText("after",`
|
|
4909
4935
|
Examples:
|
|
4910
4936
|
genie spawn engineer # Spawn built-in engineer role
|
|
4911
4937
|
genie spawn researcher --model sonnet # Spawn with model override
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automagik/genie",
|
|
3
|
-
"version": "4.260507.
|
|
3
|
+
"version": "4.260507.6",
|
|
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.260507.
|
|
3
|
+
"version": "4.260507.6",
|
|
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"
|