@automagik/genie 4.260330.12 → 4.260330.13

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": "4.260330.12",
13
+ "version": "4.260330.13",
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
@@ -1373,7 +1373,7 @@ exec ${bunPath} ${genieBin}
1373
1373
  genie serve is running. Press Ctrl+C to stop.`);let shutdown2=()=>{console.log(`
1374
1374
  Shutting down genie serve...`),handles.agentWatcher?.close(),handles.schedulerHandle?.stop(),killTmuxServer(TUI_SOCKET,tuiTmuxConf()),killTmuxServer(GENIE_SOCKET,genieTmuxConf()),removeServePid(),console.log("genie serve stopped.")};if(process.on("SIGTERM",()=>{shutdown2(),process.exit(143)}),process.on("SIGINT",()=>{shutdown2(),process.exit(130)}),handles.schedulerHandle)await handles.schedulerHandle.done;else await new Promise(()=>{});removeServePid()}async function startBackground(){let existingPid=readServePid();if(existingPid&&isProcessAlive(existingPid))console.log(`genie serve already running (PID ${existingPid})`),process.exit(0);if(existingPid)removeServePid();let bunPath=process.execPath??"bun",genieBin=process.argv[1]??"genie",child=spawn3(bunPath,[genieBin,"serve","--foreground"],{detached:!0,stdio:"ignore",env:{...process.env,GENIE_IS_DAEMON:"1"}});if(child.unref(),child.pid)if(await new Promise((resolve5)=>setTimeout(resolve5,1000)),isProcessAlive(child.pid))console.log(`genie serve started (PID ${child.pid})`);else console.error("Error: genie serve exited immediately."),process.exit(1);else console.error("Error: failed to spawn genie serve"),process.exit(1)}async function stopServe(){let pid=readServePid();if(!pid){console.log("genie serve is not running (no PID file).");return}if(!isProcessAlive(pid)){console.log(`Stale PID file (PID ${pid} not running). Cleaning up.`),removeServePid(),killTmuxServer(TUI_SOCKET,tuiTmuxConf()),killTmuxServer(GENIE_SOCKET,genieTmuxConf());return}console.log(`Stopping genie serve (PID ${pid})...`);try{process.kill(-pid,"SIGTERM")}catch{try{process.kill(pid,"SIGTERM")}catch{}}let deadline=Date.now()+1e4;while(Date.now()<deadline&&isProcessAlive(pid))await new Promise((resolve5)=>setTimeout(resolve5,250));if(isProcessAlive(pid)){console.log("Did not stop within 10s. Sending SIGKILL.");try{process.kill(-pid,"SIGKILL")}catch{try{process.kill(pid,"SIGKILL")}catch{}}}killTmuxServer(TUI_SOCKET,tuiTmuxConf()),killTmuxServer(GENIE_SOCKET,genieTmuxConf()),removeServePid(),console.log("genie serve stopped.")}async function printPgserveStatus(){try{let{isAvailable:isAvailable2,getActivePort:getActivePort2}=await Promise.resolve().then(() => (init_db(),exports_db)),dbOk=await isAvailable2();console.log(` pgserve: ${dbOk?`healthy (port ${getActivePort2()})`:"unreachable"}`)}catch{console.log(" pgserve: unavailable")}}function printTmuxStatus(){let agentRunning=isTmuxServerRunning(GENIE_SOCKET,genieTmuxConf()),sessions=agentRunning?listAgentSessions():[];if(console.log(` tmux -L ${GENIE_SOCKET}: ${agentRunning?`running (${sessions.length} sessions)`:"stopped"}`),sessions.length>0)console.log(` ${sessions.join(", ")}`);let tuiRunning=isTmuxServerRunning(TUI_SOCKET,tuiTmuxConf());console.log(` tmux -L ${TUI_SOCKET}: ${tuiRunning?"running":"stopped"}`)}async function printDaemonStatus(serveRunning){try{let schedulerPidPath=join31(genieHome(),"scheduler.pid");if(existsSync24(schedulerPidPath)){let sPid=Number.parseInt(readFileSync11(schedulerPidPath,"utf-8").trim(),10),sAlive=!Number.isNaN(sPid)&&isProcessAlive(sPid);console.log(` scheduler: ${sAlive?`running (PID ${sPid})`:"stopped"}`)}else if(serveRunning)console.log(" scheduler: integrated (in-process)");else console.log(" scheduler: stopped")}catch{console.log(" scheduler: unknown")}try{let{getInboxPollIntervalMs:getInboxPollIntervalMs2}=await Promise.resolve().then(() => (init_inbox_watcher(),exports_inbox_watcher)),pollMs=getInboxPollIntervalMs2();if(pollMs===0)console.log(" inbox: disabled");else console.log(` inbox: ${serveRunning?"watching":"stopped"} (poll ${pollMs/1000}s)`)}catch{console.log(" inbox: unavailable")}}async function statusServe(){let pid=readServePid(),running2=pid!==null&&isProcessAlive(pid);if(console.log(`
