@automagik/genie 4.260421.26 → 4.260421.28

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
@@ -403,7 +403,7 @@ ${bin} set-option -w pane-active-border-style "fg=$COLOR"
403
403
  UPDATE teams SET status = ${status}
404
404
  WHERE name = ${teamName}
405
405
  `).count===0)throw Error(`Team "${teamName}" not found.`)}var init_team_manager=__esm(()=>{init_agent_registry();init_audit();init_builtin_agents();init_claude_native_teams();init_db();init_executor_registry();init_genie_config2();init_tmux()});var exports_claude_native_teams={};__export(exports_claude_native_teams,{writeNativeInbox:()=>writeNativeInbox,unregisterNativeMember:()=>unregisterNativeMember,sanitizeTeamName:()=>sanitizeTeamName,resolveOrMintLeadSessionId:()=>resolveOrMintLeadSessionId,resolveNativeMemberName:()=>resolveNativeMemberName,registerNativeMember:()=>registerNativeMember,registerAsTeamLead:()=>registerAsTeamLead,loadNativeTeamConfig:()=>loadNativeTeamConfig,loadConfig:()=>loadConfig,loadAllNativeTeamConfigs:()=>loadAllNativeTeamConfigs,listTeamsWithUnreadInbox:()=>listTeamsWithUnreadInbox,listTeams:()=>listTeams2,isInsideClaudeCode:()=>isInsideClaudeCode,findTeamsContainingAgent:()=>findTeamsContainingAgent,ensureNativeTeamWithSessionId:()=>ensureNativeTeamWithSessionId,ensureNativeTeam:()=>ensureNativeTeam,discoverTeamName:()=>discoverTeamName,discoverClaudeParentSessionId:()=>discoverClaudeParentSessionId,deleteNativeTeam:()=>deleteNativeTeam,clearNativeInbox:()=>clearNativeInbox,assignColor:()=>assignColor});import{randomUUID as randomUUID3}from"crypto";import{existsSync as existsSync11}from"fs";import{mkdir as mkdir3,open,readFile as readFile3,readdir,rm as rm2,stat,writeFile as writeFile3}from"fs/promises";import{homedir as homedir8}from"os";import{join as join13}from"path";function claudeConfigDir2(){return process.env.CLAUDE_CONFIG_DIR??join13(homedir8(),".claude")}function teamsBaseDir(){return join13(claudeConfigDir2(),"teams")}function sanitizeTeamName(name){return name.replace(/[^a-zA-Z0-9]/g,"-").toLowerCase()}async function listTeams2(){try{return(await readdir(teamsBaseDir())).filter((e)=>!e.startsWith("."))}catch{return[]}}function teamDir(teamName){return join13(teamsBaseDir(),sanitizeTeamName(teamName))}function configPath(teamName){return join13(teamDir(teamName),"config.json")}function inboxesDir(teamName){return join13(teamDir(teamName),"inboxes")}function inboxPath(teamName,agentName){return join13(inboxesDir(teamName),`${sanitizeTeamName(agentName)}.json`)}async function loadConfig(teamName){try{let content=await readFile3(configPath(teamName),"utf-8");return JSON.parse(content)}catch(err){if(err instanceof Error&&"code"in err&&err.code==="ENOENT")return null;let message=err instanceof Error?err.message:String(err);return console.warn(`[claude-native-teams] Failed to load config for "${teamName}": ${message}`),null}}async function loadNativeTeamConfig(teamName){return loadConfig(teamName)}async function loadAllNativeTeamConfigs(){let teamNames=await listTeams2(),configs=[];for(let name of teamNames){let cfg=await loadConfig(name);if(cfg)configs.push(cfg)}return configs}async function findTeamsContainingAgent(agentName){let teams=await listTeams2(),matches=[];for(let teamName of teams){let config=await loadConfig(teamName);if(!config)continue;if(config.members.some((m)=>m.name===agentName||m.agentType===agentName))matches.push(teamName)}return matches}async function saveConfig(teamName,config){await writeFile3(configPath(teamName),JSON.stringify(config,null,2))}async function countLeadSessionRefs(){let counts=new Map,teams=await listTeams2();for(let team of teams){let leadSessionId=(await loadConfig(team))?.leadSessionId;if(!leadSessionId)continue;counts.set(leadSessionId,(counts.get(leadSessionId)??0)+1)}return counts}async function ensureNativeTeam(teamName,description,leadSessionId,leaderName){let dir=teamDir(teamName),inboxDir=inboxesDir(teamName);await mkdir3(dir,{recursive:!0}),await mkdir3(inboxDir,{recursive:!0}),ensureTeammateBypassPermissions();let existing=await loadConfig(teamName);if(existing)return await backfillTeamRow(sanitizeTeamName(teamName),existing),existing;let sanitized=sanitizeTeamName(teamName),resolvedLeader=sanitizeTeamName(leaderName??teamName),config={name:sanitized,description,createdAt:Date.now(),leadAgentId:`${resolvedLeader}@${sanitized}`,leadSessionId,members:[]};return await saveConfig(teamName,config),await backfillTeamRow(sanitized,config),config}async function backfillTeamRow(name,nativeConfig){try{let{ensureTeamRow:ensureTeamRow2}=await Promise.resolve().then(() => (init_team_manager(),exports_team_manager));await ensureTeamRow2(name,{nativeConfig})}catch{}}function isHealthyLeadSessionId(id){if(typeof id!=="string"||id.length===0)return!1;return/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id)}async function ensureNativeTeamWithSessionId(teamName,description,sessionId,leaderName){let config=await ensureNativeTeam(teamName,description,sessionId,leaderName);if(config.leadSessionId===sessionId)return config;if(isHealthyLeadSessionId(config.leadSessionId))return config;return config.leadSessionId=sessionId,await saveConfig(teamName,config),config}async function resolveOrMintLeadSessionId(teamName,cwd){let priorId=await findNewestSessionIdForTeam(teamName,cwd);if(priorId)return{sessionId:priorId,shouldResume:!0};return{sessionId:randomUUID3(),shouldResume:!1}}async function findNewestSessionIdForTeam(teamName,cwd){let projectDir=join13(claudeConfigDir2(),"projects",sanitizePath(cwd)),entries;try{entries=await readdir(projectDir)}catch{return null}let jsonls=entries.filter((e)=>e.endsWith(".jsonl"));if(jsonls.length===0)return null;let needle=sanitizeTeamName(teamName),best=null;for(let name of jsonls){let full=join13(projectDir,name);if(!await jsonlMatchesTitle(full,needle))continue;try{let s=await stat(full);if(!best||s.mtimeMs>best.mtime)best={name,mtime:s.mtimeMs}}catch{}}if(!best)return null;return best.name.replace(".jsonl","")}async function jsonlMatchesTitle(filePath,needle){let handle=null;try{handle=await open(filePath,"r");let buffer=Buffer.alloc(8192),{bytesRead}=await handle.read(buffer,0,buffer.length,0),head=buffer.toString("utf-8",0,bytesRead);for(let line of head.split(`
