@automagik/genie 4.260425.2 → 4.260425.3
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
|
@@ -761,10 +761,22 @@ Next steps:`),console.log(" 1. Reload tmux: tmux source ~/.tmux.conf"),console.
|
|
|
761
761
|
`:"";return writeFileSync8(filePath,newContent),!0}async function promptUninstallFrom(filePath,marker,label){if(!existsSync19(filePath))return;if(!contentExists(filePath,marker)){console.log(`\u2713 ${label} has no genie shortcuts`);return}if(await prompt(`Remove shortcuts from ${filePath}? [Y/n] `)==="n"){console.log(`\u23ED\uFE0F Skipped ${label}`);return}if(removeMarkedContent(filePath,marker))console.log(`\u2705 Removed from ${filePath}`)}async function uninstallShortcuts(){let home=homedir18(),marker="generated by genie-cli";console.log(`Uninstalling Warp-like shortcuts...
|
|
762
762
|
`),await promptUninstallFrom(join22(home,".tmux.conf"),"generated by genie-cli","tmux.conf");for(let shellRc of[join22(home,".zshrc"),join22(home,".bashrc")])await promptUninstallFrom(shellRc,"generated by genie-cli",shellRc);let termuxDir=join22(home,".termux"),isTermux=existsSync19(termuxDir)||process.env.TERMUX_VERSION;if(isTermux){let termuxProps=join22(termuxDir,"termux.properties");if(await promptUninstallFrom(termuxProps,"generated by genie-cli","termux.properties"),!contentExists(termuxProps,"generated by genie-cli"))console.log(" Run: termux-reload-settings")}if(console.log(`
|
|
763
763
|
\u2705 Uninstallation complete!`),console.log(`
|
|
764
|
-
Next steps:`),console.log(" 1. Reload tmux: tmux source ~/.tmux.conf"),console.log(" 2. Restart your shell or run: source ~/.bashrc"),isTermux)console.log(" 3. Reload Termux: termux-reload-settings")}var GENIE_CONTENT_MARKERS;var init_shortcuts=__esm(()=>{GENIE_CONTENT_MARKERS=["genie","Ctrl+","split-window","new-window","stty -ixon","Warp-like","bind-key -n","extra-keys","F1=","bind -x"]});var exports_setup={};__export(exports_setup,{setupCommand:()=>setupCommand});import{homedir as homedir19}from"os";import{join as join23}from"path";function printHeader(){console.log(),console.log(`\x1B[1m\x1B[36m${"=".repeat(64)}\x1B[0m`),console.log("\x1B[1m\x1B[36m Genie Setup Wizard\x1B[0m"),console.log(`\x1B[1m\x1B[36m${"=".repeat(64)}\x1B[0m`),console.log()}function printSection(title,description){if(console.log(),console.log(`\x1B[1m${title}\x1B[0m`),description)console.log(`\x1B[2m${description}\x1B[0m`);console.log()}async function configureSession(config,quick){if(printSection("2. Session Configuration","Configure tmux session settings"),quick)return console.log(` Using defaults: session="${config.session.name}", window="${config.session.defaultWindow}"`),config;let sessionName=await esm_default5({message:"Session name:",default:config.session.name}),defaultWindow=await esm_default5({message:"Default window name:",default:config.session.defaultWindow}),autoCreate=await esm_default4({message:"Auto-create session on connect?",default:config.session.autoCreate});return config.session={name:sessionName,defaultWindow,autoCreate},config}async function configureTerminal(config,quick){if(printSection("3. Terminal Defaults","Configure default values for term commands"),quick)return console.log(` Using defaults: timeout=${config.terminal.execTimeout}ms, lines=${config.terminal.readLines}`),config;let timeoutStr=await esm_default5({message:"Exec timeout (milliseconds):",default:String(config.terminal.execTimeout),validate:(v)=>{let n=Number.parseInt(v,10);return!Number.isNaN(n)&&n>0?!0:"Must be a positive number"}}),linesStr=await esm_default5({message:"Read lines (default for genie agent read):",default:String(config.terminal.readLines),validate:(v)=>{let n=Number.parseInt(v,10);return!Number.isNaN(n)&&n>0?!0:"Must be a positive number"}}),worktreeBase=await esm_default5({message:"Worktree base directory (leave empty for ~/.genie/worktrees/<project>/):",default:config.terminal.worktreeBase??""});return config.terminal={execTimeout:Number.parseInt(timeoutStr,10),readLines:Number.parseInt(linesStr,10),...worktreeBase?{worktreeBase}:{}},config}async function configureShortcuts(config,quick){printSection("4. Keyboard Shortcuts","Warp-like tmux shortcuts for quick navigation");let home=homedir19(),tmuxConf=join23(home,".tmux.conf");if(isShortcutsInstalled(tmuxConf))return console.log(" \x1B[32m\u2713\x1B[0m Tmux shortcuts already installed"),config.shortcuts.tmuxInstalled=!0,config;if(console.log(" Available shortcuts:"),console.log(" \x1B[36mCtrl+T\x1B[0m \u2192 New tab (window)"),console.log(" \x1B[36mCtrl+S\x1B[0m \u2192 Vertical split"),console.log(" \x1B[36mCtrl+H\x1B[0m \u2192 Horizontal split"),console.log(),quick)return console.log(" Skipped in quick mode. Run \x1B[36mgenie setup --shortcuts\x1B[0m to install."),config;if(await esm_default4({message:"Install tmux keyboard shortcuts?",default:!1}))console.log(),await installShortcuts(),config.shortcuts.tmuxInstalled=!0,await updateShortcutsConfig({tmuxInstalled:!0});else console.log(" Skipped. Run \x1B[36mgenie shortcuts install\x1B[0m later.");return config}function printCodexResult(result2){if(result2==="changed")console.log(" \x1B[32m\u2713\x1B[0m Codex config updated");else if(result2==="unchanged")console.log(" \x1B[32m\u2713\x1B[0m Codex config already up to date");else console.log(" \x1B[31m\u2717\x1B[0m Failed to update codex config")}async function configureCodex(config,quick){printSection("5. Codex Integration","Configure OpenAI Codex for genie agents");let codexCheck=await checkCommand("codex");if(!codexCheck.exists)return console.log(" \x1B[33m!\x1B[0m Codex CLI not found. Skipping codex integration."),config;if(console.log(` \x1B[32m\u2713\x1B[0m Codex CLI found (${codexCheck.version??"unknown version"})`),isCodexConfigured())return console.log(" \x1B[32m\u2713\x1B[0m Codex config already configured"),config.codex={configured:!0},config;if(console.log(),console.log(" Genie needs to configure codex for agent communication:"),console.log(" \x1B[36mdisable_paste_burst\x1B[0m \u2192 Reliable tmux command injection"),console.log(" \x1B[36mOTel exporter\x1B[0m \u2192 Telemetry relay for state detection"),console.log(` Config: \x1B[2m${contractPath(getCodexConfigPath())}\x1B[0m`),console.log(),quick){let result2=ensureCodexOtelConfig();return printCodexResult(result2),config.codex={configured:result2!=="error"},config}if(await esm_default4({message:"Configure Codex for genie agent integration?",default:!0})){let result2=ensureCodexOtelConfig();printCodexResult(result2),config.codex={configured:result2!=="error"}}else console.log(" Skipped. Run \x1B[36mgenie setup --codex\x1B[0m later.");return config}async function configureDebug(config,quick){if(printSection("6. Debug Options","Logging and debugging settings"),quick)return console.log(" Using defaults: tmuxDebug=false, verbose=false"),config;let tmuxDebug=await esm_default4({message:"Enable tmux debug logging?",default:config.logging.tmuxDebug}),verbose=await esm_default4({message:"Enable verbose mode?",default:config.logging.verbose});return config.logging={tmuxDebug,verbose},config}async function configurePromptMode(config,quick){if(printSection("7. Prompt Mode","Controls how genie injects system prompts into Claude Code"),quick)return console.log(` Using default: promptMode="${config.promptMode}"`),config;console.log(" append \u2014 Uses --append-system-prompt-file (preserves Claude Code default system prompt)"),console.log(" system \u2014 Uses --system-prompt-file (replaces Claude Code default system prompt)"),console.log();let promptMode=await esm_default11({message:"Prompt mode:",choices:[{name:"append (recommended \u2014 preserves CC default)",value:"append"},{name:"system (replaces CC default)",value:"system"}],default:config.promptMode});return config.promptMode=promptMode,config}async function showSummaryAndSave(config){printSection("Summary",`Configuration will be saved to ${contractPath(getGenieConfigPath())}`),console.log(` Session: \x1B[36m${config.session.name}\x1B[0m (window: ${config.session.defaultWindow})`),console.log(` Terminal: timeout=${config.terminal.execTimeout}ms, lines=${config.terminal.readLines}`),console.log(` Shortcuts: ${config.shortcuts.tmuxInstalled?"\x1B[32minstalled\x1B[0m":"\x1B[2mnot installed\x1B[0m"}`),console.log(` Codex: ${config.codex?.configured?"\x1B[32mconfigured\x1B[0m":"\x1B[2mnot configured\x1B[0m"}`),console.log(` Debug: tmux=${config.logging.tmuxDebug}, verbose=${config.logging.verbose}`),console.log(` Prompt mode: \x1B[36m${config.promptMode}\x1B[0m`),console.log(),config.setupComplete=!0,config.lastSetupAt=new Date().toISOString(),await saveGenieConfig(config),console.log("\x1B[32m\u2713 Configuration saved!\x1B[0m")}async function showCurrentConfig(){let config=await loadGenieConfig();console.log(),console.log("\x1B[1mCurrent Genie Configuration\x1B[0m"),console.log(`\x1B[2m${contractPath(getGenieConfigPath())}\x1B[0m`),console.log(),console.log(JSON.stringify(config,null,2)),console.log()}function printNextSteps(){console.log(),console.log("\x1B[1mNext Steps:\x1B[0m"),console.log(),console.log(" Start a session: \x1B[36mgenie\x1B[0m"),console.log(" Watch AI work: \x1B[36mtmux attach -t genie\x1B[0m"),console.log(" Check health: \x1B[36mgenie doctor\x1B[0m"),console.log()}async function setupCommand(options={}){if(options.show){await showCurrentConfig();return}if(options.reset){await resetConfig(),console.log("\x1B[32m\u2713 Configuration reset to defaults.\x1B[0m"),console.log();return}let config=await loadGenieConfig();if(options.shortcuts){printHeader(),await configureShortcuts(config,!1),await markSetupComplete();return}if(options.terminal){printHeader(),config=await configureTerminal(config,!1),await saveGenieConfig(config),console.log("\x1B[32m\u2713 Terminal configuration saved.\x1B[0m");return}if(options.session){printHeader(),config=await configureSession(config,!1),await saveGenieConfig(config),console.log("\x1B[32m\u2713 Session configuration saved.\x1B[0m");return}if(options.codex){if(printHeader(),config=await configureCodex(config,!1),await saveGenieConfig(config),config.codex?.configured)console.log("\x1B[32m\u2713 Codex configuration saved.\x1B[0m");return}let quick=options.quick??!1;if(printHeader(),quick)console.log("\x1B[2mQuick mode: accepting all defaults\x1B[0m");config=await configureSession(config,quick),config=await configureTerminal(config,quick),config=await configureShortcuts(config,quick),config=await configureCodex(config,quick),config=await configureDebug(config,quick),config=await configurePromptMode(config,quick),await showSummaryAndSave(config),installGenieTmuxConf(),printNextSteps()}function installGenieTmuxConf(){let{existsSync:existsSync20,copyFileSync:copyFileSync2,mkdirSync:mkdirSync10,chmodSync:chmodSync2}=__require("fs"),{resolve:resolve3,dirname:dirname6}=__require("path"),genieHome3=process.env.GENIE_HOME??join23(homedir19(),".genie"),dest=join23(genieHome3,"tmux.conf");if(existsSync20(dest))return;let src=[resolve3(__dirname,"..","..","scripts","tmux","genie.tmux.conf"),resolve3(__dirname,"..","scripts","tmux","genie.tmux.conf")].find((p)=>existsSync20(p));if(!src)return;try{mkdirSync10(genieHome3,{recursive:!0}),copyFileSync2(src,dest),console.log(`\x1B[32m\u2713\x1B[0m Installed genie tmux config to ${dest}`)}catch{}let osc52Src=join23(dirname6(src),"osc52-copy.sh"),osc52Dest=join23(genieHome3,"osc52-copy.sh");if(existsSync20(osc52Src))try{copyFileSync2(osc52Src,osc52Dest),chmodSync2(osc52Dest,493)}catch{}}var __dirname="/home/runner/_work/genie/genie/src/genie-commands";var init_setup=__esm(()=>{init_esm14();init_codex_config();init_genie_config2();init_system_detect();init_shortcuts()});var exports_version={};__export(exports_version,{VERSION:()=>VERSION});import{existsSync as existsSync23,readFileSync as readFileSync17}from"fs";import{dirname as dirname6,resolve as resolve3}from"path";function readVersionFromPackageJson(){let candidates=[resolve3(dirname6(import.meta.dir??__dirname),"..","..","package.json"),resolve3(dirname6(import.meta.dir??__dirname),"..","package.json"),resolve3(dirname6(import.meta.dir??__dirname),"package.json")];for(let candidate of candidates)try{if(existsSync23(candidate)){let pkg=JSON.parse(readFileSync17(candidate,"utf-8"));if(pkg.version)return pkg.version}}catch{}return FALLBACK_VERSION}var __dirname="/home/runner/_work/genie/genie/src/lib",FALLBACK_VERSION="0.0.0-unknown",VERSION;var init_version=__esm(()=>{VERSION=readVersionFromPackageJson()});var exports_agent_directory={};__export(exports_agent_directory,{rm:()=>rm3,resolve:()=>resolve4,ls:()=>ls,loadIdentity:()=>loadIdentity,getProjectRoot:()=>getProjectRoot,get:()=>get2,findSessionByRepo:()=>findSessionByRepo,edit:()=>edit,add:()=>add});import{existsSync as existsSync24}from"fs";import{join as join27}from"path";function getProjectRoot(){if(process.env.GENIE_PROJECT_ROOT)return process.env.GENIE_PROJECT_ROOT;try{let{execSync:execSync6}=__require("child_process");return execSync6("git rev-parse --show-toplevel",{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}catch{return process.cwd()}}async function add(entry2,_options){if(!entry2.name||entry2.name.trim()==="")throw Error("Agent name is required.");if(!entry2.dir||entry2.dir.trim()==="")throw Error("Agent directory (--dir) is required.");if(!existsSync24(entry2.dir))throw Error(`Directory does not exist: ${entry2.dir}`);let agentsPath=join27(entry2.dir,"AGENTS.md");if(!existsSync24(agentsPath))throw Error(`AGENTS.md not found in ${entry2.dir}. Each agent directory must contain an AGENTS.md file.`);let full={...entry2,promptMode:entry2.promptMode??"append",registeredAt:new Date().toISOString()},existing=await resolve4(entry2.name);if(existing&&!existing.builtin)throw Error(`Agent "${entry2.name}" already exists. Use "genie dir edit" to update or "genie dir rm" first.`);let metadata=buildMetadata(full),{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),sql=await getConnection2();return await sql`
|
|
765
|
-
INSERT INTO agents (id, role, custom_name, started_at, state, metadata)
|
|
766
|
-
VALUES (
|
|
767
|
-
|
|
764
|
+
Next steps:`),console.log(" 1. Reload tmux: tmux source ~/.tmux.conf"),console.log(" 2. Restart your shell or run: source ~/.bashrc"),isTermux)console.log(" 3. Reload Termux: termux-reload-settings")}var GENIE_CONTENT_MARKERS;var init_shortcuts=__esm(()=>{GENIE_CONTENT_MARKERS=["genie","Ctrl+","split-window","new-window","stty -ixon","Warp-like","bind-key -n","extra-keys","F1=","bind -x"]});var exports_setup={};__export(exports_setup,{setupCommand:()=>setupCommand});import{homedir as homedir19}from"os";import{join as join23}from"path";function printHeader(){console.log(),console.log(`\x1B[1m\x1B[36m${"=".repeat(64)}\x1B[0m`),console.log("\x1B[1m\x1B[36m Genie Setup Wizard\x1B[0m"),console.log(`\x1B[1m\x1B[36m${"=".repeat(64)}\x1B[0m`),console.log()}function printSection(title,description){if(console.log(),console.log(`\x1B[1m${title}\x1B[0m`),description)console.log(`\x1B[2m${description}\x1B[0m`);console.log()}async function configureSession(config,quick){if(printSection("2. Session Configuration","Configure tmux session settings"),quick)return console.log(` Using defaults: session="${config.session.name}", window="${config.session.defaultWindow}"`),config;let sessionName=await esm_default5({message:"Session name:",default:config.session.name}),defaultWindow=await esm_default5({message:"Default window name:",default:config.session.defaultWindow}),autoCreate=await esm_default4({message:"Auto-create session on connect?",default:config.session.autoCreate});return config.session={name:sessionName,defaultWindow,autoCreate},config}async function configureTerminal(config,quick){if(printSection("3. Terminal Defaults","Configure default values for term commands"),quick)return console.log(` Using defaults: timeout=${config.terminal.execTimeout}ms, lines=${config.terminal.readLines}`),config;let timeoutStr=await esm_default5({message:"Exec timeout (milliseconds):",default:String(config.terminal.execTimeout),validate:(v)=>{let n=Number.parseInt(v,10);return!Number.isNaN(n)&&n>0?!0:"Must be a positive number"}}),linesStr=await esm_default5({message:"Read lines (default for genie agent read):",default:String(config.terminal.readLines),validate:(v)=>{let n=Number.parseInt(v,10);return!Number.isNaN(n)&&n>0?!0:"Must be a positive number"}}),worktreeBase=await esm_default5({message:"Worktree base directory (leave empty for ~/.genie/worktrees/<project>/):",default:config.terminal.worktreeBase??""});return config.terminal={execTimeout:Number.parseInt(timeoutStr,10),readLines:Number.parseInt(linesStr,10),...worktreeBase?{worktreeBase}:{}},config}async function configureShortcuts(config,quick){printSection("4. Keyboard Shortcuts","Warp-like tmux shortcuts for quick navigation");let home=homedir19(),tmuxConf=join23(home,".tmux.conf");if(isShortcutsInstalled(tmuxConf))return console.log(" \x1B[32m\u2713\x1B[0m Tmux shortcuts already installed"),config.shortcuts.tmuxInstalled=!0,config;if(console.log(" Available shortcuts:"),console.log(" \x1B[36mCtrl+T\x1B[0m \u2192 New tab (window)"),console.log(" \x1B[36mCtrl+S\x1B[0m \u2192 Vertical split"),console.log(" \x1B[36mCtrl+H\x1B[0m \u2192 Horizontal split"),console.log(),quick)return console.log(" Skipped in quick mode. Run \x1B[36mgenie setup --shortcuts\x1B[0m to install."),config;if(await esm_default4({message:"Install tmux keyboard shortcuts?",default:!1}))console.log(),await installShortcuts(),config.shortcuts.tmuxInstalled=!0,await updateShortcutsConfig({tmuxInstalled:!0});else console.log(" Skipped. Run \x1B[36mgenie shortcuts install\x1B[0m later.");return config}function printCodexResult(result2){if(result2==="changed")console.log(" \x1B[32m\u2713\x1B[0m Codex config updated");else if(result2==="unchanged")console.log(" \x1B[32m\u2713\x1B[0m Codex config already up to date");else console.log(" \x1B[31m\u2717\x1B[0m Failed to update codex config")}async function configureCodex(config,quick){printSection("5. Codex Integration","Configure OpenAI Codex for genie agents");let codexCheck=await checkCommand("codex");if(!codexCheck.exists)return console.log(" \x1B[33m!\x1B[0m Codex CLI not found. Skipping codex integration."),config;if(console.log(` \x1B[32m\u2713\x1B[0m Codex CLI found (${codexCheck.version??"unknown version"})`),isCodexConfigured())return console.log(" \x1B[32m\u2713\x1B[0m Codex config already configured"),config.codex={configured:!0},config;if(console.log(),console.log(" Genie needs to configure codex for agent communication:"),console.log(" \x1B[36mdisable_paste_burst\x1B[0m \u2192 Reliable tmux command injection"),console.log(" \x1B[36mOTel exporter\x1B[0m \u2192 Telemetry relay for state detection"),console.log(` Config: \x1B[2m${contractPath(getCodexConfigPath())}\x1B[0m`),console.log(),quick){let result2=ensureCodexOtelConfig();return printCodexResult(result2),config.codex={configured:result2!=="error"},config}if(await esm_default4({message:"Configure Codex for genie agent integration?",default:!0})){let result2=ensureCodexOtelConfig();printCodexResult(result2),config.codex={configured:result2!=="error"}}else console.log(" Skipped. Run \x1B[36mgenie setup --codex\x1B[0m later.");return config}async function configureDebug(config,quick){if(printSection("6. Debug Options","Logging and debugging settings"),quick)return console.log(" Using defaults: tmuxDebug=false, verbose=false"),config;let tmuxDebug=await esm_default4({message:"Enable tmux debug logging?",default:config.logging.tmuxDebug}),verbose=await esm_default4({message:"Enable verbose mode?",default:config.logging.verbose});return config.logging={tmuxDebug,verbose},config}async function configurePromptMode(config,quick){if(printSection("7. Prompt Mode","Controls how genie injects system prompts into Claude Code"),quick)return console.log(` Using default: promptMode="${config.promptMode}"`),config;console.log(" append \u2014 Uses --append-system-prompt-file (preserves Claude Code default system prompt)"),console.log(" system \u2014 Uses --system-prompt-file (replaces Claude Code default system prompt)"),console.log();let promptMode=await esm_default11({message:"Prompt mode:",choices:[{name:"append (recommended \u2014 preserves CC default)",value:"append"},{name:"system (replaces CC default)",value:"system"}],default:config.promptMode});return config.promptMode=promptMode,config}async function showSummaryAndSave(config){printSection("Summary",`Configuration will be saved to ${contractPath(getGenieConfigPath())}`),console.log(` Session: \x1B[36m${config.session.name}\x1B[0m (window: ${config.session.defaultWindow})`),console.log(` Terminal: timeout=${config.terminal.execTimeout}ms, lines=${config.terminal.readLines}`),console.log(` Shortcuts: ${config.shortcuts.tmuxInstalled?"\x1B[32minstalled\x1B[0m":"\x1B[2mnot installed\x1B[0m"}`),console.log(` Codex: ${config.codex?.configured?"\x1B[32mconfigured\x1B[0m":"\x1B[2mnot configured\x1B[0m"}`),console.log(` Debug: tmux=${config.logging.tmuxDebug}, verbose=${config.logging.verbose}`),console.log(` Prompt mode: \x1B[36m${config.promptMode}\x1B[0m`),console.log(),config.setupComplete=!0,config.lastSetupAt=new Date().toISOString(),await saveGenieConfig(config),console.log("\x1B[32m\u2713 Configuration saved!\x1B[0m")}async function showCurrentConfig(){let config=await loadGenieConfig();console.log(),console.log("\x1B[1mCurrent Genie Configuration\x1B[0m"),console.log(`\x1B[2m${contractPath(getGenieConfigPath())}\x1B[0m`),console.log(),console.log(JSON.stringify(config,null,2)),console.log()}function printNextSteps(){console.log(),console.log("\x1B[1mNext Steps:\x1B[0m"),console.log(),console.log(" Start a session: \x1B[36mgenie\x1B[0m"),console.log(" Watch AI work: \x1B[36mtmux attach -t genie\x1B[0m"),console.log(" Check health: \x1B[36mgenie doctor\x1B[0m"),console.log()}async function setupCommand(options={}){if(options.show){await showCurrentConfig();return}if(options.reset){await resetConfig(),console.log("\x1B[32m\u2713 Configuration reset to defaults.\x1B[0m"),console.log();return}let config=await loadGenieConfig();if(options.shortcuts){printHeader(),await configureShortcuts(config,!1),await markSetupComplete();return}if(options.terminal){printHeader(),config=await configureTerminal(config,!1),await saveGenieConfig(config),console.log("\x1B[32m\u2713 Terminal configuration saved.\x1B[0m");return}if(options.session){printHeader(),config=await configureSession(config,!1),await saveGenieConfig(config),console.log("\x1B[32m\u2713 Session configuration saved.\x1B[0m");return}if(options.codex){if(printHeader(),config=await configureCodex(config,!1),await saveGenieConfig(config),config.codex?.configured)console.log("\x1B[32m\u2713 Codex configuration saved.\x1B[0m");return}let quick=options.quick??!1;if(printHeader(),quick)console.log("\x1B[2mQuick mode: accepting all defaults\x1B[0m");config=await configureSession(config,quick),config=await configureTerminal(config,quick),config=await configureShortcuts(config,quick),config=await configureCodex(config,quick),config=await configureDebug(config,quick),config=await configurePromptMode(config,quick),await showSummaryAndSave(config),installGenieTmuxConf(),printNextSteps()}function installGenieTmuxConf(){let{existsSync:existsSync20,copyFileSync:copyFileSync2,mkdirSync:mkdirSync10,chmodSync:chmodSync2}=__require("fs"),{resolve:resolve3,dirname:dirname6}=__require("path"),genieHome3=process.env.GENIE_HOME??join23(homedir19(),".genie"),dest=join23(genieHome3,"tmux.conf");if(existsSync20(dest))return;let src=[resolve3(__dirname,"..","..","scripts","tmux","genie.tmux.conf"),resolve3(__dirname,"..","scripts","tmux","genie.tmux.conf")].find((p)=>existsSync20(p));if(!src)return;try{mkdirSync10(genieHome3,{recursive:!0}),copyFileSync2(src,dest),console.log(`\x1B[32m\u2713\x1B[0m Installed genie tmux config to ${dest}`)}catch{}let osc52Src=join23(dirname6(src),"osc52-copy.sh"),osc52Dest=join23(genieHome3,"osc52-copy.sh");if(existsSync20(osc52Src))try{copyFileSync2(osc52Src,osc52Dest),chmodSync2(osc52Dest,493)}catch{}}var __dirname="/home/runner/_work/genie/genie/src/genie-commands";var init_setup=__esm(()=>{init_esm14();init_codex_config();init_genie_config2();init_system_detect();init_shortcuts()});var exports_version={};__export(exports_version,{VERSION:()=>VERSION});import{existsSync as existsSync23,readFileSync as readFileSync17}from"fs";import{dirname as dirname6,resolve as resolve3}from"path";function readVersionFromPackageJson(){let candidates=[resolve3(dirname6(import.meta.dir??__dirname),"..","..","package.json"),resolve3(dirname6(import.meta.dir??__dirname),"..","package.json"),resolve3(dirname6(import.meta.dir??__dirname),"package.json")];for(let candidate of candidates)try{if(existsSync23(candidate)){let pkg=JSON.parse(readFileSync17(candidate,"utf-8"));if(pkg.version)return pkg.version}}catch{}return FALLBACK_VERSION}var __dirname="/home/runner/_work/genie/genie/src/lib",FALLBACK_VERSION="0.0.0-unknown",VERSION;var init_version=__esm(()=>{VERSION=readVersionFromPackageJson()});var exports_agent_directory={};__export(exports_agent_directory,{rm:()=>rm3,resolve:()=>resolve4,ls:()=>ls,loadIdentity:()=>loadIdentity,getProjectRoot:()=>getProjectRoot,get:()=>get2,findSessionByRepo:()=>findSessionByRepo,edit:()=>edit,add:()=>add});import{existsSync as existsSync24}from"fs";import{join as join27}from"path";function getProjectRoot(){if(process.env.GENIE_PROJECT_ROOT)return process.env.GENIE_PROJECT_ROOT;try{let{execSync:execSync6}=__require("child_process");return execSync6("git rev-parse --show-toplevel",{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}catch{return process.cwd()}}async function add(entry2,_options){if(!entry2.name||entry2.name.trim()==="")throw Error("Agent name is required.");if(!entry2.dir||entry2.dir.trim()==="")throw Error("Agent directory (--dir) is required.");if(!existsSync24(entry2.dir))throw Error(`Directory does not exist: ${entry2.dir}`);let agentsPath=join27(entry2.dir,"AGENTS.md");if(!existsSync24(agentsPath))throw Error(`AGENTS.md not found in ${entry2.dir}. Each agent directory must contain an AGENTS.md file.`);let full={...entry2,promptMode:entry2.promptMode??"append",registeredAt:new Date().toISOString()},existing=await resolve4(entry2.name);if(existing&&!existing.builtin)throw Error(`Agent "${entry2.name}" already exists. Use "genie dir edit" to update or "genie dir rm" first.`);let metadata=buildMetadata(full),team=entry2.team??entry2.bridgeTmuxSession??null,{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),sql=await getConnection2();return await sql`
|
|
765
|
+
INSERT INTO agents (id, role, custom_name, team, repo_path, started_at, state, metadata)
|
|
766
|
+
VALUES (
|
|
767
|
+
${`dir:${entry2.name}`},
|
|
768
|
+
${entry2.name},
|
|
769
|
+
${entry2.name},
|
|
770
|
+
${team},
|
|
771
|
+
${entry2.dir},
|
|
772
|
+
now(),
|
|
773
|
+
${null},
|
|
774
|
+
${sql.json(metadata)}
|
|
775
|
+
)
|
|
776
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
777
|
+
team = COALESCE(EXCLUDED.team, agents.team),
|
|
778
|
+
repo_path = COALESCE(NULLIF(EXCLUDED.repo_path, ''), agents.repo_path),
|
|
779
|
+
metadata = ${sql.json(metadata)}
|
|
768
780
|
`,full}async function rm3(name,options){let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),sql=await getConnection2(),dirRemoved=(await sql`DELETE FROM agents WHERE id = ${`dir:${name}`}`).count>0;if(options?.force){let roleDelete=await sql`DELETE FROM agents WHERE role = ${name}`;return{removed:dirRemoved||roleDelete.count>0}}if(dirRemoved)return{removed:!0};let instances=await sql`SELECT id FROM agents WHERE role = ${name}`;if(instances.length===0)return{removed:!1};let idList=instances.map((r)=>r.id).join(", ");return{removed:!1,message:`No directory entry for "${name}". Active instances: ${idList}. Use 'genie kill <id>' to terminate, or re-run with --force to remove all.`}}async function resolve4(name){let templateTeam=await lookupTemplateTeam(name);try{let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),rows=await(await getConnection2())`
|
|
769
781
|
SELECT role, metadata, created_at FROM agents
|
|
770
782
|
WHERE role = ${name}
|
|
@@ -2012,8 +2024,7 @@ ${body}`;writeFileSync12(filePath,output,"utf-8")}function serializeSdkConfig(sd
|
|
|
2012
2024
|
FOR UPDATE
|
|
2013
2025
|
`;if(execRows.length>0&&(execRows[0].closed_at!==null||execRows[0].outcome!==null))return await tx`
|
|
2014
2026
|
UPDATE agents
|
|
2015
|
-
SET
|
|
2016
|
-
state = 'error',
|
|
2027
|
+
SET state = 'error',
|
|
2017
2028
|
last_state_change = ${nowIso}
|
|
2018
2029
|
WHERE id = ${worker.id}
|
|
2019
2030
|
`,{terminalized:!1,executorId};return await tx`
|
|
@@ -2026,8 +2037,7 @@ ${body}`;writeFileSync12(filePath,output,"utf-8")}function serializeSdkConfig(sd
|
|
|
2026
2037
|
WHERE id = ${executorId}
|
|
2027
2038
|
`,await tx`
|
|
2028
2039
|
UPDATE agents
|
|
2029
|
-
SET
|
|
2030
|
-
state = 'error',
|
|
2040
|
+
SET state = 'error',
|
|
2031
2041
|
last_state_change = ${nowIso}
|
|
2032
2042
|
WHERE id = ${worker.id}
|
|
2033
2043
|
`,await tx`
|
|
@@ -2792,10 +2802,6 @@ ${label} <TODO>
|
|
|
2792
2802
|
state = 'error',
|
|
2793
2803
|
ended_at = ${now}
|
|
2794
2804
|
WHERE id = ${executorId}
|
|
2795
|
-
`,await tx`
|
|
2796
|
-
UPDATE agents
|
|
2797
|
-
SET current_executor_id = NULL
|
|
2798
|
-
WHERE current_executor_id = ${executorId}
|
|
2799
2805
|
`,await tx`
|
|
2800
2806
|
INSERT INTO audit_events (entity_type, entity_id, event_type, actor, details)
|
|
2801
2807
|
VALUES (
|
|
@@ -3685,7 +3691,7 @@ ${context}`}}}catch{return}}import{spawnSync as spawnSync2}from"child_process";v
|
|
|
3685
3691
|
`+" genie agent send --to <a> \u2014 communicate directly"},{test:/sleep\s+\d+\s*&&\s*.*(?:capture-pane|tmux\s+list)/,message:`Consider using genie primitives instead of terminal polling:
|
|
3686
3692
|
genie task status <slug>
|
|
3687
3693
|
genie events list --since 5m`}];async function orchestrationGuard(payload){let command=payload.tool_input?.command;if(typeof command!=="string")return;for(let{test,message}of NUDGE_PATTERNS)if(test.test(command))return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:`[orchestration-guard] ${message}`}};return}import{existsSync as existsSync26,readFileSync as readFileSync18}from"fs";import{basename as basename4,join as join29}from"path";function readAgentNameFromSettings(cwd){let localSettings=join29(cwd,".claude","settings.local.json");if(!existsSync26(localSettings))return;try{return JSON.parse(readFileSync18(localSettings,"utf-8")).agentName||void 0}catch{return}}function nameFromCwd(cwd){let name=basename4(cwd);return name&&name!=="/"&&name!=="."?name:void 0}function resolveAgentName(payload){let cwd=payload.cwd;return process.env.GENIE_AGENT_NAME||payload.teammate_name||cwd&&readAgentNameFromSettings(cwd)||cwd&&nameFromCwd(cwd)||payload.session_id&&`session-${payload.session_id.slice(0,8)}`||"unknown"}function resolveTeamName(payload){return payload.team_name??process.env.GENIE_TEAM??void 0}async function emit(subject,event){try{let{publishSubjectEvent:publishSubjectEvent2}=await Promise.resolve().then(() => (init_runtime_events(),exports_runtime_events));await publishSubjectEvent2(process.cwd(),subject,event)}catch(error2){let msg=error2 instanceof Error?error2.message:String(error2);console.warn(`[runtime-emit] event log unavailable: ${msg}`)}}async function emitToolCallEvent(payload){let{tool_name:toolName,tool_input:input}=payload;if(!toolName||!input)return;let agent=resolveAgentName(payload);await emit(`genie.tool.${agent}.call`,{timestamp:new Date().toISOString(),kind:"tool_call",agent,team:resolveTeamName(payload),text:summarizeToolCall(toolName,input),data:{toolCall:{name:toolName,input}},source:"hook"});return}async function emitMessageEvent(payload){let input=payload.tool_input;if(!input)return;let msgType=input.type;if(msgType&&msgType!=="message"&&msgType!=="broadcast")return;let to=input.to,content=input.content??input.message;if(!to||!content)return;let agent=resolveAgentName(payload),subject=msgType==="broadcast"?"genie.msg.broadcast":`genie.msg.${to}`;await emit(subject,{timestamp:new Date().toISOString(),kind:"message",agent,team:resolveTeamName(payload),peer:to,direction:"out",text:content,source:"hook"});return}async function emitUserPromptEvent(payload){let prompt2=payload.prompt;if(!prompt2)return;let agent=resolveAgentName(payload);await emit(`genie.user.${agent}.prompt`,{timestamp:new Date().toISOString(),kind:"user",agent,team:resolveTeamName(payload),text:prompt2,source:"hook"});return}async function emitAssistantResponseEvent(payload){let lastMessage=payload.last_assistant_message;if(!lastMessage)return;let agent=resolveAgentName(payload);await emit(`genie.agent.${agent}.response`,{timestamp:new Date().toISOString(),kind:"assistant",agent,team:resolveTeamName(payload),text:lastMessage,source:"hook"});return}function summarizeToolCall(name,input){switch(name){case"Read":case"Edit":case"Write":return`${name} ${input.file_path??""}`;case"Bash":return`$ ${String(input.command??"").split(`
|
|
3688
|
-
`)[0]}`;case"Grep":return`Grep "${input.pattern}" ${input.path??""}`;case"Glob":return`Glob ${input.pattern}`;case"Agent":return`Agent: ${input.description??""}`;case"SendMessage":return`SendMessage \u2192 ${input.to}: ${String(input.message??"").slice(0,80)}`;default:return name}}var syncedSessions=new Map;var _deps={getAgentByName:null,getExecutor:null,updateClaudeSessionId:null,emitAuditEvent:null};async function resolveDeps(){let[agentMod,execMod,audit]=await Promise.all([_deps.getAgentByName?null:Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry)),_deps.getExecutor&&_deps.updateClaudeSessionId?null:Promise.resolve().then(() => (init_executor_registry(),exports_executor_registry)),_deps.emitAuditEvent?null:Promise.resolve().then(() => (init_audit(),exports_audit))]);return{getAgentByName:_deps.getAgentByName??agentMod.getAgentByName,getExecutor:_deps.getExecutor??execMod.getExecutor,updateClaudeSessionId:_deps.updateClaudeSessionId??execMod.updateClaudeSessionId,emitAuditEvent:_deps.emitAuditEvent??audit.recordAuditEvent}}function shouldSkipSync(payload){let sessionId=payload.session_id;if(!sessionId||typeof sessionId!=="string")return null;let hasOverrides=Object.values(_deps).some((v)=>v!==null),agentName=process.env.GENIE_AGENT_NAME??payload.teammate_name,teamName=process.env.GENIE_TEAM??payload.team_name;if(!agentName||!teamName)return null;return{sessionId,agentName,teamName}}async function sessionSync(payload){try{let ctx=shouldSkipSync(payload);if(!ctx)return;let deps=await resolveDeps(),executorId=(await deps.getAgentByName(ctx.agentName,ctx.teamName))?.currentExecutorId;if(!executorId)return;if(syncedSessions.get(executorId)===ctx.sessionId)return;let executor=await deps.getExecutor(executorId);if(!executor)return;let oldSessionId=executor.claudeSessionId??null;if(oldSessionId!==ctx.sessionId)await deps.updateClaudeSessionId(executorId,ctx.sessionId),await deps.emitAuditEvent("executor",executorId,"session.reconciled",ctx.agentName,{old_session_id:oldSessionId,new_session_id:ctx.sessionId,team:ctx.teamName})
|
|
3694
|
+
`)[0]}`;case"Grep":return`Grep "${input.pattern}" ${input.path??""}`;case"Glob":return`Glob ${input.pattern}`;case"Agent":return`Agent: ${input.description??""}`;case"SendMessage":return`SendMessage \u2192 ${input.to}: ${String(input.message??"").slice(0,80)}`;default:return name}}var syncedSessions=new Map;var _deps={getAgentByName:null,getExecutor:null,updateClaudeSessionId:null,emitAuditEvent:null};async function resolveDeps(){let[agentMod,execMod,audit]=await Promise.all([_deps.getAgentByName?null:Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry)),_deps.getExecutor&&_deps.updateClaudeSessionId?null:Promise.resolve().then(() => (init_executor_registry(),exports_executor_registry)),_deps.emitAuditEvent?null:Promise.resolve().then(() => (init_audit(),exports_audit))]);return{getAgentByName:_deps.getAgentByName??agentMod.getAgentByName,getExecutor:_deps.getExecutor??execMod.getExecutor,updateClaudeSessionId:_deps.updateClaudeSessionId??execMod.updateClaudeSessionId,emitAuditEvent:_deps.emitAuditEvent??audit.recordAuditEvent}}function shouldSkipSync(payload){let sessionId=payload.session_id;if(!sessionId||typeof sessionId!=="string")return null;let hasOverrides=Object.values(_deps).some((v)=>v!==null),agentName=process.env.GENIE_AGENT_NAME??payload.teammate_name,teamName=process.env.GENIE_TEAM??payload.team_name;if(!agentName||!teamName)return null;return{sessionId,agentName,teamName}}var TERMINAL_EXECUTOR_STATES=new Set(["done","error","terminated"]);async function sessionSync(payload){try{let ctx=shouldSkipSync(payload);if(!ctx)return;let deps=await resolveDeps(),executorId=(await deps.getAgentByName(ctx.agentName,ctx.teamName))?.currentExecutorId;if(!executorId)return;if(syncedSessions.get(executorId)===ctx.sessionId)return;let executor=await deps.getExecutor(executorId);if(!executor)return;let oldSessionId=executor.claudeSessionId??null;if(oldSessionId===ctx.sessionId){syncedSessions.set(executorId,ctx.sessionId);return}let isTerminal=TERMINAL_EXECUTOR_STATES.has(executor.state??"");if(oldSessionId!==null&&isTerminal){await deps.emitAuditEvent("executor",executorId,"session.divergence_preserved",ctx.agentName,{stored_session_id:oldSessionId,live_session_id:ctx.sessionId,executor_state:executor.state??null,team:ctx.teamName,reason:"terminal_executor_is_recovery_anchor"}),syncedSessions.set(executorId,ctx.sessionId);return}await deps.updateClaudeSessionId(executorId,ctx.sessionId),await deps.emitAuditEvent("executor",executorId,"session.reconciled",ctx.agentName,{old_session_id:oldSessionId,new_session_id:ctx.sessionId,team:ctx.teamName}),syncedSessions.set(executorId,ctx.sessionId)}catch(err){let msg=err instanceof Error?err.message:String(err);console.warn(`[session-sync] ${msg}`)}return}init_types2();var handlers=[{name:"branch-guard",event:"PreToolUse",matcher:/^Bash$/,priority:1,fn:branchGuard},{name:"orchestration-guard",event:"PreToolUse",matcher:/^Bash$/,priority:2,fn:orchestrationGuard},{name:"brain-inject",event:"PreToolUse",matcher:/.*/,priority:5,fn:brainInject},{name:"freshness",event:"PreToolUse",matcher:/^Read$/,priority:8,fn:freshness},{name:"audit-context",event:"PreToolUse",matcher:/^(Write|Edit)$/,priority:8,fn:auditContext},{name:"identity-inject",event:"PreToolUse",matcher:/^SendMessage$/,priority:10,fn:identityInject},{name:"auto-spawn",event:"PreToolUse",matcher:/^SendMessage$/,priority:20,fn:autoSpawn},{name:"runtime-emit-tool",event:"PreToolUse",matcher:/.*/,priority:30,fn:emitToolCallEvent},{name:"runtime-emit-msg",event:"PostToolUse",matcher:/^SendMessage$/,priority:30,fn:emitMessageEvent},{name:"runtime-emit-user-prompt",event:"UserPromptSubmit",priority:30,fn:emitUserPromptEvent},{name:"runtime-emit-assistant-response",event:"Stop",priority:30,fn:emitAssistantResponseEvent},{name:"session-sync-tool",event:"PreToolUse",matcher:/.*/,priority:35,fn:sessionSync},{name:"session-sync-prompt",event:"UserPromptSubmit",priority:35,fn:sessionSync}];function resolveHandlers(event,toolName){return handlers.filter((h)=>{if(h.event!==event)return!1;if(h.matcher&&toolName&&!h.matcher.test(toolName))return!1;if(h.matcher&&!toolName)return!1;return!0}).sort((a,b2)=>a.priority-b2.priority)}function hookDebug(handlerName,decision,elapsedMs){if(process.env.GENIE_HOOK_DEBUG==="1")console.error(`[hook-debug] ${handlerName} \u2192 ${decision} (${elapsedMs}ms)`)}async function runHandler(handler,payload,currentInput,isBlocking){let handlerPayload={...payload};if(currentInput)handlerPayload.tool_input=currentInput;let start=Date.now(),agentId=process.env.GENIE_AGENT_NAME??"unknown",span=isWideEmitEnabled()?startSpan("hook.delivery",{hook_name:handler.name,agent_id:agentId,tool:payload.tool_name},{source_subsystem:"hooks",ctx:getAmbient()??void 0,agent:agentId}):null;try{let result2=await handler.fn(handlerPayload);if(hookDebug(handler.name,result2?.decision??result2?.hookSpecificOutput?.permissionDecision??"allow",Date.now()-start),span)endSpan(span,{hook_name:handler.name,agent_id:agentId,status:result2?.decision==="deny"?"rejected":"ok"},{source_subsystem:"hooks",agent:agentId});return result2}catch(err){let msg=err instanceof Error?err.message:String(err);if(console.error(`[genie-hook] Handler "${handler.name}" threw: ${msg}`),span)endSpan(span,{hook_name:handler.name,agent_id:agentId,status:"error",stderr_excerpt:msg.slice(0,1024)},{source_subsystem:"hooks",agent:agentId});if(isBlocking)return hookDebug(handler.name,"deny (crash)",Date.now()-start),{decision:"deny",reason:`handler crashed: ${msg}`};hookDebug(handler.name,"allow (crash, non-blocking)",Date.now()-start);return}}function buildDenyResponse(handler,reason,hookEventName){if(hookEventName==="PreToolUse")return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:reason??`Denied by handler: ${handler.name}`}};return{decision:"block",reason:reason??`Denied by handler: ${handler.name}`}}function buildBlockingResponse(hookEventName,contextMessages,currentInput,originalInput){let response={},hasContext=contextMessages.length>0,hasInputChange=currentInput&&originalInput&&JSON.stringify(currentInput)!==JSON.stringify(originalInput);if(hasInputChange)response.updatedInput=currentInput;if(hookEventName==="PreToolUse"&&(hasContext||hasInputChange)){let output={hookEventName:"PreToolUse"};if(hasContext)output.additionalContext=contextMessages.join(`
|
|
3689
3695
|
`);if(hasInputChange)output.permissionDecision="allow",output.updatedInput=currentInput;response.hookSpecificOutput=output}return response}async function executeBlockingChain(matched,payload){let currentInput=payload.tool_input?{...payload.tool_input}:void 0,contextMessages=[],hookEventName=payload.hook_event_name;for(let handler of matched){let result2=await runHandler(handler,payload,currentInput,!0);if(!result2)continue;if(result2.decision==="deny")return buildDenyResponse(handler,result2.reason,hookEventName);if(result2.hookSpecificOutput?.additionalContext)contextMessages.push(result2.hookSpecificOutput.additionalContext);let inputUpdate=result2.hookSpecificOutput?.updatedInput??result2.updatedInput;if(inputUpdate)currentInput={...currentInput,...inputUpdate}}return buildBlockingResponse(hookEventName,contextMessages,currentInput,payload.tool_input)}async function executeNonBlockingHandlers(matched,payload){await Promise.allSettled(matched.map((h)=>h.fn(payload).catch((err)=>{let msg=err instanceof Error?err.message:String(err);console.error(`[genie-hook] Handler "${h.name}" threw: ${msg}`)})))}async function dispatch(stdin){let payload;try{payload=JSON.parse(stdin)}catch{return console.error("[genie-hook] Invalid JSON on stdin"),""}let event=payload.hook_event_name;if(!event)return console.error("[genie-hook] Missing hook_event_name in payload"),"";let toolName=payload.tool_name,matched=resolveHandlers(event,toolName);if(matched.length===0)return"";if(isBlockingEvent(event)){let result2=await executeBlockingChain(matched,payload);if(Object.keys(result2).length>0)return JSON.stringify(result2);return""}return await executeNonBlockingHandlers(matched,payload),""}async function readStdin(){let chunks=[];for await(let chunk of Bun.stdin.stream())chunks.push(Buffer.from(chunk));return Buffer.concat(chunks).toString("utf-8")}async function dispatchAction(){let stdin=await readStdin();if(!stdin.trim())process.exit(0);let result2=await dispatch(stdin);if(result2)process.stdout.write(result2)}function registerHookNamespace(program2){program2.command("hook").description("Hook middleware for Claude Code integration").command("dispatch").description("Dispatch a CC hook event (reads JSON from stdin, writes decision to stdout)").action(dispatchAction)}init_audit();init_db();init_interactivity();init_otel_receiver();init_target_resolver();init_tmux();init_orchestrator();async function resolveOrcTarget(target){let resolved=await resolveTarget(target);return{paneId:resolved.paneId,session:resolved.session||target,label:formatResolvedLabel(resolved,target)}}async function sendTextChoice(paneId,text){await executeTmux2(`send-keys -t '${paneId}' End`),await sleep(100),await executeTmux2(`send-keys -t '${paneId}' Enter`),await sleep(100),await executeTmux2(`send-keys -t '${paneId}' ${shellEscape(text)}`),await sleep(100),await executeTmux2(`send-keys -t '${paneId}' Enter`)}function findCurrentOption(output){let lines=stripAnsi(output).split(`
|
|
3690
3696
|
`);for(let line of lines){let match=line.match(/^\s*\u276F\s*(\d+)\./);if(match)return Number.parseInt(match[1],10)}return 1}async function navigateToOption(paneId,targetOption,currentOption){let diff=targetOption-currentOption,key=diff>0?"Down":"Up";for(let i2=0;i2<Math.abs(diff);i2++)await executeTmux2(`send-keys -t '${paneId}' ${key}`),await sleep(50);await sleep(100),await executeTmux2(`send-keys -t '${paneId}' Enter`)}async function answerQuestion(target,choice){try{let{paneId,label}=await resolveOrcTarget(target),output=await capturePaneContent(paneId,50),state=detectState(output);if(state.type!=="question"){console.log(`No question pending (state: ${state.type})`);return}if(choice.startsWith("text:")){let text=choice.slice(5);await sendTextChoice(paneId,text),console.log(`Sent feedback: "${text.substring(0,50)}${text.length>50?"...":""}"`)}else if(/^\d+$/.test(choice)){let targetOption=Number.parseInt(choice,10);await navigateToOption(paneId,targetOption,findCurrentOption(output)),console.log(`Selected option ${targetOption} for ${label}`)}else await executeTmux2(`send-keys -t '${paneId}' '${choice}'`),console.log(`Sent '${choice}' to ${label}`)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}}function shellEscape(str2){return`"${str2.replace(/"/g,"\\\"").replace(/\$/g,"\\$")}"`}function sleep(ms){return new Promise((resolve5)=>setTimeout(resolve5,ms))}function registerAgentAnswer(parent){parent.command("answer <name> <choice>").description('Answer a question for an agent (use "text:..." for text input)').action(async(name,choice)=>{try{await answerQuestion(name,choice)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}var _brief;async function getBrief(){if(!_brief)_brief=await Promise.resolve().then(() => (init_brief(),exports_brief));return _brief}async function handleBrief(options){let team=options.team??process.env.GENIE_TEAM;if(!team)console.error("Error: --team is required (or set GENIE_TEAM)"),process.exit(1);let agent=options.agent??process.env.GENIE_AGENT_NAME,briefService=await getBrief(),brief=await briefService.generateBrief({team,agent,since:options.since,repoPath:process.cwd()});console.log(briefService.formatBrief(brief))}function registerAgentBrief(parent){parent.command("brief").description("Show startup brief \u2014 aggregated context since last session").option("--team <name>","Team name (default: GENIE_TEAM)").option("--agent <name>","Agent name (default: GENIE_AGENT_NAME)").option("--since <iso>","Start timestamp (default: last executor end)").action(async(options)=>{try{await handleBrief(options)}catch(error2){console.error(`Error: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}})}init_agent_directory();init_agent_sync();init_builtin_agents();init_genie_config2();async function showEntry(name,json2){let resolved=await resolve4(name);if(!resolved)console.error(`Agent "${name}" not found in directory or built-ins.`),process.exit(1);if(json2){console.log(JSON.stringify({...resolved.entry,builtin:resolved.builtin},null,2));return}if(resolved.builtin)console.log(`
|
|
3691
3697
|
(built-in agent)`);if(console.log(""),console.log(` Name: ${resolved.entry.name}`),console.log(` Dir: ${contractPath(resolved.entry.dir)}`),resolved.entry.repo)console.log(` Repo: ${contractPath(resolved.entry.repo)}`);if(console.log(` Prompt mode: ${resolved.entry.promptMode}`),resolved.entry.model)console.log(` Model: ${resolved.entry.model}`);if(resolved.entry.roles?.length)console.log(` Roles: ${resolved.entry.roles.join(", ")}`);console.log(` Registered: ${resolved.entry.registeredAt}`),console.log("")}function printRegisteredAgentsTable(entries){let termW=process.stdout.columns||120,repoValues=entries.map((e)=>e.repo?contractPath(e.repo):contractPath(e.dir)),maxRepoLen=Math.max(4,...repoValues.map((v)=>v.length)),fixedW=42,repoW=Math.min(maxRepoLen+2,Math.max(30,termW-42-20));console.log(""),console.log("REGISTERED AGENTS"),console.log("-".repeat(Math.max(90,42+repoW+20))),console.log(` ${"NAME".padEnd(22)}${"SCOPE".padEnd(10)}${"REPO".padEnd(repoW)}${"MODEL".padEnd(8)}ROLES`);for(let i2=0;i2<entries.length;i2++){let entry2=entries[i2],repo=repoValues[i2],roles=entry2.roles?.join(", ")||"-";console.log(` ${entry2.name.padEnd(22)}${entry2.scope.padEnd(10)}${repo.padEnd(repoW)}${(entry2.model||"-").padEnd(8)}${roles}`)}console.log("")}function printBuiltinAgentsTable(){console.log("BUILT-IN AGENTS"),console.log("-".repeat(80)),console.log(` ${"NAME".padEnd(22)}${"TYPE".padEnd(10)}${"MODEL".padEnd(8)}DESCRIPTION`);for(let agent of ALL_BUILTINS)console.log(` ${agent.name.padEnd(22)}${agent.category.padEnd(10)}${(agent.model||"-").padEnd(8)}${agent.description}`);console.log("")}async function listEntries(json2,includeBuiltins,_includeArchived){let entries=await ls();if(json2){let result2=entries.map((e)=>({...e,builtin:!1}));if(includeBuiltins)for(let b2 of ALL_BUILTINS)result2.push({name:b2.name,description:b2.description,model:b2.model,category:b2.category,scope:"built-in",builtin:!0});console.log(JSON.stringify(result2,null,2));return}if(entries.length===0&&!includeBuiltins){console.log(`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genie",
|
|
3
|
-
"version": "4.260425.
|
|
3
|
+
"version": "4.260425.3",
|
|
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"
|