1375
1375
  Genie Serve`),console.log("\u2500".repeat(50)),console.log(` Status: ${running2?"running":"stopped"}`),running2&&pid)console.log(` PID: ${pid}`);await printPgserveStatus(),printTmuxStatus(),await printDaemonStatus(running2),console.log(` PID file: ${servePidPath()}`),console.log("")}function registerServeCommands(program2){let serve=program2.command("serve").description("Start all genie infrastructure (pgserve, tmux, scheduler)");serve.command("start",{isDefault:!0}).description("Start genie serve").option("--daemon","Run in background").option("--foreground","Run in foreground (default)").action(async(options)=>{if(options.daemon)await startBackground();else await startForeground()}),serve.command("stop").description("Stop genie serve and all services").action(async()=>{await stopServe()}),serve.command("status").description("Show service health").action(async()=>{await statusServe()})}var GENIE_SOCKET="genie",TUI_SOCKET="genie-tui",TUI_SESSION="genie-tui",NAV_WIDTH=30,KEY_TABLE="genie-tui",TUI_STYLE,handles;var init_serve=__esm(()=>{TUI_STYLE={activeBorder:"#7c3aed",inactiveBorder:"#414868"};handles={schedulerHandle:null,agentWatcher:null}});var exports_tmux2={};__export(exports_tmux2,{attachTuiSession:()=>attachTuiSession,attachProjectWindow:()=>attachProjectWindow});import{execSync as execSync7,spawnSync as spawnSync2}from"child_process";function resolveRightPane(rightPane){try{return execSync7(`${TMUX} display-message -t ${rightPane} -p ''`,{stdio:"ignore"}),rightPane}catch{try{let panes=execSync7(`${TMUX} list-panes -t ${SESSION_NAME}:0 -F '#{pane_id}'`,{encoding:"utf-8"}).trim().split(`