406
- `).slice(0,10)){let trimmed=line.trim();if(!trimmed||!trimmed.includes("custom-title"))continue;try{let entry=JSON.parse(trimmed);if(entry.type!=="custom-title"||typeof entry.customTitle!=="string")continue;if(entry.customTitle.toLowerCase()===needle)return!0}catch{}}}catch{return!1}finally{await handle?.close().catch(()=>{})}return!1}async function registerNativeMember(teamName,member){let config=await loadConfig(teamName);if(!config)throw Error(`Native team "${teamName}" not found`);let sanitized=sanitizeTeamName(teamName),agentId=`${sanitizeTeamName(member.agentName)}@${sanitized}`;config.members=config.members.filter((m)=>m.agentId!==agentId),config.members.push({agentId,name:sanitizeTeamName(member.agentName),agentType:member.agentType??"general-purpose",joinedAt:Date.now(),tmuxPaneId:member.tmuxPaneId,cwd:member.cwd??process.cwd(),backendType:"tmux",color:member.color,planModeRequired:member.planModeRequired??!1,isActive:!0}),await saveConfig(teamName,config);let inbox=inboxPath(teamName,member.agentName);if(!existsSync11(inbox))await writeFile3(inbox,"[]")}async function unregisterNativeMember(teamName,agentName){let config=await loadConfig(teamName);if(!config)return;let sanitized=sanitizeTeamName(teamName),agentId=`${sanitizeTeamName(agentName)}@${sanitized}`,before=config.members.length;if(config.members=config.members.filter((m)=>m.agentId!==agentId),config.members.length===before)return;await saveConfig(teamName,config)}async function writeNativeInbox(teamName,agentName,message){let path2=inboxPath(teamName,agentName);await mkdir3(inboxesDir(teamName),{recursive:!0}),await acquireLock(path2);try{let messages=[];try{let content=await readFile3(path2,"utf-8");messages=JSON.parse(content)}catch{}messages.push(message),await writeFile3(path2,JSON.stringify(messages,null,2))}finally{await releaseLock(path2)}}async function resolveNativeMemberName(teamName,genieWorkerId){let config=await loadConfig(teamName);if(!config||config.members.length===0)return null;let sanitizedId=sanitizeTeamName(genieWorkerId),sanitizedTeam=sanitizeTeamName(teamName),exactMatch=config.members.find((m)=>m.name===sanitizedId&&m.isActive);if(exactMatch)return exactMatch.name;let agentIdMatch=config.members.find((m)=>m.agentId===`${sanitizedId}@${sanitizedTeam}`&&m.isActive);if(agentIdMatch)return agentIdMatch.name;let teamPrefix=`${sanitizedTeam}-`;if(sanitizedId.startsWith(teamPrefix)){let stripped=sanitizedId.slice(teamPrefix.length),prefixMatch=config.members.find((m)=>m.name===stripped&&m.isActive);if(prefixMatch)return prefixMatch.name}let inactiveMatch=config.members.find((m)=>m.name===sanitizedId);if(inactiveMatch)return inactiveMatch.name;return null}async function assignColor(teamName){let config=await loadConfig(teamName);if(!config)return CLAUDE_TEAM_COLORS[0];let usedColors=new Set(config.members.map((m)=>m.color));for(let color of CLAUDE_TEAM_COLORS)if(!usedColors.has(color))return color;return CLAUDE_TEAM_COLORS[config.members.length%CLAUDE_TEAM_COLORS.length]}async function clearNativeInbox(teamName,agentName){let path2=inboxPath(teamName,agentName);await acquireLock(path2);try{await writeFile3(path2,"[]")}finally{await releaseLock(path2)}}async function deleteNativeTeam(teamName){let dir=teamDir(teamName);if(!existsSync11(dir))return!1;return await rm2(dir,{recursive:!0,force:!0}),!0}function extractLeaderInboxName(config,teamName){if(!config?.leadAgentId)return teamName??"unknown";let atIdx=config.leadAgentId.indexOf("@");return atIdx>0?config.leadAgentId.slice(0,atIdx):teamName??"unknown"}async function scanTeamInbox(base,name){let config=null;try{let cfgContent=await readFile3(join13(base,name,"config.json"),"utf-8");config=JSON.parse(cfgContent)}catch{}let leaderInboxName=extractLeaderInboxName(config,name),inboxFile=join13(base,name,"inboxes",`${leaderInboxName}.json`),messages;try{let content=await readFile3(inboxFile,"utf-8");messages=JSON.parse(content)}catch{return null}if(!Array.isArray(messages))return null;let unread=messages.filter((m)=>m.read===!1);if(unread.length===0)return null;let workingDir=null;if(config){let leadMember=config.members.find((m)=>m.agentId===config?.leadAgentId||m.name===leaderInboxName);if(leadMember?.cwd)workingDir=leadMember.cwd}return{teamName:name,unreadCount:unread.length,workingDir,firstUnreadText:unread[0]?.text??null}}async function listTeamsWithUnreadInbox(){let base=teamsBaseDir(),teamDirs;try{teamDirs=await readdir(base)}catch{return[]}let results=[];for(let name of teamDirs){let entry=await scanTeamInbox(base,name);if(entry)results.push(entry)}return results}function sanitizePath(p){return p.replace(/[^a-zA-Z0-9]/g,"-")}async function discoverClaudeSessionId(cwd){let envSessionId=process.env.CLAUDE_CODE_SESSION_ID;if(envSessionId)return envSessionId;let projectDir=join13(claudeConfigDir2(),"projects",sanitizePath(cwd??process.cwd()));try{let jsonls=(await readdir(projectDir)).filter((e)=>e.endsWith(".jsonl"));if(jsonls.length===0)return null;let newest=null;for(let name of jsonls){let s=await stat(join13(projectDir,name));if(!newest||s.mtimeMs>newest.mtime)newest={name,mtime:s.mtimeMs}}if(!newest)return null;return newest.name.replace(".jsonl","")}catch{return null}}async function readSessionMetadata(filePath){let handle=null;try{handle=await open(filePath,"r");let buffer=Buffer.alloc(8192),{bytesRead}=await handle.read(buffer,0,buffer.length,0),head=buffer.toString("utf-8",0,bytesRead);for(let line of head.split(`
406
+ `).slice(0,10)){let trimmed=line.trim();if(!trimmed||!trimmed.includes("custom-title"))continue;try{let entry=JSON.parse(trimmed);if(entry.type!=="custom-title"||typeof entry.customTitle!=="string")continue;if(entry.customTitle.toLowerCase()===needle)return!0}catch{}}}catch{return!1}finally{await handle?.close().catch(()=>{})}return!1}async function registerNativeMember(teamName,member){let config=await loadConfig(teamName);if(!config)throw Error(`Native team "${teamName}" not found`);let sanitized=sanitizeTeamName(teamName),agentId=`${sanitizeTeamName(member.agentName)}@${sanitized}`;config.members=config.members.filter((m)=>m.agentId!==agentId),config.members.push({agentId,name:sanitizeTeamName(member.agentName),agentType:member.agentType??"general-purpose",joinedAt:Date.now(),tmuxPaneId:member.tmuxPaneId,cwd:member.cwd??process.cwd(),backendType:"tmux",color:member.color,planModeRequired:member.planModeRequired??!1,isActive:!0}),await saveConfig(teamName,config);let inbox=inboxPath(teamName,member.agentName);if(!existsSync11(inbox))await writeFile3(inbox,"[]")}async function unregisterNativeMember(teamName,agentName){let config=await loadConfig(teamName);if(!config)return;let sanitized=sanitizeTeamName(teamName),agentId=`${sanitizeTeamName(agentName)}@${sanitized}`,before=config.members.length;if(config.members=config.members.filter((m)=>m.agentId!==agentId),config.members.length===before)return;await saveConfig(teamName,config)}async function writeNativeInbox(teamName,agentName,message){let path2=inboxPath(teamName,agentName);await mkdir3(inboxesDir(teamName),{recursive:!0}),await acquireLock(path2);try{let messages=[];try{let content=await readFile3(path2,"utf-8");messages=JSON.parse(content)}catch{}messages.push(message),await writeFile3(path2,JSON.stringify(messages,null,2))}finally{await releaseLock(path2)}}async function resolveNativeMemberName(teamName,genieWorkerId){let config=await loadConfig(teamName);if(!config||config.members.length===0)return null;let sanitizedId=sanitizeTeamName(genieWorkerId),sanitizedTeam=sanitizeTeamName(teamName),exactMatch=config.members.find((m)=>m.name===sanitizedId&&m.isActive);if(exactMatch)return exactMatch.name;let agentIdMatch=config.members.find((m)=>m.agentId===`${sanitizedId}@${sanitizedTeam}`&&m.isActive);if(agentIdMatch)return agentIdMatch.name;let teamPrefix=`${sanitizedTeam}-`;if(sanitizedId.startsWith(teamPrefix)){let stripped=sanitizedId.slice(teamPrefix.length),prefixMatch=config.members.find((m)=>m.name===stripped&&m.isActive);if(prefixMatch)return prefixMatch.name}let inactiveMatch=config.members.find((m)=>m.name===sanitizedId);if(inactiveMatch)return inactiveMatch.name;return null}async function assignColor(teamName){let config=await loadConfig(teamName);if(!config)return CLAUDE_TEAM_COLORS[0];let usedColors=new Set(config.members.map((m)=>m.color));for(let color of CLAUDE_TEAM_COLORS)if(!usedColors.has(color))return color;return CLAUDE_TEAM_COLORS[config.members.length%CLAUDE_TEAM_COLORS.length]}async function clearNativeInbox(teamName,agentName){let path2=inboxPath(teamName,agentName);await acquireLock(path2);try{await writeFile3(path2,"[]")}finally{await releaseLock(path2)}}async function deleteNativeTeam(teamName){let dir=teamDir(teamName);if(!existsSync11(dir))return!1;return await rm2(dir,{recursive:!0,force:!0}),!0}function extractLeaderInboxName(config,teamName){if(!config?.leadAgentId)return teamName??"unknown";let atIdx=config.leadAgentId.indexOf("@");return atIdx>0?config.leadAgentId.slice(0,atIdx):teamName??"unknown"}async function scanTeamInbox(base,name){let config=null;try{let cfgContent=await readFile3(join13(base,name,"config.json"),"utf-8");config=JSON.parse(cfgContent)}catch{}let leaderInboxName=extractLeaderInboxName(config,name),inboxFile=join13(base,name,"inboxes",`${leaderInboxName}.json`),messages;try{let content=await readFile3(inboxFile,"utf-8");messages=JSON.parse(content)}catch{return null}if(!Array.isArray(messages))return null;let unread=messages.filter((m)=>m.read===!1);if(unread.length===0)return null;let workingDir=null;if(config){let leadMember=config.members.find((m)=>m.agentId===config?.leadAgentId||m.name===leaderInboxName);if(leadMember?.cwd)workingDir=leadMember.cwd;else if(config.worktreePath)workingDir=config.worktreePath;else if(config.repo)workingDir=config.repo}return{teamName:name,unreadCount:unread.length,workingDir,firstUnreadText:unread[0]?.text??null}}async function listTeamsWithUnreadInbox(){let base=teamsBaseDir(),teamDirs;try{teamDirs=await readdir(base)}catch{return[]}let results=[];for(let name of teamDirs){let entry=await scanTeamInbox(base,name);if(entry)results.push(entry)}return results}function sanitizePath(p){return p.replace(/[^a-zA-Z0-9]/g,"-")}async function discoverClaudeSessionId(cwd){let envSessionId=process.env.CLAUDE_CODE_SESSION_ID;if(envSessionId)return envSessionId;let projectDir=join13(claudeConfigDir2(),"projects",sanitizePath(cwd??process.cwd()));try{let jsonls=(await readdir(projectDir)).filter((e)=>e.endsWith(".jsonl"));if(jsonls.length===0)return null;let newest=null;for(let name of jsonls){let s=await stat(join13(projectDir,name));if(!newest||s.mtimeMs>newest.mtime)newest={name,mtime:s.mtimeMs}}if(!newest)return null;return newest.name.replace(".jsonl","")}catch{return null}}async function readSessionMetadata(filePath){let handle=null;try{handle=await open(filePath,"r");let buffer=Buffer.alloc(8192),{bytesRead}=await handle.read(buffer,0,buffer.length,0),head=buffer.toString("utf-8",0,bytesRead);for(let line of head.split(`
407
407
  `).slice(0,20)){let trimmed=line.trim();if(!trimmed)continue;try{let entry=JSON.parse(trimmed),teamName=typeof entry.teamName==="string"?entry.teamName:void 0,agentName=typeof entry.agentName==="string"?entry.agentName:void 0;if(teamName||agentName)return{teamName,agentName}}catch{}}}catch{return{}}finally{await handle?.close().catch(()=>{})}return{}}function rootScore(metadata){if(!metadata.teamName&&!metadata.agentName)return 2;if(metadata.teamName&&!metadata.agentName)return 1;return 0}function compareSessionRanking(a,b,leadRefs){let aLeadRefs=leadRefs.get(a.name.replace(".jsonl",""))??0,bLeadRefs=leadRefs.get(b.name.replace(".jsonl",""))??0;if(aLeadRefs!==bLeadRefs)return bLeadRefs-aLeadRefs;let aRoot=rootScore(a.metadata),bRoot=rootScore(b.metadata);if(aRoot!==bRoot)return bRoot-aRoot;return b.mtime-a.mtime}async function discoverClaudeParentSessionId(cwd){let envSessionId=process.env.CLAUDE_CODE_SESSION_ID;if(envSessionId)return envSessionId;let projectDir=join13(claudeConfigDir2(),"projects",sanitizePath(cwd??process.cwd()));try{let jsonls=(await readdir(projectDir)).filter((e)=>e.endsWith(".jsonl"));if(jsonls.length===0)return null;let ranked=await Promise.all(jsonls.map(async(name)=>{let filePath=join13(projectDir,name),s=await stat(filePath),metadata=await readSessionMetadata(filePath);return{name,mtime:s.mtimeMs,metadata}})),leadRefs=await countLeadSessionRefs();return ranked.sort((a,b)=>compareSessionRanking(a,b,leadRefs)),ranked[0]?.name.replace(".jsonl","")??null}catch{return null}}function isInsideClaudeCode(){return process.env.CLAUDECODE==="1"}async function discoverTeamName(cwd){let envTeam=process.env.GENIE_TEAM;if(envTeam)return envTeam;let base=teamsBaseDir(),sessionId=await discoverClaudeSessionId(cwd);if(sessionId)try{let teams=await readdir(base);for(let name of teams){let cfgPath=join13(base,name,"config.json");try{let content=await readFile3(cfgPath,"utf-8"),config=JSON.parse(content);if(config.leadSessionId===sessionId)return config.name}catch{}}}catch{}let tmuxSessionName=await currentTmuxSessionName();if(tmuxSessionName){let cfgPath=join13(base,tmuxSessionName,"config.json");try{let content=await readFile3(cfgPath,"utf-8");return JSON.parse(content).name}catch{}}return null}async function currentTmuxSessionName(){if(!process.env.TMUX)return null;try{let{getCurrentSessionName:getCurrentSessionName2}=await Promise.resolve().then(() => (init_tmux(),exports_tmux));return await getCurrentSessionName2()}catch{return null}}async function registerAsTeamLead(teamName,opts){let sessionId=await discoverClaudeSessionId(opts?.cwd);if(!sessionId)throw Error("Could not discover Claude Code session ID. Are you running inside Claude Code with CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1?");let resolvedLeaderName=opts?.leaderName??teamName,config=await ensureNativeTeam(teamName,`Genie team: ${teamName}`,sessionId,resolvedLeaderName);if(config.leadSessionId!==sessionId)config.leadSessionId=sessionId,await saveConfig(teamName,config);let sanitized=sanitizeTeamName(teamName),leadAgentId=`${sanitizeTeamName(resolvedLeaderName)}@${sanitized}`,existingLead=config.members.find((m)=>m.agentId===leadAgentId),resolvedPaneId=opts?.tmuxPaneId??process.env.TMUX_PANE;if(!existingLead||!existingLead.isActive)await registerNativeMember(teamName,{agentName:resolvedLeaderName,agentType:"general-purpose",color:opts?.color??"blue",tmuxPaneId:resolvedPaneId,cwd:opts?.cwd??process.cwd()});else if(resolvedPaneId&&existingLead.tmuxPaneId!==resolvedPaneId)existingLead.tmuxPaneId=resolvedPaneId,await saveConfig(teamName,config);let inbox=inboxPath(teamName,resolvedLeaderName);if(!existsSync11(inbox))await writeFile3(inbox,"[]");let finalConfig=await loadConfig(teamName);if(!finalConfig)throw Error(`Failed to load config for team "${teamName}" after creation`);return{sessionId,config:finalConfig}}var init_claude_native_teams=__esm(()=>{init_claude_settings();init_lockfile();init_provider_adapters()});import{existsSync as existsSync12}from"fs";import{readFile as readFile4,readdir as readdir2,rename}from"fs/promises";import{homedir as homedir9}from"os";import{join as join14}from"path";function getGenieHome(){return process.env.GENIE_HOME??join14(homedir9(),".genie")}function workersJsonPath(){return join14(getGenieHome(),"workers.json")}function needsMigration(filePath){return existsSync12(filePath)&&!existsSync12(`${filePath}.migrated`)}async function readJson(filePath){try{let content=await readFile4(filePath,"utf-8");return JSON.parse(content)}catch{return null}}async function renameMatchingFiles(dir,filter){if(!existsSync12(dir))return;try{let files=await readdir2(dir);for(let f of files){if(!filter(f))continue;let fp=join14(dir,f);if(needsMigration(fp))await rename(fp,`${fp}.migrated`)}}catch{}}function needsSeed(){if(needsMigration(workersJsonPath()))return!0;let claudeTeamsDir=join14(process.env.CLAUDE_CONFIG_DIR??join14(homedir9(),".claude"),"teams");if(!existsSync12(claudeTeamsDir))return!1;try{return __require("fs").readdirSync(claudeTeamsDir).some((e)=>!e.startsWith("."))}catch{return!1}}function toAgentRow(a){let now=new Date().toISOString();return{id:a.id,pane_id:a.paneId??"",session:a.session??"",worktree:a.worktree??null,task_id:a.taskId??null,task_title:a.taskTitle??null,wish_slug:a.wishSlug??null,group_number:a.groupNumber??null,started_at:a.startedAt??now,state:a.state??"spawning",last_state_change:a.lastStateChange??now,repo_path:a.repoPath??"",claude_session_id:a.claudeSessionId??null,window_name:a.windowName??null,window_id:a.windowId??null,role:a.role??null,custom_name:a.customName??null,sub_panes:a.subPanes??[],provider:a.provider??null,transport:a.transport??"tmux",skill:a.skill??null,team:a.team??null,tmux_window:a.window??null,native_agent_id:a.nativeAgentId??null,native_color:a.nativeColor??null,native_team_enabled:a.nativeTeamEnabled??!1,parent_session_id:a.parentSessionId??null,suspended_at:a.suspendedAt??null,auto_resume:a.autoResume??!0,resume_attempts:a.resumeAttempts??0,last_resume_attempt:a.lastResumeAttempt??null,max_resume_attempts:a.maxResumeAttempts??3,pane_color:null}}async function upsertAgent(sql,a){let r=toAgentRow(a);await sql`
