@automagik/genie 3.260316.6 → 3.260316.7
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.
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "genie",
|
|
13
|
-
"version": "3.260316.
|
|
13
|
+
"version": "3.260316.7",
|
|
14
14
|
"source": "./plugins/genie",
|
|
15
15
|
"description": "Human-AI partnership for Claude Code. Share a terminal, orchestrate workers, evolve together. Brainstorm ideas, wish them into plans, make with parallel agents, ship as one team. A coding genie that grows with your project."
|
|
16
16
|
}
|
package/dist/genie.js
CHANGED
|
@@ -438,7 +438,7 @@ Next steps:`),console.log(" 1. Reload tmux: tmux source ~/.tmux.conf"),console.
|
|
|
438
438
|
`:"";return bQ(D,B),!0}async function r6(D,F,$){if(!N2(D))return;if(!s0(D,F)){console.log(`\u2713 ${$} has no genie shortcuts`);return}if(await L9(`Remove shortcuts from ${D}? [Y/n] `)==="n"){console.log(`\u23ED\uFE0F Skipped ${$}`);return}if(hQ(D,F))console.log(`\u2705 Removed from ${D}`)}async function Z9(){let D=C9(),F="generated by genie-cli";console.log(`Uninstalling Warp-like shortcuts...
|
|
439
439
|
`),await r6(jD(D,".tmux.conf"),"generated by genie-cli","tmux.conf");for(let B of[jD(D,".zshrc"),jD(D,".bashrc")])await r6(B,"generated by genie-cli",B);let $=jD(D,".termux"),J=N2($)||process.env.TERMUX_VERSION;if(J){let B=jD($,"termux.properties");if(await r6(B,"generated by genie-cli","termux.properties"),!s0(B,"generated by genie-cli"))console.log(" Run: termux-reload-settings")}if(console.log(`
|
|
440
440
|
\u2705 Uninstallation complete!`),console.log(`
|
|
441
|
-
Next steps:`),console.log(" 1. Reload tmux: tmux source ~/.tmux.conf"),console.log(" 2. Restart your shell or run: source ~/.bashrc"),J)console.log(" 3. Reload Termux: termux-reload-settings")}function t0(){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 I2(D,F){if(console.log(),console.log(`\x1B[1m${D}\x1B[0m`),F)console.log(`\x1B[2m${F}\x1B[0m`);console.log()}async function T9(D,F){if(I2("2. Session Configuration","Configure tmux session settings"),F)return console.log(` Using defaults: session="${D.session.name}", window="${D.session.defaultWindow}"`),D;let $=await S2({message:"Session name:",default:D.session.name}),J=await S2({message:"Default window name:",default:D.session.defaultWindow}),B=await dD({message:"Auto-create session on connect?",default:D.session.autoCreate});return D.session={name:$,defaultWindow:J,autoCreate:B},D}async function S9(D,F){if(I2("3. Terminal Defaults","Configure default values for term commands"),F)return console.log(` Using defaults: timeout=${D.terminal.execTimeout}ms, lines=${D.terminal.readLines}`),D;let $=await S2({message:"Exec timeout (milliseconds):",default:String(D.terminal.execTimeout),validate:(X)=>{let Q=Number.parseInt(X,10);return!Number.isNaN(Q)&&Q>0?!0:"Must be a positive number"}}),J=await S2({message:"Read lines (default for genie agent read):",default:String(D.terminal.readLines),validate:(X)=>{let Q=Number.parseInt(X,10);return!Number.isNaN(Q)&&Q>0?!0:"Must be a positive number"}}),B=await S2({message:"Worktree base directory:",default:D.terminal.worktreeBase});return D.terminal={execTimeout:Number.parseInt($,10),readLines:Number.parseInt(J,10),worktreeBase:B},D}async function N9(D,F){I2("4. Keyboard Shortcuts","Warp-like tmux shortcuts for quick navigation");let $=gQ(),J=mQ($,".tmux.conf");if(a0(J))return console.log(" \x1B[32m\u2713\x1B[0m Tmux shortcuts already installed"),D.shortcuts.tmuxInstalled=!0,D;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(),F)return console.log(" Skipped in quick mode. Run \x1B[36mgenie setup --shortcuts\x1B[0m to install."),D;if(await dD({message:"Install tmux keyboard shortcuts?",default:!1}))console.log(),await Q8(),D.shortcuts.tmuxInstalled=!0,await G7({tmuxInstalled:!0});else console.log(" Skipped. Run \x1B[36mgenie shortcuts install\x1B[0m later.");return D}function I9(D){if(D==="changed")console.log(" \x1B[32m\u2713\x1B[0m Codex config updated");else if(D==="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 b9(D,F){I2("5. Codex Integration","Configure OpenAI Codex for genie agents");let $=await R2("codex");if(!$.exists)return console.log(" \x1B[33m!\x1B[0m Codex CLI not found. Skipping codex integration."),D;if(console.log(` \x1B[32m\u2713\x1B[0m Codex CLI found (${$.version??"unknown version"})`),E9())return console.log(" \x1B[32m\u2713\x1B[0m Codex config already configured"),D.codex={configured:!0},D;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${WD(R9())}\x1B[0m`),console.log(),F){let B=o0();return I9(B),D.codex={configured:B!=="error"},D}if(await dD({message:"Configure Codex for genie agent integration?",default:!0})){let B=o0();I9(B),D.codex={configured:B!=="error"}}else console.log(" Skipped. Run \x1B[36mgenie setup --codex\x1B[0m later.");return D}async function lQ(D,F){if(I2("6. Debug Options","Logging and debugging settings"),F)return console.log(" Using defaults: tmuxDebug=false, verbose=false"),D;let $=await dD({message:"Enable tmux debug logging?",default:D.logging.tmuxDebug}),J=await dD({message:"Enable verbose mode?",default:D.logging.verbose});return D.logging={tmuxDebug:$,verbose:J},D}async function pQ(D,F){if(I2("7. Prompt Mode","Controls how genie injects system prompts into Claude Code"),F)return console.log(` Using default: promptMode="${D.promptMode}"`),D;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 $=await d6({message:"Prompt mode:",choices:[{name:"append (recommended \u2014 preserves CC default)",value:"append"},{name:"system (replaces CC default)",value:"system"}],default:D.promptMode});return D.promptMode=$,D}async function dQ(D){I2("Summary",`Configuration will be saved to ${WD(g0())}`),console.log(` Session: \x1B[36m${D.session.name}\x1B[0m (window: ${D.session.defaultWindow})`),console.log(` Terminal: timeout=${D.terminal.execTimeout}ms, lines=${D.terminal.readLines}`),console.log(` Shortcuts: ${D.shortcuts.tmuxInstalled?"\x1B[32minstalled\x1B[0m":"\x1B[2mnot installed\x1B[0m"}`),console.log(` Codex: ${D.codex?.configured?"\x1B[32mconfigured\x1B[0m":"\x1B[2mnot configured\x1B[0m"}`),console.log(` Debug: tmux=${D.logging.tmuxDebug}, verbose=${D.logging.verbose}`),console.log(` Prompt mode: \x1B[36m${D.promptMode}\x1B[0m`),console.log(),D.setupComplete=!0,D.lastSetupAt=new Date().toISOString(),await bD(D),console.log("\x1B[32m\u2713 Configuration saved!\x1B[0m")}async function cQ(){let D=await VD();console.log(),console.log("\x1B[1mCurrent Genie Configuration\x1B[0m"),console.log(`\x1B[2m${WD(g0())}\x1B[0m`),console.log(),console.log(JSON.stringify(D,null,2)),console.log()}function iQ(){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 P9(D={}){if(D.show){await cQ();return}if(D.reset){await q7(),console.log("\x1B[32m\u2713 Configuration reset to defaults.\x1B[0m"),console.log();return}let F=await VD();if(D.shortcuts){t0(),await N9(F,!1),await Y7();return}if(D.terminal){t0(),F=await S9(F,!1),await bD(F),console.log("\x1B[32m\u2713 Terminal configuration saved.\x1B[0m");return}if(D.session){t0(),F=await T9(F,!1),await bD(F),console.log("\x1B[32m\u2713 Session configuration saved.\x1B[0m");return}if(D.codex){if(t0(),F=await b9(F,!1),await bD(F),F.codex?.configured)console.log("\x1B[32m\u2713 Codex configuration saved.\x1B[0m");return}let $=D.quick??!1;if(t0(),$)console.log("\x1B[2mQuick mode: accepting all defaults\x1B[0m");F=await T9(F,$),F=await S9(F,$),F=await N9(F,$),F=await b9(F,$),F=await lQ(F,$),F=await pQ(F,$),await dQ(F),iQ()}import{existsSync as rQ}from"fs";import{homedir as nQ}from"os";import{join as n6}from"path";async function o6(){_9();let D=nQ(),F=n6(D,".tmux.conf"),$=n6(D,".zshrc"),J=n6(D,".bashrc");if(console.log("Installation status:"),a0(F))console.log(" \x1B[32m\u2713\x1B[0m tmux.conf");else console.log(" \x1B[33m-\x1B[0m tmux.conf");let B=rQ($)?$:J;if(a0(B))console.log(` \x1B[32m\u2713\x1B[0m ${B.replace(D,"~")}`);else console.log(` \x1B[33m-\x1B[0m ${B.replace(D,"~")}`);console.log(),console.log("Run \x1B[36mgenie shortcuts install\x1B[0m to install shortcuts."),console.log("Run \x1B[36mgenie shortcuts uninstall\x1B[0m to remove shortcuts."),console.log()}async function v9(){await Q8()}async function k9(){await Z9()}import{existsSync as Y8,lstatSync as oQ,rmSync as sQ,unlinkSync as w9}from"fs";import{homedir as f9}from"os";import{join as q8}from"path";mD();var s6=q8(f9(),".claude","rules","genie-orchestration.md"),u9=q8(f9(),".local","bin"),x9=["genie","term"];function y9(D){try{if(!Y8(D))return!1;if(!oQ(D).isSymbolicLink())return!1;return!0}catch{return!1}}function aQ(){let D=[];for(let F of x9){let $=q8(u9,F);if(y9($))try{w9($),D.push(F)}catch{}}return D}function tQ(D,F,$,J){if(D){console.log("\x1B[2mRemoving hook script...\x1B[0m");try{h5(),console.log(" \x1B[32m+\x1B[0m Hook script removed")}catch(B){let X=B instanceof Error?B.message:String(B);console.log(` \x1B[33m!\x1B[0m Could not remove hook script: ${X}`)}}if(F.length>0){console.log("\x1B[2mRemoving symlinks...\x1B[0m");let B=aQ();if(B.length>0)console.log(` \x1B[32m+\x1B[0m Removed: ${B.join(", ")}`)}if(Y8(s6)){console.log("\x1B[2mRemoving orchestration rules...\x1B[0m");try{w9(s6),console.log(" \x1B[32m+\x1B[0m Orchestration rules removed (~/.claude/rules/genie-orchestration.md)")}catch(B){let X=B instanceof Error?B.message:String(B);console.log(` \x1B[33m!\x1B[0m Could not remove orchestration rules: ${X}`)}}if(J){console.log("\x1B[2mRemoving genie directory...\x1B[0m");try{sQ($,{recursive:!0,force:!0}),console.log(" \x1B[32m+\x1B[0m Directory removed")}catch(B){let X=B instanceof Error?B.message:String(B);console.log(` \x1B[33m!\x1B[0m Could not remove directory: ${X}`)}}}async function h9(){console.log(),console.log("\x1B[1m\x1B[33m Uninstall Genie CLI\x1B[0m"),console.log();let D=B7(),F=Y8(D),$=y5(),J=Y8(s6),B=x9.filter((Q)=>y9(q8(u9,Q)));if(console.log("\x1B[2mThis will remove:\x1B[0m"),$)console.log(" \x1B[31m-\x1B[0m Hook script (~/.claude/hooks/genie-bash-hook.sh)");if(J)console.log(" \x1B[31m-\x1B[0m Orchestration rules (~/.claude/rules/genie-orchestration.md)");if(F)console.log(` \x1B[31m-\x1B[0m Genie directory (${WD(D)})`);if(B.length>0)console.log(` \x1B[31m-\x1B[0m Symlinks from ~/.local/bin: ${B.join(", ")}`);if(console.log(),!F&&!$&&!J&&B.length===0){console.log("\x1B[33mNothing to uninstall.\x1B[0m"),console.log();return}if(!await dD({message:"Are you sure you want to uninstall Genie CLI?",default:!1})){console.log(),console.log("\x1B[2mUninstall cancelled.\x1B[0m"),console.log();return}console.log(),tQ($,B,D,F),console.log(),console.log("\x1B[32m+\x1B[0m Genie CLI uninstalled."),console.log(),console.log("\x1B[2mNote: If you installed via npm/bun, also run:\x1B[0m"),console.log(" \x1B[36mbun remove -g @automagik/genie\x1B[0m"),console.log(" \x1B[2mor\x1B[0m"),console.log(" \x1B[36mnpm uninstall -g @automagik/genie\x1B[0m"),console.log()}mD();import{spawn as c9}from"child_process";import{copyFileSync as eQ,existsSync as cD,mkdirSync as DY,readFileSync as g9,readdirSync as FY,rmSync as $Y,writeFileSync as JY}from"fs";import{chmod as BY,copyFile as i9,mkdir as m9,unlink as l9}from"fs/promises";import{homedir as e0}from"os";import{join as m}from"path";var r9=process.env.GENIE_HOME||m(e0(),".genie"),J2=m(r9,"src"),G8=m(r9,"bin"),H8=m(e0(),".local","bin");function XD(D){console.log(`\x1B[32m\u25B8\x1B[0m ${D}`)}function M0(D){console.log(`\x1B[32m\u2714\x1B[0m ${D}`)}function vD(D){console.log(`\x1B[31m\u2716\x1B[0m ${D}`)}async function K0(D,F,$){return new Promise((J)=>{let B=[],X=c9(D,F,{cwd:$,stdio:["inherit","pipe","pipe"],env:{...process.env,FORCE_COLOR:"1"}});X.stdout?.on("data",(Q)=>{let Y=Q.toString();B.push(Y),process.stdout.write(Y)}),X.stderr?.on("data",(Q)=>{let Y=Q.toString();B.push(Y),process.stderr.write(Y)}),X.on("close",(Q)=>{J({success:Q===0,output:B.join("")})}),X.on("error",(Q)=>{vD(Q.message),J({success:!1,output:Q.message})})})}async function p9(D){try{let F=await b2("git",["rev-parse","--abbrev-ref","HEAD"],D),$=await b2("git",["rev-parse","--short","HEAD"],D),J=await b2("git",["log","-1","--format=%ci"],D);if(F.success&&$.success&&J.success)return{branch:F.output.trim(),commit:$.output.trim(),commitDate:J.output.trim().split(" ")[0]}}catch{}return null}async function b2(D,F,$){return new Promise((J)=>{let B=[],X=c9(D,F,{cwd:$,stdio:["inherit","pipe","pipe"]});X.stdout?.on("data",(Q)=>{B.push(Q.toString())}),X.stderr?.on("data",(Q)=>{B.push(Q.toString())}),X.on("close",(Q)=>{J({success:Q===0,output:B.join("")})}),X.on("error",(Q)=>{J({success:!1,output:Q.message})})})}function XY(D){if(D.includes(".bun"))return"bun";if(D.includes("node_modules"))return"npm";if(D===m(H8,"genie")||D.startsWith(G8))return"source";return null}async function QY(){if(E2())try{let J=await VD();if(J.installMethod)return J.installMethod}catch{}if(cD(m(J2,".git")))return"source";let D=await b2("which",["genie"]);if(!D.success)return"unknown";let F=XY(D.output.trim());if(F)return F;return(await b2("which",["bun"])).success?"bun":"npm"}async function YY(D){if(XD(`Updating via bun (channel: ${D})...`),!(await K0("bun",["install","-g",`@automagik/genie@${D}`])).success)vD("Failed to update via bun"),process.exit(1);console.log(),M0(`Genie CLI updated (${D})!`)}async function qY(D){if(XD(`Updating via npm (channel: ${D})...`),!(await K0("npm",["install","-g",`@automagik/genie@${D}`])).success)vD("Failed to update via npm"),process.exit(1);console.log(),M0(`Genie CLI updated (${D})!`)}async function GY(){let D=await p9(J2);if(D)console.log(`Current: \x1B[2m${D.branch}@${D.commit} (${D.commitDate})\x1B[0m`),console.log();if(XD("Fetching latest changes..."),!(await K0("git",["fetch","origin"],J2)).success)vD("Failed to fetch from origin"),process.exit(1);if(XD("Resetting to origin/main..."),!(await K0("git",["reset","--hard","origin/main"],J2)).success)vD("Failed to reset to origin/main"),process.exit(1);console.log();let J=await p9(J2);if(D&&J&&D.commit===J.commit){M0("Already up to date!"),console.log();return}if(XD("Installing dependencies..."),!(await K0("bun",["install"],J2)).success)vD("Failed to install dependencies"),process.exit(1);if(console.log(),XD("Building..."),!(await K0("bun",["run","build"],J2)).success)vD("Failed to build"),process.exit(1);console.log(),XD("Installing binaries...");try{await m9(G8,{recursive:!0}),await m9(H8,{recursive:!0});let Q=["genie.js","term.js"],Y=["genie","term"];for(let q=0;q<Q.length;q++){let G=m(J2,"dist",Q[q]),H=m(G8,Q[q]),V=m(H8,Y[q]);await i9(G,H),await BY(H,493),await HY(H,V)}for(let q of["claudio.js","claudio"]){let G=m(G8,q),H=m(H8,q);try{await l9(G)}catch{}try{await l9(H)}catch{}}M0("Binaries installed")}catch(Q){vD(`Failed to install binaries: ${Q}`),process.exit(1)}if(console.log(),console.log("\x1B[2m\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\x1B[0m"),M0("Genie CLI updated successfully!"),console.log(),J)console.log(`Version: \x1B[36m${J.branch}@${J.commit}\x1B[0m (${J.commitDate})`),console.log()}async function HY(D,F){let{symlink:$,unlink:J}=await import("fs/promises");try{if(cD(F))await J(F);await $(D,F)}catch{await i9(D,F)}}function n9(D,F){DY(F,{recursive:!0});for(let $ of FY(D,{withFileTypes:!0})){let J=m(D,$.name),B=m(F,$.name);if($.isDirectory())n9(J,B);else eQ(J,B)}}async function VY(D){if(D==="bun"){let J=m(e0(),".bun","install","global","node_modules","@automagik","genie");if(cD(J))return J}if(D==="npm"){let J=await b2("npm",["root","-g"]);if(J.success){let B=m(J.output.trim(),"@automagik","genie");if(cD(B))return B}}let F=m(e0(),".bun","install","global","node_modules","@automagik","genie");if(cD(F))return F;let $=await b2("npm",["root","-g"]);if($.success){let J=m($.output.trim(),"@automagik","genie");if(cD(J))return J}return null}async function d9(D){XD("Syncing Claude Code plugin...");let F=await VY(D);if(!F){XD("Could not find installed package \u2014 skipping plugin sync");return}let $=m(F,"plugins","genie");if(!cD($)){XD("Plugin source not found in package \u2014 skipping plugin sync");return}let J;try{J=JSON.parse(g9(m(F,"package.json"),"utf-8")).version}catch{XD("Could not read package version \u2014 skipping plugin sync");return}let B=m(e0(),".claude","plugins"),X=m(B,"cache","automagik","genie",J);try{if(cD(X))$Y(X,{recursive:!0,force:!0});n9($,X)}catch(Y){vD(`Failed to copy plugin: ${Y}`);return}let Q=m(B,"installed_plugins.json");try{if(cD(Q)){let Y=JSON.parse(g9(Q,"utf-8")),q=Y.plugins?.["genie@automagik"];if(Array.isArray(q)){for(let G of q)if(G.scope==="user")G.installPath=X,G.version=J,G.lastUpdated=new Date().toISOString();JY(Q,JSON.stringify(Y,null,2))}}}catch(Y){XD(`Registry update failed (non-fatal): ${Y}`)}M0(`Plugin synced to v${J}`)}async function WY(D){if(D.next)return"next";if(D.stable)return"latest";if(E2())try{let F=await VD();if(F.updateChannel)return F.updateChannel}catch{}return"latest"}async function UY(D){try{let F=await VD();F.updateChannel=D,await bD(F)}catch{}}async function o9(D={}){console.log(),console.log("\x1B[1m\uD83E\uDDDE Genie CLI Update\x1B[0m"),console.log("\x1B[2m\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\x1B[0m"),console.log();let F=await WY(D);if(D.next||D.stable)await UY(F);let $=await QY();if(XD(`Detected installation: ${$}`),XD(`Channel: ${F}${F==="next"?" (dev builds)":" (stable)"}`),console.log(),$==="unknown")vD("No Genie CLI installation found"),console.log(),console.log("Install method not configured. Please reinstall genie:"),console.log("\x1B[36m curl -fsSL https://raw.githubusercontent.com/automagik-dev/genie/main/install.sh | bash\x1B[0m"),console.log(),process.exit(1);switch($){case"source":await GY();break;case"bun":await YY(F),await d9($);break;case"npm":await qY(F),await d9($);break}}import{existsSync as zY,readFileSync as KY}from"fs";import{dirname as a6,resolve as t6}from"path";var __dirname="/home/runner/_work/genie/genie/src/lib",MY="0.0.0-unknown";function EY(){let D=[t6(a6(import.meta.dir??__dirname),"..","..","package.json"),t6(a6(import.meta.dir??__dirname),"..","package.json"),t6(a6(import.meta.dir??__dirname),"package.json")];for(let F of D)try{if(zY(F)){let $=JSON.parse(KY(F,"utf-8"));if($.version)return $.version}}catch{}return MY}var s9=EY();async function GF(D){let F=D.tool_input;if(!F)return;if(F.type!=="message")return;let $=F.recipient;if(!$)return;if($==="team-lead")return;let J=process.env.GENIE_TEAM??D.team_name;if(!J)return;try{let B=await Promise.resolve().then(() => (KD(),zD)),X=await Promise.resolve().then(() => (FD(),ZD)),Q=await Promise.resolve().then(() => (A3(),R3)),q=(await B.list()).find((M)=>(M.role===$||M.id===$)&&M.team===J);if(q&&await X.isPaneAlive(q.paneId))return;let G=await Q.resolve($),H=await B.listTemplates(),V=new Set([$]);if(G){if(V.add(G.entry.name),G.entry.roles)for(let M of G.entry.roles)V.add(M)}let W=H.find((M)=>{if(M.team!==J)return!1;return[...V].some((C)=>M.id===C||M.role===C)});if(!W){if(G)console.error(`[genie-hook] Agent "${$}" is registered in directory but has no spawn template in team "${J}".`);return}let{spawnSync:U}=w("child_process"),K=["spawn","--provider",W.provider,"--team",W.team];if(W.role)K.push("--role",W.role);if(W.skill)K.push("--skill",W.skill);if(W.cwd)K.push("--cwd",W.cwd);if(W.lastSessionId)K.push("--resume",W.lastSessionId);if(W.extraArgs)K.push(...W.extraArgs);U("genie",K,{timeout:1e4,stdio:"ignore",env:{...process.env,GENIE_TEAM:J}}),console.error(`[genie-hook] Auto-spawned "${$}" in team "${J}"`)}catch(B){let X=B instanceof Error?B.message:String(B);console.error(`[genie-hook] Auto-spawn failed for "${$}": ${X}`)}return}async function HF(D){let F=D.tool_input;if(!F)return;let $=F.type;if($!=="message"&&$!=="broadcast")return;let J=process.env.GENIE_AGENT_NAME;if(!J)return;let B=F.content;if(!B)return;if(B.startsWith(`[from:${J}]`))return;return{updatedInput:{...F,content:`[from:${J}] ${B}`}}}u1();var cH=[{name:"identity-inject",event:"PreToolUse",matcher:/^SendMessage$/,priority:10,fn:HF},{name:"auto-spawn",event:"PreToolUse",matcher:/^SendMessage$/,priority:20,fn:GF}];function iH(D,F){return cH.filter(($)=>{if($.event!==D)return!1;if($.matcher&&F&&!$.matcher.test(F))return!1;if($.matcher&&!F)return!1;return!0}).sort(($,J)=>$.priority-J.priority)}async function rH(D,F){let $=F.tool_input?{...F.tool_input}:void 0;for(let J of D)try{let B={...F};if($)B.tool_input=$;let X=await J.fn(B);if(!X)continue;if(X.decision==="deny")return{decision:"deny",reason:X.reason??`Denied by handler: ${J.name}`};if(X.updatedInput)$={...$,...X.updatedInput}}catch(B){let X=B instanceof Error?B.message:String(B);console.error(`[genie-hook] Handler "${J.name}" threw: ${X}`)}if($&&F.tool_input&&JSON.stringify($)!==JSON.stringify(F.tool_input))return{updatedInput:$};return{}}async function nH(D,F){await Promise.allSettled(D.map(($)=>$.fn(F).catch((J)=>{let B=J instanceof Error?J.message:String(J);console.error(`[genie-hook] Handler "${$.name}" threw: ${B}`)})))}async function WF(D){let F;try{F=JSON.parse(D)}catch{return console.error("[genie-hook] Invalid JSON on stdin"),""}let $=F.hook_event_name;if(!$)return console.error("[genie-hook] Missing hook_event_name in payload"),"";let J=F.tool_name,B=iH($,J);if(B.length===0)return"";if(VF($)){let X=await rH(B,F);if(X.decision||X.updatedInput)return JSON.stringify(X);return""}return await nH(B,F),""}async function oH(){let D=[];for await(let F of Bun.stdin.stream())D.push(Buffer.from(F));return Buffer.concat(D).toString("utf-8")}async function sH(){let D=await oH();if(!D.trim())process.exit(0);let F=await WF(D);if(F)process.stdout.write(F)}function UF(D){D.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(sH)}g8();A3();U3();mD();import{resolve as m8}from"path";function wF(D){let F=D.command("dir").description("Agent directory management");F.command("add <name>").description("Register an agent in the directory").requiredOption("--dir <path>","Agent folder (CWD + AGENTS.md)").option("--repo <path>","Default git repo (overridden by team)").option("--prompt-mode <mode>","Prompt mode: append or system","append").option("--model <model>","Default model (sonnet, opus, codex)").option("--roles <roles...>","Built-in roles this agent can orchestrate").action(async($,J)=>{try{let B=fF(J.promptMode),X=await v1({name:$,dir:m8(J.dir),repo:J.repo?m8(J.repo):void 0,promptMode:B,model:J.model,roles:J.roles});if(console.log(`Agent "${X.name}" registered.`),console.log(` Dir: ${WD(X.dir)}`),X.repo)console.log(` Repo: ${WD(X.repo)}`);if(console.log(` Prompt mode: ${X.promptMode}`),X.model)console.log(` Model: ${X.model}`);if(X.roles?.length)console.log(` Roles: ${X.roles.join(", ")}`)}catch(B){let X=B instanceof Error?B.message:String(B);console.error(`Error: ${X}`),process.exit(1)}}),F.command("rm <name>").description("Remove an agent from the directory").action(async($)=>{try{if(await k1($))console.log(`Agent "${$}" removed from directory.`);else console.error(`Agent "${$}" not found in directory.`),process.exit(1)}catch(J){let B=J instanceof Error?J.message:String(J);console.error(`Error: ${B}`),process.exit(1)}}),F.command("ls [name]").description("List all agents or show single entry details").option("--json","Output as JSON").option("--builtins","Include built-in roles and council members").action(async($,J)=>{try{if($)await kV($,J.json);else await wV(J.json,J.builtins)}catch(B){let X=B instanceof Error?B.message:String(B);console.error(`Error: ${X}`),process.exit(1)}}),F.command("edit <name>").description("Update an agent directory entry").option("--dir <path>","Agent folder (CWD + AGENTS.md)").option("--repo <path>","Default git repo").option("--prompt-mode <mode>","Prompt mode: append or system").option("--model <model>","Default model").option("--roles <roles...>","Built-in roles this agent can orchestrate").action(async($,J)=>{try{await vV($,J)}catch(B){let X=B instanceof Error?B.message:String(B);console.error(`Error: ${X}`),process.exit(1)}})}async function vV(D,F){let $={};if(F.dir)$.dir=m8(F.dir);if(F.repo)$.repo=m8(F.repo);if(F.promptMode)$.promptMode=fF(F.promptMode);if(F.model)$.model=F.model;if(F.roles)$.roles=F.roles;if(Object.keys($).length===0)console.error("No fields to update. Provide at least one of: --dir, --repo, --prompt-mode, --model, --roles"),process.exit(1);let J=await w1(D,$);console.log(`Agent "${D}" updated.`),uF(J)}function fF(D){if(D!=="system"&&D!=="append")throw Error(`Invalid prompt mode "${D}". Must be "append" or "system".`);return D}function uF(D){if(console.log(` Name: ${D.name}`),console.log(` Dir: ${WD(D.dir)}`),D.repo)console.log(` Repo: ${WD(D.repo)}`);if(console.log(` Prompt mode: ${D.promptMode}`),D.model)console.log(` Model: ${D.model}`);if(D.roles?.length)console.log(` Roles: ${D.roles.join(", ")}`);console.log(` Registered: ${D.registeredAt}`)}async function kV(D,F){let $=await M3(D);if(!$)console.error(`Agent "${D}" not found in directory or built-ins.`),process.exit(1);if(F){console.log(JSON.stringify({...$.entry,builtin:$.builtin},null,2));return}if($.builtin)console.log(`
|
|
441
|
+
Next steps:`),console.log(" 1. Reload tmux: tmux source ~/.tmux.conf"),console.log(" 2. Restart your shell or run: source ~/.bashrc"),J)console.log(" 3. Reload Termux: termux-reload-settings")}function t0(){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 I2(D,F){if(console.log(),console.log(`\x1B[1m${D}\x1B[0m`),F)console.log(`\x1B[2m${F}\x1B[0m`);console.log()}async function T9(D,F){if(I2("2. Session Configuration","Configure tmux session settings"),F)return console.log(` Using defaults: session="${D.session.name}", window="${D.session.defaultWindow}"`),D;let $=await S2({message:"Session name:",default:D.session.name}),J=await S2({message:"Default window name:",default:D.session.defaultWindow}),B=await dD({message:"Auto-create session on connect?",default:D.session.autoCreate});return D.session={name:$,defaultWindow:J,autoCreate:B},D}async function S9(D,F){if(I2("3. Terminal Defaults","Configure default values for term commands"),F)return console.log(` Using defaults: timeout=${D.terminal.execTimeout}ms, lines=${D.terminal.readLines}`),D;let $=await S2({message:"Exec timeout (milliseconds):",default:String(D.terminal.execTimeout),validate:(X)=>{let Q=Number.parseInt(X,10);return!Number.isNaN(Q)&&Q>0?!0:"Must be a positive number"}}),J=await S2({message:"Read lines (default for genie agent read):",default:String(D.terminal.readLines),validate:(X)=>{let Q=Number.parseInt(X,10);return!Number.isNaN(Q)&&Q>0?!0:"Must be a positive number"}}),B=await S2({message:"Worktree base directory:",default:D.terminal.worktreeBase});return D.terminal={execTimeout:Number.parseInt($,10),readLines:Number.parseInt(J,10),worktreeBase:B},D}async function N9(D,F){I2("4. Keyboard Shortcuts","Warp-like tmux shortcuts for quick navigation");let $=gQ(),J=mQ($,".tmux.conf");if(a0(J))return console.log(" \x1B[32m\u2713\x1B[0m Tmux shortcuts already installed"),D.shortcuts.tmuxInstalled=!0,D;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(),F)return console.log(" Skipped in quick mode. Run \x1B[36mgenie setup --shortcuts\x1B[0m to install."),D;if(await dD({message:"Install tmux keyboard shortcuts?",default:!1}))console.log(),await Q8(),D.shortcuts.tmuxInstalled=!0,await G7({tmuxInstalled:!0});else console.log(" Skipped. Run \x1B[36mgenie shortcuts install\x1B[0m later.");return D}function I9(D){if(D==="changed")console.log(" \x1B[32m\u2713\x1B[0m Codex config updated");else if(D==="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 b9(D,F){I2("5. Codex Integration","Configure OpenAI Codex for genie agents");let $=await R2("codex");if(!$.exists)return console.log(" \x1B[33m!\x1B[0m Codex CLI not found. Skipping codex integration."),D;if(console.log(` \x1B[32m\u2713\x1B[0m Codex CLI found (${$.version??"unknown version"})`),E9())return console.log(" \x1B[32m\u2713\x1B[0m Codex config already configured"),D.codex={configured:!0},D;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${WD(R9())}\x1B[0m`),console.log(),F){let B=o0();return I9(B),D.codex={configured:B!=="error"},D}if(await dD({message:"Configure Codex for genie agent integration?",default:!0})){let B=o0();I9(B),D.codex={configured:B!=="error"}}else console.log(" Skipped. Run \x1B[36mgenie setup --codex\x1B[0m later.");return D}async function lQ(D,F){if(I2("6. Debug Options","Logging and debugging settings"),F)return console.log(" Using defaults: tmuxDebug=false, verbose=false"),D;let $=await dD({message:"Enable tmux debug logging?",default:D.logging.tmuxDebug}),J=await dD({message:"Enable verbose mode?",default:D.logging.verbose});return D.logging={tmuxDebug:$,verbose:J},D}async function pQ(D,F){if(I2("7. Prompt Mode","Controls how genie injects system prompts into Claude Code"),F)return console.log(` Using default: promptMode="${D.promptMode}"`),D;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 $=await d6({message:"Prompt mode:",choices:[{name:"append (recommended \u2014 preserves CC default)",value:"append"},{name:"system (replaces CC default)",value:"system"}],default:D.promptMode});return D.promptMode=$,D}async function dQ(D){I2("Summary",`Configuration will be saved to ${WD(g0())}`),console.log(` Session: \x1B[36m${D.session.name}\x1B[0m (window: ${D.session.defaultWindow})`),console.log(` Terminal: timeout=${D.terminal.execTimeout}ms, lines=${D.terminal.readLines}`),console.log(` Shortcuts: ${D.shortcuts.tmuxInstalled?"\x1B[32minstalled\x1B[0m":"\x1B[2mnot installed\x1B[0m"}`),console.log(` Codex: ${D.codex?.configured?"\x1B[32mconfigured\x1B[0m":"\x1B[2mnot configured\x1B[0m"}`),console.log(` Debug: tmux=${D.logging.tmuxDebug}, verbose=${D.logging.verbose}`),console.log(` Prompt mode: \x1B[36m${D.promptMode}\x1B[0m`),console.log(),D.setupComplete=!0,D.lastSetupAt=new Date().toISOString(),await bD(D),console.log("\x1B[32m\u2713 Configuration saved!\x1B[0m")}async function cQ(){let D=await VD();console.log(),console.log("\x1B[1mCurrent Genie Configuration\x1B[0m"),console.log(`\x1B[2m${WD(g0())}\x1B[0m`),console.log(),console.log(JSON.stringify(D,null,2)),console.log()}function iQ(){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 P9(D={}){if(D.show){await cQ();return}if(D.reset){await q7(),console.log("\x1B[32m\u2713 Configuration reset to defaults.\x1B[0m"),console.log();return}let F=await VD();if(D.shortcuts){t0(),await N9(F,!1),await Y7();return}if(D.terminal){t0(),F=await S9(F,!1),await bD(F),console.log("\x1B[32m\u2713 Terminal configuration saved.\x1B[0m");return}if(D.session){t0(),F=await T9(F,!1),await bD(F),console.log("\x1B[32m\u2713 Session configuration saved.\x1B[0m");return}if(D.codex){if(t0(),F=await b9(F,!1),await bD(F),F.codex?.configured)console.log("\x1B[32m\u2713 Codex configuration saved.\x1B[0m");return}let $=D.quick??!1;if(t0(),$)console.log("\x1B[2mQuick mode: accepting all defaults\x1B[0m");F=await T9(F,$),F=await S9(F,$),F=await N9(F,$),F=await b9(F,$),F=await lQ(F,$),F=await pQ(F,$),await dQ(F),iQ()}import{existsSync as rQ}from"fs";import{homedir as nQ}from"os";import{join as n6}from"path";async function o6(){_9();let D=nQ(),F=n6(D,".tmux.conf"),$=n6(D,".zshrc"),J=n6(D,".bashrc");if(console.log("Installation status:"),a0(F))console.log(" \x1B[32m\u2713\x1B[0m tmux.conf");else console.log(" \x1B[33m-\x1B[0m tmux.conf");let B=rQ($)?$:J;if(a0(B))console.log(` \x1B[32m\u2713\x1B[0m ${B.replace(D,"~")}`);else console.log(` \x1B[33m-\x1B[0m ${B.replace(D,"~")}`);console.log(),console.log("Run \x1B[36mgenie shortcuts install\x1B[0m to install shortcuts."),console.log("Run \x1B[36mgenie shortcuts uninstall\x1B[0m to remove shortcuts."),console.log()}async function v9(){await Q8()}async function k9(){await Z9()}import{existsSync as Y8,lstatSync as oQ,rmSync as sQ,unlinkSync as w9}from"fs";import{homedir as f9}from"os";import{join as q8}from"path";mD();var s6=q8(f9(),".claude","rules","genie-orchestration.md"),u9=q8(f9(),".local","bin"),x9=["genie","term"];function y9(D){try{if(!Y8(D))return!1;if(!oQ(D).isSymbolicLink())return!1;return!0}catch{return!1}}function aQ(){let D=[];for(let F of x9){let $=q8(u9,F);if(y9($))try{w9($),D.push(F)}catch{}}return D}function tQ(D,F,$,J){if(D){console.log("\x1B[2mRemoving hook script...\x1B[0m");try{h5(),console.log(" \x1B[32m+\x1B[0m Hook script removed")}catch(B){let X=B instanceof Error?B.message:String(B);console.log(` \x1B[33m!\x1B[0m Could not remove hook script: ${X}`)}}if(F.length>0){console.log("\x1B[2mRemoving symlinks...\x1B[0m");let B=aQ();if(B.length>0)console.log(` \x1B[32m+\x1B[0m Removed: ${B.join(", ")}`)}if(Y8(s6)){console.log("\x1B[2mRemoving orchestration rules...\x1B[0m");try{w9(s6),console.log(" \x1B[32m+\x1B[0m Orchestration rules removed (~/.claude/rules/genie-orchestration.md)")}catch(B){let X=B instanceof Error?B.message:String(B);console.log(` \x1B[33m!\x1B[0m Could not remove orchestration rules: ${X}`)}}if(J){console.log("\x1B[2mRemoving genie directory...\x1B[0m");try{sQ($,{recursive:!0,force:!0}),console.log(" \x1B[32m+\x1B[0m Directory removed")}catch(B){let X=B instanceof Error?B.message:String(B);console.log(` \x1B[33m!\x1B[0m Could not remove directory: ${X}`)}}}async function h9(){console.log(),console.log("\x1B[1m\x1B[33m Uninstall Genie CLI\x1B[0m"),console.log();let D=B7(),F=Y8(D),$=y5(),J=Y8(s6),B=x9.filter((Q)=>y9(q8(u9,Q)));if(console.log("\x1B[2mThis will remove:\x1B[0m"),$)console.log(" \x1B[31m-\x1B[0m Hook script (~/.claude/hooks/genie-bash-hook.sh)");if(J)console.log(" \x1B[31m-\x1B[0m Orchestration rules (~/.claude/rules/genie-orchestration.md)");if(F)console.log(` \x1B[31m-\x1B[0m Genie directory (${WD(D)})`);if(B.length>0)console.log(` \x1B[31m-\x1B[0m Symlinks from ~/.local/bin: ${B.join(", ")}`);if(console.log(),!F&&!$&&!J&&B.length===0){console.log("\x1B[33mNothing to uninstall.\x1B[0m"),console.log();return}if(!await dD({message:"Are you sure you want to uninstall Genie CLI?",default:!1})){console.log(),console.log("\x1B[2mUninstall cancelled.\x1B[0m"),console.log();return}console.log(),tQ($,B,D,F),console.log(),console.log("\x1B[32m+\x1B[0m Genie CLI uninstalled."),console.log(),console.log("\x1B[2mNote: If you installed via npm/bun, also run:\x1B[0m"),console.log(" \x1B[36mbun remove -g @automagik/genie\x1B[0m"),console.log(" \x1B[2mor\x1B[0m"),console.log(" \x1B[36mnpm uninstall -g @automagik/genie\x1B[0m"),console.log()}mD();import{spawn as c9}from"child_process";import{copyFileSync as eQ,existsSync as cD,mkdirSync as DY,readFileSync as g9,readdirSync as FY,rmSync as $Y,writeFileSync as JY}from"fs";import{chmod as BY,copyFile as i9,mkdir as m9,unlink as l9}from"fs/promises";import{homedir as e0}from"os";import{join as m}from"path";var r9=process.env.GENIE_HOME||m(e0(),".genie"),J2=m(r9,"src"),G8=m(r9,"bin"),H8=m(e0(),".local","bin");function XD(D){console.log(`\x1B[32m\u25B8\x1B[0m ${D}`)}function M0(D){console.log(`\x1B[32m\u2714\x1B[0m ${D}`)}function vD(D){console.log(`\x1B[31m\u2716\x1B[0m ${D}`)}async function K0(D,F,$){return new Promise((J)=>{let B=[],X=c9(D,F,{cwd:$,stdio:["inherit","pipe","pipe"],env:{...process.env,FORCE_COLOR:"1"}});X.stdout?.on("data",(Q)=>{let Y=Q.toString();B.push(Y),process.stdout.write(Y)}),X.stderr?.on("data",(Q)=>{let Y=Q.toString();B.push(Y),process.stderr.write(Y)}),X.on("close",(Q)=>{J({success:Q===0,output:B.join("")})}),X.on("error",(Q)=>{vD(Q.message),J({success:!1,output:Q.message})})})}async function p9(D){try{let F=await b2("git",["rev-parse","--abbrev-ref","HEAD"],D),$=await b2("git",["rev-parse","--short","HEAD"],D),J=await b2("git",["log","-1","--format=%ci"],D);if(F.success&&$.success&&J.success)return{branch:F.output.trim(),commit:$.output.trim(),commitDate:J.output.trim().split(" ")[0]}}catch{}return null}async function b2(D,F,$){return new Promise((J)=>{let B=[],X=c9(D,F,{cwd:$,stdio:["inherit","pipe","pipe"]});X.stdout?.on("data",(Q)=>{B.push(Q.toString())}),X.stderr?.on("data",(Q)=>{B.push(Q.toString())}),X.on("close",(Q)=>{J({success:Q===0,output:B.join("")})}),X.on("error",(Q)=>{J({success:!1,output:Q.message})})})}function XY(D){if(D.includes(".bun"))return"bun";if(D.includes("node_modules"))return"npm";if(D===m(H8,"genie")||D.startsWith(G8))return"source";return null}async function QY(){if(E2())try{let J=await VD();if(J.installMethod)return J.installMethod}catch{}if(cD(m(J2,".git")))return"source";let D=await b2("which",["genie"]);if(!D.success)return"unknown";let F=XY(D.output.trim());if(F)return F;return(await b2("which",["bun"])).success?"bun":"npm"}async function YY(D){if(XD(`Updating via bun (channel: ${D})...`),!(await K0("bun",["update","-g",`@automagik/genie@${D}`])).success)vD("Failed to update via bun"),process.exit(1);console.log(),M0(`Genie CLI updated (${D})!`)}async function qY(D){if(XD(`Updating via npm (channel: ${D})...`),!(await K0("npm",["install","-g",`@automagik/genie@${D}`])).success)vD("Failed to update via npm"),process.exit(1);console.log(),M0(`Genie CLI updated (${D})!`)}async function GY(){let D=await p9(J2);if(D)console.log(`Current: \x1B[2m${D.branch}@${D.commit} (${D.commitDate})\x1B[0m`),console.log();if(XD("Fetching latest changes..."),!(await K0("git",["fetch","origin"],J2)).success)vD("Failed to fetch from origin"),process.exit(1);if(XD("Resetting to origin/main..."),!(await K0("git",["reset","--hard","origin/main"],J2)).success)vD("Failed to reset to origin/main"),process.exit(1);console.log();let J=await p9(J2);if(D&&J&&D.commit===J.commit){M0("Already up to date!"),console.log();return}if(XD("Installing dependencies..."),!(await K0("bun",["install"],J2)).success)vD("Failed to install dependencies"),process.exit(1);if(console.log(),XD("Building..."),!(await K0("bun",["run","build"],J2)).success)vD("Failed to build"),process.exit(1);console.log(),XD("Installing binaries...");try{await m9(G8,{recursive:!0}),await m9(H8,{recursive:!0});let Q=["genie.js","term.js"],Y=["genie","term"];for(let q=0;q<Q.length;q++){let G=m(J2,"dist",Q[q]),H=m(G8,Q[q]),V=m(H8,Y[q]);await i9(G,H),await BY(H,493),await HY(H,V)}for(let q of["claudio.js","claudio"]){let G=m(G8,q),H=m(H8,q);try{await l9(G)}catch{}try{await l9(H)}catch{}}M0("Binaries installed")}catch(Q){vD(`Failed to install binaries: ${Q}`),process.exit(1)}if(console.log(),console.log("\x1B[2m\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\x1B[0m"),M0("Genie CLI updated successfully!"),console.log(),J)console.log(`Version: \x1B[36m${J.branch}@${J.commit}\x1B[0m (${J.commitDate})`),console.log()}async function HY(D,F){let{symlink:$,unlink:J}=await import("fs/promises");try{if(cD(F))await J(F);await $(D,F)}catch{await i9(D,F)}}function n9(D,F){DY(F,{recursive:!0});for(let $ of FY(D,{withFileTypes:!0})){let J=m(D,$.name),B=m(F,$.name);if($.isDirectory())n9(J,B);else eQ(J,B)}}async function VY(D){if(D==="bun"){let J=m(e0(),".bun","install","global","node_modules","@automagik","genie");if(cD(J))return J}if(D==="npm"){let J=await b2("npm",["root","-g"]);if(J.success){let B=m(J.output.trim(),"@automagik","genie");if(cD(B))return B}}let F=m(e0(),".bun","install","global","node_modules","@automagik","genie");if(cD(F))return F;let $=await b2("npm",["root","-g"]);if($.success){let J=m($.output.trim(),"@automagik","genie");if(cD(J))return J}return null}async function d9(D){XD("Syncing Claude Code plugin...");let F=await VY(D);if(!F){XD("Could not find installed package \u2014 skipping plugin sync");return}let $=m(F,"plugins","genie");if(!cD($)){XD("Plugin source not found in package \u2014 skipping plugin sync");return}let J;try{J=JSON.parse(g9(m(F,"package.json"),"utf-8")).version}catch{XD("Could not read package version \u2014 skipping plugin sync");return}let B=m(e0(),".claude","plugins"),X=m(B,"cache","automagik","genie",J);try{if(cD(X))$Y(X,{recursive:!0,force:!0});n9($,X)}catch(Y){vD(`Failed to copy plugin: ${Y}`);return}let Q=m(B,"installed_plugins.json");try{if(cD(Q)){let Y=JSON.parse(g9(Q,"utf-8")),q=Y.plugins?.["genie@automagik"];if(Array.isArray(q)){for(let G of q)if(G.scope==="user")G.installPath=X,G.version=J,G.lastUpdated=new Date().toISOString();JY(Q,JSON.stringify(Y,null,2))}}}catch(Y){XD(`Registry update failed (non-fatal): ${Y}`)}M0(`Plugin synced to v${J}`)}async function WY(D){if(D.next)return"next";if(D.stable)return"latest";if(E2())try{let F=await VD();if(F.updateChannel)return F.updateChannel}catch{}return"latest"}async function UY(D){try{let F=await VD();F.updateChannel=D,await bD(F)}catch{}}async function o9(D={}){console.log(),console.log("\x1B[1m\uD83E\uDDDE Genie CLI Update\x1B[0m"),console.log("\x1B[2m\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\x1B[0m"),console.log();let F=await WY(D);if(D.next||D.stable)await UY(F);let $=await QY();if(XD(`Detected installation: ${$}`),XD(`Channel: ${F}${F==="next"?" (dev builds)":" (stable)"}`),console.log(),$==="unknown")vD("No Genie CLI installation found"),console.log(),console.log("Install method not configured. Please reinstall genie:"),console.log("\x1B[36m curl -fsSL https://raw.githubusercontent.com/automagik-dev/genie/main/install.sh | bash\x1B[0m"),console.log(),process.exit(1);switch($){case"source":await GY();break;case"bun":await YY(F),await d9($);break;case"npm":await qY(F),await d9($);break}}import{existsSync as zY,readFileSync as KY}from"fs";import{dirname as a6,resolve as t6}from"path";var __dirname="/home/runner/_work/genie/genie/src/lib",MY="0.0.0-unknown";function EY(){let D=[t6(a6(import.meta.dir??__dirname),"..","..","package.json"),t6(a6(import.meta.dir??__dirname),"..","package.json"),t6(a6(import.meta.dir??__dirname),"package.json")];for(let F of D)try{if(zY(F)){let $=JSON.parse(KY(F,"utf-8"));if($.version)return $.version}}catch{}return MY}var s9=EY();async function GF(D){let F=D.tool_input;if(!F)return;if(F.type!=="message")return;let $=F.recipient;if(!$)return;if($==="team-lead")return;let J=process.env.GENIE_TEAM??D.team_name;if(!J)return;try{let B=await Promise.resolve().then(() => (KD(),zD)),X=await Promise.resolve().then(() => (FD(),ZD)),Q=await Promise.resolve().then(() => (A3(),R3)),q=(await B.list()).find((M)=>(M.role===$||M.id===$)&&M.team===J);if(q&&await X.isPaneAlive(q.paneId))return;let G=await Q.resolve($),H=await B.listTemplates(),V=new Set([$]);if(G){if(V.add(G.entry.name),G.entry.roles)for(let M of G.entry.roles)V.add(M)}let W=H.find((M)=>{if(M.team!==J)return!1;return[...V].some((C)=>M.id===C||M.role===C)});if(!W){if(G)console.error(`[genie-hook] Agent "${$}" is registered in directory but has no spawn template in team "${J}".`);return}let{spawnSync:U}=w("child_process"),K=["spawn","--provider",W.provider,"--team",W.team];if(W.role)K.push("--role",W.role);if(W.skill)K.push("--skill",W.skill);if(W.cwd)K.push("--cwd",W.cwd);if(W.lastSessionId)K.push("--resume",W.lastSessionId);if(W.extraArgs)K.push(...W.extraArgs);U("genie",K,{timeout:1e4,stdio:"ignore",env:{...process.env,GENIE_TEAM:J}}),console.error(`[genie-hook] Auto-spawned "${$}" in team "${J}"`)}catch(B){let X=B instanceof Error?B.message:String(B);console.error(`[genie-hook] Auto-spawn failed for "${$}": ${X}`)}return}async function HF(D){let F=D.tool_input;if(!F)return;let $=F.type;if($!=="message"&&$!=="broadcast")return;let J=process.env.GENIE_AGENT_NAME;if(!J)return;let B=F.content;if(!B)return;if(B.startsWith(`[from:${J}]`))return;return{updatedInput:{...F,content:`[from:${J}] ${B}`}}}u1();var cH=[{name:"identity-inject",event:"PreToolUse",matcher:/^SendMessage$/,priority:10,fn:HF},{name:"auto-spawn",event:"PreToolUse",matcher:/^SendMessage$/,priority:20,fn:GF}];function iH(D,F){return cH.filter(($)=>{if($.event!==D)return!1;if($.matcher&&F&&!$.matcher.test(F))return!1;if($.matcher&&!F)return!1;return!0}).sort(($,J)=>$.priority-J.priority)}async function rH(D,F){let $=F.tool_input?{...F.tool_input}:void 0;for(let J of D)try{let B={...F};if($)B.tool_input=$;let X=await J.fn(B);if(!X)continue;if(X.decision==="deny")return{decision:"deny",reason:X.reason??`Denied by handler: ${J.name}`};if(X.updatedInput)$={...$,...X.updatedInput}}catch(B){let X=B instanceof Error?B.message:String(B);console.error(`[genie-hook] Handler "${J.name}" threw: ${X}`)}if($&&F.tool_input&&JSON.stringify($)!==JSON.stringify(F.tool_input))return{updatedInput:$};return{}}async function nH(D,F){await Promise.allSettled(D.map(($)=>$.fn(F).catch((J)=>{let B=J instanceof Error?J.message:String(J);console.error(`[genie-hook] Handler "${$.name}" threw: ${B}`)})))}async function WF(D){let F;try{F=JSON.parse(D)}catch{return console.error("[genie-hook] Invalid JSON on stdin"),""}let $=F.hook_event_name;if(!$)return console.error("[genie-hook] Missing hook_event_name in payload"),"";let J=F.tool_name,B=iH($,J);if(B.length===0)return"";if(VF($)){let X=await rH(B,F);if(X.decision||X.updatedInput)return JSON.stringify(X);return""}return await nH(B,F),""}async function oH(){let D=[];for await(let F of Bun.stdin.stream())D.push(Buffer.from(F));return Buffer.concat(D).toString("utf-8")}async function sH(){let D=await oH();if(!D.trim())process.exit(0);let F=await WF(D);if(F)process.stdout.write(F)}function UF(D){D.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(sH)}g8();A3();U3();mD();import{resolve as m8}from"path";function wF(D){let F=D.command("dir").description("Agent directory management");F.command("add <name>").description("Register an agent in the directory").requiredOption("--dir <path>","Agent folder (CWD + AGENTS.md)").option("--repo <path>","Default git repo (overridden by team)").option("--prompt-mode <mode>","Prompt mode: append or system","append").option("--model <model>","Default model (sonnet, opus, codex)").option("--roles <roles...>","Built-in roles this agent can orchestrate").action(async($,J)=>{try{let B=fF(J.promptMode),X=await v1({name:$,dir:m8(J.dir),repo:J.repo?m8(J.repo):void 0,promptMode:B,model:J.model,roles:J.roles});if(console.log(`Agent "${X.name}" registered.`),console.log(` Dir: ${WD(X.dir)}`),X.repo)console.log(` Repo: ${WD(X.repo)}`);if(console.log(` Prompt mode: ${X.promptMode}`),X.model)console.log(` Model: ${X.model}`);if(X.roles?.length)console.log(` Roles: ${X.roles.join(", ")}`)}catch(B){let X=B instanceof Error?B.message:String(B);console.error(`Error: ${X}`),process.exit(1)}}),F.command("rm <name>").description("Remove an agent from the directory").action(async($)=>{try{if(await k1($))console.log(`Agent "${$}" removed from directory.`);else console.error(`Agent "${$}" not found in directory.`),process.exit(1)}catch(J){let B=J instanceof Error?J.message:String(J);console.error(`Error: ${B}`),process.exit(1)}}),F.command("ls [name]").description("List all agents or show single entry details").option("--json","Output as JSON").option("--builtins","Include built-in roles and council members").action(async($,J)=>{try{if($)await kV($,J.json);else await wV(J.json,J.builtins)}catch(B){let X=B instanceof Error?B.message:String(B);console.error(`Error: ${X}`),process.exit(1)}}),F.command("edit <name>").description("Update an agent directory entry").option("--dir <path>","Agent folder (CWD + AGENTS.md)").option("--repo <path>","Default git repo").option("--prompt-mode <mode>","Prompt mode: append or system").option("--model <model>","Default model").option("--roles <roles...>","Built-in roles this agent can orchestrate").action(async($,J)=>{try{await vV($,J)}catch(B){let X=B instanceof Error?B.message:String(B);console.error(`Error: ${X}`),process.exit(1)}})}async function vV(D,F){let $={};if(F.dir)$.dir=m8(F.dir);if(F.repo)$.repo=m8(F.repo);if(F.promptMode)$.promptMode=fF(F.promptMode);if(F.model)$.model=F.model;if(F.roles)$.roles=F.roles;if(Object.keys($).length===0)console.error("No fields to update. Provide at least one of: --dir, --repo, --prompt-mode, --model, --roles"),process.exit(1);let J=await w1(D,$);console.log(`Agent "${D}" updated.`),uF(J)}function fF(D){if(D!=="system"&&D!=="append")throw Error(`Invalid prompt mode "${D}". Must be "append" or "system".`);return D}function uF(D){if(console.log(` Name: ${D.name}`),console.log(` Dir: ${WD(D.dir)}`),D.repo)console.log(` Repo: ${WD(D.repo)}`);if(console.log(` Prompt mode: ${D.promptMode}`),D.model)console.log(` Model: ${D.model}`);if(D.roles?.length)console.log(` Roles: ${D.roles.join(", ")}`);console.log(` Registered: ${D.registeredAt}`)}async function kV(D,F){let $=await M3(D);if(!$)console.error(`Agent "${D}" not found in directory or built-ins.`),process.exit(1);if(F){console.log(JSON.stringify({...$.entry,builtin:$.builtin},null,2));return}if($.builtin)console.log(`
|
|
442
442
|
(built-in ${$.entry.registeredAt==="(built-in)"?"agent":"agent"})`);console.log(""),uF($.entry),console.log("")}async function wV(D,F){let $=await E3();if(D){fV($,F);return}if($.length===0&&!F){console.log(`
|
|
443
443
|
No agents registered. Add one with: genie dir add <name> --dir <path>`),console.log(`Use --builtins to also see built-in roles and council members.
|
|
444
444
|
`);return}if($.length>0)uV($);if(F)xV()}function fV(D,F){let $=D.map((J)=>({...J,builtin:!1}));if(F)for(let J of b8)$.push({name:J.name,description:J.description,model:J.model,category:J.category,builtin:!0});console.log(JSON.stringify($,null,2))}function uV(D){console.log(""),console.log("REGISTERED AGENTS"),console.log("-".repeat(80)),console.log(` ${"NAME".padEnd(22)}${"DIR".padEnd(35)}${"MODE".padEnd(8)}${"MODEL".padEnd(8)}ROLES`),console.log(` ${"-".repeat(20)} ${"-".repeat(33)} ${"-".repeat(6)} ${"-".repeat(6)} ${"-".repeat(15)}`);for(let X of D){let Q=WD(X.dir),Y=Q.length>33?`${Q.slice(0,30)}...`:Q,q=X.roles?.join(", ")||"-";console.log(` ${X.name.padEnd(22)}${Y.padEnd(35)}${X.promptMode.padEnd(8)}${(X.model||"-").padEnd(8)}${q}`)}console.log("")}function xV(){console.log("BUILT-IN AGENTS"),console.log("-".repeat(80)),console.log(` ${"NAME".padEnd(22)}${"TYPE".padEnd(10)}${"MODEL".padEnd(8)}DESCRIPTION`),console.log(` ${"-".repeat(20)} ${"-".repeat(8)} ${"-".repeat(6)} ${"-".repeat(30)}`);for(let J of b8)console.log(` ${J.name.padEnd(22)}${J.category.padEnd(10)}${(J.model||"-").padEnd(8)}${J.description}`);console.log("")}import{execSync as rF}from"child_process";import{existsSync as l8}from"fs";import{mkdir as aV,readFile as p8,writeFile as tV}from"fs/promises";import{tmpdir as eV}from"os";import{join as S0}from"path";n3();P2();import{mkdir as xF,readFile as yV,writeFile as hV}from"fs/promises";import{dirname as yF,join as gV}from"path";var mV=R.enum(["blocked","ready","in_progress","done"]),lV=R.object({status:mV,assignee:R.string().optional(),dependsOn:R.array(R.string()).default([]),startedAt:R.string().optional(),completedAt:R.string().optional()}),pV=R.object({wish:R.string(),groups:R.record(R.string(),lV),createdAt:R.string(),updatedAt:R.string()});async function n1(D,F){let $=await HD(D);try{let J=await hF(D);if(!J)throw Error(`State file not found: ${D}`);let B=await F(J);return await gF(D,J),B}finally{await $()}}function _3(D,F){return gV(F??process.cwd(),".genie","state",`${D}.json`)}async function hF(D){try{let F=await yV(D,"utf-8");return pV.parse(JSON.parse(F))}catch{return null}}async function gF(D,F){await xF(yF(D),{recursive:!0}),F.updatedAt=new Date().toISOString(),await hV(D,JSON.stringify(F,null,2))}function dV(D){for(let[,F]of Object.entries(D.groups)){if(F.status!=="blocked")continue;if(F.dependsOn.length===0)continue;if(F.dependsOn.every((J)=>{return D.groups[J]?.status==="done"}))F.status="ready"}}function cV(D){let F=new Set(D.map(($)=>$.name));for(let $ of D){if($.dependsOn?.includes($.name))throw Error(`Group "${$.name}" depends on itself`);for(let J of $.dependsOn??[])if(!F.has(J))throw Error(`Group "${$.name}" depends on non-existent group "${J}"`)}}function iV(D){let F={},$={};for(let X of D)F[X.name]=(X.dependsOn??[]).length,$[X.name]=[];for(let X of D)for(let Q of X.dependsOn??[])$[Q].push(X.name);let J=Object.entries(F).filter(([,X])=>X===0).map(([X])=>X),B=0;while(J.length>0){let X=J.shift();if(!X)break;B++;for(let Q of $[X])if(F[Q]--,F[Q]===0)J.push(Q)}if(B!==D.length){let X=Object.entries(F).filter(([,Q])=>Q>0).map(([Q])=>Q);throw Error(`Dependency cycle detected among groups: ${X.join(", ")}`)}}function rV(D){cV(D),iV(D)}async function mF(D,F,$){rV(F);let J=_3(D,$);await xF(yF(J),{recursive:!0});let B=new Date().toISOString(),X={};for(let Y of F){let q=Y.dependsOn??[];X[Y.name]={status:q.length===0?"ready":"blocked",dependsOn:q}}let Q={wish:D,groups:X,createdAt:B,updatedAt:B};return await gF(J,Q),Q}async function lF(D,F,$,J){let B=_3(D,J);return n1(B,(X)=>{let Q=X.groups[F];if(!Q)throw Error(`Group "${F}" not found in wish "${D}"`);if(Q.status==="in_progress")throw Error(`Group "${F}" is already in progress (assigned to ${Q.assignee??"unknown"})`);if(Q.status==="done")throw Error(`Group "${F}" is already done`);for(let Y of Q.dependsOn){let q=X.groups[Y];if(!q)throw Error(`Dependency "${Y}" not found in wish "${D}"`);if(q.status!=="done")throw Error(`Cannot start group "${F}": dependency "${Y}" is ${q.status} (must be done)`)}return Q.status="in_progress",Q.assignee=$,Q.startedAt=new Date().toISOString(),{...Q}})}async function pF(D,F,$){let J=_3(D,$);return n1(J,(B)=>{let X=B.groups[F];if(!X)throw Error(`Group "${F}" not found in wish "${D}"`);if(X.status!=="in_progress")throw Error(`Cannot complete group "${F}": must be in_progress (currently ${X.status})`);return X.status="done",X.completedAt=new Date().toISOString(),dV(B),{...X}})}async function dF(D,F,$){let J=_3(D,$);return n1(J,(B)=>{let X=B.groups[F];if(!X)throw Error(`Group "${F}" not found`);if(X.status!=="in_progress")throw Error(`Cannot reset: must be in_progress (currently ${X.status})`);return X.status="ready",X.assignee=void 0,X.startedAt=void 0,{...X}})}async function L3(D,F){let $=_3(D,F);return hF($)}g8();function T3(D){let F=D.indexOf("#");if(F===-1)throw Error(`Invalid reference "${D}". Expected format: <slug>#<group>`);let $=D.slice(0,F),J=D.slice(F+1);if(!$||!J)throw Error(`Invalid reference "${D}". Both slug and group are required.`);return{slug:$,group:J}}var nV={blocked:"\uD83D\uDD12",ready:"\uD83D\uDFE2",in_progress:"\uD83D\uDD04",done:"\u2705"};function o1(D){if(!D)return"";return new Date(D).toLocaleString("en-US",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1})}function Z3(D,F){return D.length>=F?D:D+" ".repeat(F-D.length)}async function oV(D){try{let{slug:F,group:$}=T3(D),J=await pF(F,$);if(console.log(`\u2705 Group "${$}" marked as done in wish "${F}"`),J.completedAt)console.log(` Completed at: ${o1(J.completedAt)}`);let B=await L3(F);if(B){let X=Object.entries(B.groups).filter(([,Q])=>Q.status==="ready"&&Q.dependsOn.includes($)).map(([Q])=>Q);if(X.length>0)console.log(` Unblocked: ${X.join(", ")}`)}}catch(F){let $=F instanceof Error?F.message:String(F);console.error(`\u274C ${$}`),process.exit(1)}}async function sV(D){try{let F=await L3(D);if(!F)console.error(`\u274C No state found for wish "${D}"`),console.error(" State file expected at: .genie/state/<slug>.json"),process.exit(1);console.log(`
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genie",
|
|
3
|
-
"version": "3.260316.
|
|
3
|
+
"version": "3.260316.7",
|
|
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"
|
|
@@ -146,7 +146,7 @@ async function detectInstallationType(): Promise<InstallationType> {
|
|
|
146
146
|
|
|
147
147
|
async function updateViaBun(channel: string): Promise<void> {
|
|
148
148
|
log(`Updating via bun (channel: ${channel})...`);
|
|
149
|
-
const result = await runCommand('bun', ['
|
|
149
|
+
const result = await runCommand('bun', ['update', '-g', `@automagik/genie@${channel}`]);
|
|
150
150
|
if (!result.success) {
|
|
151
151
|
error('Failed to update via bun');
|
|
152
152
|
process.exit(1);
|