1376
- `);return panes[1]||panes[0]}catch{return rightPane}}}function ensureAgentSession(sessionName){let agentTmux=`tmux -L ${GENIE_AGENT_SOCKET}`;try{execSync7(`${agentTmux} has-session -t '${sessionName}' 2>/dev/null`,{stdio:"ignore"})}catch{try{execSync7(`${agentTmux} new-session -d -s '${sessionName}'`,{stdio:"ignore"})}catch{}}}function attachProjectWindow(rightPane,targetSession,windowIndex){if(targetSession===SESSION_NAME)return;let pane=resolveRightPane(rightPane);if(ensureAgentSession(targetSession),windowIndex!==void 0)try{let agentTmux=`tmux -L ${GENIE_AGENT_SOCKET}`;execSync7(`${agentTmux} select-window -t '${targetSession}:${windowIndex}'`,{stdio:"ignore"})}catch{}try{let agentTmux=`tmux -L ${GENIE_AGENT_SOCKET}`;execSync7(`${TMUX} respawn-pane -k -t ${pane} "TMUX='' ${agentTmux} attach-session -t '${targetSession}'"`,{stdio:"ignore"})}catch{}}function attachTuiSession(){spawnSync2("tmux",["-L",TMUX_SOCKET,"-f",GENIE_TMUX_CONF,"attach-session","-t",SESSION_NAME],{stdio:"inherit"})}var SESSION_NAME="genie-tui",TMUX_SOCKET="genie-tui",GENIE_AGENT_SOCKET="genie",GENIE_TMUX_CONF,TMUX;var init_tmux2=__esm(()=>{GENIE_TMUX_CONF=(()=>{let{existsSync:existsSync25}=__require("fs");return[`${process.env.GENIE_HOME??`${process.env.HOME}/.genie`}/tmux.conf`,`${process.env.HOME}/.tmux.conf`].find((p)=>existsSync25(p))??"/dev/null"})(),TMUX=`tmux -L ${TMUX_SOCKET} -f ${GENIE_TMUX_CONF}`});function onBridgeEvent(handler){return listeners.add(handler),()=>{listeners.delete(handler)}}function emit2(event){for(let handler of listeners)handler(event)}async function listAgents2(){return(await getConnection())`
1376
+ `);return panes[1]||panes[0]}catch{return rightPane}}}function ensureAgentSession(sessionName){let agentTmux=`tmux -L ${GENIE_AGENT_SOCKET}`;try{execSync7(`${agentTmux} has-session -t '${sessionName}' 2>/dev/null`,{stdio:"ignore"})}catch{try{execSync7(`${agentTmux} new-session -d -s '${sessionName}'`,{stdio:"ignore"})}catch{}}}function attachProjectWindow(rightPane,targetSession,windowIndex){if(targetSession===SESSION_NAME)return;let pane=resolveRightPane(rightPane);if(ensureAgentSession(targetSession),windowIndex!==void 0)try{let agentTmux=`tmux -L ${GENIE_AGENT_SOCKET}`;execSync7(`${agentTmux} select-window -t '${targetSession}:${windowIndex}'`,{stdio:"ignore"})}catch{}try{let attachCmd=`sleep 0.1 && printf '\\033[2J\\033[H' && TMUX='' ${`tmux -L ${GENIE_AGENT_SOCKET}`} attach-session -t '${targetSession}'`;execSync7(`${TMUX} respawn-pane -k -t ${pane} "sh -c \\"${attachCmd}\\""`,{stdio:"ignore"})}catch{}}function attachTuiSession(){spawnSync2("tmux",["-L",TMUX_SOCKET,"-f",GENIE_TMUX_CONF,"attach-session","-t",SESSION_NAME],{stdio:"inherit"})}var SESSION_NAME="genie-tui",TMUX_SOCKET="genie-tui",GENIE_AGENT_SOCKET="genie",GENIE_TMUX_CONF,TMUX;var init_tmux2=__esm(()=>{GENIE_TMUX_CONF=(()=>{let{existsSync:existsSync25}=__require("fs");return[`${process.env.GENIE_HOME??`${process.env.HOME}/.genie`}/tmux.conf`,`${process.env.HOME}/.tmux.conf`].find((p)=>existsSync25(p))??"/dev/null"})(),TMUX=`tmux -L ${TMUX_SOCKET} -f ${GENIE_TMUX_CONF}`});function onBridgeEvent(handler){return listeners.add(handler),()=>{listeners.delete(handler)}}function emit2(event){for(let handler of listeners)handler(event)}async function listAgents2(){return(await getConnection())`
1377
1377
  SELECT a.id, a.custom_name, a.role, a.team, a.title, a.state,
1378
1378
  a.reports_to, a.current_executor_id, a.started_at
1379
1379
  FROM agents a
@@ -2,7 +2,7 @@
2
2
  "id": "genie",
3
3
  "name": "Genie",
4
4
  "description": "Skills, agents, and hooks for the Genie CLI terminal orchestration toolkit",