408
408
  INSERT INTO agents (
409
409
  id, pane_id, session, worktree, task_id, task_title,
@@ -755,7 +755,7 @@ Next steps:`),console.log(" 1. Reload tmux: tmux source ~/.tmux.conf"),console.
755
755
  UPDATE agents
756
756
  SET metadata = metadata || ${sql.json(metadataPatch)}
757
757
  WHERE role = ${name}
758
- `}catch{}return updated}function loadIdentity(entry2){if(!entry2.dir)return null;let agentsPath=join26(entry2.dir,"AGENTS.md");if(existsSync24(agentsPath))return agentsPath;return null}function builtinToEntry(agent){return{name:agent.name,dir:"",promptMode:agent.promptMode??"append",model:agent.model,roles:[],registeredAt:"(built-in)"}}function roleToEntry(role,team,metadata,createdAt){if(!(metadata&&Object.keys(metadata).length>0)){let builtin=[...BUILTIN_ROLES,...BUILTIN_COUNCIL_MEMBERS].find((b2)=>b2.name===role);if(builtin)return builtinToEntry(builtin)}let registeredAt=(typeof metadata?.registeredAt==="string"?metadata.registeredAt:void 0)??createdAt??"";return{name:role,dir:metadata?.dir||"",promptMode:metadata?.promptMode||"append",model:metadata?.model,roles:[],registeredAt,description:metadata?.description,color:metadata?.color,provider:metadata?.provider,permissions:metadata?.permissions,disallowedTools:metadata?.disallowedTools,omniScopes:metadata?.omniScopes,hooks:metadata?.hooks,sdk:metadata?.sdk,bridgeTmuxSession:metadata?.bridgeTmuxSession,...metadata?.repo?{repo:metadata.repo}:team?{repo:team}:{}}}function buildMetadata(entry2){let meta={};if(entry2.dir)meta.dir=entry2.dir;if(entry2.repo)meta.repo=entry2.repo;if(entry2.model)meta.model=entry2.model;if(entry2.promptMode&&entry2.promptMode!=="append")meta.promptMode=entry2.promptMode;if(entry2.description)meta.description=entry2.description;if(entry2.color)meta.color=entry2.color;if(entry2.provider)meta.provider=entry2.provider;if(entry2.permissions)meta.permissions=entry2.permissions;if(entry2.disallowedTools)meta.disallowedTools=entry2.disallowedTools;if(entry2.omniScopes)meta.omniScopes=entry2.omniScopes;if(entry2.hooks)meta.hooks=entry2.hooks;if(entry2.sdk)meta.sdk=entry2.sdk;return meta.bridgeTmuxSession=entry2.bridgeTmuxSession??null,meta}function parseMetadata(raw){if(!raw)return{};if(typeof raw==="object"&&!Array.isArray(raw))return raw;if(typeof raw==="string")try{return JSON.parse(raw)}catch{return{}}return{}}var init_agent_directory=__esm(()=>{init_builtin_agents()});var exports_runtime_events={};__export(exports_runtime_events,{waitForRuntimeEvent:()=>waitForRuntimeEvent,queryRuntimeEventThroughput:()=>queryRuntimeEventThroughput,publishSubjectEvent:()=>publishSubjectEvent,publishRuntimeEvent:()=>publishRuntimeEvent,listRuntimeEvents:()=>listRuntimeEvents,getLatestRuntimeEventId:()=>getLatestRuntimeEventId,followRuntimeEvents:()=>followRuntimeEvents});class EventCircuitBreaker{failures=0;lastFailure=0;loggedOpen=!1;threshold=5;cooldown=30000;isOpen(){if(this.failures<this.threshold)return!1;if(Date.now()-this.lastFailure>this.cooldown)return this.failures=0,!1;return!0}recordSuccess(){if(this.failures>=this.threshold)console.warn("[runtime-events] circuit breaker closed \u2014 PG writes resumed");this.failures=0,this.loggedOpen=!1}recordFailure(){if(this.failures++,this.lastFailure=Date.now(),this.failures>=this.threshold&&!this.loggedOpen)console.warn(`[runtime-events] circuit breaker open \u2014 skipping PG writes for ${this.cooldown/1000}s after ${this.threshold} consecutive failures`),this.loggedOpen=!0}get state(){if(this.failures<this.threshold)return"closed";if(Date.now()-this.lastFailure>this.cooldown)return"half-open";return"open"}}function logFollowDrainError(context,error2,active){if(!active)return;let message=error2 instanceof Error?error2.message:String(error2);console.error(`[runtime-events] ${context} drain failed: ${message}`)}function rowToRuntimeEvent(row){return{id:Number(row.id),repoPath:row.repo_path,timestamp:row.created_at instanceof Date?row.created_at.toISOString():String(row.created_at),kind:row.kind,agent:row.agent,team:row.team??void 0,direction:row.direction??void 0,peer:row.peer??void 0,text:row.text,data:row.data??void 0,source:row.source,subject:row.subject??void 0,threadId:row.thread_id??void 0,traceId:row.trace_id??void 0,parentEventId:row.parent_event_id!=null?Number(row.parent_event_id):void 0}}function nextParam(values2,value){return values2.push(value),`$${values2.length}`}function buildScopeClause(query,values2){let scopeClauses=[];if(query.agentIds&&query.agentIds.length>0)scopeClauses.push(`agent = ANY(${nextParam(values2,query.agentIds)})`);if(query.team)scopeClauses.push(`team = ${nextParam(values2,query.team)}`);if(query.teamPrefix)scopeClauses.push(`team LIKE ${nextParam(values2,`${query.teamPrefix}%`)}`);if(scopeClauses.length===0)return null;if(scopeClauses.length===1)return scopeClauses[0];if(query.scopeMode==="any")return`(${scopeClauses.join(" OR ")})`;return`(${scopeClauses.join(" AND ")})`}function buildWhere(query){let values2=[],clauses=[];if(query.afterId!=null)clauses.push(`id > ${nextParam(values2,query.afterId)}`);if(query.repoPath)clauses.push(`repo_path = ${nextParam(values2,query.repoPath)}`);if(query.subject)clauses.push(`subject = ${nextParam(values2,query.subject)}`);if(query.kinds&&query.kinds.length>0)clauses.push(`kind = ANY(${nextParam(values2,query.kinds)})`);if(query.since)clauses.push(`created_at >= ${nextParam(values2,query.since)}`);if(query.threadId)clauses.push(`thread_id = ${nextParam(values2,query.threadId)}`);if(query.traceId)clauses.push(`trace_id = ${nextParam(values2,query.traceId)}`);let scopeClause=buildScopeClause(query,values2);if(scopeClause)clauses.push(scopeClause);return{clause:clauses.length>0?`WHERE ${clauses.join(" AND ")}`:"",values:values2}}async function publishRuntimeEvent(input){if(circuitBreaker.isOpen())throw Error("circuit breaker open \u2014 PG event write skipped");try{let sql=await getConnection(),threadId=input.threadId??`agent:${input.agent}`,rows=await sql`
758
+ `}catch{}return updated}function loadIdentity(entry2){if(!entry2.dir)return null;let agentsPath=join26(entry2.dir,"AGENTS.md");if(existsSync24(agentsPath))return agentsPath;return null}function builtinToEntry(agent){return{name:agent.name,dir:"",promptMode:agent.promptMode??"append",model:agent.model,roles:[],registeredAt:"(built-in)"}}function roleToEntry(role,team,metadata,createdAt){if(!(metadata&&Object.keys(metadata).length>0)){let builtin=[...BUILTIN_ROLES,...BUILTIN_COUNCIL_MEMBERS].find((b2)=>b2.name===role);if(builtin)return builtinToEntry(builtin)}let registeredAt=(typeof metadata?.registeredAt==="string"?metadata.registeredAt:void 0)??createdAt??"";return{name:role,dir:metadata?.dir||"",promptMode:metadata?.promptMode||"append",model:metadata?.model,roles:Array.isArray(metadata?.roles)?metadata.roles:[],registeredAt,description:metadata?.description,color:metadata?.color,provider:metadata?.provider,permissions:metadata?.permissions,disallowedTools:metadata?.disallowedTools,omniScopes:metadata?.omniScopes,hooks:metadata?.hooks,sdk:metadata?.sdk,bridgeTmuxSession:metadata?.bridgeTmuxSession,...metadata?.repo?{repo:metadata.repo}:team?{repo:team}:{}}}function buildMetadata(entry2){let meta={};if(entry2.dir)meta.dir=entry2.dir;if(entry2.repo)meta.repo=entry2.repo;if(entry2.model)meta.model=entry2.model;if(entry2.promptMode&&entry2.promptMode!=="append")meta.promptMode=entry2.promptMode;if(entry2.description)meta.description=entry2.description;if(entry2.color)meta.color=entry2.color;if(entry2.provider)meta.provider=entry2.provider;if(entry2.roles&&entry2.roles.length>0)meta.roles=entry2.roles;if(entry2.permissions)meta.permissions=entry2.permissions;if(entry2.disallowedTools)meta.disallowedTools=entry2.disallowedTools;if(entry2.omniScopes)meta.omniScopes=entry2.omniScopes;if(entry2.hooks)meta.hooks=entry2.hooks;if(entry2.sdk)meta.sdk=entry2.sdk;return meta.bridgeTmuxSession=entry2.bridgeTmuxSession??null,meta}function parseMetadata(raw){if(!raw)return{};if(typeof raw==="object"&&!Array.isArray(raw))return raw;if(typeof raw==="string")try{return JSON.parse(raw)}catch{return{}}return{}}var init_agent_directory=__esm(()=>{init_builtin_agents()});var exports_runtime_events={};__export(exports_runtime_events,{waitForRuntimeEvent:()=>waitForRuntimeEvent,queryRuntimeEventThroughput:()=>queryRuntimeEventThroughput,publishSubjectEvent:()=>publishSubjectEvent,publishRuntimeEvent:()=>publishRuntimeEvent,listRuntimeEvents:()=>listRuntimeEvents,getLatestRuntimeEventId:()=>getLatestRuntimeEventId,followRuntimeEvents:()=>followRuntimeEvents});class EventCircuitBreaker{failures=0;lastFailure=0;loggedOpen=!1;threshold=5;cooldown=30000;isOpen(){if(this.failures<this.threshold)return!1;if(Date.now()-this.lastFailure>this.cooldown)return this.failures=0,!1;return!0}recordSuccess(){if(this.failures>=this.threshold)console.warn("[runtime-events] circuit breaker closed \u2014 PG writes resumed");this.failures=0,this.loggedOpen=!1}recordFailure(){if(this.failures++,this.lastFailure=Date.now(),this.failures>=this.threshold&&!this.loggedOpen)console.warn(`[runtime-events] circuit breaker open \u2014 skipping PG writes for ${this.cooldown/1000}s after ${this.threshold} consecutive failures`),this.loggedOpen=!0}get state(){if(this.failures<this.threshold)return"closed";if(Date.now()-this.lastFailure>this.cooldown)return"half-open";return"open"}}function logFollowDrainError(context,error2,active){if(!active)return;let message=error2 instanceof Error?error2.message:String(error2);console.error(`[runtime-events] ${context} drain failed: ${message}`)}function rowToRuntimeEvent(row){return{id:Number(row.id),repoPath:row.repo_path,timestamp:row.created_at instanceof Date?row.created_at.toISOString():String(row.created_at),kind:row.kind,agent:row.agent,team:row.team??void 0,direction:row.direction??void 0,peer:row.peer??void 0,text:row.text,data:row.data??void 0,source:row.source,subject:row.subject??void 0,threadId:row.thread_id??void 0,traceId:row.trace_id??void 0,parentEventId:row.parent_event_id!=null?Number(row.parent_event_id):void 0}}function nextParam(values2,value){return values2.push(value),`$${values2.length}`}function buildScopeClause(query,values2){let scopeClauses=[];if(query.agentIds&&query.agentIds.length>0)scopeClauses.push(`agent = ANY(${nextParam(values2,query.agentIds)})`);if(query.team)scopeClauses.push(`team = ${nextParam(values2,query.team)}`);if(query.teamPrefix)scopeClauses.push(`team LIKE ${nextParam(values2,`${query.teamPrefix}%`)}`);if(scopeClauses.length===0)return null;if(scopeClauses.length===1)return scopeClauses[0];if(query.scopeMode==="any")return`(${scopeClauses.join(" OR ")})`;return`(${scopeClauses.join(" AND ")})`}function buildWhere(query){let values2=[],clauses=[];if(query.afterId!=null)clauses.push(`id > ${nextParam(values2,query.afterId)}`);if(query.repoPath)clauses.push(`repo_path = ${nextParam(values2,query.repoPath)}`);if(query.subject)clauses.push(`subject = ${nextParam(values2,query.subject)}`);if(query.kinds&&query.kinds.length>0)clauses.push(`kind = ANY(${nextParam(values2,query.kinds)})`);if(query.since)clauses.push(`created_at >= ${nextParam(values2,query.since)}`);if(query.threadId)clauses.push(`thread_id = ${nextParam(values2,query.threadId)}`);if(query.traceId)clauses.push(`trace_id = ${nextParam(values2,query.traceId)}`);let scopeClause=buildScopeClause(query,values2);if(scopeClause)clauses.push(scopeClause);return{clause:clauses.length>0?`WHERE ${clauses.join(" AND ")}`:"",values:values2}}async function publishRuntimeEvent(input){if(circuitBreaker.isOpen())throw Error("circuit breaker open \u2014 PG event write skipped");try{let sql=await getConnection(),threadId=input.threadId??`agent:${input.agent}`,rows=await sql`
759
759
  INSERT INTO genie_runtime_events (
760
760
  repo_path, subject, kind, source, agent, team, direction, peer, text, data, thread_id, trace_id, parent_event_id, created_at
761
761
  )
@@ -890,7 +890,7 @@ Run 'genie agent list' to list agents.`)}async function resolveTarget(target,opt
890
890
  `))return{frontmatter:null,body:content};let after=content.slice(4),frontmatter,afterClose;if(after.startsWith("---"))frontmatter="",afterClose=after.slice(3);else{let closeIdx=after.indexOf(`
891
891
  ---`);if(closeIdx===-1)return{frontmatter:null,body:content};frontmatter=after.slice(0,closeIdx),afterClose=after.slice(closeIdx+4)}let body=afterClose.startsWith(`
892
892
  `)?afterClose.slice(1):afterClose;return{frontmatter,body}}var SdkPermissionModeSchema,SdkEffortLevelSchema,SdkThinkingConfigSchema,SdkMcpStdioServerConfigSchema,SdkMcpSSEServerConfigSchema,SdkMcpHttpServerConfigSchema,SdkMcpServerConfigSchema,SdkSubagentConfigSchema,SdkCustomToolConfigSchema,SdkOutputFormatSchema,SdkPluginConfigSchema,SdkSandboxConfigSchema,SdkHookMatcherConfigSchema,SdkHookEventSchema,SdkBetaSchema,SdkSystemPromptSchema,SdkDirectoryConfigSchema,AgentConfigSchema,DERIVED_KEYS;var init_agent_yaml=__esm(()=>{init_js_yaml();init_zod();init_lockfile();SdkPermissionModeSchema=exports_external.enum(["default","acceptEdits","bypassPermissions","plan","dontAsk","auto","remoteApproval"]),SdkEffortLevelSchema=exports_external.union([exports_external.enum(["low","medium","high","max"]),exports_external.number()]),SdkThinkingConfigSchema=exports_external.union([exports_external.object({type:exports_external.literal("adaptive")}).strict(),exports_external.object({type:exports_external.literal("enabled"),budgetTokens:exports_external.number().optional()}).strict(),exports_external.object({type:exports_external.literal("disabled")}).strict()]),SdkMcpStdioServerConfigSchema=exports_external.object({type:exports_external.literal("stdio").optional(),command:exports_external.string(),args:exports_external.array(exports_external.string()).optional(),env:exports_external.record(exports_external.string()).optional()}).strict(),SdkMcpSSEServerConfigSchema=exports_external.object({type:exports_external.literal("sse"),url:exports_external.string(),headers:exports_external.record(exports_external.string()).optional()}).strict(),SdkMcpHttpServerConfigSchema=exports_external.object({type:exports_external.literal("http"),url:exports_external.string(),headers:exports_external.record(exports_external.string()).optional()}).strict(),SdkMcpServerConfigSchema=exports_external.union([SdkMcpStdioServerConfigSchema,SdkMcpSSEServerConfigSchema,SdkMcpHttpServerConfigSchema]),SdkSubagentConfigSchema=exports_external.object({description:exports_external.string(),prompt:exports_external.string(),tools:exports_external.array(exports_external.string()).optional(),disallowedTools:exports_external.array(exports_external.string()).optional(),model:exports_external.string().optional(),mcpServers:exports_external.array(exports_external.union([exports_external.string(),exports_external.record(SdkMcpStdioServerConfigSchema)])).optional(),skills:exports_external.array(exports_external.string()).optional(),maxTurns:exports_external.number().optional(),background:exports_external.boolean().optional(),memory:exports_external.enum(["user","project","local"]).optional(),effort:SdkEffortLevelSchema.optional(),permissionMode:SdkPermissionModeSchema.optional()}).strict(),SdkCustomToolConfigSchema=exports_external.object({name:exports_external.string(),description:exports_external.string(),inputSchema:exports_external.record(exports_external.unknown()),handler:exports_external.string().optional()}).strict(),SdkOutputFormatSchema=exports_external.object({type:exports_external.literal("json_schema"),schema:exports_external.record(exports_external.unknown())}).strict(),SdkPluginConfigSchema=exports_external.object({type:exports_external.literal("local"),path:exports_external.string()}).strict(),SdkSandboxConfigSchema=exports_external.object({enabled:exports_external.boolean().optional(),autoAllowBashIfSandboxed:exports_external.boolean().optional(),failIfUnavailable:exports_external.boolean().optional(),network:exports_external.object({allowLocalBinding:exports_external.boolean().optional(),allowUnixSockets:exports_external.array(exports_external.string()).optional()}).strict().optional()}).strict(),SdkHookMatcherConfigSchema=exports_external.object({toolName:exports_external.string().optional(),agentName:exports_external.string().optional()}).strict(),SdkHookEventSchema=exports_external.enum(["PreToolUse","PostToolUse","PostToolUseFailure","Notification","UserPromptSubmit","SessionStart","SessionEnd","Stop","StopFailure","SubagentStart","SubagentStop","PreCompact","PostCompact","PermissionRequest","PermissionDenied","Setup","TeammateIdle","TaskCreated","TaskCompleted","Elicitation","ElicitationResult","ConfigChange","WorktreeCreate","WorktreeRemove","InstructionsLoaded","CwdChanged","FileChanged"]),SdkBetaSchema=exports_external.enum(["context-1m-2025-08-07"]),SdkSystemPromptSchema=exports_external.union([exports_external.string(),exports_external.object({type:exports_external.literal("preset"),preset:exports_external.literal("claude_code"),append:exports_external.string().optional()}).strict()]),SdkDirectoryConfigSchema=exports_external.object({permissionMode:SdkPermissionModeSchema.optional(),tools:exports_external.union([exports_external.array(exports_external.string()),exports_external.object({type:exports_external.literal("preset"),preset:exports_external.literal("claude_code")}).strict()]).optional(),allowedTools:exports_external.array(exports_external.string()).optional(),disallowedTools:exports_external.array(exports_external.string()).optional(),maxTurns:exports_external.number().optional(),maxBudgetUsd:exports_external.number().optional(),effort:SdkEffortLevelSchema.optional(),thinking:SdkThinkingConfigSchema.optional(),agent:exports_external.string().optional(),agents:exports_external.record(SdkSubagentConfigSchema).optional(),mcpServers:exports_external.record(SdkMcpServerConfigSchema).optional(),plugins:exports_external.array(SdkPluginConfigSchema).optional(),customTools:exports_external.array(SdkCustomToolConfigSchema).optional(),persistSession:exports_external.boolean().optional(),enableFileCheckpointing:exports_external.boolean().optional(),outputFormat:SdkOutputFormatSchema.optional(),includePartialMessages:exports_external.boolean().optional(),includeHookEvents:exports_external.boolean().optional(),promptSuggestions:exports_external.boolean().optional(),agentProgressSummaries:exports_external.boolean().optional(),systemPrompt:SdkSystemPromptSchema.optional(),sandbox:SdkSandboxConfigSchema.optional(),betas:exports_external.array(SdkBetaSchema).optional(),settingSources:exports_external.array(exports_external.enum(["user","project","local"])).optional(),settings:exports_external.union([exports_external.string(),exports_external.record(exports_external.unknown())]).optional(),hooks:exports_external.record(SdkHookEventSchema,exports_external.array(SdkHookMatcherConfigSchema)).optional()}).strict(),AgentConfigSchema=exports_external.object({name:exports_external.string().optional(),dir:exports_external.string().optional(),repo:exports_external.string().optional(),team:exports_external.string().optional(),promptMode:exports_external.enum(["system","append"]).optional(),model:exports_external.string().optional(),roles:exports_external.array(exports_external.string()).optional(),omniAgentId:exports_external.string().optional(),registeredAt:exports_external.string().optional(),description:exports_external.string().optional(),color:exports_external.string().optional(),provider:exports_external.string().optional(),permissions:exports_external.object({preset:exports_external.string().optional(),allow:exports_external.array(exports_external.string()).optional(),deny:exports_external.array(exports_external.string()).optional(),bashAllowPatterns:exports_external.array(exports_external.string()).optional()}).strict().optional(),disallowedTools:exports_external.array(exports_external.string()).optional(),omniScopes:exports_external.array(exports_external.string()).optional(),hooks:exports_external.record(exports_external.unknown()).optional(),sdk:SdkDirectoryConfigSchema.optional(),bridgeTmuxSession:exports_external.string().optional()}).strict(),DERIVED_KEYS=["name","dir","registeredAt"]});import{existsSync as existsSync27}from"fs";import{copyFile as copyFile2,readFile as readFile6,writeFile as writeFile5}from"fs/promises";import{join as join29}from"path";async function migrateAgentToYaml(agentDir,dbRow){let yamlPath=join29(agentDir,"agent.yaml"),agentsMdPath=join29(agentDir,"AGENTS.md"),bakPath=`${agentsMdPath}.bak`;if(existsSync27(yamlPath))return{migrated:!1,reason:"already-migrated",yamlPath};let agentsMdRaw=await readFile6(agentsMdPath,"utf-8"),{frontmatter,body}=extractFrontmatterFromAgentsMd(agentsMdRaw);if(frontmatter===null)return{migrated:!1,reason:"no-frontmatter",yamlPath};let fmParsed=parseFrontmatter2(frontmatter,agentsMdPath),fmClean=pickYamlFields(fmParsed),merged={...dbRow?pickYamlFields(dbRow):{},...fmClean},config=AgentConfigSchema.parse(merged);return await writeAgentYaml(yamlPath,config),await copyFile2(agentsMdPath,bakPath),await writeFile5(agentsMdPath,body),{migrated:!0,yamlPath,bakPath}}function parseFrontmatter2(frontmatter,sourcePath){let raw;try{raw=load(frontmatter)}catch(err){let msg=err instanceof Error?err.message:String(err);throw Error(`Malformed frontmatter in ${sourcePath}: ${msg}`)}if(raw===null||typeof raw!=="object"||Array.isArray(raw))throw Error(`Malformed frontmatter in ${sourcePath}: expected a YAML mapping at the top level`);return raw}function pickYamlFields(source){let out={};for(let[k,v]of Object.entries(source))if(YAML_ALLOWED_KEYS.has(k)&&v!==null&&v!==void 0)out[k]=v;return out}var YAML_ALLOWED_KEYS;var init_agent_migrate=__esm(()=>{init_js_yaml();init_agent_yaml();YAML_ALLOWED_KEYS=(()=>{let shape=AgentConfigSchema._def.shape(),keys=new Set(Object.keys(shape));return keys.delete("name"),keys.delete("dir"),keys.delete("registeredAt"),keys})()});var exports_agent_sync={};__export(exports_agent_sync,{watchAgentDirectory:()=>watchAgentDirectory,syncSingleAgentByName:()=>syncSingleAgentByName,syncAgentDirectory:()=>syncAgentDirectory,printSyncResult:()=>printSyncResult,healAgentFile:()=>healAgentFile});import{execSync as execSync7}from"child_process";import{existsSync as existsSync28,watch as fsWatch,readFileSync as readFileSync19,readdirSync as readdirSync7,realpathSync as realpathSync4,writeFileSync as writeFileSync10}from"fs";import{join as join30}from"path";function getGitRemoteUrl(dir){try{return execSync7(`git -C "${dir}" config --get remote.origin.url`,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}}function extractOrgRepo(remoteUrl){let sshMatch=remoteUrl.match(/[^/:]+\/[^/]+?(?:\.git)?$/);if(sshMatch)return sshMatch[0].replace(/\.git$/,"");return null}function getRepoPathForAgent(agentDir){let reposLink=join30(agentDir,"repos");try{if(!existsSync28(reposLink))return null;let target=realpathSync4(reposLink);if(!existsSync28(target))return null;return target}catch{return null}}function discoverAgents(workspaceRoot){let agentsDir=join30(workspaceRoot,"agents");if(!existsSync28(agentsDir))return[];let agents=[];try{let entries=readdirSync7(agentsDir,{withFileTypes:!0});for(let entry2 of entries){if(!entry2.isDirectory())continue;let agentDir=join30(agentsDir,entry2.name);if(!existsSync28(join30(agentDir,"AGENTS.md")))continue;agents.push({name:entry2.name,dir:agentDir,repoUrl:getGitRemoteUrl(agentDir),productRepo:getRepoPathForAgent(agentDir)}),discoverSubAgents(agentDir,entry2.name,agents)}}catch{}return agents}function discoverSubAgents(parentDir,parentName,agents){let subAgentsDir=join30(parentDir,".genie","agents");if(!existsSync28(subAgentsDir))return;try{let entries=readdirSync7(subAgentsDir,{withFileTypes:!0});for(let entry2 of entries){if(!entry2.isDirectory())continue;let subDir=join30(subAgentsDir,entry2.name);if(!existsSync28(join30(subDir,"AGENTS.md")))continue;agents.push({name:`${parentName}/${entry2.name}`,dir:subDir,repoUrl:getGitRemoteUrl(parentDir),productRepo:getRepoPathForAgent(parentDir)})}}catch{}}function discoverSingleAgent(workspaceRoot,agentName){let agentDir=join30(workspaceRoot,"agents",agentName);if(!existsSync28(join30(agentDir,"AGENTS.md")))return null;return{name:agentName,dir:agentDir,repoUrl:getGitRemoteUrl(agentDir),productRepo:getRepoPathForAgent(agentDir)}}function healAgentFile(agentsMdPath,agentName,healResult){let content=readFileSync19(agentsMdPath,"utf-8"),fmMatch=content.match(/^(---\n)([\s\S]*?)(\n---)/);if(!fmMatch)return!1;let prefix=fmMatch[1],fmBlock=fmMatch[2],suffix=fmMatch[3],rest=content.slice(fmMatch[0].length),modified=!1,healedBlock=fmBlock;for(let{field,value}of INVALID_LITERALS)if(new RegExp(`^${field}:\\s*${value}\\s*$`,"m").test(healedBlock))healedBlock=healedBlock.replace(new RegExp(`${field}:\\s*${value}\\s*\\n?`,"m"),""),healResult.healed.push({agent:agentName,field,value}),modified=!0;if(!modified)return!1;let newContent=prefix+healedBlock+suffix+rest,tmpPath=`${agentsMdPath}.tmp.${Date.now()}`;writeFileSync10(tmpPath,newContent,"utf-8");let{renameSync:renameSync3}=__require("fs");return renameSync3(tmpPath,agentsMdPath),!0}function buildResolveContext(workspaceRoot,agentName){let workspaceDefaults;try{workspaceDefaults=getWorkspaceConfig(workspaceRoot).agents?.defaults}catch{}let parent;if(agentName.includes("/")){let parentName=agentName.split("/")[0],parentAgentsMd=join30(workspaceRoot,"agents",parentName,"AGENTS.md");if(existsSync28(parentAgentsMd)){let parentContent=readFileSync19(parentAgentsMd,"utf-8"),parentFm=parseFrontmatter(parentContent);parent={name:parentName,fields:parentFm}}}return{workspaceDefaults,parent}}function computeResolvedMetadata(fm,ctx){let declared={},resolved={};for(let field of Object.keys(BUILTIN_DEFAULTS)){let fmValue=fm[field];if(fmValue!==void 0&&fmValue!==null&&fmValue!==""&&fmValue!=="inherit")declared[field]=fmValue;let result2=resolveFieldWithSource(fm,field,ctx);resolved[field]={value:result2.value,source:result2.source}}return{declared,resolved}}async function syncAgentDirectory(workspaceRoot){let result2={registered:[],updated:[],migrated:[],archived:[],reactivated:[],healed:[],errors:[]},agents=discoverAgents(workspaceRoot),discoveredNames=new Set(agents.map((a)=>a.name)),healResult={healed:[]};for(let agent of agents){let agentsMdPath=join30(agent.dir,"AGENTS.md");try{healAgentFile(agentsMdPath,agent.name,healResult)}catch{}}result2.healed=healResult.healed;for(let h of healResult.healed)console.log(`[sync] healed ${h.agent}/AGENTS.md: removed invalid '${h.field}: ${h.value}' line`);for(let agent of agents)try{await syncSingleAgent(agent,result2,workspaceRoot)}catch(err){result2.errors.push({name:agent.name,error:err instanceof Error?err.message:String(err)})}return await removeMissingAgents(discoveredNames,result2),result2}function printSyncResult(result2){if(result2.healed.length>0)console.log(` Healed: ${result2.healed.length} invalid literal(s) removed`);if(result2.migrated.length>0)console.log(` Migrated: ${result2.migrated.join(", ")} (AGENTS.md frontmatter \u2192 agent.yaml)`);if(result2.registered.length>0)console.log(` Registered: ${result2.registered.join(", ")}`);if(result2.updated.length>0)console.log(` Updated: ${result2.updated.join(", ")}`);if(result2.reactivated.length>0)console.log(` Reactivated: ${result2.reactivated.join(", ")}`);if(result2.archived.length>0)console.log(` Removed: ${result2.archived.join(", ")}`);for(let err of result2.errors)console.error(` Error (${err.name}): ${err.error}`);let total=result2.registered.length+result2.updated.length+result2.reactivated.length;console.log(`
893
- Synced: ${total} agent(s), ${result2.archived.length} removed.`)}async function removeMissingAgents(discoveredNames,result2){try{let entries=await ls();for(let entry2 of entries){if(discoveredNames.has(entry2.name))continue;if(entry2.scope==="built-in")continue;if(!entry2.dir||!entry2.dir.includes("/agents/"))continue;let{removed}=await rm3(entry2.name);if(removed)result2.archived.push(entry2.name)}}catch{}}async function syncSingleAgent(agent,result2,workspaceRoot){let repoPath=(agent.repoUrl?extractOrgRepo(agent.repoUrl):null)??agent.repoUrl??agent.dir,yamlPath=join30(agent.dir,"agent.yaml"),agentsMdPath=join30(agent.dir,"AGENTS.md");if(!existsSync28(yamlPath)&&existsSync28(agentsMdPath)){let agentsMdContent=readFileSync19(agentsMdPath,"utf-8"),{frontmatter}=extractFrontmatterFromAgentsMd(agentsMdContent);if(frontmatter!==null){let existingEntry=await resolve4(agent.name),dbRow=existingEntry&&!existingEntry.builtin?dbRowFromEntry(existingEntry.entry):void 0;if((await migrateAgentToYaml(agent.dir,dbRow)).migrated)result2.migrated.push(agent.name)}}let configFields=existsSync28(yamlPath)?await readYamlAsConfigFields(yamlPath):readFrontmatterAsConfigFields(agentsMdPath);if(workspaceRoot){let ctx=buildResolveContext(workspaceRoot,agent.name);computeResolvedMetadata(configFields.rawForResolution,ctx)}let resolved=await resolve4(agent.name);if(!(resolved&&!resolved.builtin?resolved.entry:null)){await add({name:agent.name,dir:agent.dir,repo:repoPath,promptMode:configFields.promptMode,model:configFields.model,description:configFields.description,color:configFields.color,provider:configFields.provider,permissions:configFields.permissions,disallowedTools:configFields.disallowedTools,omniScopes:configFields.omniScopes,hooks:configFields.hooks,sdk:configFields.sdk,bridgeTmuxSession:configFields.bridgeTmuxSession}),result2.registered.push(agent.name);return}await edit(agent.name,{dir:agent.dir,repo:repoPath,promptMode:configFields.promptMode,model:configFields.model,description:configFields.description,color:configFields.color,provider:configFields.provider,permissions:configFields.permissions,disallowedTools:configFields.disallowedTools,omniScopes:configFields.omniScopes,hooks:configFields.hooks,sdk:configFields.sdk,bridgeTmuxSession:configFields.bridgeTmuxSession}),result2.updated.push(agent.name)}async function readYamlAsConfigFields(yamlPath){let cfg=await parseAgentYaml(yamlPath);return{promptMode:cfg.promptMode??"append",model:cfg.model,description:cfg.description,color:cfg.color,provider:cfg.provider,permissions:cfg.permissions,disallowedTools:cfg.disallowedTools,omniScopes:cfg.omniScopes,hooks:cfg.hooks,sdk:cfg.sdk,bridgeTmuxSession:cfg.bridgeTmuxSession,rawForResolution:cfg}}function readFrontmatterAsConfigFields(agentsMdPath){let content=existsSync28(agentsMdPath)?readFileSync19(agentsMdPath,"utf-8"):"",fm=parseFrontmatter(content);return{promptMode:fm.promptMode??"append",model:fm.model,description:fm.description,color:fm.color,provider:fm.provider,permissions:fm.permissions,disallowedTools:fm.disallowedTools,omniScopes:fm.omniScopes,hooks:fm.hooks,sdk:fm.sdk,bridgeTmuxSession:fm.bridgeTmuxSession,rawForResolution:fm}}function dbRowFromEntry(entry2){return{team:entry2.team,model:entry2.model,description:entry2.description,color:entry2.color,provider:entry2.provider,promptMode:entry2.promptMode,permissions:entry2.permissions,disallowedTools:entry2.disallowedTools,omniScopes:entry2.omniScopes,hooks:entry2.hooks,sdk:entry2.sdk,bridgeTmuxSession:entry2.bridgeTmuxSession}}async function syncSingleAgentByName(workspaceRoot,agentName){let agent=discoverSingleAgent(workspaceRoot,agentName);if(!agent)return"not-found";let result2={registered:[],updated:[],migrated:[],archived:[],reactivated:[],healed:[],errors:[]};if(await syncSingleAgent(agent,result2,workspaceRoot),result2.registered.length>0)return"registered";if(result2.migrated.length>0)return"migrated";if(result2.updated.length>0)return"updated";return"synced"}function watchAgentDirectory(workspaceRoot,options){let agentsDir=join30(workspaceRoot,"agents");if(!existsSync28(agentsDir))return null;let debounceTimer=null,pendingChanges=new Set,processChanges=async()=>{let names=[...pendingChanges];pendingChanges.clear();for(let name of names)try{let action=await processWatchedAgent(workspaceRoot,agentsDir,name);if(action)options?.onSync?.(name,action)}catch{}},watcher=fsWatch(agentsDir,{persistent:!1},(_event,filename)=>{if(!filename)return;let name=filename.split("/")[0];if(!name||name.startsWith("."))return;if(pendingChanges.add(name),debounceTimer)clearTimeout(debounceTimer);debounceTimer=setTimeout(processChanges,2000)});return{close:()=>{if(debounceTimer)clearTimeout(debounceTimer);watcher.close()}}}async function processWatchedAgent(workspaceRoot,agentsDir,name){let agentDir=join30(agentsDir,name);if(existsSync28(agentDir)&&existsSync28(join30(agentDir,"AGENTS.md"))){let action=await syncSingleAgentByName(workspaceRoot,name);return action!=="synced"&&action!=="not-found"?action:null}if(!existsSync28(agentDir)){let{removed}=await rm3(name);if(removed)return"removed"}return null}var INVALID_LITERALS;var init_agent_sync=__esm(()=>{init_agent_directory();init_agent_migrate();init_agent_yaml();init_defaults();init_frontmatter();init_workspace();INVALID_LITERALS=[{field:"model",value:"inherit"}]});var exports_term_format={};__export(exports_term_format,{truncate:()=>truncate2,stripAnsi:()=>stripAnsi2,padRight:()=>padRight,formatTimestamp:()=>formatTimestamp,formatTime:()=>formatTime,formatRelativeTimestamp:()=>formatRelativeTimestamp,formatDate:()=>formatDate,color:()=>color});function padRight(str2,len){return str2.length>=len?str2:str2+" ".repeat(len-str2.length)}function truncate2(str2,len){return str2.length<=len?str2:`${str2.slice(0,len-1)}\u2026`}function formatDate(iso){if(!iso)return"-";return new Date(iso).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function formatRelativeTimestamp(ts3){let d=new Date(ts3),diffMs=Date.now()-d.getTime();if(diffMs<60000)return`${Math.floor(diffMs/1000)}s ago`;if(diffMs<3600000)return`${Math.floor(diffMs/60000)}m ago`;if(diffMs<86400000)return`${Math.floor(diffMs/3600000)}h ago`;return d.toISOString().replace("T"," ").slice(0,19)}function formatTimestamp(iso,opts){if(!iso)return opts?.fallback??"-";let d=iso instanceof Date?iso:new Date(iso),fmt={month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1};if(opts?.seconds)fmt.second="2-digit";return d.toLocaleString("en-US",fmt)}function formatTime(iso,opts){try{let date=new Date(iso),fmt={hour:"2-digit",minute:"2-digit",hour12:!1};if(opts?.seconds)fmt.second="2-digit";return date.toLocaleTimeString("en-US",fmt)}catch{return opts?.fallback??"??:??"}}function color(name,text){return isTTY?`${ANSI[name]}${text}${ANSI.reset}`:text}function stripAnsi2(str2){return str2.replace(ANSI_REGEX,"")}var ANSI,isTTY,ANSI_REGEX;var init_term_format=__esm(()=>{ANSI={reset:"\x1B[0m",dim:"\x1B[2m",bold:"\x1B[1m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",gray:"\x1B[90m",brightRed:"\x1B[91m",brightGreen:"\x1B[92m",brightYellow:"\x1B[93m",brightCyan:"\x1B[96m"},isTTY=process.stdout.isTTY&&!process.env.NO_COLOR;ANSI_REGEX=/\x1b\[[0-9;]*m/g});var exports_task_service={};__export(exports_task_service,{updateTask:()=>updateTask,updateMessage:()=>updateMessage,untagTask:()=>untagTask,unblockTask:()=>unblockTask,unarchiveTask:()=>unarchiveTask,unarchiveProject:()=>unarchiveProject,tagTask:()=>tagTask,setRelease:()=>setRelease,setPreference:()=>setPreference,sendMessage:()=>sendMessage,resolveTaskId:()=>resolveTaskId,resolveChannels:()=>resolveChannels,removeMember:()=>removeMember,removeDependency:()=>removeDependency,removeActor:()=>removeActor,releaseTask:()=>releaseTask,moveTask:()=>moveTask,markDone:()=>markDone,listTypes:()=>listTypes,listTasksForActor:()=>listTasksForActor,listTasks:()=>listTasks,listTags:()=>listTags,listReleases:()=>listReleases,listProjectsFiltered:()=>listProjectsFiltered,listProjects:()=>listProjects,listConversations:()=>listConversations,linkTask:()=>linkTask,getType:()=>getType,getTaskTags:()=>getTaskTags,getTaskActors:()=>getTaskActors,getTask:()=>getTask,getStageLog:()=>getStageLog,getProjectByRepoPath:()=>getProjectByRepoPath,getProjectByName:()=>getProjectByName,getPreferences:()=>getPreferences,getMessages:()=>getMessages,getMessage:()=>getMessage,getMembers:()=>getMembers,getDependents:()=>getDependents,getConversation:()=>getConversation,getCheckoutOwner:()=>getCheckoutOwner,getBlockingDependencies:()=>getBlockingDependencies,getBlockers:()=>getBlockers,forceUnlockTask:()=>forceUnlockTask,findOrCreateConversation:()=>findOrCreateConversation,expireStaleCheckouts:()=>expireStaleCheckouts,ensureProject:()=>ensureProject,deletePreference:()=>deletePreference,createType:()=>createType,createTask:()=>createTask,createTag:()=>createTag,createProject:()=>createProject,commentOnTask:()=>commentOnTask,checkoutTask:()=>checkoutTask,blockTask:()=>blockTask,assignTask:()=>assignTask,archiveTask:()=>archiveTask,archiveProject:()=>archiveProject,archiveBoard:()=>archiveBoard,addMember:()=>addMember,addDependency:()=>addDependency});import{execSync as execSync8}from"child_process";function str2(v){return v!=null?String(v):null}function strOrDefault(v,def){return v!=null?String(v):def}function mapTask(row){return{id:row.id,seq:row.seq,parentId:str2(row.parent_id),repoPath:row.repo_path,projectId:str2(row.project_id),genieOsFolderId:str2(row.genie_os_folder_id),wishFile:str2(row.wish_file),groupName:str2(row.group_name),title:row.title,description:str2(row.description),acceptanceCriteria:str2(row.acceptance_criteria),typeId:row.type_id,stage:row.stage,status:row.status,priority:row.priority,startDate:str2(row.start_date),dueDate:str2(row.due_date),estimatedEffort:str2(row.estimated_effort),startedAt:str2(row.started_at),endedAt:str2(row.ended_at),blockedReason:str2(row.blocked_reason),releaseId:str2(row.release_id),checkoutRunId:str2(row.checkout_run_id),executionLockedAt:str2(row.execution_locked_at),checkoutTimeoutMs:row.checkout_timeout_ms??600000,sessionId:str2(row.session_id),paneId:str2(row.pane_id),traceId:str2(row.trace_id),boardId:str2(row.board_id),columnId:str2(row.column_id),externalId:str2(row.external_id),externalUrl:str2(row.external_url),archivedAt:str2(row.archived_at),metadata:row.metadata??{},createdAt:strOrDefault(row.created_at,""),updatedAt:strOrDefault(row.updated_at,"")}}function mapConversation(row){return{id:row.id,parentMessageId:row.parent_message_id!=null?Number(row.parent_message_id):null,name:row.name??null,type:row.type,linkedEntity:row.linked_entity??null,linkedEntityId:row.linked_entity_id??null,createdByType:row.created_by_type??null,createdById:row.created_by_id??null,metadata:row.metadata??{},createdAt:String(row.created_at),updatedAt:String(row.updated_at)}}function mapMessage(row){return{id:Number(row.id),conversationId:row.conversation_id,replyToId:row.reply_to_id!=null?Number(row.reply_to_id):null,senderType:row.sender_type,senderId:row.sender_id,body:row.body,metadata:row.metadata??{},createdAt:String(row.created_at),updatedAt:String(row.updated_at)}}function mapTaskActor(row){return{taskId:row.task_id,actorType:row.actor_type,actorId:row.actor_id,role:row.role,permissions:row.permissions??{},createdAt:String(row.created_at)}}function mapDependency(row){return{taskId:row.task_id,dependsOnId:row.depends_on_id,depType:row.dep_type,createdAt:String(row.created_at)}}function mapTag(row){return{id:row.id,name:row.name,color:row.color??"#9ca3af",typeId:row.type_id??null,createdAt:String(row.created_at)}}function mapTaskType(row){return{id:row.id,name:row.name,description:row.description??null,icon:row.icon??null,stages:row.stages,isBuiltin:row.is_builtin,createdAt:String(row.created_at),updatedAt:String(row.updated_at)}}function mapNotificationPref(row){return{actorType:row.actor_type,actorId:row.actor_id,channel:row.channel,priorityThreshold:row.priority_threshold,isDefault:row.is_default,enabled:row.enabled,metadata:row.metadata??{},createdAt:String(row.created_at),updatedAt:String(row.updated_at)}}function mapStageLog(row){return{id:Number(row.id),taskId:row.task_id,fromStage:row.from_stage??null,toStage:row.to_stage,actorType:row.actor_type??null,actorId:row.actor_id??null,runId:row.run_id??null,gateType:row.gate_type??null,createdAt:String(row.created_at)}}function mapConversationMember(row){return{conversationId:row.conversation_id,actorType:row.actor_type,actorId:row.actor_id,role:row.role,joinedAt:String(row.joined_at)}}function mapProject(row){return{id:row.id,name:row.name,repoPath:str2(row.repo_path),description:str2(row.description),leaderAgent:str2(row.leader_agent),tmuxSession:str2(row.tmux_session),status:strOrDefault(row.status,"active"),archivedAt:str2(row.archived_at),createdAt:String(row.created_at)}}function getRepoPath(){try{return execSync8("git rev-parse --show-toplevel",{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}catch{return process.cwd()}}async function resolveTaskId(idOrSeq,repoPath){let sql=await getConnection(),repo=repoPath??getRepoPath(),projectSeqMatch=idOrSeq.match(/^([^#]+)#(\d+)$/);if(projectSeqMatch&&!idOrSeq.startsWith("#")){let[,projectName,seqStr]=projectSeqMatch,seq2=Number.parseInt(seqStr,10);if(Number.isNaN(seq2))return null;let rows2=await sql`
893
+ Synced: ${total} agent(s), ${result2.archived.length} removed.`)}async function removeMissingAgents(discoveredNames,result2){try{let entries=await ls();for(let entry2 of entries){if(discoveredNames.has(entry2.name))continue;if(entry2.scope==="built-in")continue;if(!entry2.dir||!entry2.dir.includes("/agents/"))continue;let{removed}=await rm3(entry2.name);if(removed)result2.archived.push(entry2.name)}}catch{}}async function syncSingleAgent(agent,result2,workspaceRoot){let repoPath=(agent.repoUrl?extractOrgRepo(agent.repoUrl):null)??agent.repoUrl??agent.dir,yamlPath=join30(agent.dir,"agent.yaml"),agentsMdPath=join30(agent.dir,"AGENTS.md");if(!existsSync28(yamlPath)&&existsSync28(agentsMdPath)){let agentsMdContent=readFileSync19(agentsMdPath,"utf-8"),{frontmatter}=extractFrontmatterFromAgentsMd(agentsMdContent);if(frontmatter!==null){let existingEntry=await resolve4(agent.name),dbRow=existingEntry&&!existingEntry.builtin?dbRowFromEntry(existingEntry.entry):void 0;if((await migrateAgentToYaml(agent.dir,dbRow)).migrated)result2.migrated.push(agent.name)}}let configFields=existsSync28(yamlPath)?await readYamlAsConfigFields(yamlPath):readFrontmatterAsConfigFields(agentsMdPath);if(workspaceRoot){let ctx=buildResolveContext(workspaceRoot,agent.name);computeResolvedMetadata(configFields.rawForResolution,ctx)}let resolved=await resolve4(agent.name);if(!(resolved&&!resolved.builtin?resolved.entry:null)){await add({name:agent.name,dir:agent.dir,repo:repoPath,promptMode:configFields.promptMode,model:configFields.model,description:configFields.description,color:configFields.color,provider:configFields.provider,roles:configFields.roles,permissions:configFields.permissions,disallowedTools:configFields.disallowedTools,omniScopes:configFields.omniScopes,hooks:configFields.hooks,sdk:configFields.sdk,bridgeTmuxSession:configFields.bridgeTmuxSession}),result2.registered.push(agent.name);return}await edit(agent.name,{dir:agent.dir,repo:repoPath,promptMode:configFields.promptMode,model:configFields.model,description:configFields.description,color:configFields.color,provider:configFields.provider,roles:configFields.roles,permissions:configFields.permissions,disallowedTools:configFields.disallowedTools,omniScopes:configFields.omniScopes,hooks:configFields.hooks,sdk:configFields.sdk,bridgeTmuxSession:configFields.bridgeTmuxSession}),result2.updated.push(agent.name)}async function readYamlAsConfigFields(yamlPath){let cfg=await parseAgentYaml(yamlPath);return{promptMode:cfg.promptMode??"append",model:cfg.model,description:cfg.description,color:cfg.color,provider:cfg.provider,roles:cfg.roles,permissions:cfg.permissions,disallowedTools:cfg.disallowedTools,omniScopes:cfg.omniScopes,hooks:cfg.hooks,sdk:cfg.sdk,bridgeTmuxSession:cfg.bridgeTmuxSession,rawForResolution:cfg}}function readFrontmatterAsConfigFields(agentsMdPath){let content=existsSync28(agentsMdPath)?readFileSync19(agentsMdPath,"utf-8"):"",fm=parseFrontmatter(content);return{promptMode:fm.promptMode??"append",model:fm.model,description:fm.description,color:fm.color,provider:fm.provider,roles:fm.roles,permissions:fm.permissions,disallowedTools:fm.disallowedTools,omniScopes:fm.omniScopes,hooks:fm.hooks,sdk:fm.sdk,bridgeTmuxSession:fm.bridgeTmuxSession,rawForResolution:fm}}function dbRowFromEntry(entry2){return{team:entry2.team,model:entry2.model,description:entry2.description,color:entry2.color,provider:entry2.provider,promptMode:entry2.promptMode,permissions:entry2.permissions,disallowedTools:entry2.disallowedTools,omniScopes:entry2.omniScopes,hooks:entry2.hooks,sdk:entry2.sdk,bridgeTmuxSession:entry2.bridgeTmuxSession}}async function syncSingleAgentByName(workspaceRoot,agentName){let agent=discoverSingleAgent(workspaceRoot,agentName);if(!agent)return"not-found";let result2={registered:[],updated:[],migrated:[],archived:[],reactivated:[],healed:[],errors:[]};if(await syncSingleAgent(agent,result2,workspaceRoot),result2.registered.length>0)return"registered";if(result2.migrated.length>0)return"migrated";if(result2.updated.length>0)return"updated";return"synced"}function watchAgentDirectory(workspaceRoot,options){let agentsDir=join30(workspaceRoot,"agents");if(!existsSync28(agentsDir))return null;let debounceTimer=null,pendingChanges=new Set,processChanges=async()=>{let names=[...pendingChanges];pendingChanges.clear();for(let name of names)try{let action=await processWatchedAgent(workspaceRoot,agentsDir,name);if(action)options?.onSync?.(name,action)}catch{}},watcher=fsWatch(agentsDir,{persistent:!1},(_event,filename)=>{if(!filename)return;let name=filename.split("/")[0];if(!name||name.startsWith("."))return;if(pendingChanges.add(name),debounceTimer)clearTimeout(debounceTimer);debounceTimer=setTimeout(processChanges,2000)});return{close:()=>{if(debounceTimer)clearTimeout(debounceTimer);watcher.close()}}}async function processWatchedAgent(workspaceRoot,agentsDir,name){let agentDir=join30(agentsDir,name);if(existsSync28(agentDir)&&existsSync28(join30(agentDir,"AGENTS.md"))){let action=await syncSingleAgentByName(workspaceRoot,name);return action!=="synced"&&action!=="not-found"?action:null}if(!existsSync28(agentDir)){let{removed}=await rm3(name);if(removed)return"removed"}return null}var INVALID_LITERALS;var init_agent_sync=__esm(()=>{init_agent_directory();init_agent_migrate();init_agent_yaml();init_defaults();init_frontmatter();init_workspace();INVALID_LITERALS=[{field:"model",value:"inherit"}]});var exports_term_format={};__export(exports_term_format,{truncate:()=>truncate2,stripAnsi:()=>stripAnsi2,padRight:()=>padRight,formatTimestamp:()=>formatTimestamp,formatTime:()=>formatTime,formatRelativeTimestamp:()=>formatRelativeTimestamp,formatDate:()=>formatDate,color:()=>color});function padRight(str2,len){return str2.length>=len?str2:str2+" ".repeat(len-str2.length)}function truncate2(str2,len){return str2.length<=len?str2:`${str2.slice(0,len-1)}\u2026`}function formatDate(iso){if(!iso)return"-";return new Date(iso).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function formatRelativeTimestamp(ts3){let d=new Date(ts3),diffMs=Date.now()-d.getTime();if(diffMs<60000)return`${Math.floor(diffMs/1000)}s ago`;if(diffMs<3600000)return`${Math.floor(diffMs/60000)}m ago`;if(diffMs<86400000)return`${Math.floor(diffMs/3600000)}h ago`;return d.toISOString().replace("T"," ").slice(0,19)}function formatTimestamp(iso,opts){if(!iso)return opts?.fallback??"-";let d=iso instanceof Date?iso:new Date(iso),fmt={month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1};if(opts?.seconds)fmt.second="2-digit";return d.toLocaleString("en-US",fmt)}function formatTime(iso,opts){try{let date=new Date(iso),fmt={hour:"2-digit",minute:"2-digit",hour12:!1};if(opts?.seconds)fmt.second="2-digit";return date.toLocaleTimeString("en-US",fmt)}catch{return opts?.fallback??"??:??"}}function color(name,text){return isTTY?`${ANSI[name]}${text}${ANSI.reset}`:text}function stripAnsi2(str2){return str2.replace(ANSI_REGEX,"")}var ANSI,isTTY,ANSI_REGEX;var init_term_format=__esm(()=>{ANSI={reset:"\x1B[0m",dim:"\x1B[2m",bold:"\x1B[1m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",gray:"\x1B[90m",brightRed:"\x1B[91m",brightGreen:"\x1B[92m",brightYellow:"\x1B[93m",brightCyan:"\x1B[96m"},isTTY=process.stdout.isTTY&&!process.env.NO_COLOR;ANSI_REGEX=/\x1b\[[0-9;]*m/g});var exports_task_service={};__export(exports_task_service,{updateTask:()=>updateTask,updateMessage:()=>updateMessage,untagTask:()=>untagTask,unblockTask:()=>unblockTask,unarchiveTask:()=>unarchiveTask,unarchiveProject:()=>unarchiveProject,tagTask:()=>tagTask,setRelease:()=>setRelease,setPreference:()=>setPreference,sendMessage:()=>sendMessage,resolveTaskId:()=>resolveTaskId,resolveChannels:()=>resolveChannels,removeMember:()=>removeMember,removeDependency:()=>removeDependency,removeActor:()=>removeActor,releaseTask:()=>releaseTask,moveTask:()=>moveTask,markDone:()=>markDone,listTypes:()=>listTypes,listTasksForActor:()=>listTasksForActor,listTasks:()=>listTasks,listTags:()=>listTags,listReleases:()=>listReleases,listProjectsFiltered:()=>listProjectsFiltered,listProjects:()=>listProjects,listConversations:()=>listConversations,linkTask:()=>linkTask,getType:()=>getType,getTaskTags:()=>getTaskTags,getTaskActors:()=>getTaskActors,getTask:()=>getTask,getStageLog:()=>getStageLog,getProjectByRepoPath:()=>getProjectByRepoPath,getProjectByName:()=>getProjectByName,getPreferences:()=>getPreferences,getMessages:()=>getMessages,getMessage:()=>getMessage,getMembers:()=>getMembers,getDependents:()=>getDependents,getConversation:()=>getConversation,getCheckoutOwner:()=>getCheckoutOwner,getBlockingDependencies:()=>getBlockingDependencies,getBlockers:()=>getBlockers,forceUnlockTask:()=>forceUnlockTask,findOrCreateConversation:()=>findOrCreateConversation,expireStaleCheckouts:()=>expireStaleCheckouts,ensureProject:()=>ensureProject,deletePreference:()=>deletePreference,createType:()=>createType,createTask:()=>createTask,createTag:()=>createTag,createProject:()=>createProject,commentOnTask:()=>commentOnTask,checkoutTask:()=>checkoutTask,blockTask:()=>blockTask,assignTask:()=>assignTask,archiveTask:()=>archiveTask,archiveProject:()=>archiveProject,archiveBoard:()=>archiveBoard,addMember:()=>addMember,addDependency:()=>addDependency});import{execSync as execSync8}from"child_process";function str2(v){return v!=null?String(v):null}function strOrDefault(v,def){return v!=null?String(v):def}function mapTask(row){return{id:row.id,seq:row.seq,parentId:str2(row.parent_id),repoPath:row.repo_path,projectId:str2(row.project_id),genieOsFolderId:str2(row.genie_os_folder_id),wishFile:str2(row.wish_file),groupName:str2(row.group_name),title:row.title,description:str2(row.description),acceptanceCriteria:str2(row.acceptance_criteria),typeId:row.type_id,stage:row.stage,status:row.status,priority:row.priority,startDate:str2(row.start_date),dueDate:str2(row.due_date),estimatedEffort:str2(row.estimated_effort),startedAt:str2(row.started_at),endedAt:str2(row.ended_at),blockedReason:str2(row.blocked_reason),releaseId:str2(row.release_id),checkoutRunId:str2(row.checkout_run_id),executionLockedAt:str2(row.execution_locked_at),checkoutTimeoutMs:row.checkout_timeout_ms??600000,sessionId:str2(row.session_id),paneId:str2(row.pane_id),traceId:str2(row.trace_id),boardId:str2(row.board_id),columnId:str2(row.column_id),externalId:str2(row.external_id),externalUrl:str2(row.external_url),archivedAt:str2(row.archived_at),metadata:row.metadata??{},createdAt:strOrDefault(row.created_at,""),updatedAt:strOrDefault(row.updated_at,"")}}function mapConversation(row){return{id:row.id,parentMessageId:row.parent_message_id!=null?Number(row.parent_message_id):null,name:row.name??null,type:row.type,linkedEntity:row.linked_entity??null,linkedEntityId:row.linked_entity_id??null,createdByType:row.created_by_type??null,createdById:row.created_by_id??null,metadata:row.metadata??{},createdAt:String(row.created_at),updatedAt:String(row.updated_at)}}function mapMessage(row){return{id:Number(row.id),conversationId:row.conversation_id,replyToId:row.reply_to_id!=null?Number(row.reply_to_id):null,senderType:row.sender_type,senderId:row.sender_id,body:row.body,metadata:row.metadata??{},createdAt:String(row.created_at),updatedAt:String(row.updated_at)}}function mapTaskActor(row){return{taskId:row.task_id,actorType:row.actor_type,actorId:row.actor_id,role:row.role,permissions:row.permissions??{},createdAt:String(row.created_at)}}function mapDependency(row){return{taskId:row.task_id,dependsOnId:row.depends_on_id,depType:row.dep_type,createdAt:String(row.created_at)}}function mapTag(row){return{id:row.id,name:row.name,color:row.color??"#9ca3af",typeId:row.type_id??null,createdAt:String(row.created_at)}}function mapTaskType(row){return{id:row.id,name:row.name,description:row.description??null,icon:row.icon??null,stages:row.stages,isBuiltin:row.is_builtin,createdAt:String(row.created_at),updatedAt:String(row.updated_at)}}function mapNotificationPref(row){return{actorType:row.actor_type,actorId:row.actor_id,channel:row.channel,priorityThreshold:row.priority_threshold,isDefault:row.is_default,enabled:row.enabled,metadata:row.metadata??{},createdAt:String(row.created_at),updatedAt:String(row.updated_at)}}function mapStageLog(row){return{id:Number(row.id),taskId:row.task_id,fromStage:row.from_stage??null,toStage:row.to_stage,actorType:row.actor_type??null,actorId:row.actor_id??null,runId:row.run_id??null,gateType:row.gate_type??null,createdAt:String(row.created_at)}}function mapConversationMember(row){return{conversationId:row.conversation_id,actorType:row.actor_type,actorId:row.actor_id,role:row.role,joinedAt:String(row.joined_at)}}function mapProject(row){return{id:row.id,name:row.name,repoPath:str2(row.repo_path),description:str2(row.description),leaderAgent:str2(row.leader_agent),tmuxSession:str2(row.tmux_session),status:strOrDefault(row.status,"active"),archivedAt:str2(row.archived_at),createdAt:String(row.created_at)}}function getRepoPath(){try{return execSync8("git rev-parse --show-toplevel",{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}catch{return process.cwd()}}async function resolveTaskId(idOrSeq,repoPath){let sql=await getConnection(),repo=repoPath??getRepoPath(),projectSeqMatch=idOrSeq.match(/^([^#]+)#(\d+)$/);if(projectSeqMatch&&!idOrSeq.startsWith("#")){let[,projectName,seqStr]=projectSeqMatch,seq2=Number.parseInt(seqStr,10);if(Number.isNaN(seq2))return null;let rows2=await sql`
894
894
  SELECT t.id FROM tasks t
895
895
  JOIN projects p ON t.project_id = p.id
896
896
  WHERE p.name = ${projectName} AND t.seq = ${seq2}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/genie",
3
- "version": "4.260421.26",
3
+ "version": "4.260421.28",
4
4
  "description": "Collaborative terminal toolkit for human + AI workflows",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genie",
3
- "version": "4.260421.26",
3
+ "version": "4.260421.28",
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.260421.26",
3
+ "version": "4.260421.28",
4
4
  "private": true,
5
5
  "description": "Runtime dependencies for genie bundled CLIs",
6
6
  "type": "module",