@automagik/genie 4.260428.3 → 4.260428.4

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
@@ -1502,7 +1502,7 @@ Synced: ${total} agent(s), ${result2.archived.length} removed.`)}async function
1502
1502
  ) AS latest_assignment_outcome
1503
1503
  FROM agents a
1504
1504
  WHERE a.id = ${agentId}
1505
- `)[0]??null}function isPermanent(row){return row.kind==="permanent"}async function shouldResume(agentId){let row=await readAgentResumeRow(agentId);if(!row)return{resume:!1,reason:"unknown_agent",rehydrate:"lazy"};let rehydrate=isPermanent(row)?"eager":"lazy";if(row.auto_resume===!1){let sessionId2=await getResumeSessionId(agentId).catch(()=>null),result2={resume:!1,reason:"auto_resume_disabled",rehydrate};if(sessionId2)result2.sessionId=sessionId2;return result2}if(row.latest_assignment_outcome!==null){let sessionId2=await getResumeSessionId(agentId).catch(()=>null),result2={resume:!1,reason:"assignment_closed",rehydrate};if(sessionId2)result2.sessionId=sessionId2;return result2}let sessionId=await getResumeSessionId(agentId).catch(()=>null);if(!sessionId)return{resume:!1,reason:"no_session_id",rehydrate};return{resume:!0,reason:"ok",sessionId,rehydrate}}function classifyBootPass(agentId,decision){if(!decision.resume)return{agentId,decision,action:"skip"};if(decision.rehydrate==="eager")return{agentId,decision,action:"eager_invoke"};return{agentId,decision,action:"lazy_surface"}}function bootPassEventType(action,decision){if(action==="eager_invoke")return"agent.boot_pass.eager_invoked";if(action==="lazy_surface")return"agent.boot_pass.lazy_pending";if(decision.reason==="assignment_closed")return"agent.boot_pass.skipped_task_done";return"agent.boot_pass.rehydrated"}async function bootPassDecisions(agentIds){let cap=Math.min(BOOT_PASS_CONCURRENCY_CAP,Math.max(1,agentIds.length)),results=Array(agentIds.length),cursor=0,workers=Array.from({length:cap},async()=>{while(cursor<agentIds.length){let i2=cursor++;if(i2>=agentIds.length)return;let agentId=agentIds[i2];try{let decision=await shouldResume(agentId);results[i2]=classifyBootPass(agentId,decision)}catch{let decision={resume:!1,reason:"no_session_id",rehydrate:"lazy"};results[i2]=classifyBootPass(agentId,decision)}}});return await Promise.all(workers),results}async function emitBootPassEvent(decision,actor=process.env.GENIE_AGENT_NAME??"scheduler"){let eventType=bootPassEventType(decision.action,decision.decision),details={action:decision.action,reason:decision.decision.reason,rehydrate:decision.decision.rehydrate};if(decision.decision.sessionId)details.sessionId=decision.decision.sessionId;await recordAuditEvent("agent",decision.agentId,eventType,actor,details)}var BOOT_PASS_CONCURRENCY_CAP=32;var init_should_resume=__esm(()=>{init_audit();init_db();init_executor_registry()});var exports_team_auto_spawn={};__export(exports_team_auto_spawn,{isTeamActive:()=>isTeamActive,isAgentAlive:()=>isAgentAlive,ensureTeamLead:()=>ensureTeamLead});import{randomUUID as randomUUID6}from"crypto";import{existsSync as existsSync32}from"fs";import{join as join37}from"path";function getSystemPromptFile(workingDir){let agentsPath=join37(workingDir,"AGENTS.md");if(existsSync32(agentsPath))return agentsPath;return null}async function ensureSession2(teamName){let{getTeam:getTeam2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),teamConfig=await getTeam2(teamName);if(teamConfig?.tmuxSessionName){if(await findSessionByName(teamConfig.tmuxSessionName))return teamConfig.tmuxSessionName}if(!teamConfig){let current=await getCurrentSessionName();if(current)return current}let sessionName=teamConfig?.tmuxSessionName??sanitizeTeamName(teamName);try{await createSession(sessionName)}catch(error2){if(!(error2 instanceof Error?error2.message:String(error2)).includes("duplicate session"))throw error2}return sessionName}async function isTeamActive(teamName){if(!await loadConfig(teamName))return!1;let{getTeam:getTeam2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),sessionName=(await getTeam2(teamName))?.tmuxSessionName??await getCurrentSessionName()??sanitizeTeamName(teamName);if(!await findSessionByName(sessionName))return!1;try{let windows=await listWindows(sessionName),sanitized=sanitizeTeamName(teamName);return windows.some((w)=>w.name===sanitized||w.name===teamName)}catch{return!1}}async function isAgentAlive(agentName){try{let{list:list2}=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry)),match=(await list2()).find((a)=>a.id===agentName||a.role===agentName);if(!match?.paneId)return!1;return resolveWorkerLivenessByTransport(match)}catch{return!1}}async function ensureTeamLead(teamName,workingDir){let{getTeam:getTeam2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),targetSession=(await getTeam2(teamName))?.tmuxSessionName??await getCurrentSessionName()??sanitizeTeamName(teamName);if(await isTeamActive(teamName))return{created:!1,session:targetSession,window:sanitizeWindowName(teamName)};let{resolveLeaderName:resolveLeaderName2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),leaderName=await resolveLeaderName2(teamName),sanitized=sanitizeTeamName(teamName),leaderAgent=await findOrCreateAgent(leaderName,sanitized,leaderName),priorSessionId=(await shouldResume(leaderAgent.id).catch(()=>null))?.sessionId??null,sessionId=priorSessionId??randomUUID6(),resumeLeader=priorSessionId!==null;await ensureNativeTeamWithSessionId(teamName,`Genie team: ${teamName}`,sessionId,leaderName),await registerNativeMember(teamName,{agentName:leaderName,agentType:"general-purpose",color:"blue",cwd:workingDir});let session=await ensureSession2(teamName),windowName=sanitizeWindowName(teamName),teamWindow=await ensureTeamWindow(session,windowName,workingDir);if(teamWindow.created){let systemPromptFile=getSystemPromptFile(workingDir),target=`${session}:${windowName}`,cdCmd=`cd ${shellQuote(workingDir)}`;await executeTmux2(`send-keys -t ${shellQuote(target)} ${shellQuote(cdCmd)} Enter`);let cmd=buildTeamLeadCommand(teamName,{systemPromptFile:systemPromptFile??void 0,leaderName,sessionId,resume:resumeLeader});await executeTmux2(`send-keys -t ${shellQuote(target)} ${shellQuote(cmd)} Enter`),await recordTeamLeadExecutor({agentId:leaderAgent.id,session,windowName,windowId:teamWindow.windowId,paneId:teamWindow.paneId,sessionId,workingDir}).catch(()=>{})}return{created:teamWindow.created,session,window:windowName}}async function recordTeamLeadExecutor(opts){await terminateActiveExecutor(opts.agentId);let pid=null;try{let target=`${opts.session}:${opts.windowName}`,pidStr=(await executeTmux2(`display -t ${shellQuote(target)} -p '#{pane_pid}'`)).trim(),parsed=Number.parseInt(pidStr,10);if(parsed>0)pid=parsed}catch{}await createAndLinkExecutor(opts.agentId,"claude","tmux",{pid,tmuxSession:opts.session,tmuxPaneId:opts.paneId,tmuxWindow:opts.windowName,tmuxWindowId:opts.windowId??null,claudeSessionId:opts.sessionId,state:"spawning",repoPath:opts.workingDir})}var init_team_auto_spawn=__esm(()=>{init_session();init_agent_registry();init_claude_native_teams();init_executor_registry();init_should_resume();init_team_lead_command();init_tmux()});var exports_inbox_watcher={};__export(exports_inbox_watcher,{stopInboxWatcher:()=>stopInboxWatcher,startInboxWatcher:()=>startInboxWatcher,resetSpawnFailures:()=>resetSpawnFailures,resetNoWorkingDirWarned:()=>resetNoWorkingDirWarned,getInboxPollIntervalMs:()=>getInboxPollIntervalMs,checkInboxes:()=>checkInboxes});function getInboxPollIntervalMs(){let env=process.env.GENIE_INBOX_POLL_MS;if(env!==void 0){if(env==="")return INBOX_POLL_INTERVAL_MS;let parsed=Number(env);if(!Number.isNaN(parsed)&&parsed>=0)return parsed}return INBOX_POLL_INTERVAL_MS}function resetSpawnFailures(){spawnFailures.clear()}function resetNoWorkingDirWarned(){noWorkingDirWarned.clear()}function resolveSessionKeyFromMessage(teamName,firstUnreadText){if(!firstUnreadText)return teamName;let header=parseRoutingHeader(firstUnreadText);return header?resolveSessionKey(teamName,header):teamName}function shouldWarnMissingWorkingDir(teamName){let now=Date.now(),lastWarned=noWorkingDirWarned.get(teamName)??0;if(now-lastWarned<NO_WORKING_DIR_RECHECK_MS)return!1;return noWorkingDirWarned.set(teamName,now),!0}async function attemptSpawn(deps,teamName,workingDir,sessionKey2,currentFailures){try{return await deps.ensureTeamLead(teamName,workingDir),spawnFailures.set(sessionKey2,0),!0}catch(err){let newCount=currentFailures+1;spawnFailures.set(sessionKey2,newCount);let message=err instanceof Error?err.message:String(err);if(deps.warn(`[inbox-watcher] Failed to spawn team-lead for "${teamName}" (attempt ${newCount}/${MAX_SPAWN_FAILURES}): ${message}`),newCount===MAX_SPAWN_FAILURES)deps.emitDeadInbox({team_name:teamName,session_key:sessionKey2,failure_count:newCount,last_error_message:message.length>2048?`${message.slice(0,2045)}...`:message});return!1}}async function checkInboxes(deps=defaultDeps2){if(getInboxPollIntervalMs()===0)return[];let teamsWithUnread=await deps.listTeamsWithUnreadInbox(),spawned=[];for(let{teamName,workingDir,firstUnreadText}of teamsWithUnread){let sessionKey2=resolveSessionKeyFromMessage(teamName,firstUnreadText),failures=spawnFailures.get(sessionKey2)??0;if(failures>=MAX_SPAWN_FAILURES){deps.warn(`[inbox-watcher] Skipping "${sessionKey2}" \u2014 ${failures} consecutive spawn failures`);continue}if(await deps.isTeamActive(teamName))continue;if(!workingDir){if(shouldWarnMissingWorkingDir(teamName))deps.warn(`[inbox-watcher] Cannot spawn team-lead for "${teamName}" \u2014 no workingDir in config`);continue}if(noWorkingDirWarned.delete(teamName),await attemptSpawn(deps,teamName,workingDir,sessionKey2,failures))spawned.push(teamName)}return spawned}function startInboxWatcher(deps=defaultDeps2){return setInterval(()=>{checkInboxes(deps).catch((err)=>{let message=err instanceof Error?err.message:String(err);deps.warn(`[inbox-watcher] Poll error: ${message}`)})},getInboxPollIntervalMs())}function stopInboxWatcher(handle){clearInterval(handle)}var defaultDeps2,INBOX_POLL_INTERVAL_MS=30000,MAX_SPAWN_FAILURES=3,NO_WORKING_DIR_RECHECK_MS=3600000,spawnFailures,noWorkingDirWarned;var init_inbox_watcher=__esm(()=>{init_claude_native_teams();init_emit();init_routing_header();init_team_auto_spawn();defaultDeps2={listTeamsWithUnreadInbox,isTeamActive:(teamName)=>isTeamActive(teamName),isAgentAlive:(agentName)=>isAgentAlive(agentName),ensureTeamLead:(teamName,workingDir)=>ensureTeamLead(teamName,workingDir),warn:(msg)=>console.warn(msg),emitDeadInbox:(payload)=>{try{emitEvent("rot.inbox-watcher-spawn-loop.detected",payload)}catch{}}};spawnFailures=new Map,noWorkingDirWarned=new Map});var exports_msg={};__export(exports_msg,{suggestRelayLeader:()=>suggestRelayLeader,resolveSenderTeams:()=>resolveSenderTeams,registerSendInboxCommands:()=>registerSendInboxCommands,printBridgeSuggestion:()=>printBridgeSuggestion,detectSenderIdentity:()=>detectSenderIdentity,checkSendScope:()=>checkSendScope});import{readFile as readFile7}from"fs/promises";import{homedir as homedir26}from"os";import{join as join38}from"path";async function getRegistry(){if(!_registry)_registry=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry));return _registry}async function getTaskService(){if(!_taskService)_taskService=await Promise.resolve().then(() => (init_task_service(),exports_task_service));return _taskService}async function getTeamManager(){if(!_teamManager)_teamManager=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager));return _teamManager}async function getMailbox(){if(!_mailbox)_mailbox=await Promise.resolve().then(() => (init_mailbox(),exports_mailbox));return _mailbox}async function detectSenderIdentity(teamName){let envName=process.env.GENIE_AGENT_NAME;if(envName)return envName;let paneId=process.env.TMUX_PANE;if(!paneId)return"cli";let registry=await getRegistry(),worker=typeof registry.findByPane==="function"?await registry.findByPane(paneId):null;if(worker)return worker.role??worker.id;let resolvedTeam=teamName??process.env.GENIE_TEAM;if(resolvedTeam){let memberName=await findMemberByPane(resolvedTeam,paneId);if(memberName)return memberName}return"cli"}async function findMemberByPane(teamName,paneId){let configDir=process.env.CLAUDE_CONFIG_DIR??join38(homedir26(),".claude"),sanitized=teamName.replace(/[^a-zA-Z0-9]/g,"-").toLowerCase(),cfgPath=join38(configDir,"teams",sanitized,"config.json");try{let raw=await readFile7(cfgPath,"utf-8");return(JSON.parse(raw).members??[]).find((m)=>m.tmuxPaneId===paneId)?.name??null}catch{return null}}async function resolveLeaderAlias(recipient,teamContext){if(recipient!=="team-lead")return recipient;let teamName=teamContext??process.env.GENIE_TEAM;if(teamName)return(await getTeamManager()).resolveLeaderName(teamName);return recipient}async function checkSendScope(_repoPath,sender,recipient){if(sender==="cli")return null;let teams=await(await getTeamManager()).listTeams(),senderTeams=resolveSenderTeams(teams,sender);if(senderTeams.length===0)return null;for(let team of senderTeams)if(isRecipientInTeam(team,recipient))return null;let reachableChildren=resolveReachableChildren(teams,senderTeams);for(let child of reachableChildren){if(recipient===child.name)return null;if(isRecipientInTeam(child,recipient))return null}let teamNames=senderTeams.map((t)=>t.name).join(", ");return`Scope violation: "${recipient}" is not in sender's team(s): ${teamNames}`}function childReachbackAllowed(child,parent){if(parent.allowChildReachback?.some((prefix)=>child.name.startsWith(prefix)))return!0;return DEFAULT_REACHBACK_PREFIXES.some((prefix)=>child.name.startsWith(prefix))}function walkParentChain(teams,start,visited,out){let current=start,depth=0;while(current.parentTeam&&depth<PARENT_CHAIN_MAX_DEPTH){if(visited.has(current.parentTeam))return;let parent=teams.find((t)=>t.name===current.parentTeam);if(!parent)return;if(!childReachbackAllowed(current,parent))return;out.push(parent),visited.add(parent.name),current=parent,depth++}}function walkChildTeams(teams,parent,visited,out,depth){if(depth>=PARENT_CHAIN_MAX_DEPTH)return;for(let child of teams){if(visited.has(child.name))continue;if(child.parentTeam!==parent.name)continue;if(!childReachbackAllowed(child,parent))continue;out.push(child),visited.add(child.name),walkChildTeams(teams,child,visited,out,depth+1)}}function resolveReachableChildren(teams,senderTeams){let visited=new Set(senderTeams.map((t)=>t.name)),result2=[];for(let team of senderTeams)walkChildTeams(teams,team,visited,result2,0);return result2}function resolveSenderTeams(teams,sender){let direct=teams.filter((t)=>t.members.includes(sender)),visited=new Set(direct.map((t)=>t.name)),result2=[...direct];for(let team of direct)walkParentChain(teams,team,visited,result2);if(teams.some((t)=>t.leader===sender)||sender==="team-lead"){let envTeam=process.env.GENIE_TEAM;if(envTeam){let leaderTeam=teams.find((t)=>t.name===envTeam);if(leaderTeam&&!visited.has(leaderTeam.name))result2.push(leaderTeam),visited.add(leaderTeam.name),walkParentChain(teams,leaderTeam,visited,result2)}}return result2}async function suggestRelayLeader(sender){if(sender==="cli")return null;let teams=await(await getTeamManager()).listTeams(),reachable=resolveSenderTeams(teams,sender);if(reachable.length===0)return null;let target=reachable[0];return{leader:target.leader??target.name,team:target.name}}function isRecipientInTeam(team,recipient){if(team.members.includes(recipient)||recipient===team.leader||recipient==="team-lead")return!0;if(recipient.startsWith(`${team.name}-`)){let roleOnly=recipient.slice(team.name.length+1);if(team.members.includes(roleOnly))return!0}return!1}async function findAgentTeam(_repoPath,agentName){let teams=await(await getTeamManager()).listTeams(),memberTeam=teams.find((t)=>t.members.includes(agentName));if(memberTeam)return memberTeam;if(agentName==="team-lead"||teams.some((t)=>t.leader===agentName)){let envTeam=process.env.GENIE_TEAM;if(envTeam)return teams.find((t)=>t.name===envTeam)??null;let leaderTeam=teams.find((t)=>t.leader===agentName);if(leaderTeam)return leaderTeam}return null}function localActor(name){return{actorType:"local",actorId:name}}async function resolveTeamName2(explicit,repoPath,from){if(explicit)return explicit;let name=(await findAgentTeam(repoPath,from))?.name??process.env.GENIE_TEAM;if(!name)console.error("Error: Could not auto-detect team. Use --team <name>."),process.exit(1);return name}async function handleInbox(agent,options){let ts3=await getTaskService(),resolvedAgent=agent??await detectSenderIdentity(),actor=localActor(resolvedAgent),conversations=await ts3.listConversations(actor);if(options.json){console.log(JSON.stringify(conversations,null,2));return}if(conversations.length===0){console.log(`No conversations for "${resolvedAgent}".`);return}console.log(""),console.log(`INBOX: ${resolvedAgent}`),console.log("\u2500".repeat(60));for(let conv of conversations)await printConversationSummary(ts3,conv)}async function printConversationSummary(ts3,conv){let messages2=await ts3.getMessages(conv.id,{limit:1}),lastMsg=messages2.length>0?messages2[messages2.length-1]:null,name=conv.name??conv.id,type2=conv.type==="dm"?"DM":"Group",linked=conv.linkedEntity?` [${conv.linkedEntity}:${conv.linkedEntityId}]`:"",preview=lastMsg?truncate2(lastMsg.body,50):"(no messages)",time=lastMsg?formatTime(lastMsg.createdAt):"";if(console.log(` ${padRight(name,30)} ${padRight(type2,6)}${linked}`),lastMsg)console.log(` ${time} ${lastMsg.senderId}: ${preview}`);console.log("")}async function handleChatThread(messageId,options){let ts3=await getTaskService(),from=options.from??await detectSenderIdentity(),actor=localActor(from),parentMsgId=Number(messageId),parentMsg=await ts3.getMessage(parentMsgId);if(!parentMsg)console.error(`Error: Message not found: ${messageId}`),process.exit(1);let conv=await ts3.findOrCreateConversation({type:"group",name:options.name??`Thread on message #${parentMsgId}`,parentMessageId:parentMsgId,createdBy:actor,members:[actor]});console.log(`Thread created: ${conv.id}`),console.log(` Parent message: #${parentMsgId} in ${parentMsg.conversationId}`),console.log(` Name: ${conv.name??"(unnamed)"}`)}function printConversationTable(conversations){console.log(` ${padRight("ID",20)} ${padRight("NAME",25)} ${padRight("TYPE",8)} ${padRight("LINKED",20)} UPDATED`),console.log(` ${"\u2500".repeat(80)}`);for(let c of conversations){let name=truncate2(c.name??"(unnamed)",23),linked=c.linkedEntity?`${c.linkedEntity}:${c.linkedEntityId}`:"-",updated=formatTime(c.updatedAt);console.log(` ${padRight(c.id,20)} ${padRight(name,25)} ${padRight(c.type,8)} ${padRight(linked,20)} ${updated}`)}console.log(`
1505
+ `)[0]??null}function isPermanent(row){return row.kind==="permanent"}async function shouldResume(agentId){let row=await readAgentResumeRow(agentId);if(!row)return{resume:!1,reason:"unknown_agent",rehydrate:"lazy"};let rehydrate=isPermanent(row)?"eager":"lazy";if(row.auto_resume===!1){let sessionId2=await getResumeSessionId(agentId).catch(()=>null),result2={resume:!1,reason:"auto_resume_disabled",rehydrate};if(sessionId2)result2.sessionId=sessionId2;return result2}if(row.latest_assignment_outcome!==null){let sessionId2=await getResumeSessionId(agentId).catch(()=>null),result2={resume:!1,reason:"assignment_closed",rehydrate};if(sessionId2)result2.sessionId=sessionId2;return result2}let sessionId=await getResumeSessionId(agentId).catch(()=>null);if(!sessionId)return{resume:!1,reason:"no_session_id",rehydrate};return{resume:!0,reason:"ok",sessionId,rehydrate}}function classifyBootPass(agentId,decision){if(!decision.resume)return{agentId,decision,action:"skip"};if(decision.rehydrate==="eager")return{agentId,decision,action:"eager_invoke"};return{agentId,decision,action:"lazy_surface"}}function bootPassEventType(action,decision){if(action==="eager_invoke")return"agent.boot_pass.eager_invoked";if(action==="lazy_surface")return"agent.boot_pass.lazy_pending";if(decision.reason==="assignment_closed")return"agent.boot_pass.skipped_task_done";return"agent.boot_pass.rehydrated"}async function bootPassDecisions(agentIds){let cap=Math.min(BOOT_PASS_CONCURRENCY_CAP,Math.max(1,agentIds.length)),results=Array(agentIds.length),cursor=0,workers=Array.from({length:cap},async()=>{while(cursor<agentIds.length){let i2=cursor++;if(i2>=agentIds.length)return;let agentId=agentIds[i2];try{let decision=await shouldResume(agentId);results[i2]=classifyBootPass(agentId,decision)}catch{let decision={resume:!1,reason:"no_session_id",rehydrate:"lazy"};results[i2]=classifyBootPass(agentId,decision)}}});return await Promise.all(workers),results}async function emitBootPassEvent(decision,actor=process.env.GENIE_AGENT_NAME??"scheduler"){let eventType=bootPassEventType(decision.action,decision.decision),details={action:decision.action,reason:decision.decision.reason,rehydrate:decision.decision.rehydrate};if(decision.decision.sessionId)details.sessionId=decision.decision.sessionId;await recordAuditEvent("agent",decision.agentId,eventType,actor,details)}var BOOT_PASS_CONCURRENCY_CAP=32;var init_should_resume=__esm(()=>{init_audit();init_db();init_executor_registry()});var exports_team_auto_spawn={};__export(exports_team_auto_spawn,{isTeamActive:()=>isTeamActive,isAgentAlive:()=>isAgentAlive,ensureTeamLead:()=>ensureTeamLead});import{randomUUID as randomUUID6}from"crypto";import{existsSync as existsSync32}from"fs";import{join as join37}from"path";function getSystemPromptFile(workingDir){let agentsPath=join37(workingDir,"AGENTS.md");if(existsSync32(agentsPath))return agentsPath;return null}async function ensureSession2(teamName){let{getTeam:getTeam2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),teamConfig=await getTeam2(teamName);if(teamConfig?.tmuxSessionName){if(await findSessionByName(teamConfig.tmuxSessionName))return teamConfig.tmuxSessionName}if(!teamConfig){let current=await getCurrentSessionName();if(current)return current}let sessionName=teamConfig?.tmuxSessionName??sanitizeTeamName(teamName);try{await createSession(sessionName)}catch(error2){if(!(error2 instanceof Error?error2.message:String(error2)).includes("duplicate session"))throw error2}return sessionName}async function isTeamActive(teamName){if(!await loadConfig(teamName))return!1;let{getTeam:getTeam2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),sessionName=(await getTeam2(teamName))?.tmuxSessionName??await getCurrentSessionName()??sanitizeTeamName(teamName);if(!await findSessionByName(sessionName))return!1;try{let windows=await listWindows(sessionName),sanitized=sanitizeTeamName(teamName);return windows.some((w)=>w.name===sanitized||w.name===teamName)}catch{return!1}}async function isAgentAlive(agentName){try{let{list:list2}=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry)),match=(await list2()).find((a)=>a.id===agentName||a.role===agentName);if(!match?.paneId)return!1;return resolveWorkerLivenessByTransport(match)}catch{return!1}}async function ensureTeamLead(teamName,workingDir){let{getTeam:getTeam2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),targetSession=(await getTeam2(teamName))?.tmuxSessionName??await getCurrentSessionName()??sanitizeTeamName(teamName);if(await isTeamActive(teamName))return{created:!1,session:targetSession,window:sanitizeWindowName(teamName)};let{resolveLeaderName:resolveLeaderName2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),leaderName=await resolveLeaderName2(teamName),sanitized=sanitizeTeamName(teamName),leaderAgent=await findOrCreateAgent(leaderName,sanitized,leaderName),priorSessionId=(await shouldResume(leaderAgent.id).catch(()=>null))?.sessionId??null,sessionId=priorSessionId??randomUUID6(),resumeLeader=priorSessionId!==null;await ensureNativeTeamWithSessionId(teamName,`Genie team: ${teamName}`,sessionId,leaderName),await registerNativeMember(teamName,{agentName:leaderName,agentType:"general-purpose",color:"blue",cwd:workingDir});let session=await ensureSession2(teamName),windowName=sanitizeWindowName(teamName),teamWindow=await ensureTeamWindow(session,windowName,workingDir);if(teamWindow.created){let systemPromptFile=getSystemPromptFile(workingDir),target=`${session}:${windowName}`,cdCmd=`cd ${shellQuote(workingDir)}`;await executeTmux2(`send-keys -t ${shellQuote(target)} ${shellQuote(cdCmd)} Enter`);let cmd=buildTeamLeadCommand(teamName,{systemPromptFile:systemPromptFile??void 0,leaderName,sessionId,resume:resumeLeader});await executeTmux2(`send-keys -t ${shellQuote(target)} ${shellQuote(cmd)} Enter`),await recordTeamLeadExecutor({agentId:leaderAgent.id,session,windowName,windowId:teamWindow.windowId,paneId:teamWindow.paneId,sessionId,workingDir}).catch(()=>{})}return{created:teamWindow.created,session,window:windowName}}async function recordTeamLeadExecutor(opts){await terminateActiveExecutor(opts.agentId);let pid=null;try{let target=`${opts.session}:${opts.windowName}`,pidStr=(await executeTmux2(`display -t ${shellQuote(target)} -p '#{pane_pid}'`)).trim(),parsed=Number.parseInt(pidStr,10);if(parsed>0)pid=parsed}catch{}await createAndLinkExecutor(opts.agentId,"claude","tmux",{pid,tmuxSession:opts.session,tmuxPaneId:opts.paneId,tmuxWindow:opts.windowName,tmuxWindowId:opts.windowId??null,claudeSessionId:opts.sessionId,state:"spawning",repoPath:opts.workingDir})}var init_team_auto_spawn=__esm(()=>{init_session();init_agent_registry();init_claude_native_teams();init_executor_registry();init_should_resume();init_team_lead_command();init_tmux()});var exports_inbox_watcher={};__export(exports_inbox_watcher,{stopInboxWatcher:()=>stopInboxWatcher,startInboxWatcher:()=>startInboxWatcher,resetSpawnFailures:()=>resetSpawnFailures,resetNoWorkingDirWarned:()=>resetNoWorkingDirWarned,getInboxPollIntervalMs:()=>getInboxPollIntervalMs,checkInboxes:()=>checkInboxes});function getInboxPollIntervalMs(){let env=process.env.GENIE_INBOX_POLL_MS;if(env!==void 0){if(env==="")return INBOX_POLL_INTERVAL_MS;let parsed=Number(env);if(!Number.isNaN(parsed)&&parsed>=0)return parsed}return INBOX_POLL_INTERVAL_MS}function resetSpawnFailures(){spawnFailures.clear()}function resetNoWorkingDirWarned(){noWorkingDirWarned.clear()}function resolveSessionKeyFromMessage(teamName,firstUnreadText){if(!firstUnreadText)return teamName;let header=parseRoutingHeader(firstUnreadText);return header?resolveSessionKey(teamName,header):teamName}function shouldWarnMissingWorkingDir(teamName){let now=Date.now(),lastWarned=noWorkingDirWarned.get(teamName)??0;if(now-lastWarned<NO_WORKING_DIR_RECHECK_MS)return!1;return noWorkingDirWarned.set(teamName,now),!0}async function attemptSpawn(deps,teamName,workingDir,sessionKey2,currentFailures){try{return await deps.ensureTeamLead(teamName,workingDir),spawnFailures.set(sessionKey2,0),!0}catch(err){let newCount=currentFailures+1;spawnFailures.set(sessionKey2,newCount);let message=err instanceof Error?err.message:String(err);if(deps.warn(`[inbox-watcher] Failed to spawn team-lead for "${teamName}" (attempt ${newCount}/${MAX_SPAWN_FAILURES}): ${message}`),newCount===MAX_SPAWN_FAILURES)deps.emitDeadInbox({team_name:teamName,session_key:sessionKey2,failure_count:newCount,last_error_message:message.length>2048?`${message.slice(0,2045)}...`:message});return!1}}async function checkInboxes(deps=defaultDeps2){if(getInboxPollIntervalMs()===0)return[];let teamsWithUnread=await deps.listTeamsWithUnreadInbox(),spawned=[];for(let{teamName,workingDir,firstUnreadText}of teamsWithUnread){let sessionKey2=resolveSessionKeyFromMessage(teamName,firstUnreadText),failures=spawnFailures.get(sessionKey2)??0;if(failures>=MAX_SPAWN_FAILURES){deps.warn(`[inbox-watcher] Skipping "${sessionKey2}" \u2014 ${failures} consecutive spawn failures`);continue}if(await deps.isTeamActive(teamName))continue;if(!workingDir){if(shouldWarnMissingWorkingDir(teamName))deps.warn(`[inbox-watcher] Cannot spawn team-lead for "${teamName}" \u2014 no workingDir in config`);continue}if(noWorkingDirWarned.delete(teamName),await attemptSpawn(deps,teamName,workingDir,sessionKey2,failures))spawned.push(teamName)}return spawned}function startInboxWatcher(deps=defaultDeps2){return setInterval(()=>{checkInboxes(deps).catch((err)=>{let message=err instanceof Error?err.message:String(err);deps.warn(`[inbox-watcher] Poll error: ${message}`)})},getInboxPollIntervalMs())}function stopInboxWatcher(handle){clearInterval(handle)}var defaultDeps2,INBOX_POLL_INTERVAL_MS=30000,MAX_SPAWN_FAILURES=3,NO_WORKING_DIR_RECHECK_MS=3600000,spawnFailures,noWorkingDirWarned;var init_inbox_watcher=__esm(()=>{init_claude_native_teams();init_emit();init_routing_header();init_team_auto_spawn();defaultDeps2={listTeamsWithUnreadInbox,isTeamActive:(teamName)=>isTeamActive(teamName),isAgentAlive:(agentName)=>isAgentAlive(agentName),ensureTeamLead:(teamName,workingDir)=>ensureTeamLead(teamName,workingDir),warn:(msg)=>console.warn(msg),emitDeadInbox:(payload)=>{try{emitEvent("rot.inbox-watcher-spawn-loop.detected",payload)}catch{}}};spawnFailures=new Map,noWorkingDirWarned=new Map});var exports_msg={};__export(exports_msg,{suggestRelayLeader:()=>suggestRelayLeader,resolveSenderTeams:()=>resolveSenderTeams,registerSendInboxCommands:()=>registerSendInboxCommands,printBridgeSuggestion:()=>printBridgeSuggestion,isCliSender:()=>isCliSender,detectSenderIdentity:()=>detectSenderIdentity,checkSendScope:()=>checkSendScope});import{readFile as readFile7}from"fs/promises";import{homedir as homedir26}from"os";import{join as join38}from"path";async function getRegistry(){if(!_registry)_registry=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry));return _registry}async function getTaskService(){if(!_taskService)_taskService=await Promise.resolve().then(() => (init_task_service(),exports_task_service));return _taskService}async function getTeamManager(){if(!_teamManager)_teamManager=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager));return _teamManager}async function getMailbox(){if(!_mailbox)_mailbox=await Promise.resolve().then(() => (init_mailbox(),exports_mailbox));return _mailbox}function isCliSender(sender){return sender==="cli"||sender.startsWith("cli:")}async function detectSenderIdentity(teamName){let envName=process.env.GENIE_AGENT_NAME;if(envName)return envName;let paneId=process.env.TMUX_PANE;if(!paneId)return"cli";let registry=await getRegistry(),worker=typeof registry.findByPane==="function"?await registry.findByPane(paneId):null;if(worker)return worker.role??worker.id;let resolvedTeam=teamName??process.env.GENIE_TEAM;if(resolvedTeam){let memberName=await findMemberByPane(resolvedTeam,paneId);if(memberName)return memberName}return"cli"}async function findMemberByPane(teamName,paneId){let configDir=process.env.CLAUDE_CONFIG_DIR??join38(homedir26(),".claude"),sanitized=teamName.replace(/[^a-zA-Z0-9]/g,"-").toLowerCase(),cfgPath=join38(configDir,"teams",sanitized,"config.json");try{let raw=await readFile7(cfgPath,"utf-8");return(JSON.parse(raw).members??[]).find((m)=>m.tmuxPaneId===paneId)?.name??null}catch{return null}}async function resolveLeaderAlias(recipient,teamContext){if(recipient!=="team-lead")return recipient;let teamName=teamContext??process.env.GENIE_TEAM;if(teamName)return(await getTeamManager()).resolveLeaderName(teamName);return recipient}async function checkSendScope(_repoPath,sender,recipient){if(isCliSender(sender))return null;let teams=await(await getTeamManager()).listTeams(),senderTeams=resolveSenderTeams(teams,sender);if(senderTeams.length===0)return null;for(let team of senderTeams)if(isRecipientInTeam(team,recipient))return null;let reachableChildren=resolveReachableChildren(teams,senderTeams);for(let child of reachableChildren){if(recipient===child.name)return null;if(isRecipientInTeam(child,recipient))return null}let teamNames=senderTeams.map((t)=>t.name).join(", ");return`Scope violation: "${recipient}" is not in sender's team(s): ${teamNames}`}function childReachbackAllowed(child,parent){if(parent.allowChildReachback?.some((prefix)=>child.name.startsWith(prefix)))return!0;return DEFAULT_REACHBACK_PREFIXES.some((prefix)=>child.name.startsWith(prefix))}function walkParentChain(teams,start,visited,out){let current=start,depth=0;while(current.parentTeam&&depth<PARENT_CHAIN_MAX_DEPTH){if(visited.has(current.parentTeam))return;let parent=teams.find((t)=>t.name===current.parentTeam);if(!parent)return;if(!childReachbackAllowed(current,parent))return;out.push(parent),visited.add(parent.name),current=parent,depth++}}function walkChildTeams(teams,parent,visited,out,depth){if(depth>=PARENT_CHAIN_MAX_DEPTH)return;for(let child of teams){if(visited.has(child.name))continue;if(child.parentTeam!==parent.name)continue;if(!childReachbackAllowed(child,parent))continue;out.push(child),visited.add(child.name),walkChildTeams(teams,child,visited,out,depth+1)}}function resolveReachableChildren(teams,senderTeams){let visited=new Set(senderTeams.map((t)=>t.name)),result2=[];for(let team of senderTeams)walkChildTeams(teams,team,visited,result2,0);return result2}function resolveSenderTeams(teams,sender){let direct=teams.filter((t)=>t.members.includes(sender)),visited=new Set(direct.map((t)=>t.name)),result2=[...direct];for(let team of direct)walkParentChain(teams,team,visited,result2);if(teams.some((t)=>t.leader===sender)||sender==="team-lead"){let envTeam=process.env.GENIE_TEAM;if(envTeam){let leaderTeam=teams.find((t)=>t.name===envTeam);if(leaderTeam&&!visited.has(leaderTeam.name))result2.push(leaderTeam),visited.add(leaderTeam.name),walkParentChain(teams,leaderTeam,visited,result2)}}return result2}async function suggestRelayLeader(sender){if(isCliSender(sender))return null;let teams=await(await getTeamManager()).listTeams(),reachable=resolveSenderTeams(teams,sender);if(reachable.length===0)return null;let target=reachable[0];return{leader:target.leader??target.name,team:target.name}}function isRecipientInTeam(team,recipient){if(team.members.includes(recipient)||recipient===team.leader||recipient==="team-lead")return!0;if(recipient.startsWith(`${team.name}-`)){let roleOnly=recipient.slice(team.name.length+1);if(team.members.includes(roleOnly))return!0}return!1}async function findAgentTeam(_repoPath,agentName){let teams=await(await getTeamManager()).listTeams(),memberTeam=teams.find((t)=>t.members.includes(agentName));if(memberTeam)return memberTeam;if(agentName==="team-lead"||teams.some((t)=>t.leader===agentName)){let envTeam=process.env.GENIE_TEAM;if(envTeam)return teams.find((t)=>t.name===envTeam)??null;let leaderTeam=teams.find((t)=>t.leader===agentName);if(leaderTeam)return leaderTeam}return null}function localActor(name){return{actorType:"local",actorId:name}}async function resolveTeamName2(explicit,repoPath,from){if(explicit)return explicit;let name=(await findAgentTeam(repoPath,from))?.name??process.env.GENIE_TEAM;if(!name)console.error("Error: Could not auto-detect team. Use --team <name>."),process.exit(1);return name}async function handleInbox(agent,options){let ts3=await getTaskService(),resolvedAgent=agent??await detectSenderIdentity(),actor=localActor(resolvedAgent),conversations=await ts3.listConversations(actor);if(options.json){console.log(JSON.stringify(conversations,null,2));return}if(conversations.length===0){console.log(`No conversations for "${resolvedAgent}".`);return}console.log(""),console.log(`INBOX: ${resolvedAgent}`),console.log("\u2500".repeat(60));for(let conv of conversations)await printConversationSummary(ts3,conv)}async function printConversationSummary(ts3,conv){let messages2=await ts3.getMessages(conv.id,{limit:1}),lastMsg=messages2.length>0?messages2[messages2.length-1]:null,name=conv.name??conv.id,type2=conv.type==="dm"?"DM":"Group",linked=conv.linkedEntity?` [${conv.linkedEntity}:${conv.linkedEntityId}]`:"",preview=lastMsg?truncate2(lastMsg.body,50):"(no messages)",time=lastMsg?formatTime(lastMsg.createdAt):"";if(console.log(` ${padRight(name,30)} ${padRight(type2,6)}${linked}`),lastMsg)console.log(` ${time} ${lastMsg.senderId}: ${preview}`);console.log("")}async function handleChatThread(messageId,options){let ts3=await getTaskService(),from=options.from??await detectSenderIdentity(),actor=localActor(from),parentMsgId=Number(messageId),parentMsg=await ts3.getMessage(parentMsgId);if(!parentMsg)console.error(`Error: Message not found: ${messageId}`),process.exit(1);let conv=await ts3.findOrCreateConversation({type:"group",name:options.name??`Thread on message #${parentMsgId}`,parentMessageId:parentMsgId,createdBy:actor,members:[actor]});console.log(`Thread created: ${conv.id}`),console.log(` Parent message: #${parentMsgId} in ${parentMsg.conversationId}`),console.log(` Name: ${conv.name??"(unnamed)"}`)}function printConversationTable(conversations){console.log(` ${padRight("ID",20)} ${padRight("NAME",25)} ${padRight("TYPE",8)} ${padRight("LINKED",20)} UPDATED`),console.log(` ${"\u2500".repeat(80)}`);for(let c of conversations){let name=truncate2(c.name??"(unnamed)",23),linked=c.linkedEntity?`${c.linkedEntity}:${c.linkedEntityId}`:"-",updated=formatTime(c.updatedAt);console.log(` ${padRight(c.id,20)} ${padRight(name,25)} ${padRight(c.type,8)} ${padRight(linked,20)} ${updated}`)}console.log(`
1506
1506
  ${conversations.length} conversation${conversations.length===1?"":"s"}`)}async function handleChatList(options){let ts3=await getTaskService(),from=options.from??await detectSenderIdentity(),actor=localActor(from),conversations=await ts3.listConversations(actor);if(options.type)conversations=conversations.filter((c)=>c.type===options.type);if(options.linked)conversations=conversations.filter((c)=>c.linkedEntity===options.linked);if(options.json){console.log(JSON.stringify(conversations,null,2));return}if(conversations.length===0){console.log("No conversations found.");return}printConversationTable(conversations)}async function handleChatRead(conversationId,options){let ts3=await getTaskService(),conv=await ts3.getConversation(conversationId);if(!conv)console.error(`Error: Conversation not found: ${conversationId}`),process.exit(1);let messages2=await ts3.getMessages(conversationId,{since:options.since,limit:Number(options.limit)||50});if(options.json){console.log(JSON.stringify(messages2,null,2));return}let name=conv.name??conversationId;if(messages2.length===0){console.log(`No messages in "${name}".`);return}console.log(""),console.log(`CHAT: ${name}`),console.log("\u2500".repeat(60));for(let msg of messages2){let time=formatTime(msg.createdAt),reply=msg.replyToId?` (reply to #${msg.replyToId})`:"";console.log(` [${time}] ${msg.senderId}: ${msg.body}${reply}`)}console.log("")}async function discoverCurrentTeam(nativeTeams,from,explicitTeam){if(explicitTeam)return explicitTeam;let discovered=await nativeTeams.discoverTeamName().catch(()=>null);if(discovered)return discovered;return(await(await getRegistry()).list()).find((w)=>w.role===from||w.id===from||w.customName===from)?.team??null}async function deliverToTeam(nativeTeams,team,recipient,msg){let nativeName=await nativeTeams.resolveNativeMemberName(team,recipient);if(!nativeName)return!1;return await nativeTeams.writeNativeInbox(team,nativeName,msg),!0}async function bridgeToNativeInbox(from,recipient,body,explicitTeam){if(from===recipient)return!1;let nativeTeams=await Promise.resolve().then(() => (init_claude_native_teams(),exports_claude_native_teams)),nativeMsg={from,text:body,summary:body.length>50?`${body.substring(0,50)}...`:body,timestamp:new Date().toISOString(),color:"blue",read:!1},currentTeam=await discoverCurrentTeam(nativeTeams,from,explicitTeam);if(currentTeam&&await deliverToTeam(nativeTeams,currentTeam,recipient,nativeMsg))return!0;let allTeams=await nativeTeams.listTeams().catch(()=>[]);for(let team of allTeams){if(team===currentTeam)continue;if(await deliverToTeam(nativeTeams,team,recipient,nativeMsg))return!0}return console.warn(`[genie send] Native inbox bridge: could not find native team member for "${recipient}"`),!1}function quoteForShell(value){return`'${value.replace(/'/g,"'\\''")}'`}async function printBridgeSuggestion(sender,recipient,body,scopeError){let suggestion=await suggestRelayLeader(sender);if(console.error(`Scope violation: ${scopeError}`),!suggestion){console.error("No reachable leader found \u2014 sender is not bound to any team.");return}if(suggestion.leader===sender){console.error(`You are already the nearest reachable leader (${suggestion.leader}@${suggestion.team}) \u2014 no external relay path available.`);return}console.error(`Nearest reachable leader: ${suggestion.leader}@${suggestion.team}`),console.error("Relay manually via:"),console.error(` genie send ${quoteForShell(`[relay to ${recipient}] ${body}`)} --to ${suggestion.leader} --team ${suggestion.team}`)}async function handleSend(body,options){let ts3=await getTaskService(),mailbox=await getMailbox(),repoPath=process.cwd(),from=options.from??await detectSenderIdentity(options.team),to=await resolveLeaderAlias(options.to,options.team),scopeError=await checkSendScope(repoPath,from,to);if(scopeError){if(options.bridge){await printBridgeSuggestion(from,to,body,scopeError);return}console.error(`Error: ${scopeError}`),process.exit(1)}let senderActor=localActor(from),recipientActor=localActor(to),conv=await ts3.findOrCreateConversation({type:"dm",members:[senderActor,recipientActor],createdBy:senderActor});await ts3.addMember(conv.id,senderActor),await ts3.addMember(conv.id,recipientActor);let mailboxMessage=await mailbox.send(repoPath,from,to,body),msg=await ts3.sendMessage(conv.id,senderActor,body);try{let{publishSubjectEvent:publishSubjectEvent2}=await Promise.resolve().then(() => (init_runtime_events(),exports_runtime_events));await publishSubjectEvent2(repoPath,`genie.msg.${to}`,{kind:"message",agent:from,direction:"out",peer:to,text:body,data:{messageId:msg.id,conversationId:conv.id,from,to},source:"mailbox"})}catch{}if(await bridgeToNativeInbox(from,to,body,options.team).catch((err)=>{let reason=err instanceof Error?err.message:String(err);return console.warn(`[genie send] Native inbox bridge failed: ${reason}`),!1}))await mailbox.markDelivered(repoPath,to,mailboxMessage.id).catch(()=>{});console.log(`Message sent to "${to}".`),console.log(` ID: ${msg.id}`),console.log(` Conversation: ${conv.id}`)}function registerSendInboxCommands(program2){program2.command("send <body>").description("Send a direct message to an agent (PG-backed)").option("--to <agent>","Recipient agent name (default: team leader)","team-lead").option("--from <sender>","Sender ID (auto-detected from context)").option("--team <name>","Explicit team context for sender/recipient resolution").option("--bridge","On scope violation, print an advisory + relay command instead of failing (exit 0)").addHelpText("after",`
1507
1507
  Examples:
1508
1508
  genie send 'start task #3' --to engineer # Message a specific agent
@@ -2785,24 +2785,24 @@ Return ONLY a bulleted list of relevant excerpts with their source file paths.
2785
2785
  Keep it under 500 words. If nothing is relevant, say "No relevant prior context."`;try{let result2=execSync14(`rlmx ${shellQuote4(rlmxQuery)} --context ${shellQuote4(brainPath)} --output json --max-iterations ${maxIterations} --max-cost ${maxCost}`,{encoding:"utf-8",timeout,env:{...process.env},stdio:["pipe","pipe","pipe"]}),answer=JSON.parse(result2).answer?.trim();if(!answer||answer==="No relevant prior context."||answer.length<20)return"";return`## Prior Context (from brain vault)
2786
2786
 
2787
2787
  ${answer}
2788
- `}catch{return""}}function shellQuote4(s2){return`'${s2.replace(/'/g,"'\\''")}'`}var init_context_enrichment=()=>{};import{execSync as execSync15}from"child_process";import{existsSync as existsSync51}from"fs";import{mkdir as mkdir7,readFile as readFile13,writeFile as writeFile7}from"fs/promises";import{tmpdir as tmpdir3}from"os";import{join as join60}from"path";async function writeContextFile(content){let dir=join60(tmpdir3(),"genie-dispatch");await mkdir7(dir,{recursive:!0});let ts3=Date.now().toString(36),rand=Math.random().toString(36).slice(2,8),filePath=join60(dir,`ctx-${ts3}-${rand}.md`);return await writeFile7(filePath,content),filePath}function extractGroup(content,groupName){let pattern=new RegExp(`^### Group ${escapeRegExp(groupName)}:`,"m"),match=content.match(pattern);if(!match||match.index===void 0)return null;let start3=match.index,nextBoundary=content.slice(start3).slice(1).search(/^### Group \d|^---$/m),end=nextBoundary!==-1?start3+1+nextBoundary:content.length;return content.slice(start3,end).trim()}function extractWishContext(content){let execGroupsIdx=content.indexOf("## Execution Groups");if(execGroupsIdx!==-1)return content.slice(0,execGroupsIdx).trim();return content.slice(0,2000).trim()}function validateSlug(slug){if(!SLUG_PATTERN.test(slug))console.error(`\u274C Invalid slug: "${slug}"`),console.error(" Slugs must match [a-zA-Z0-9._-]+ (no slashes, dots-dots, or special characters)"),process.exit(1)}function escapeRegExp(str5){return str5.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function buildContextPrompt(opts){let parts=[`# Dispatch Context (${opts.command})`,"",`**Source file:** \`${opts.filePath}\``,"(Read the full document at the path above for complete context)",""];if(opts.wishContext)parts.push("## Wish Context","",opts.wishContext,"");if(parts.push("## Assigned Section","",opts.sectionContent,""),opts.enrichedContext)parts.push(opts.enrichedContext);if(opts.skill)parts.push("## Initial Command","",`Run \`/${opts.skill}\` to begin.`,"");return parts.join(`
2788
+ `}catch{return""}}function shellQuote4(s2){return`'${s2.replace(/'/g,"'\\''")}'`}var init_context_enrichment=()=>{};import{execSync as execSync15}from"child_process";import{existsSync as existsSync51}from"fs";import{mkdir as mkdir7,readFile as readFile13,writeFile as writeFile7}from"fs/promises";import{tmpdir as tmpdir3}from"os";import{join as join60}from"path";async function cliSender(){let origin=await detectSenderIdentity();return origin==="cli"?"cli":`cli:${origin}`}async function writeContextFile(content){let dir=join60(tmpdir3(),"genie-dispatch");await mkdir7(dir,{recursive:!0});let ts3=Date.now().toString(36),rand=Math.random().toString(36).slice(2,8),filePath=join60(dir,`ctx-${ts3}-${rand}.md`);return await writeFile7(filePath,content),filePath}function extractGroup(content,groupName){let pattern=new RegExp(`^### Group ${escapeRegExp(groupName)}:`,"m"),match=content.match(pattern);if(!match||match.index===void 0)return null;let start3=match.index,nextBoundary=content.slice(start3).slice(1).search(/^### Group \d|^---$/m),end=nextBoundary!==-1?start3+1+nextBoundary:content.length;return content.slice(start3,end).trim()}function extractWishContext(content){let execGroupsIdx=content.indexOf("## Execution Groups");if(execGroupsIdx!==-1)return content.slice(0,execGroupsIdx).trim();return content.slice(0,2000).trim()}function validateSlug(slug){if(!SLUG_PATTERN.test(slug))console.error(`\u274C Invalid slug: "${slug}"`),console.error(" Slugs must match [a-zA-Z0-9._-]+ (no slashes, dots-dots, or special characters)"),process.exit(1)}function escapeRegExp(str5){return str5.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function buildContextPrompt(opts){let parts=[`# Dispatch Context (${opts.command})`,"",`**Source file:** \`${opts.filePath}\``,"(Read the full document at the path above for complete context)",""];if(opts.wishContext)parts.push("## Wish Context","",opts.wishContext,"");if(parts.push("## Assigned Section","",opts.sectionContent,""),opts.enrichedContext)parts.push(opts.enrichedContext);if(opts.skill)parts.push("## Initial Command","",`Run \`/${opts.skill}\` to begin.`,"");return parts.join(`
2789
2789
  `)}function getGitDiff(){try{let diff=execSync15("git diff HEAD",{encoding:"utf-8",maxBuffer:1048576}),staged=execSync15("git diff --cached",{encoding:"utf-8",maxBuffer:1048576}),combined=[diff,staged].filter(Boolean).join(`
2790
2790
  `);if(combined.length>50000)return`${combined.slice(0,50000)}
2791
2791
 
2792
2792
  ... (diff truncated at 50KB)`;return combined}catch{return""}}function parseWishGroups(content){let groups=[],groupPattern=/^### Group ([A-Za-z0-9]+):/gim,match=groupPattern.exec(content);while(match!==null){let name=match[1],start3=match.index,rest=content.slice(start3+match[0].length),nextGroupIdx=rest.search(/^### Group [A-Za-z0-9]+:/m),depsMatch=(nextGroupIdx!==-1?rest.slice(0,nextGroupIdx):rest).match(/\*\*depends-on:\*\*\s*(.+)/i),dependsOn=[];if(depsMatch){let depsNormalized=depsMatch[1].trim().replace(/\s*\([^)]*\)/g,"").trim();if(depsNormalized.toLowerCase()!=="none")dependsOn=depsNormalized.split(",").map((d)=>d.trim().replace(/^groups?\s*/i,"").trim()).filter(Boolean)}groups.push({name,dependsOn}),match=groupPattern.exec(content)}return groups}function parseExecutionStrategy(content){let strategyMatch=content.match(/^## Execution Strategy\s*$/m);if(!strategyMatch||strategyMatch.index===void 0)return buildFallbackWaves(content);let strategyStart=strategyMatch.index+strategyMatch[0].length,nextSectionMatch=content.slice(strategyStart).match(/^## /m),strategyEnd=nextSectionMatch?.index!==void 0?strategyStart+nextSectionMatch.index:content.length,strategyContent=content.slice(strategyStart,strategyEnd),waves=[],wavePattern=/^### (Wave \d+[^\n]*)/gm,waveMatch=wavePattern.exec(strategyContent);while(waveMatch!==null){let waveName=waveMatch[1].trim(),waveStart=waveMatch.index+waveMatch[0].length,nextWaveIdx=strategyContent.slice(waveStart).search(/^### /m),waveEnd=nextWaveIdx!==-1?waveStart+nextWaveIdx:strategyContent.length,waveContent=strategyContent.slice(waveStart,waveEnd),waveGroups=[],tableRowPattern=/^\|\s*([^|]+?)\s*\|\s*([^|]+?)\s*\|\s*[^|]*\s*\|$/gm,rowMatch=tableRowPattern.exec(waveContent);while(rowMatch!==null){let groupVal=rowMatch[1].trim(),agentVal=rowMatch[2].trim();if(groupVal!=="Group"&&!groupVal.startsWith("-"))waveGroups.push({group:groupVal,agent:agentVal});rowMatch=tableRowPattern.exec(waveContent)}if(waveGroups.length>0)waves.push({name:waveName,groups:waveGroups});waveMatch=wavePattern.exec(strategyContent)}if(waves.length===0)return buildFallbackWaves(content);return waves}function buildFallbackWaves(content){let groups=parseWishGroups(content);if(groups.length===0)return[];return[{name:"Wave 1 (sequential fallback)",groups:groups.map((g)=>({group:g.name,agent:"engineer"}))}]}async function resolveLeaderTarget(){let teamName=process.env.GENIE_TEAM;if(!teamName)return"team-lead";try{let{resolveLeaderName:resolveLeaderName2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager));return await resolveLeaderName2(teamName)}catch{return teamName}}function detectWorkMode(ref,agent){if(!agent){if(ref.includes("#"))throw Error("Manual dispatch requires an agent: genie work <slug>#<group> <agent>");return{mode:"auto",slug:ref}}if(ref.includes("#"))return{mode:"manual",ref,agent};if(agent.includes("#"))return{mode:"manual",ref:agent,agent:ref};throw Error('Invalid: ref must contain "#" \u2014 use "genie work <slug>" or "genie work <agent> <slug>#<group>"')}async function autoOrchestrateCommand(slug){let wishPath,actualSlug=slug;if(parseWishRef(slug).namespace){let resolved=await resolveWish(slug);wishPath=resolved.wishPath,actualSlug=resolved.slug;let{handleTeamCreate:handleTeamCreate2}=await Promise.resolve().then(() => (init_team(),exports_team));await handleTeamCreate2(actualSlug,{repo:resolved.repo,branch:"dev",wish:actualSlug,tmuxSession:resolved.session});return}if(validateSlug(slug),wishPath=join60(process.cwd(),".genie","wishes",slug,"WISH.md"),!existsSync51(wishPath))console.error(`\u274C Wish not found: ${wishPath}`),console.error(` Create it first: genie wish <agent> ${slug}`),process.exit(1);Promise.resolve().then(() => (init_wish_sync(),exports_wish_sync)).then((ws)=>ws.syncWishes(process.cwd())).catch(()=>{});let content=await readFile13(wishPath,"utf-8"),groups=parseWishGroups(content),waves=parseExecutionStrategy(content);if(waves.length===0)console.error("\u274C No execution groups found in wish"),process.exit(1);let state=await getOrCreateState(slug,groups),nextWave=waves.find((wave)=>wave.groups.some((g)=>{let gs=state?.groups[g.group];return!gs||gs.status==="ready"}));if(!nextWave){console.log(`\u2705 All waves already dispatched for wish "${slug}"`);return}console.log(`\uD83D\uDE80 Dispatching ${nextWave.name} for wish "${slug}" \u2014 ${nextWave.groups.length} group(s)`);let results=await Promise.allSettled(nextWave.groups.map(({group,agent})=>{let ref=`${slug}#${group}`;return workDispatchCommand(agent,ref)})),succeeded=[],failed=[];if(results.forEach((r,i2)=>{let groupName=nextWave.groups[i2].group;if(r.status==="fulfilled")succeeded.push(groupName);else{let reason=r.reason instanceof Error?r.reason.message:String(r.reason);failed.push({group:groupName,reason})}}),succeeded.length>0)console.log(`
2793
2793
  \u2705 Agents dispatched for ${nextWave.name} (groups: ${succeeded.join(", ")})`);if(failed.length>0){console.error(`
2794
- \u274C ${failed.length} group(s) failed to dispatch in ${nextWave.name}:`);for(let{group,reason}of failed)console.error(` \u2022 Group ${group}: ${reason}`);console.error(` Check state with: genie status ${slug}`),console.error(" Some groups may have mutated state before failing \u2014 rerun genie work to retry.")}if(console.log(` Monitor: genie status ${slug}`),console.log(" Logs: genie read <agent>"),failed.length>0)process.exitCode=1}async function brainstormCommand(agentName,slug){validateSlug(slug);let draftPath=join60(process.cwd(),".genie","brainstorms",slug,"DRAFT.md");if(!existsSync51(draftPath))console.error(`\u274C Draft not found: ${draftPath}`),console.error(` Create it first: mkdir -p .genie/brainstorms/${slug} && touch .genie/brainstorms/${slug}/DRAFT.md`),process.exit(1);let content=await readFile13(draftPath,"utf-8"),context=buildContextPrompt({filePath:draftPath,sectionContent:content,command:"brainstorm",skill:"brainstorm"}),contextFile=await writeContextFile(context);console.log(`\uD83D\uDCDD Dispatching brainstorm to ${agentName} for "${slug}"`),console.log(` Draft: ${draftPath}`);let brainstormPrompt=`Brainstorm "${slug}". Your context is in the system prompt. Explore the idea, ask clarifying questions, and build toward a design.`;await handleWorkerSpawn(agentName,{provider:"claude",extraArgs:["--append-system-prompt-file",contextFile],initialPrompt:brainstormPrompt});let repoPath=process.cwd(),result2=await sendMessage2(repoPath,"cli",agentName,brainstormPrompt);if(!result2.delivered)console.warn(`\u26A0 Backup delivery to ${agentName} failed: ${result2.reason??"unknown"}`)}async function wishCommand(agentName,slug){validateSlug(slug);let designPath=join60(process.cwd(),".genie","brainstorms",slug,"DESIGN.md");if(!existsSync51(designPath))console.error(`\u274C Design not found: ${designPath}`),console.error(` Run brainstorm first: genie brainstorm <agent> ${slug}`),process.exit(1);let content=await readFile13(designPath,"utf-8"),context=buildContextPrompt({filePath:designPath,sectionContent:content,command:"wish",skill:"wish"}),contextFile=await writeContextFile(context);console.log(`\uD83D\uDCDD Dispatching wish to ${agentName} for "${slug}"`),console.log(` Design: ${designPath}`);let wishPrompt=`Create a wish from the design for "${slug}". Your context is in the system prompt. Write the WISH.md with execution groups, acceptance criteria, and validation commands.`;await handleWorkerSpawn(agentName,{provider:"claude",extraArgs:["--append-system-prompt-file",contextFile],initialPrompt:wishPrompt});let repoPath=process.cwd(),result2=await sendMessage2(repoPath,"cli",agentName,wishPrompt);if(!result2.delivered)console.warn(`\u26A0 Backup delivery to ${agentName} failed: ${result2.reason??"unknown"}`)}async function workDispatchCommand(agentName,ref){let{slug,group}=parseRef(ref);validateSlug(slug);let wishPath=join60(process.cwd(),".genie","wishes",slug,"WISH.md"),dispatchSpan=isWideEmitEnabled()?startSpan("wish.dispatch",{wish_slug:slug,group_name:group},{source_subsystem:"dispatch",ctx:getAmbient()??void 0,agent:agentName}):null;try{if(await runWorkDispatch(slug,group,agentName,wishPath,ref),dispatchSpan)endSpan(dispatchSpan,{outcome:"completed"},{source_subsystem:"dispatch",agent:agentName})}catch(err){if(dispatchSpan)endSpan(dispatchSpan,{outcome:"failed"},{source_subsystem:"dispatch",agent:agentName});throw err}}async function runWorkDispatch(slug,group,agentName,wishPath,ref){if(!existsSync51(wishPath))console.error(`\u274C Wish not found: ${wishPath}`),console.error(` Create it first: genie wish <agent> ${slug}`),process.exit(1);let content=await readFile13(wishPath,"utf-8"),groupSection=extractGroup(content,group);if(!groupSection){console.error(`\u274C Group "${group}" not found in ${wishPath}`),console.error(" Available groups:");let groups2=content.match(/^### Group [A-Za-z0-9]+:.*$/gm);if(groups2)for(let g of groups2)console.error(` ${g}`);process.exit(1)}let groups=parseWishGroups(content);await getOrCreateState(slug,groups);try{await startGroup(slug,group,agentName),console.log(`\u2705 Group "${group}" set to in_progress (assigned to ${agentName})`)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`\u274C ${message}`),process.exit(1)}let wishContext=extractWishContext(content),enrichedContext;try{let{enrichContext:enrichContext2}=await Promise.resolve().then(() => (init_context_enrichment(),exports_context_enrichment));enrichedContext=enrichContext2({query:`${slug} ${group}: ${groupSection.slice(0,500)}`})||void 0}catch{}let context=buildContextPrompt({filePath:wishPath,sectionContent:groupSection,wishContext,command:`work ${ref}`,skill:"work",enrichedContext}),contextFile=await writeContextFile(context);console.log(`\uD83D\uDD27 Dispatching work to ${agentName} for "${ref}"`),console.log(` Wish: ${wishPath}`),console.log(` Group: ${group}`);let effectiveRole=`${agentName}-${group}`,leaderTarget=await resolveLeaderTarget(),workPrompt=`Execute Group ${group} of wish "${slug}". Your full context is in the system prompt. Read the wish at ${wishPath} if needed. Implement all deliverables, run validation, and report completion.
2794
+ \u274C ${failed.length} group(s) failed to dispatch in ${nextWave.name}:`);for(let{group,reason}of failed)console.error(` \u2022 Group ${group}: ${reason}`);console.error(` Check state with: genie status ${slug}`),console.error(" Some groups may have mutated state before failing \u2014 rerun genie work to retry.")}if(console.log(` Monitor: genie status ${slug}`),console.log(" Logs: genie read <agent>"),failed.length>0)process.exitCode=1}async function brainstormCommand(agentName,slug){validateSlug(slug);let draftPath=join60(process.cwd(),".genie","brainstorms",slug,"DRAFT.md");if(!existsSync51(draftPath))console.error(`\u274C Draft not found: ${draftPath}`),console.error(` Create it first: mkdir -p .genie/brainstorms/${slug} && touch .genie/brainstorms/${slug}/DRAFT.md`),process.exit(1);let content=await readFile13(draftPath,"utf-8"),context=buildContextPrompt({filePath:draftPath,sectionContent:content,command:"brainstorm",skill:"brainstorm"}),contextFile=await writeContextFile(context);console.log(`\uD83D\uDCDD Dispatching brainstorm to ${agentName} for "${slug}"`),console.log(` Draft: ${draftPath}`);let brainstormPrompt=`Brainstorm "${slug}". Your context is in the system prompt. Explore the idea, ask clarifying questions, and build toward a design.`;await handleWorkerSpawn(agentName,{provider:"claude",extraArgs:["--append-system-prompt-file",contextFile],initialPrompt:brainstormPrompt});let repoPath=process.cwd(),result2=await sendMessage2(repoPath,await cliSender(),agentName,brainstormPrompt);if(!result2.delivered)console.warn(`\u26A0 Backup delivery to ${agentName} failed: ${result2.reason??"unknown"}`)}async function wishCommand(agentName,slug){validateSlug(slug);let designPath=join60(process.cwd(),".genie","brainstorms",slug,"DESIGN.md");if(!existsSync51(designPath))console.error(`\u274C Design not found: ${designPath}`),console.error(` Run brainstorm first: genie brainstorm <agent> ${slug}`),process.exit(1);let content=await readFile13(designPath,"utf-8"),context=buildContextPrompt({filePath:designPath,sectionContent:content,command:"wish",skill:"wish"}),contextFile=await writeContextFile(context);console.log(`\uD83D\uDCDD Dispatching wish to ${agentName} for "${slug}"`),console.log(` Design: ${designPath}`);let wishPrompt=`Create a wish from the design for "${slug}". Your context is in the system prompt. Write the WISH.md with execution groups, acceptance criteria, and validation commands.`;await handleWorkerSpawn(agentName,{provider:"claude",extraArgs:["--append-system-prompt-file",contextFile],initialPrompt:wishPrompt});let repoPath=process.cwd(),result2=await sendMessage2(repoPath,await cliSender(),agentName,wishPrompt);if(!result2.delivered)console.warn(`\u26A0 Backup delivery to ${agentName} failed: ${result2.reason??"unknown"}`)}async function workDispatchCommand(agentName,ref){let{slug,group}=parseRef(ref);validateSlug(slug);let wishPath=join60(process.cwd(),".genie","wishes",slug,"WISH.md"),dispatchSpan=isWideEmitEnabled()?startSpan("wish.dispatch",{wish_slug:slug,group_name:group},{source_subsystem:"dispatch",ctx:getAmbient()??void 0,agent:agentName}):null;try{if(await runWorkDispatch(slug,group,agentName,wishPath,ref),dispatchSpan)endSpan(dispatchSpan,{outcome:"completed"},{source_subsystem:"dispatch",agent:agentName})}catch(err){if(dispatchSpan)endSpan(dispatchSpan,{outcome:"failed"},{source_subsystem:"dispatch",agent:agentName});throw err}}async function runWorkDispatch(slug,group,agentName,wishPath,ref){if(!existsSync51(wishPath))console.error(`\u274C Wish not found: ${wishPath}`),console.error(` Create it first: genie wish <agent> ${slug}`),process.exit(1);let content=await readFile13(wishPath,"utf-8"),groupSection=extractGroup(content,group);if(!groupSection){console.error(`\u274C Group "${group}" not found in ${wishPath}`),console.error(" Available groups:");let groups2=content.match(/^### Group [A-Za-z0-9]+:.*$/gm);if(groups2)for(let g of groups2)console.error(` ${g}`);process.exit(1)}let groups=parseWishGroups(content);await getOrCreateState(slug,groups);try{await startGroup(slug,group,agentName),console.log(`\u2705 Group "${group}" set to in_progress (assigned to ${agentName})`)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`\u274C ${message}`),process.exit(1)}let wishContext=extractWishContext(content),enrichedContext;try{let{enrichContext:enrichContext2}=await Promise.resolve().then(() => (init_context_enrichment(),exports_context_enrichment));enrichedContext=enrichContext2({query:`${slug} ${group}: ${groupSection.slice(0,500)}`})||void 0}catch{}let context=buildContextPrompt({filePath:wishPath,sectionContent:groupSection,wishContext,command:`work ${ref}`,skill:"work",enrichedContext}),contextFile=await writeContextFile(context);console.log(`\uD83D\uDD27 Dispatching work to ${agentName} for "${ref}"`),console.log(` Wish: ${wishPath}`),console.log(` Group: ${group}`);let effectiveRole=`${agentName}-${group}`,leaderTarget=await resolveLeaderTarget(),workPrompt=`Execute Group ${group} of wish "${slug}". Your full context is in the system prompt. Read the wish at ${wishPath} if needed. Implement all deliverables, run validation, and report completion.
2795
2795
 
2796
2796
  When done:
2797
2797
  1. Run: genie done ${slug}#${group}
2798
- 2. Run: genie send 'Group ${group} complete. <summary>' --to ${leaderTarget}`;await handleWorkerSpawn(agentName,{provider:"claude",team:process.env.GENIE_TEAM,role:effectiveRole,extraArgs:["--append-system-prompt-file",contextFile],initialPrompt:workPrompt});let repoPath=process.cwd(),result2=await sendMessage2(repoPath,"cli",effectiveRole,workPrompt);if(!result2.delivered)console.warn(`\u26A0 Backup delivery to ${effectiveRole} failed: ${result2.reason??"unknown"}`)}async function reviewCommand(agentName,ref){let{slug,group}=parseRef(ref);validateSlug(slug);let wishPath=join60(process.cwd(),".genie","wishes",slug,"WISH.md");if(!existsSync51(wishPath))console.error(`\u274C Wish not found: ${wishPath}`),process.exit(1);let content=await readFile13(wishPath,"utf-8"),groupSection=extractGroup(content,group);if(!groupSection)console.error(`\u274C Group "${group}" not found in ${wishPath}`),process.exit(1);let diff=getGitDiff(),wishContext=extractWishContext(content),reviewContent=[groupSection,"","## Git Diff (changes to review)","",diff?`\`\`\`diff
2798
+ 2. Run: genie send 'Group ${group} complete. <summary>' --to ${leaderTarget}`;await handleWorkerSpawn(agentName,{provider:"claude",team:process.env.GENIE_TEAM,role:effectiveRole,extraArgs:["--append-system-prompt-file",contextFile],initialPrompt:workPrompt});let repoPath=process.cwd(),result2=await sendMessage2(repoPath,await cliSender(),effectiveRole,workPrompt);if(!result2.delivered)console.warn(`\u26A0 Backup delivery to ${effectiveRole} failed: ${result2.reason??"unknown"}`)}async function reviewCommand(agentName,ref){let{slug,group}=parseRef(ref);validateSlug(slug);let wishPath=join60(process.cwd(),".genie","wishes",slug,"WISH.md");if(!existsSync51(wishPath))console.error(`\u274C Wish not found: ${wishPath}`),process.exit(1);let content=await readFile13(wishPath,"utf-8"),groupSection=extractGroup(content,group);if(!groupSection)console.error(`\u274C Group "${group}" not found in ${wishPath}`),process.exit(1);let diff=getGitDiff(),wishContext=extractWishContext(content),reviewContent=[groupSection,"","## Git Diff (changes to review)","",diff?`\`\`\`diff
2799
2799
  ${diff}
2800
2800
  \`\`\``:"(no uncommitted changes found \u2014 review committed changes)"].join(`
2801
2801
  `),enrichedReviewContext;try{let{enrichContext:enrichContext2}=await Promise.resolve().then(() => (init_context_enrichment(),exports_context_enrichment));enrichedReviewContext=enrichContext2({query:`review ${slug} ${group}: ${groupSection.slice(0,500)}`})||void 0}catch{}let context=buildContextPrompt({filePath:wishPath,sectionContent:reviewContent,wishContext,command:`review ${ref}`,skill:"review",enrichedContext:enrichedReviewContext}),contextFile=await writeContextFile(context);if(console.log(`\uD83D\uDD0D Dispatching review to ${agentName} for "${ref}"`),console.log(` Wish: ${wishPath}`),console.log(` Group: ${group}`),diff)console.log(` Diff: ${diff.split(`
2802
2802
  `).length} lines`);let reviewLeaderTarget=await resolveLeaderTarget(),reviewPrompt=`Review "${ref}". Your context and diff are in the system prompt. Evaluate against acceptance criteria and return SHIP, FIX-FIRST, or BLOCKED with severity-tagged findings.
2803
2803
 
2804
2804
  When done, report your verdict:
2805
- Run: genie send '<SHIP|FIX-FIRST|BLOCKED> \u2014 <summary>' --to ${reviewLeaderTarget}`;await handleWorkerSpawn(agentName,{provider:"claude",team:process.env.GENIE_TEAM,extraArgs:["--append-system-prompt-file",contextFile],initialPrompt:reviewPrompt});let repoPath=process.cwd(),result2=await sendMessage2(repoPath,"cli",agentName,reviewPrompt);if(!result2.delivered)console.warn(`\u26A0 Backup delivery to ${agentName} failed: ${result2.reason??"unknown"}`)}function registerDispatchCommands(program2){program2.command("work <ref> [agent]").description("Auto-orchestrate a wish, or dispatch work on a specific group").action(async(ref,agent)=>{try{let work=detectWorkMode(ref,agent);if(work.mode==="auto")await autoOrchestrateCommand(work.slug);else await workDispatchCommand(work.agent,work.ref)}catch(error2){console.error(`\u274C ${error2 instanceof Error?error2.message:error2}`),process.exit(1)}})}var SLUG_PATTERN;var init_dispatch=__esm(()=>{init_emit();init_protocol_router();init_trace_context();init_wish_resolve();init_wish_state();init_agents();init_state();SLUG_PATTERN=/^[a-zA-Z0-9._-]+$/});var exports_export_format={};__export(exports_export_format,{validateExportDocument:()=>validateExportDocument,createExportDocument:()=>createExportDocument,GROUP_TABLES:()=>GROUP_TABLES,EXPORT_VERSION:()=>EXPORT_VERSION,ALL_GROUPS:()=>ALL_GROUPS});function createExportDocument(type2,groups,genieVersion,actor){return{version:"1.0",exportedAt:new Date().toISOString(),exportedBy:actor,genieVersion,type:type2,groups,skippedTables:[],data:{}}}function validateExportDocument(obj){if(!obj||typeof obj!=="object")return{valid:!1,error:"Not a valid JSON object"};let doc=obj;if(doc.version!=="1.0")return{valid:!1,error:`Unsupported version: ${doc.version} (expected 1.0)`};if(!doc.exportedAt||typeof doc.exportedAt!=="string")return{valid:!1,error:"Missing or invalid exportedAt"};if(!doc.data||typeof doc.data!=="object")return{valid:!1,error:"Missing or invalid data"};return{valid:!0,doc}}var EXPORT_VERSION="1.0",GROUP_TABLES,ALL_GROUPS;var init_export_format=__esm(()=>{GROUP_TABLES={boards:["boards","board_templates","task_types"],tasks:["tasks","task_tags","task_actors","task_dependencies","task_stage_log"],tags:["tags"],projects:["projects"],schedules:["schedules"],agents:["agents","agent_templates","agent_checkpoints"],comms:["conversations","conversation_members","messages","mailbox","team_chat","notification_preferences"],config:["os_config","instances","warm_pool","golden_images"]},ALL_GROUPS=["boards","tasks","tags","projects","schedules","agents","comms","config"]});var exports_table_detect={};__export(exports_table_detect,{filterAvailableTables:()=>filterAvailableTables});async function getAvailableTables(sql){return(await sql`
2805
+ Run: genie send '<SHIP|FIX-FIRST|BLOCKED> \u2014 <summary>' --to ${reviewLeaderTarget}`;await handleWorkerSpawn(agentName,{provider:"claude",team:process.env.GENIE_TEAM,extraArgs:["--append-system-prompt-file",contextFile],initialPrompt:reviewPrompt});let repoPath=process.cwd(),result2=await sendMessage2(repoPath,await cliSender(),agentName,reviewPrompt);if(!result2.delivered)console.warn(`\u26A0 Backup delivery to ${agentName} failed: ${result2.reason??"unknown"}`)}function registerDispatchCommands(program2){program2.command("work <ref> [agent]").description("Auto-orchestrate a wish, or dispatch work on a specific group").action(async(ref,agent)=>{try{let work=detectWorkMode(ref,agent);if(work.mode==="auto")await autoOrchestrateCommand(work.slug);else await workDispatchCommand(work.agent,work.ref)}catch(error2){console.error(`\u274C ${error2 instanceof Error?error2.message:error2}`),process.exit(1)}})}var SLUG_PATTERN;var init_dispatch=__esm(()=>{init_emit();init_protocol_router();init_trace_context();init_wish_resolve();init_msg();init_wish_state();init_agents();init_state();SLUG_PATTERN=/^[a-zA-Z0-9._-]+$/});var exports_export_format={};__export(exports_export_format,{validateExportDocument:()=>validateExportDocument,createExportDocument:()=>createExportDocument,GROUP_TABLES:()=>GROUP_TABLES,EXPORT_VERSION:()=>EXPORT_VERSION,ALL_GROUPS:()=>ALL_GROUPS});function createExportDocument(type2,groups,genieVersion,actor){return{version:"1.0",exportedAt:new Date().toISOString(),exportedBy:actor,genieVersion,type:type2,groups,skippedTables:[],data:{}}}function validateExportDocument(obj){if(!obj||typeof obj!=="object")return{valid:!1,error:"Not a valid JSON object"};let doc=obj;if(doc.version!=="1.0")return{valid:!1,error:`Unsupported version: ${doc.version} (expected 1.0)`};if(!doc.exportedAt||typeof doc.exportedAt!=="string")return{valid:!1,error:"Missing or invalid exportedAt"};if(!doc.data||typeof doc.data!=="object")return{valid:!1,error:"Missing or invalid data"};return{valid:!0,doc}}var EXPORT_VERSION="1.0",GROUP_TABLES,ALL_GROUPS;var init_export_format=__esm(()=>{GROUP_TABLES={boards:["boards","board_templates","task_types"],tasks:["tasks","task_tags","task_actors","task_dependencies","task_stage_log"],tags:["tags"],projects:["projects"],schedules:["schedules"],agents:["agents","agent_templates","agent_checkpoints"],comms:["conversations","conversation_members","messages","mailbox","team_chat","notification_preferences"],config:["os_config","instances","warm_pool","golden_images"]},ALL_GROUPS=["boards","tasks","tags","projects","schedules","agents","comms","config"]});var exports_table_detect={};__export(exports_table_detect,{filterAvailableTables:()=>filterAvailableTables});async function getAvailableTables(sql){return(await sql`
2806
2806
  SELECT table_name
2807
2807
  FROM information_schema.tables
2808
2808
  WHERE table_schema = current_schema()
@@ -3863,7 +3863,7 @@ ${yamlStr}---`)}function buildDirResolveContext(agentName){let ctx={};try{let ws
3863
3863
  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.
3864
3864
  `);return}if(entries.length>0)printRegisteredTable(entries),printResolvedTable(entries);if(includeBuiltins)printBuiltinsTable()}function listEntriesJson(entries,includeBuiltins){let result2=entries.map((e)=>({...e,builtin:!1}));if(includeBuiltins)for(let b2 of ALL_BUILTINS)result2.push({name:b2.name,description:b2.description,model:b2.model,category:b2.category,scope:"built-in",builtin:!0});let{writeSync}=__require("fs"),data=`${JSON.stringify(result2,null,2)}
3865
3865
  `,CHUNK=4096;for(let i2=0;i2<data.length;i2+=CHUNK)writeSync(1,data.slice(i2,i2+CHUNK))}function registerSdkFlags(cmd){cmd.option("--sdk-permission-mode <mode>","SDK permission mode: default|acceptEdits|bypassPermissions|plan|dontAsk|auto").option("--sdk-tools <list>","SDK tools: comma-separated tool names").option("--sdk-allowed-tools <list>","SDK auto-approved tools: comma-separated").option("--sdk-disallowed-tools <list>","SDK blacklisted tools: comma-separated").option("--sdk-max-turns <n>","SDK max conversation turns").option("--sdk-max-budget <usd>","SDK max budget in USD").option("--sdk-effort <level>","SDK effort: low|medium|high|max").option("--sdk-thinking <config>","SDK thinking: adaptive|disabled|enabled[:budgetTokens]").option("--sdk-persist-session","SDK: enable session persistence").option("--no-sdk-persist-session","SDK: disable session persistence").option("--sdk-file-checkpointing","SDK: enable file checkpointing").option("--sdk-output-format <path>","SDK: path to JSON schema file for output format").option("--sdk-stream-partial","SDK: include partial messages in stream").option("--sdk-hook-events","SDK: include hook events in stream").option("--sdk-prompt-suggestions","SDK: enable prompt suggestions").option("--sdk-progress-summaries","SDK: enable agent progress summaries").option("--sdk-sandbox","SDK: enable sandbox").option("--sdk-betas <list>","SDK beta flags: comma-separated").option("--sdk-system-prompt <string>","SDK system prompt text").option("--sdk-mcp-server <spec>","SDK MCP server: name:command:args (repeatable)",collectRepeat,[]).option("--sdk-plugin <path>","SDK plugin path (repeatable)",collectRepeat,[]).option("--sdk-agent <name>","SDK main agent name").option("--sdk-subagent <spec>","SDK subagent: name:json (repeatable)",collectRepeat,[])}function collectRepeat(value,previous){return previous.concat([value])}function buildSdkConfig(options){let config={};return applyScalarSdkOptions(config,options),applyBooleanSdkOptions(config,options),applyRepeatableSdkOptions(config,options),Object.keys(config).length>0?config:void 0}function toSafeNumber(value,flagName){let n=Number(value);if(Number.isNaN(n))throw Error(`${flagName} must be a number, got: ${value}`);return n}function applyScalarSdkOptions(config,options){if(options.sdkPermissionMode!==void 0)config.permissionMode=options.sdkPermissionMode;if(options.sdkTools!==void 0)config.tools=splitComma(options.sdkTools);if(options.sdkAllowedTools!==void 0)config.allowedTools=splitComma(options.sdkAllowedTools);if(options.sdkDisallowedTools!==void 0)config.disallowedTools=splitComma(options.sdkDisallowedTools);if(options.sdkMaxTurns!==void 0)config.maxTurns=toSafeNumber(options.sdkMaxTurns,"--sdk-max-turns");if(options.sdkMaxBudget!==void 0)config.maxBudgetUsd=toSafeNumber(options.sdkMaxBudget,"--sdk-max-budget");if(options.sdkEffort!==void 0)config.effort=options.sdkEffort;if(options.sdkThinking!==void 0)config.thinking=parseThinkingConfig(options.sdkThinking);if(options.sdkBetas!==void 0)config.betas=splitComma(options.sdkBetas);if(options.sdkSystemPrompt!==void 0)config.systemPrompt=options.sdkSystemPrompt;if(options.sdkAgent!==void 0)config.agent=options.sdkAgent;if(options.sdkOutputFormat!==void 0)config.outputFormat={type:"json_schema",schema:{$ref:options.sdkOutputFormat}}}function applyBooleanSdkOptions(config,options){if(options.sdkPersistSession!==void 0)config.persistSession=options.sdkPersistSession;if(options.sdkFileCheckpointing===!0)config.enableFileCheckpointing=!0;if(options.sdkStreamPartial===!0)config.includePartialMessages=!0;if(options.sdkHookEvents===!0)config.includeHookEvents=!0;if(options.sdkPromptSuggestions===!0)config.promptSuggestions=!0;if(options.sdkProgressSummaries===!0)config.agentProgressSummaries=!0;if(options.sdkSandbox===!0)config.sandbox={enabled:!0}}function applyRepeatableSdkOptions(config,options){if(options.sdkMcpServer&&options.sdkMcpServer.length>0){config.mcpServers={};for(let spec of options.sdkMcpServer){let parsed=parseMcpServer(spec);config.mcpServers[parsed.name]=parsed.config}}if(options.sdkPlugin&&options.sdkPlugin.length>0)config.plugins=options.sdkPlugin.map((p)=>({type:"local",path:p}));if(options.sdkSubagent&&options.sdkSubagent.length>0)config.agents=parseSubagents(options.sdkSubagent)}function parseSubagents(specs){let agents={};for(let spec of specs){let colonIdx=spec.indexOf(":");if(colonIdx===-1)throw Error(`Invalid --sdk-subagent format: "${spec}". Expected "name:json".`);let agentName=spec.slice(0,colonIdx),jsonStr=spec.slice(colonIdx+1);try{agents[agentName]=JSON.parse(jsonStr)}catch{throw Error(`Invalid JSON in --sdk-subagent "${agentName}": ${jsonStr}`)}}return agents}function parseThinkingConfig(value){if(value==="adaptive")return{type:"adaptive"};if(value==="disabled")return{type:"disabled"};if(value==="enabled")return{type:"enabled"};if(value.startsWith("enabled:"))return{type:"enabled",budgetTokens:toSafeNumber(value.slice(8),"--sdk-thinking budgetTokens")};throw Error(`Invalid --sdk-thinking value: "${value}". Expected adaptive|disabled|enabled[:budgetTokens].`)}function parseMcpServer(spec){let firstColon=spec.indexOf(":");if(firstColon===-1)throw Error(`Invalid --sdk-mcp-server format: "${spec}". Expected "name:command:args".`);let name=spec.slice(0,firstColon),rest=spec.slice(firstColon+1),secondColon=rest.indexOf(":");if(secondColon===-1)throw Error(`Invalid --sdk-mcp-server format: "${spec}". Expected "name:command:args".`);let command=rest.slice(0,secondColon),argsStr=rest.slice(secondColon+1),args=argsStr?argsStr.split(",").map((s)=>s.trim()).filter(Boolean):[];return{name,config:{type:"stdio",command,args}}}function splitComma(value){return value.split(",").map((s)=>s.trim()).filter(Boolean)}function printSdkConfig(sdk){console.log(" SDK Config:");let lines=collectSdkDisplayLines(sdk);for(let line of lines)console.log(` ${line}`)}function collectSdkDisplayLines(sdk){let lines=[];if(sdk.permissionMode)lines.push(`Permission Mode: ${sdk.permissionMode}`);if(sdk.tools)lines.push(`Tools: ${Array.isArray(sdk.tools)?sdk.tools.join(", "):`preset:${sdk.tools.preset}`}`);if(sdk.allowedTools?.length)lines.push(`Allowed Tools: ${sdk.allowedTools.join(", ")}`);if(sdk.disallowedTools?.length)lines.push(`Disallowed Tools: ${sdk.disallowedTools.join(", ")}`);if(sdk.maxTurns!==void 0)lines.push(`Max Turns: ${sdk.maxTurns}`);if(sdk.maxBudgetUsd!==void 0)lines.push(`Max Budget: $${sdk.maxBudgetUsd.toFixed(2)}`);if(sdk.effort)lines.push(`Effort: ${sdk.effort}`);if(sdk.thinking)lines.push(`Thinking: ${formatThinking(sdk.thinking)}`);if(sdk.agent)lines.push(`Agent: ${sdk.agent}`);if(sdk.persistSession!==void 0)lines.push(`Persist Session: ${sdk.persistSession}`);if(sdk.enableFileCheckpointing)lines.push("File Checkpointing: enabled");if(sdk.outputFormat)lines.push(`Output Format: ${JSON.stringify(sdk.outputFormat.schema)}`);return collectSdkBooleanLines(sdk,lines),collectSdkComplexLines(sdk,lines),lines}function collectSdkBooleanLines(sdk,lines){if(sdk.includePartialMessages)lines.push("Stream Partial: enabled");if(sdk.includeHookEvents)lines.push("Hook Events: enabled");if(sdk.promptSuggestions)lines.push("Prompt Suggestions: enabled");if(sdk.agentProgressSummaries)lines.push("Progress Summaries: enabled");if(sdk.sandbox?.enabled)lines.push("Sandbox: enabled");if(sdk.betas?.length)lines.push(`Betas: ${sdk.betas.join(", ")}`)}function collectSdkComplexLines(sdk,lines){if(sdk.systemPrompt){let prompt2=typeof sdk.systemPrompt==="string"?sdk.systemPrompt:`preset:${sdk.systemPrompt.preset}`;lines.push(`System Prompt: ${prompt2.length>60?`${prompt2.slice(0,60)}...`:prompt2}`)}if(sdk.mcpServers)lines.push(`MCP Servers: ${Object.keys(sdk.mcpServers).join(", ")}`);if(sdk.plugins?.length)lines.push(`Plugins: ${sdk.plugins.map((p)=>p.path).join(", ")}`);if(sdk.agents)lines.push(`Subagents: ${Object.keys(sdk.agents).join(", ")}`)}function formatThinking(thinking){if(thinking.type==="enabled"&&thinking.budgetTokens)return`enabled:${thinking.budgetTokens}`;return thinking.type}function buildPermissions(permissionPreset,allow,bashAllow){if(!permissionPreset&&!allow&&!bashAllow)return;if(permissionPreset)return{preset:permissionPreset};return{...allow&&{allow:allow.split(",").map((s)=>s.trim()).filter(Boolean)},...bashAllow&&{bashAllowPatterns:bashAllow.split(",").map((s)=>s.trim()).filter(Boolean)}}}function normalizeRoles(roles){if(!roles)return;return roles.flatMap((r)=>r.split(",")).map((r)=>r.trim()).filter(Boolean)}function printRegisteredTable(entries){let repoValues=[],roleValues=[];for(let entry2 of entries)repoValues.push(entry2.repo?contractPath(entry2.repo):contractPath(entry2.dir)),roleValues.push(entry2.roles?.join(", ")||"-");let termW=process.stdout.columns||120,fixedW=54,maxRepoLen=Math.max(4,...repoValues.map((v)=>v.length)),repoW=Math.min(maxRepoLen+2,Math.max(30,termW-fixedW-20)),totalW=fixedW+repoW+20;console.log(""),console.log("REGISTERED AGENTS"),console.log("-".repeat(Math.max(90,totalW))),console.log(` ${"NAME".padEnd(22)}${"SCOPE".padEnd(10)}${"REPO".padEnd(repoW)}${"MODEL".padEnd(10)}${"PROVIDER".padEnd(10)}ROLES`),console.log(` ${"-".repeat(20)} ${"-".repeat(8)} ${"-".repeat(repoW-2)} ${"-".repeat(8)} ${"-".repeat(8)} ${"-".repeat(20)}`);for(let i2=0;i2<entries.length;i2++){let entry2=entries[i2],repo=repoValues[i2],roles=roleValues[i2];console.log(` ${entry2.name.padEnd(22)}${entry2.scope.padEnd(10)}${repo.padEnd(repoW)}${(entry2.model||"-").padEnd(10)}${(entry2.provider||"-").padEnd(10)}${roles}`)}console.log("")}function printResolvedTable(entries){if(entries.length===0)return;let nameW=22,declW=14,resolvedW=14;console.log("RESOLVED DEFAULTS"),console.log("-".repeat(70));for(let field of RESOLVED_FIELDS){let fieldUpper=field.toUpperCase();console.log(` ${"AGENT".padEnd(nameW)}${`${fieldUpper} (declared)`.padEnd(declW)}${`${fieldUpper} (resolved)`.padEnd(resolvedW)}SOURCE`),console.log(` ${"-".repeat(nameW-2)} ${"-".repeat(declW-2)} ${"-".repeat(resolvedW-2)} ${"-".repeat(16)}`);for(let entry2 of entries){let ctx=buildDirResolveContext(entry2.name),result2=resolveFieldWithSource(entry2,field,ctx),declared=entry2[field]||"-";console.log(` ${entry2.name.padEnd(nameW)}${declared.padEnd(declW)}${result2.value.padEnd(resolvedW)}${result2.source}`)}}console.log("")}function printBuiltinsTable(){console.log("BUILT-IN AGENTS"),console.log("-".repeat(80)),console.log(` ${"NAME".padEnd(22)}${"TYPE".padEnd(10)}${"MODEL".padEnd(8)}DESCRIPTION`),console.log(` ${"-".repeat(20)} ${"-".repeat(8)} ${"-".repeat(6)} ${"-".repeat(30)}`);for(let agent of ALL_BUILTINS)console.log(` ${agent.name.padEnd(22)}${agent.category.padEnd(10)}${(agent.model||"-").padEnd(8)}${agent.description}`);console.log("")}function validatePromptMode2(mode){if(mode!=="system"&&mode!=="append")throw Error(`Invalid prompt mode "${mode}". Must be "append" or "system".`);return mode}function normalizeRoles2(roles){if(!roles)return;return roles.flatMap((r)=>r.split(",")).map((r)=>r.trim()).filter(Boolean)}function printEntry2(entry2){if(console.log(` Name: ${entry2.name}`),console.log(` Dir: ${contractPath(entry2.dir)}`),entry2.repo)console.log(` Repo: ${contractPath(entry2.repo)}`);if(console.log(` Prompt mode: ${entry2.promptMode}`),entry2.model)console.log(` Model: ${entry2.model}`);if(entry2.roles?.length)console.log(` Roles: ${entry2.roles.join(", ")}`);console.log(` Registered: ${entry2.registeredAt}`)}async function handleOmniRegistration(name,options){let omniUrl=await resolveOmniApiUrl();if(!omniUrl)return;console.log(`
3866
- Registering in Omni (${omniUrl})...`);let existingId=await findOmniAgent(name);if(existingId){console.log(` Agent already exists in Omni: ${existingId}`),await edit(name,{omniAgentId:existingId},{global:options.global}),console.log(" Linked existing Omni agent to directory entry.");return}let omniAgentId=await registerAgentInOmni(name,{model:options.model,roles:options.roles});if(omniAgentId)await edit(name,{omniAgentId},{global:options.global}),console.log(` Omni agent created: ${omniAgentId}`),console.log(" Session isolation: per-person + per-channel")}async function handleAgentRegister(name,options){let promptMode=validatePromptMode2(options.promptMode);if(options.repo)validateRepoPath(options.repo);let roles=normalizeRoles2(options.roles),entry2=await add({name,dir:resolvePath2(options.dir),repo:options.repo?resolvePath2(options.repo):void 0,promptMode,model:options.model,roles},{global:options.global}),scope=options.global?"global":"project";if(console.log(`Agent "${entry2.name}" registered (${scope}).`),printEntry2(entry2),!options.skipOmni)await handleOmniRegistration(name,{...options,roles})}function registerAgentRegister(parent){parent.command("register <name>").description("Register an agent locally and auto-register in Omni when configured").requiredOption("--dir <path>","Agent folder (CWD + AGENTS.md)").option("--repo <path>","Default git repo (overridden by team)").option("--prompt-mode <mode>","Prompt mode: append or system","append").option("--model <model>","Default model (sonnet, opus, codex)").option("--roles <roles...>","Built-in roles this agent can orchestrate").option("--global","Write to global directory instead of project").option("--skip-omni","Skip Omni auto-registration").action(async(name,options)=>{try{await handleAgentRegister(name,options)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}init_agents();function registerAgentResume(parent){parent.command("resume [name]").description("Resume a suspended/failed agent with its Claude session").option("--all","Resume all eligible agents").option("--no-reset-attempts","Preserve resumeAttempts counter (scheduler auto-resume use)").action(async(name,options)=>{try{await handleWorkerResume(name,{all:options.all,noResetAttempts:options.resetAttempts===!1})}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}init_msg();function registerAgentSend(parent){parent.command("send <body>").description("Send a direct message to an agent (hierarchy-enforced)").option("--to <agent>","Recipient agent name (default: team leader)","team-lead").option("--from <sender>","Sender ID (auto-detected from context)").option("--team <name>","Explicit team context for sender/recipient resolution").option("--broadcast","Send to all direct reports").action(async(body,options)=>{try{let from=options.from??await detectSenderIdentity(options.team);if(options.broadcast){await handleBroadcast(from,body,options.team);return}await handleDirectMessage(from,options.to,body,options.team)}catch(error2){console.error(`Error: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}})}async function isTeamLeader(agentName,teamName){try{let{resolveLeaderName:resolveLeaderName2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),leaderName=await resolveLeaderName2(teamName);return agentName===leaderName}catch{return!1}}async function checkHierarchy(from,to){if(from==="cli")return{allowed:!0};if(from===to)return{allowed:!0};try{let agents=await(await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry))).listAgents({}),sender=agents.find((a)=>a.customName===from||a.role===from||a.id===from),recipient=agents.find((a)=>a.customName===to||a.role===to||a.id===to);if(!sender||!recipient)return{allowed:!0};if(recipient.reportsTo===from||recipient.reportsTo===sender.id)return{allowed:!0};if(sender.reportsTo===to||sender.reportsTo===recipient.id)return{allowed:!0};if(sender.reportsTo&&sender.reportsTo===recipient.reportsTo)return{allowed:!0};if(sender.team&&sender.team===recipient.team&&await isTeamLeader(from,sender.team))return{allowed:!0};let manager=sender.reportsTo??"your manager";return{allowed:!1,reason:`Cannot reach "${to}". Escalate to ${manager}.`}}catch{return{allowed:!0}}}async function handleDirectMessage(from,to,body,team){let{allowed,reason}=await checkHierarchy(from,to);if(!allowed)console.error(`Error: ${reason}`),process.exit(1);let{checkSendScope:checkSendScope2}=await Promise.resolve().then(() => (init_msg(),exports_msg)),repoPath=process.cwd(),scopeError=await checkSendScope2(repoPath,from,to);if(scopeError)console.error(`Error: ${scopeError}`),process.exit(1);let taskService=await Promise.resolve().then(() => (init_task_service(),exports_task_service)),mailbox=await Promise.resolve().then(() => (init_mailbox(),exports_mailbox)),senderActor={actorType:"local",actorId:from},recipientActor={actorType:"local",actorId:to},conv=await taskService.findOrCreateConversation({type:"dm",members:[senderActor,recipientActor],createdBy:senderActor});await taskService.addMember(conv.id,senderActor),await taskService.addMember(conv.id,recipientActor),await mailbox.send(repoPath,from,to,body);let msg=await taskService.sendMessage(conv.id,senderActor,body);try{let{publishSubjectEvent:publishSubjectEvent2}=await Promise.resolve().then(() => (init_runtime_events(),exports_runtime_events));await publishSubjectEvent2(repoPath,`genie.msg.${to}`,{kind:"message",agent:from,direction:"out",peer:to,text:body,data:{messageId:msg.id,conversationId:conv.id,from,to},source:"mailbox"})}catch{}try{let nativeTeams=await Promise.resolve().then(() => (init_claude_native_teams(),exports_claude_native_teams)),nativeMsg={from,text:body,summary:body.length>50?`${body.substring(0,50)}...`:body,timestamp:new Date().toISOString(),color:"blue",read:!1},currentTeam=team??process.env.GENIE_TEAM;if(currentTeam){let nativeName=await nativeTeams.resolveNativeMemberName(currentTeam,to);if(nativeName)await nativeTeams.writeNativeInbox(currentTeam,nativeName,nativeMsg)}}catch{}console.log(`Message sent to "${to}".`),console.log(` ID: ${msg.id}`),console.log(` Conversation: ${conv.id}`)}async function deliverBroadcastToMembers(deps,repoPath,from,teamName,body){let members=await deps.listMembers(teamName)??[],results=[];for(let member of members){if(member===from)continue;try{let r=await deps.sendMessage(repoPath,from,member,body,teamName);results.push({member,delivered:r.delivered,reason:r.reason})}catch(err){results.push({member,delivered:!1,reason:err instanceof Error?err.message:String(err)})}}return results}async function handleBroadcast(from,body,team){let taskService=await Promise.resolve().then(() => (init_task_service(),exports_task_service)),repoPath=process.cwd(),teamName=team??process.env.GENIE_TEAM;if(!teamName)console.error("Error: Could not detect team. Use --team <name>."),process.exit(1);let senderActor={actorType:"local",actorId:from},conv=await taskService.findOrCreateConversation({type:"group",name:`Team: ${teamName}`,linkedEntity:"team",linkedEntityId:teamName,createdBy:senderActor,members:[senderActor]});await taskService.addMember(conv.id,senderActor);let msg=await taskService.sendMessage(conv.id,senderActor,body);try{let{publishSubjectEvent:publishSubjectEvent2}=await Promise.resolve().then(() => (init_runtime_events(),exports_runtime_events));await publishSubjectEvent2(repoPath,"genie.msg.broadcast",{kind:"message",agent:from,direction:"out",peer:teamName,text:body,data:{messageId:msg.id,conversationId:conv.id,from,team:teamName},source:"mailbox"})}catch{}let{listMembers:listMembers2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),protocolRouter=await Promise.resolve().then(() => (init_protocol_router(),exports_protocol_router)),fanoutResults=await deliverBroadcastToMembers({listMembers:listMembers2,sendMessage:protocolRouter.sendMessage},repoPath,from,teamName,body);console.log(`Broadcast sent to team "${teamName}".`),console.log(` Message ID: ${msg.id}`),console.log(` Conversation: ${conv.id}`);let deliveredCount=fanoutResults.filter((r)=>r.delivered).length;console.log(` Fan-out: ${deliveredCount}/${fanoutResults.length} members reached`);for(let r of fanoutResults)if(!r.delivered)console.log(` \u26A0 ${r.member}: ${r.reason??"delivery failed"}`)}init_term_format();function printAgentFields(agent){if(console.log(""),console.log(`AGENT: ${agent.customName??agent.role??agent.id}`),console.log("\u2500".repeat(60)),console.log(` ${padRight("ID:",20)} ${agent.id}`),agent.role)console.log(` ${padRight("Role:",20)} ${agent.role}`);if(agent.customName)console.log(` ${padRight("Name:",20)} ${agent.customName}`);if(agent.team)console.log(` ${padRight("Team:",20)} ${agent.team}`);console.log(` ${padRight("Started:",20)} ${agent.startedAt}`)}function printExecutorFields(executor){if(console.log(""),console.log("Current Executor:"),console.log("\u2500".repeat(60)),console.log(` ${padRight("Executor ID:",20)} ${executor.id}`),console.log(` ${padRight("Provider:",20)} ${executor.provider}`),console.log(` ${padRight("Transport:",20)} ${executor.transport}`),console.log(` ${padRight("State:",20)} ${executor.state}`),executor.pid)console.log(` ${padRight("PID:",20)} ${executor.pid}`);if(executor.tmuxSession)console.log(` ${padRight("Tmux Session:",20)} ${executor.tmuxSession}`);if(executor.tmuxPaneId)console.log(` ${padRight("Tmux Pane:",20)} ${executor.tmuxPaneId}`);if(executor.worktree)console.log(` ${padRight("Worktree:",20)} ${executor.worktree}`);if(console.log(` ${padRight("Started:",20)} ${executor.startedAt}`),executor.endedAt)console.log(` ${padRight("Ended:",20)} ${executor.endedAt}`)}async function showAgent(name,json2){let registry=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry)),executorRegistry=await Promise.resolve().then(() => (init_executor_registry(),exports_executor_registry)),matches=(await registry.listAgents()).filter((a)=>a.customName===name||a.role===name||a.id===name),preferredTeam=process.env.GENIE_TEAM,agent=(preferredTeam&&matches.find((a)=>a.team===preferredTeam))??matches[0];if(!agent)console.error(`Agent "${name}" not found.`),process.exit(1);if(json2){let executor=agent.currentExecutorId?await executorRegistry.getExecutor(agent.currentExecutorId):null;console.log(JSON.stringify({agent,executor},null,2));return}if(printAgentFields(agent),agent.currentExecutorId){let executor=await executorRegistry.getExecutor(agent.currentExecutorId);if(executor)printExecutorFields(executor)}else console.log(`
3866
+ Registering in Omni (${omniUrl})...`);let existingId=await findOmniAgent(name);if(existingId){console.log(` Agent already exists in Omni: ${existingId}`),await edit(name,{omniAgentId:existingId},{global:options.global}),console.log(" Linked existing Omni agent to directory entry.");return}let omniAgentId=await registerAgentInOmni(name,{model:options.model,roles:options.roles});if(omniAgentId)await edit(name,{omniAgentId},{global:options.global}),console.log(` Omni agent created: ${omniAgentId}`),console.log(" Session isolation: per-person + per-channel")}async function handleAgentRegister(name,options){let promptMode=validatePromptMode2(options.promptMode);if(options.repo)validateRepoPath(options.repo);let roles=normalizeRoles2(options.roles),entry2=await add({name,dir:resolvePath2(options.dir),repo:options.repo?resolvePath2(options.repo):void 0,promptMode,model:options.model,roles},{global:options.global}),scope=options.global?"global":"project";if(console.log(`Agent "${entry2.name}" registered (${scope}).`),printEntry2(entry2),!options.skipOmni)await handleOmniRegistration(name,{...options,roles})}function registerAgentRegister(parent){parent.command("register <name>").description("Register an agent locally and auto-register in Omni when configured").requiredOption("--dir <path>","Agent folder (CWD + AGENTS.md)").option("--repo <path>","Default git repo (overridden by team)").option("--prompt-mode <mode>","Prompt mode: append or system","append").option("--model <model>","Default model (sonnet, opus, codex)").option("--roles <roles...>","Built-in roles this agent can orchestrate").option("--global","Write to global directory instead of project").option("--skip-omni","Skip Omni auto-registration").action(async(name,options)=>{try{await handleAgentRegister(name,options)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}init_agents();function registerAgentResume(parent){parent.command("resume [name]").description("Resume a suspended/failed agent with its Claude session").option("--all","Resume all eligible agents").option("--no-reset-attempts","Preserve resumeAttempts counter (scheduler auto-resume use)").action(async(name,options)=>{try{await handleWorkerResume(name,{all:options.all,noResetAttempts:options.resetAttempts===!1})}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}init_msg();function registerAgentSend(parent){parent.command("send <body>").description("Send a direct message to an agent (hierarchy-enforced)").option("--to <agent>","Recipient agent name (default: team leader)","team-lead").option("--from <sender>","Sender ID (auto-detected from context)").option("--team <name>","Explicit team context for sender/recipient resolution").option("--broadcast","Send to all direct reports").action(async(body,options)=>{try{let from=options.from??await detectSenderIdentity(options.team);if(options.broadcast){await handleBroadcast(from,body,options.team);return}await handleDirectMessage(from,options.to,body,options.team)}catch(error2){console.error(`Error: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}})}async function isTeamLeader(agentName,teamName){try{let{resolveLeaderName:resolveLeaderName2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),leaderName=await resolveLeaderName2(teamName);return agentName===leaderName}catch{return!1}}async function checkHierarchy(from,to){if(isCliSender(from))return{allowed:!0};if(from===to)return{allowed:!0};try{let agents=await(await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry))).listAgents({}),sender=agents.find((a)=>a.customName===from||a.role===from||a.id===from),recipient=agents.find((a)=>a.customName===to||a.role===to||a.id===to);if(!sender||!recipient)return{allowed:!0};if(recipient.reportsTo===from||recipient.reportsTo===sender.id)return{allowed:!0};if(sender.reportsTo===to||sender.reportsTo===recipient.id)return{allowed:!0};if(sender.reportsTo&&sender.reportsTo===recipient.reportsTo)return{allowed:!0};if(sender.team&&sender.team===recipient.team&&await isTeamLeader(from,sender.team))return{allowed:!0};let manager=sender.reportsTo??"your manager";return{allowed:!1,reason:`Cannot reach "${to}". Escalate to ${manager}.`}}catch{return{allowed:!0}}}async function handleDirectMessage(from,to,body,team){let{allowed,reason}=await checkHierarchy(from,to);if(!allowed)console.error(`Error: ${reason}`),process.exit(1);let{checkSendScope:checkSendScope2}=await Promise.resolve().then(() => (init_msg(),exports_msg)),repoPath=process.cwd(),scopeError=await checkSendScope2(repoPath,from,to);if(scopeError)console.error(`Error: ${scopeError}`),process.exit(1);let taskService=await Promise.resolve().then(() => (init_task_service(),exports_task_service)),mailbox=await Promise.resolve().then(() => (init_mailbox(),exports_mailbox)),senderActor={actorType:"local",actorId:from},recipientActor={actorType:"local",actorId:to},conv=await taskService.findOrCreateConversation({type:"dm",members:[senderActor,recipientActor],createdBy:senderActor});await taskService.addMember(conv.id,senderActor),await taskService.addMember(conv.id,recipientActor),await mailbox.send(repoPath,from,to,body);let msg=await taskService.sendMessage(conv.id,senderActor,body);try{let{publishSubjectEvent:publishSubjectEvent2}=await Promise.resolve().then(() => (init_runtime_events(),exports_runtime_events));await publishSubjectEvent2(repoPath,`genie.msg.${to}`,{kind:"message",agent:from,direction:"out",peer:to,text:body,data:{messageId:msg.id,conversationId:conv.id,from,to},source:"mailbox"})}catch{}try{let nativeTeams=await Promise.resolve().then(() => (init_claude_native_teams(),exports_claude_native_teams)),nativeMsg={from,text:body,summary:body.length>50?`${body.substring(0,50)}...`:body,timestamp:new Date().toISOString(),color:"blue",read:!1},currentTeam=team??process.env.GENIE_TEAM;if(currentTeam){let nativeName=await nativeTeams.resolveNativeMemberName(currentTeam,to);if(nativeName)await nativeTeams.writeNativeInbox(currentTeam,nativeName,nativeMsg)}}catch{}console.log(`Message sent to "${to}".`),console.log(` ID: ${msg.id}`),console.log(` Conversation: ${conv.id}`)}async function deliverBroadcastToMembers(deps,repoPath,from,teamName,body){let members=await deps.listMembers(teamName)??[],results=[];for(let member of members){if(member===from)continue;try{let r=await deps.sendMessage(repoPath,from,member,body,teamName);results.push({member,delivered:r.delivered,reason:r.reason})}catch(err){results.push({member,delivered:!1,reason:err instanceof Error?err.message:String(err)})}}return results}async function handleBroadcast(from,body,team){let taskService=await Promise.resolve().then(() => (init_task_service(),exports_task_service)),repoPath=process.cwd(),teamName=team??process.env.GENIE_TEAM;if(!teamName)console.error("Error: Could not detect team. Use --team <name>."),process.exit(1);let senderActor={actorType:"local",actorId:from},conv=await taskService.findOrCreateConversation({type:"group",name:`Team: ${teamName}`,linkedEntity:"team",linkedEntityId:teamName,createdBy:senderActor,members:[senderActor]});await taskService.addMember(conv.id,senderActor);let msg=await taskService.sendMessage(conv.id,senderActor,body);try{let{publishSubjectEvent:publishSubjectEvent2}=await Promise.resolve().then(() => (init_runtime_events(),exports_runtime_events));await publishSubjectEvent2(repoPath,"genie.msg.broadcast",{kind:"message",agent:from,direction:"out",peer:teamName,text:body,data:{messageId:msg.id,conversationId:conv.id,from,team:teamName},source:"mailbox"})}catch{}let{listMembers:listMembers2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager)),protocolRouter=await Promise.resolve().then(() => (init_protocol_router(),exports_protocol_router)),fanoutResults=await deliverBroadcastToMembers({listMembers:listMembers2,sendMessage:protocolRouter.sendMessage},repoPath,from,teamName,body);console.log(`Broadcast sent to team "${teamName}".`),console.log(` Message ID: ${msg.id}`),console.log(` Conversation: ${conv.id}`);let deliveredCount=fanoutResults.filter((r)=>r.delivered).length;console.log(` Fan-out: ${deliveredCount}/${fanoutResults.length} members reached`);for(let r of fanoutResults)if(!r.delivered)console.log(` \u26A0 ${r.member}: ${r.reason??"delivery failed"}`)}init_term_format();function printAgentFields(agent){if(console.log(""),console.log(`AGENT: ${agent.customName??agent.role??agent.id}`),console.log("\u2500".repeat(60)),console.log(` ${padRight("ID:",20)} ${agent.id}`),agent.role)console.log(` ${padRight("Role:",20)} ${agent.role}`);if(agent.customName)console.log(` ${padRight("Name:",20)} ${agent.customName}`);if(agent.team)console.log(` ${padRight("Team:",20)} ${agent.team}`);console.log(` ${padRight("Started:",20)} ${agent.startedAt}`)}function printExecutorFields(executor){if(console.log(""),console.log("Current Executor:"),console.log("\u2500".repeat(60)),console.log(` ${padRight("Executor ID:",20)} ${executor.id}`),console.log(` ${padRight("Provider:",20)} ${executor.provider}`),console.log(` ${padRight("Transport:",20)} ${executor.transport}`),console.log(` ${padRight("State:",20)} ${executor.state}`),executor.pid)console.log(` ${padRight("PID:",20)} ${executor.pid}`);if(executor.tmuxSession)console.log(` ${padRight("Tmux Session:",20)} ${executor.tmuxSession}`);if(executor.tmuxPaneId)console.log(` ${padRight("Tmux Pane:",20)} ${executor.tmuxPaneId}`);if(executor.worktree)console.log(` ${padRight("Worktree:",20)} ${executor.worktree}`);if(console.log(` ${padRight("Started:",20)} ${executor.startedAt}`),executor.endedAt)console.log(` ${padRight("Ended:",20)} ${executor.endedAt}`)}async function showAgent(name,json2){let registry=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry)),executorRegistry=await Promise.resolve().then(() => (init_executor_registry(),exports_executor_registry)),matches=(await registry.listAgents()).filter((a)=>a.customName===name||a.role===name||a.id===name),preferredTeam=process.env.GENIE_TEAM,agent=(preferredTeam&&matches.find((a)=>a.team===preferredTeam))??matches[0];if(!agent)console.error(`Agent "${name}" not found.`),process.exit(1);if(json2){let executor=agent.currentExecutorId?await executorRegistry.getExecutor(agent.currentExecutorId):null;console.log(JSON.stringify({agent,executor},null,2));return}if(printAgentFields(agent),agent.currentExecutorId){let executor=await executorRegistry.getExecutor(agent.currentExecutorId);if(executor)printExecutorFields(executor)}else console.log(`
3867
3867
  No active executor.`);console.log("")}function registerAgentShow(parent){parent.command("show <name>").description("Show agent identity and current executor detail").option("--json","Output as JSON").action(async(name,options)=>{try{await showAgent(name,options.json)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}init_agents();function parseNumericFlag(flagName){return(value)=>{let n=Number(value);if(Number.isNaN(n))throw Error(`${flagName} must be a number, got: ${value}`);return n}}function registerAgentSpawn(parent){parent.command("spawn <name>").description("Spawn a new agent by name (resolves from directory or built-ins)").option("--provider <provider>","Provider: claude, codex, or claude-sdk").option("--team <team>","Team name").option("--model <model>","Model override (e.g., sonnet, opus)").option("--skill <skill>","Skill to load (optional)").option("--layout <layout>","Layout mode: mosaic (default) or vertical").option("--color <color>","Teammate pane border color").option("--plan-mode","Start teammate in plan mode").option("--permission-mode <mode>","Permission mode (e.g., acceptEdits)").option("--extra-args <args...>","Extra CLI args forwarded to provider").option("--cwd <path>","Working directory for the agent (overrides directory entry)").option("--session <session>","Tmux session name to spawn into").option("--role <role>","Override role name for registration (avoids duplicate guard)").option("--new-window","Create a new tmux window instead of splitting").option("--window <target>","Tmux window to split into (e.g., genie:3)").option("--no-auto-resume","Disable auto-resume on pane death").option("--prompt <prompt>","Initial prompt (first user message)").option("--sdk-max-turns <n>","SDK: max conversation turns",parseNumericFlag("--sdk-max-turns")).option("--sdk-max-budget <usd>","SDK: max budget in USD",parseNumericFlag("--sdk-max-budget")).option("--sdk-stream","SDK: enable streaming output (shortcut for --stream)").option("--sdk-effort <level>","SDK: reasoning effort level (low, medium, high, max)").option("--sdk-resume <session-id>","SDK: resume a previous session by ID").action(async(name,options)=>{if(options.prompt)options.initialPrompt=options.prompt;try{await handleWorkerSpawn(name,options)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}init_agents();function registerAgentStop(parent){parent.command("stop <name>").description("Stop an agent (preserves session for resume)").action(async(name)=>{try{await handleWorkerStop(name)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}function registerAgentCommands(program2){let agent=program2.command("agent").description("Agent lifecycle management");registerAgentSpawn(agent),registerAgentStop(agent),registerAgentResume(agent),registerAgentRecover(agent),registerAgentKill(agent),registerAgentList(agent),registerAgentShow(agent),registerAgentAnswer(agent),registerAgentRegister(agent),registerAgentDirectory(agent),registerAgentInbox(agent),registerAgentBrief(agent),registerAgentLog(agent),registerAgentSend(agent),agent.on("command:*",(operands)=>{let cmd=operands[0],available=agent.commands.map((c)=>c.name()).join(", ");agent.error(`Unknown agent command '${cmd}'. Available: ${available}`)})}init_agents();async function handleTuiMode(){let{isServeRunning:isServeRunning2,autoStartServe:autoStartServe2}=await Promise.resolve().then(() => (init_serve(),exports_serve));if(!isServeRunning2())console.log("Starting genie serve..."),await autoStartServe2();let{attachTuiSession:attachTuiSession2}=await Promise.resolve().then(() => (init_tmux2(),exports_tmux2));attachTuiSession2()}async function findTauriBinary(){let{existsSync:existsSync41}=await import("fs"),{join:join50,dirname:dirname11}=await import("path"),{execSync:execSync11}=await import("child_process"),appName="genie-desktop",rootDir=join50(dirname11(new URL(import.meta.url).pathname),"..",".."),localBin=[join50(rootDir,"packages","genie-app","src-tauri","target","release","genie-desktop"),join50(rootDir,"packages","genie-app","src-tauri","target","debug","genie-desktop"),join50(rootDir,"dist","app","genie-desktop"),"/usr/local/bin/genie-desktop"].find((p)=>existsSync41(p));if(localBin)return localBin;try{return execSync11("which genie-desktop",{stdio:"ignore"}),"genie-desktop"}catch{return}}function registerAppCommand(program2){program2.command("app").description("Launch Genie desktop app (backend sidecar + views)").option("--backend-only","Start only the backend sidecar (IPC on stdin/stdout)").option("--tui","Fall back to terminal UI mode").option("--dev","Development mode").action(async(options)=>{if(options.tui){await handleTuiMode();return}if(options.backendOnly){await Promise.resolve().then(() => (init_src_backend(),exports_src_backend));return}let tauriBin=await findTauriBinary();if(tauriBin){console.log("\x1B[35m\u25C6 Genie App\x1B[0m Launching desktop...");let{execFileSync}=await import("child_process");try{execFileSync(tauriBin,[],{stdio:"inherit"})}catch{}return}console.log("\x1B[35m\u25C6 Genie App\x1B[0m Starting backend sidecar..."),console.log("\x1B[2mDesktop binary not found \u2014 running in sidecar mode.\x1B[0m"),console.log("\x1B[2mPG bridge + PTY manager + IPC on stdin/stdout\x1B[0m"),console.log(`\x1B[2mUse --tui for terminal UI, or pipe to a frontend shell.\x1B[0m
3868
3868
  `),await Promise.resolve().then(() => (init_src_backend(),exports_src_backend))})}init_claude_sdk_remote_approval();init_workspace();async function handleRequest(options){let ws=findWorkspace(),permissions=ws?getWorkspaceConfig(ws.root).permissions:void 0,timeoutSec=options.timeout?Number(options.timeout):permissions?.timeout??300,defaultAction=permissions?.defaultAction??"deny",timeoutAt=new Date(Date.now()+timeoutSec*1000),approvalId=await insertApproval(`cli-${process.pid}`,options.agent,options.tool,options.input,timeoutAt);if(console.log(`Approval created: ${approvalId}`),options.wait){console.log(`Waiting for resolution (timeout: ${timeoutSec}s, default: ${defaultAction})...`);let decision=await waitForResolution(approvalId,timeoutAt,defaultAction);if(console.log(`Decision: ${decision}`),decision==="deny")process.exit(1)}}async function handleResolve(id,options){if(options.decision!=="allow"&&options.decision!=="deny")console.error('Error: --decision must be "allow" or "deny"'),process.exit(1);let actor=process.env.GENIE_AGENT_NAME||options.by;if(await resolveApproval(id,options.decision,actor))console.log(`Approval ${id} resolved: ${options.decision} by ${options.by}`);else console.error(`Error: Approval ${id} not found or already resolved`),process.exit(1)}async function handleList(options){let rows=await listPendingApprovals(options.agent);if(options.json){console.log(JSON.stringify(rows,null,2));return}if(rows.length===0){console.log("No pending approvals.");return}console.log(` ${"ID".padEnd(38)} ${"AGENT".padEnd(20)} ${"TOOL".padEnd(15)} TIMEOUT`),console.log(` ${"\u2500".repeat(85)}`);for(let row of rows){let timeout=new Date(row.timeout_at).toLocaleTimeString();console.log(` ${String(row.id).padEnd(38)} ${String(row.agent_name).padEnd(20)} ${String(row.tool_name).padEnd(15)} ${timeout}`)}console.log(`
3869
3869
  ${rows.length} pending approval${rows.length===1?"":"s"}`)}function registerApprovalCommands(program2){let approval=program2.command("approval").description("Remote approval queue management");approval.command("request").description("Create an approval request (for tmux-path agents)").requiredOption("--tool <name>","Tool name requiring approval").requiredOption("--input <preview>","Tool input preview text").requiredOption("--agent <name>","Agent name requesting approval").option("--wait","Block until the approval is resolved").option("--timeout <seconds>","Timeout in seconds (overrides workspace config)").action(async(options)=>{try{await handleRequest(options)}catch(error2){console.error(`Error: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}}),approval.command("resolve <id>").description("Resolve a pending approval").requiredOption("--decision <decision>","Decision: allow or deny").option("--by <actor>",'Display label for decision maker (defaults to GENIE_AGENT_NAME or "cli")',"cli").action(async(id,options)=>{try{await handleResolve(id,options)}catch(error2){console.error(`Error: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}}),approval.command("list").description("List pending approvals").option("--agent <name>","Filter by agent name").option("--json","Output as JSON").action(async(options)=>{try{await handleList(options)}catch(error2){console.error(`Error: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}})}init_audit();init_db();var V2_SELECT=`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/genie",
3
- "version": "4.260428.3",
3
+ "version": "4.260428.4",
4
4
  "description": "Collaborative terminal toolkit for human + AI workflows. NOTE: the npm distribution is being soft-deprecated — the canonical install is `curl -fsSL https://get.automagik.dev/genie | bash` (cosign + SLSA verified). See https://automagik.dev/genie/security/distribution-sovereignty",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genie",
3
- "version": "4.260428.3",
3
+ "version": "4.260428.4",
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.260428.3",
3
+ "version": "4.260428.4",
4
4
  "private": true,
5
5
  "description": "Runtime dependencies for genie bundled CLIs",
6
6
  "type": "module",