5
- "version": "4.260330.12",
5
+ "version": "4.260330.13",
6
6
  "configSchema": {
7
7
  "type": "object",
8
8
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/genie",
3
- "version": "4.260330.12",
3
+ "version": "4.260330.13",
4
4
  "description": "Collaborative terminal toolkit for human + AI workflows",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genie",
3
- "version": "4.260330.12",
3
+ "version": "4.260330.13",
4
4
  "description": "Human-AI partnership for Claude Code. Share a terminal, orchestrate workers, evolve together. Brainstorm ideas, turn them into wishes, execute with /work, validate with /review, and ship as one team.",
5
5
  "author": {
6
6
  "name": "Namastex Labs"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genie-plugin",
3
- "version": "4.260330.12",
3
+ "version": "4.260330.13",
4
4
  "private": true,
5
5
  "description": "Runtime dependencies for genie bundled CLIs",
6
6
  "type": "module",
@@ -50,21 +50,19 @@ setw -g mode-style "bg=#7b2ff7,fg=#e0e0e0"
50
50
  setw -g clock-mode-colour "#7b2ff7"
51
51
 
52
52
  # ============================================================================
53
- # TOP BAR — pane-border: left = branding + folder | right = git, CPU, RAM, time
53
+ # TOP BAR — pane-border: clean labels, NO shell probes
54
+ # Shell probes (#() calls) cause garbled escape sequences when TUI/app
55
+ # attaches to agent sessions. Observability lives in TUI/app status bar.
54
56
  # ============================================================================
55
57
  set -g pane-border-status top
56
58
  set -g pane-border-lines heavy
57
59
  set -g pane-border-format "\
58
60
  #[align=left,bg=#16213e,fg=#e0e0e0]\
59
- #[fg=#7b2ff7,bold]Genie#[fg=#6c6c8a,nobold] #(PATH=$HOME/.bun/bin:$HOME/.npm-global/bin:$PATH genie --version 2>/dev/null | head -1 || echo '?') \
61
+ #[fg=#7b2ff7,bold]Genie#[fg=#6c6c8a,nobold] \
60
62
  #[fg=#0f3460]│ \
61
63
  #[fg=#b8a9c9]#{pane_current_path}\
62
64
  #[align=right,bg=#16213e]\
63
- #[fg=#f5a623]#($HOME/.genie/scripts/genie-git.sh) \
64
- #[fg=#0f3460]│ \
65
- #[fg=#00d2ff]CPU #($HOME/.genie/scripts/cpu-info.sh) \
66
- #[fg=#0f3460]│ \
67
- #[fg=#00d2ff]RAM #($HOME/.genie/scripts/ram-info.sh) \
65
+ #[fg=#e0e0e0]#{session_name}:#{window_name} \
68
66
  #[fg=#0f3460]│ \
69
67
  #[fg=#e0e0e0]%H:%M "
70
68
 
package/src/tui/tmux.ts CHANGED
@@ -76,9 +76,14 @@ export function attachProjectWindow(rightPane: string, targetSession: string, wi
76
76
  }
77
77
  }
78
78
  try {
79
- // Attach to sessions on the genie agent server
79
+ // Attach to sessions on the genie agent server.
80
+ // Use a wrapper script that clears probe artifacts:
81
+ // 1. Sleep briefly so tmux finishes its terminal capability detection
82
+ // 2. Clear screen to hide probe escape sequences
83
+ // 3. Attach to the agent session
80
84
  const agentTmux = `tmux -L ${GENIE_AGENT_SOCKET}`;
81
- execSync(`${TMUX} respawn-pane -k -t ${pane} "TMUX='' ${agentTmux} attach-session -t '${targetSession}'"`, {
85
+ const attachCmd = `sleep 0.1 && printf '\\033[2J\\033[H' && TMUX='' ${agentTmux} attach-session -t '${targetSession}'`;
86
+ execSync(`${TMUX} respawn-pane -k -t ${pane} "sh -c \\"${attachCmd}\\""`, {
82
87
  stdio: 'ignore',
83
88
  });
84
89
  } catch {