@automagik/genie 4.260418.6 → 4.260418.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/genie.js CHANGED
@@ -608,12 +608,12 @@ ${body}`;writeFileSync9(filePath,output,"utf-8")}function serializeSdkConfig(sdk
608
608
  INSERT INTO agents (id, role, custom_name, started_at, metadata)
609
609
  VALUES (${`dir:${entry.name}`}, ${entry.name}, ${entry.name}, now(), ${sql.json(metadata)})
610
610
  ON CONFLICT (id) DO UPDATE SET metadata = ${sql.json(metadata)}
611
- `,full}async function rm3(name,_options){let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db));return(await(await getConnection2())`DELETE FROM agents WHERE id = ${`dir:${name}`}`).count>0}async function resolve3(name){let templateTeam=await lookupTemplateTeam(name);try{let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),rows=await(await getConnection2())`
612
- SELECT role, metadata FROM agents
611
+ `,full}async function rm3(name,options){let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),sql=await getConnection2(),dirRemoved=(await sql`DELETE FROM agents WHERE id = ${`dir:${name}`}`).count>0;if(options?.force){let roleDelete=await sql`DELETE FROM agents WHERE role = ${name}`;return{removed:dirRemoved||roleDelete.count>0}}if(dirRemoved)return{removed:!0};let instances=await sql`SELECT id FROM agents WHERE role = ${name}`;if(instances.length===0)return{removed:!1};let idList=instances.map((r)=>r.id).join(", ");return{removed:!1,message:`No directory entry for "${name}". Active instances: ${idList}. Use 'genie kill <id>' to terminate, or re-run with --force to remove all.`}}async function resolve3(name){let templateTeam=await lookupTemplateTeam(name);try{let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),rows=await(await getConnection2())`
612
+ SELECT role, metadata, created_at FROM agents
613
613
  WHERE role = ${name}
614
614
  ORDER BY (CASE WHEN id LIKE 'dir:%' THEN 0 ELSE 1 END), started_at DESC
615
615
  LIMIT 1
616
- `;if(rows.length>0){let meta=parseMetadata(rows[0].metadata),entry=roleToEntry(name,void 0,meta);if(templateTeam)entry.team=templateTeam;return{entry,builtin:!1}}}catch{}let builtinRole=BUILTIN_ROLES.find((r)=>r.name===name);if(builtinRole){let entry=builtinToEntry(builtinRole);if(templateTeam)entry.team=templateTeam;return{entry,builtin:!0}}let councilMember=BUILTIN_COUNCIL_MEMBERS.find((m)=>m.name===name);if(councilMember){let entry=builtinToEntry(councilMember);if(templateTeam)entry.team=templateTeam;return{entry,builtin:!0}}return null}async function lookupTemplateTeam(name){try{let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),rows=await(await getConnection2())`SELECT team FROM agent_templates WHERE id = ${name} LIMIT 1`;if(rows.length===0)return null;let team=rows[0].team;return typeof team==="string"&&team.length>0?team:null}catch{return null}}async function findSessionByRepo(repoPath){try{let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),rows=await(await getConnection2())`
616
+ `;if(rows.length>0){let meta=parseMetadata(rows[0].metadata),createdAt=rows[0].created_at instanceof Date?rows[0].created_at.toISOString():rows[0].created_at,entry=roleToEntry(name,void 0,meta,createdAt);if(templateTeam)entry.team=templateTeam;return{entry,builtin:!1}}}catch{}let builtinRole=BUILTIN_ROLES.find((r)=>r.name===name);if(builtinRole){let entry=builtinToEntry(builtinRole);if(templateTeam)entry.team=templateTeam;return{entry,builtin:!0}}let councilMember=BUILTIN_COUNCIL_MEMBERS.find((m)=>m.name===name);if(councilMember){let entry=builtinToEntry(councilMember);if(templateTeam)entry.team=templateTeam;return{entry,builtin:!0}}return null}async function lookupTemplateTeam(name){try{let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),rows=await(await getConnection2())`SELECT team FROM agent_templates WHERE id = ${name} LIMIT 1`;if(rows.length===0)return null;let team=rows[0].team;return typeof team==="string"&&team.length>0?team:null}catch{return null}}async function findSessionByRepo(repoPath){try{let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),rows=await(await getConnection2())`
617
617
  SELECT session FROM agents
618
618
  WHERE repo_path = ${repoPath}
619
619
  AND session IS NOT NULL
@@ -622,12 +622,12 @@ ${body}`;writeFileSync9(filePath,output,"utf-8")}function serializeSdkConfig(sdk
622
622
  ORDER BY started_at DESC
623
623
  LIMIT 1
624
624
  `;return rows.length>0?rows[0].session:null}catch{return null}}async function ls(){let result2=[],seen=new Set;try{let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),rows=await(await getConnection2())`
625
- SELECT DISTINCT ON (a.role) a.role, a.team, a.metadata, e.repo_path, e.provider
625
+ SELECT DISTINCT ON (a.role) a.role, a.team, a.metadata, a.created_at, e.repo_path, e.provider
626
626
  FROM agents a
627
627
  LEFT JOIN executors e ON a.current_executor_id = e.id
628
628
  WHERE a.role IS NOT NULL
629
629
  ORDER BY a.role, (CASE WHEN a.id LIKE 'dir:%' THEN 0 ELSE 1 END), a.started_at DESC
630
- `;for(let row of rows){let name=row.role;if(!seen.has(name)){let meta=parseMetadata(row.metadata),entry=roleToEntry(name,row.team,meta),repoPath=row.repo_path;if(repoPath)entry.dir=repoPath,entry.repo=repoPath;result2.push({...entry,scope:"global"}),seen.add(name)}}}catch{}return result2}async function get2(name,_options){return(await resolve3(name))?.entry??null}async function edit(name,updates,_options){if(updates.dir){if(!existsSync19(updates.dir))throw Error(`Directory does not exist: ${updates.dir}`);let agentsPath=join21(updates.dir,"AGENTS.md");if(!existsSync19(agentsPath))throw Error(`AGENTS.md not found in ${updates.dir}.`)}let existing=await get2(name);if(!existing)throw Error(`Agent "${name}" not found in directory.`);let updated=Object.assign(existing,updates),metadataPatch=buildMetadata(updated);try{let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),sql=await getConnection2();if((await sql`
630
+ `;for(let row of rows){let name=row.role;if(!seen.has(name)){let meta=parseMetadata(row.metadata),createdAt=row.created_at instanceof Date?row.created_at.toISOString():row.created_at,entry=roleToEntry(name,row.team,meta,createdAt),repoPath=row.repo_path;if(repoPath)entry.dir=repoPath,entry.repo=repoPath;result2.push({...entry,scope:"global"}),seen.add(name)}}}catch{}return result2}async function get2(name,_options){return(await resolve3(name))?.entry??null}async function edit(name,updates,_options){if(updates.dir){if(!existsSync19(updates.dir))throw Error(`Directory does not exist: ${updates.dir}`);let agentsPath=join21(updates.dir,"AGENTS.md");if(!existsSync19(agentsPath))throw Error(`AGENTS.md not found in ${updates.dir}.`)}let existing=await get2(name);if(!existing)throw Error(`Agent "${name}" not found in directory.`);let updated=Object.assign(existing,updates),metadataPatch=buildMetadata(updated);try{let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db)),sql=await getConnection2();if((await sql`
631
631
  UPDATE agents
632
632
  SET metadata = metadata || ${sql.json(metadataPatch)}
633
633
  WHERE id = ${`dir:${name}`}
@@ -635,7 +635,7 @@ ${body}`;writeFileSync9(filePath,output,"utf-8")}function serializeSdkConfig(sdk
635
635
  UPDATE agents
636
636
  SET metadata = metadata || ${sql.json(metadataPatch)}
637
637
  WHERE role = ${name}
638
- `}catch{}return updated}function loadIdentity(entry){if(!entry.dir)return null;let agentsPath=join21(entry.dir,"AGENTS.md");if(existsSync19(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){if(!(metadata&&Object.keys(metadata).length>0)){let builtin=[...BUILTIN_ROLES,...BUILTIN_COUNCIL_MEMBERS].find((b2)=>b2.name===role);if(builtin)return builtinToEntry(builtin)}return{name:role,dir:metadata?.dir||"",promptMode:metadata?.promptMode||"append",model:metadata?.model,roles:[],registeredAt:new Date().toISOString(),description:metadata?.description,color:metadata?.color,provider:metadata?.provider,permissions:metadata?.permissions,disallowedTools:metadata?.disallowedTools,omniScopes:metadata?.omniScopes,hooks:metadata?.hooks,sdk:metadata?.sdk,...metadata?.repo?{repo:metadata.repo}:team?{repo:team}:{}}}function buildMetadata(entry){let meta={};if(entry.dir)meta.dir=entry.dir;if(entry.repo)meta.repo=entry.repo;if(entry.model)meta.model=entry.model;if(entry.promptMode&&entry.promptMode!=="append")meta.promptMode=entry.promptMode;if(entry.description)meta.description=entry.description;if(entry.color)meta.color=entry.color;if(entry.provider)meta.provider=entry.provider;if(entry.permissions)meta.permissions=entry.permissions;if(entry.disallowedTools)meta.disallowedTools=entry.disallowedTools;if(entry.omniScopes)meta.omniScopes=entry.omniScopes;if(entry.hooks)meta.hooks=entry.hooks;if(entry.sdk)meta.sdk=entry.sdk;return 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{}}function syncFrontmatterToDisk(entry,updates){try{if(!entry.dir)return;let agentsPath=join21(entry.dir,"AGENTS.md");if(!existsSync19(agentsPath))return;if(!Object.keys(updates).some((k)=>FRONTMATTER_KEYS.has(k)))return;let fmUpdates={};if(updates.model!==void 0)fmUpdates.model=updates.model;if(updates.description!==void 0)fmUpdates.description=updates.description;if(updates.color!==void 0)fmUpdates.color=updates.color;if(updates.promptMode!==void 0)fmUpdates.promptMode=updates.promptMode;if(updates.provider!==void 0)fmUpdates.provider=updates.provider;if(updates.sdk!==void 0)fmUpdates.sdk=serializeSdkConfig(updates.sdk);if(Object.keys(fmUpdates).length===0)return;writeFrontmatter(agentsPath,fmUpdates)}catch{}}var FRONTMATTER_KEYS;var init_agent_directory=__esm(()=>{init_builtin_agents();init_frontmatter_writer();FRONTMATTER_KEYS=new Set(["name","description","model","color","promptMode","provider","sdk"])});var exports_runtime_events={};__export(exports_runtime_events,{waitForRuntimeEvent:()=>waitForRuntimeEvent,publishSubjectEvent:()=>publishSubjectEvent,publishRuntimeEvent:()=>publishRuntimeEvent,listRuntimeEvents:()=>listRuntimeEvents,getLatestRuntimeEventId:()=>getLatestRuntimeEventId,getEventMetrics:()=>getEventMetrics,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 getEventMetrics(){return{eventsEmitted,eventsFailed,lastEmitDuration,circuitState:circuitBreaker.state}}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 eventsFailed++,Error("circuit breaker open \u2014 PG event write skipped");let start=Date.now();try{let sql=await getConnection(),threadId=input.threadId??`agent:${input.agent}`,rows=await sql`
638
+ `}catch{}return updated}function loadIdentity(entry){if(!entry.dir)return null;let agentsPath=join21(entry.dir,"AGENTS.md");if(existsSync19(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,...metadata?.repo?{repo:metadata.repo}:team?{repo:team}:{}}}function buildMetadata(entry){let meta={};if(entry.dir)meta.dir=entry.dir;if(entry.repo)meta.repo=entry.repo;if(entry.model)meta.model=entry.model;if(entry.promptMode&&entry.promptMode!=="append")meta.promptMode=entry.promptMode;if(entry.description)meta.description=entry.description;if(entry.color)meta.color=entry.color;if(entry.provider)meta.provider=entry.provider;if(entry.permissions)meta.permissions=entry.permissions;if(entry.disallowedTools)meta.disallowedTools=entry.disallowedTools;if(entry.omniScopes)meta.omniScopes=entry.omniScopes;if(entry.hooks)meta.hooks=entry.hooks;if(entry.sdk)meta.sdk=entry.sdk;return 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{}}function syncFrontmatterToDisk(entry,updates){try{if(!entry.dir)return;let agentsPath=join21(entry.dir,"AGENTS.md");if(!existsSync19(agentsPath))return;if(!Object.keys(updates).some((k)=>FRONTMATTER_KEYS.has(k)))return;let fmUpdates={};if(updates.model!==void 0)fmUpdates.model=updates.model;if(updates.description!==void 0)fmUpdates.description=updates.description;if(updates.color!==void 0)fmUpdates.color=updates.color;if(updates.promptMode!==void 0)fmUpdates.promptMode=updates.promptMode;if(updates.provider!==void 0)fmUpdates.provider=updates.provider;if(updates.sdk!==void 0)fmUpdates.sdk=serializeSdkConfig(updates.sdk);if(Object.keys(fmUpdates).length===0)return;writeFrontmatter(agentsPath,fmUpdates)}catch{}}var FRONTMATTER_KEYS;var init_agent_directory=__esm(()=>{init_builtin_agents();init_frontmatter_writer();FRONTMATTER_KEYS=new Set(["name","description","model","color","promptMode","provider","sdk"])});var exports_runtime_events={};__export(exports_runtime_events,{waitForRuntimeEvent:()=>waitForRuntimeEvent,publishSubjectEvent:()=>publishSubjectEvent,publishRuntimeEvent:()=>publishRuntimeEvent,listRuntimeEvents:()=>listRuntimeEvents,getLatestRuntimeEventId:()=>getLatestRuntimeEventId,getEventMetrics:()=>getEventMetrics,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 getEventMetrics(){return{eventsEmitted,eventsFailed,lastEmitDuration,circuitState:circuitBreaker.state}}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 eventsFailed++,Error("circuit breaker open \u2014 PG event write skipped");let start=Date.now();try{let sql=await getConnection(),threadId=input.threadId??`agent:${input.agent}`,rows=await sql`
639
639
  INSERT INTO genie_runtime_events (
640
640
  repo_path, subject, kind, source, agent, team, direction, peer, text, data, thread_id, trace_id, parent_event_id, created_at
641
641
  )
@@ -767,7 +767,7 @@ Run 'genie agent list' to list agents.`)}async function resolveTarget(target,opt
767
767
  LIMIT 100
768
768
  `).map((r)=>({id:r.id,requestType:r.request_type,senderId:r.sender_id,body:r.body,createdAt:r.created_at instanceof Date?r.created_at.toISOString():String(r.created_at)}))}async function generateBrief(options){let teamConfig=await getTeam(options.team);if(!teamConfig)throw Error(`Team not found: ${options.team}`);let since=await resolveSince(options),repoPath=options.repoPath??teamConfig.repo,agentName=options.agent??teamConfig.leader??null,agentIdentifiers=agentName?[agentName]:[],[unreadMessages,taskMessages,recentEvents,pendingRequests,teamRoster]=await Promise.all([agentIdentifiers.length>0?getUnread(repoPath,agentIdentifiers):Promise.resolve([]),getTaskMessages(options.team,since),listRuntimeEvents({team:options.team,since,limit:100}),getPendingRequestMessages(options.team),getTeamRoster(options.team)]);return{team:options.team,agent:agentName,since,unreadMessages,taskMessages,recentEvents,pendingRequests,teamRoster}}function truncate(text,max){return text.length>max?`${text.slice(0,max)}...`:text}function formatUnreadSection(messages2){if(messages2.length===0)return[];let lines=[`## Unread Messages (${messages2.length})`];for(let msg of messages2)lines.push(`- **${msg.from}**: ${truncate(msg.body,120)}`);return lines.push(""),lines}function formatTaskMessagesSection(messages2){if(messages2.length===0)return[];let lines=[`## Task Updates (${messages2.length})`],byTask=new Map;for(let msg of messages2){let existing=byTask.get(msg.taskId)??[];existing.push(msg),byTask.set(msg.taskId,existing)}for(let[taskId,msgs]of byTask){lines.push(`### ${taskId}: ${msgs[0].taskTitle}`);for(let msg of msgs)lines.push(`- [${msg.senderType}:${msg.senderId}] ${truncate(msg.body,100)}`)}return lines.push(""),lines}function formatRequestsSection(requests){if(requests.length===0)return[];let lines=[`## Pending Requests (${requests.length})`];for(let req of requests)lines.push(`- [${req.requestType}] ${req.senderId}: ${truncate(req.body,80)}`);return lines.push(""),lines}function formatRosterSection(roster){if(roster.length===0)return[];let lines=[`## Team Roster (${roster.length})`];for(let member of roster){let state=member.executorState??"offline",icon=STATE_ICONS[state]??"\u25CC";lines.push(`- ${icon} **${member.agentId}** (${member.role??"unassigned"}): ${state}`)}return lines.push(""),lines}function formatEventsSection(events){if(events.length===0)return[];let lines=[`## Recent Events (${events.length})`],tail=events.slice(-10);for(let evt of tail){let ts3=evt.timestamp.slice(11,16);lines.push(`- ${ts3} [${evt.kind}] ${evt.agent}: ${truncate(evt.text,80)}`)}if(events.length>10)lines.push(` _(${events.length-10} more events)_`);return lines.push(""),lines}function formatBrief(brief){let lines=[`# BRIEF \u2014 ${brief.team}${brief.agent?` ${brief.agent}`:""}`,`Since: ${brief.since}`,"",...formatUnreadSection(brief.unreadMessages),...formatTaskMessagesSection(brief.taskMessages),...formatRequestsSection(brief.pendingRequests),...formatRosterSection(brief.teamRoster),...formatEventsSection(brief.recentEvents)];if(!(brief.unreadMessages.length+brief.taskMessages.length+brief.pendingRequests.length+brief.recentEvents.length>0))lines.push("_No activity since last session._","");return lines.join(`
769
769
  `)}var STATE_ICONS;var init_brief=__esm(()=>{init_db();init_mailbox();init_runtime_events();init_team_manager();STATE_ICONS={working:"\u25CF",idle:"\u25CB",error:"\u2718"}});var exports_agent_sync={};__export(exports_agent_sync,{watchAgentDirectory:()=>watchAgentDirectory,syncAgentDirectory:()=>syncAgentDirectory,printSyncResult:()=>printSyncResult,healAgentFile:()=>healAgentFile});import{execSync as execSync6}from"child_process";import{existsSync as existsSync23,watch as fsWatch,readFileSync as readFileSync15,readdirSync as readdirSync6,realpathSync as realpathSync3,writeFileSync as writeFileSync11}from"fs";import{join as join25}from"path";function getGitRemoteUrl(dir){try{return execSync6(`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=join25(agentDir,"repos");try{if(!existsSync23(reposLink))return null;let target=realpathSync3(reposLink);if(!existsSync23(target))return null;return target}catch{return null}}function discoverAgents(workspaceRoot){let agentsDir=join25(workspaceRoot,"agents");if(!existsSync23(agentsDir))return[];let agents=[];try{let entries=readdirSync6(agentsDir,{withFileTypes:!0});for(let entry of entries){if(!entry.isDirectory())continue;let agentDir=join25(agentsDir,entry.name);if(!existsSync23(join25(agentDir,"AGENTS.md")))continue;agents.push({name:entry.name,dir:agentDir,repoUrl:getGitRemoteUrl(agentDir),productRepo:getRepoPathForAgent(agentDir)}),discoverSubAgents(agentDir,entry.name,agents)}}catch{}return agents}function discoverSubAgents(parentDir,parentName,agents){let subAgentsDir=join25(parentDir,".genie","agents");if(!existsSync23(subAgentsDir))return;try{let entries=readdirSync6(subAgentsDir,{withFileTypes:!0});for(let entry of entries){if(!entry.isDirectory())continue;let subDir=join25(subAgentsDir,entry.name);if(!existsSync23(join25(subDir,"AGENTS.md")))continue;agents.push({name:`${parentName}/${entry.name}`,dir:subDir,repoUrl:getGitRemoteUrl(parentDir),productRepo:getRepoPathForAgent(parentDir)})}}catch{}}function discoverSingleAgent(workspaceRoot,agentName){let agentDir=join25(workspaceRoot,"agents",agentName);if(!existsSync23(join25(agentDir,"AGENTS.md")))return null;return{name:agentName,dir:agentDir,repoUrl:getGitRemoteUrl(agentDir),productRepo:getRepoPathForAgent(agentDir)}}function healAgentFile(agentsMdPath,agentName,healResult){let content=readFileSync15(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()}`;writeFileSync11(tmpPath,newContent,"utf-8");let{renameSync:renameSync2}=__require("fs");return renameSync2(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=join25(workspaceRoot,"agents",parentName,"AGENTS.md");if(existsSync23(parentAgentsMd)){let parentContent=readFileSync15(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:[],unchanged:[],archived:[],reactivated:[],healed:[],errors:[]},agents=discoverAgents(workspaceRoot),discoveredNames=new Set(agents.map((a)=>a.name)),healResult={healed:[]};for(let agent of agents){let agentsMdPath=join25(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.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(", ")}`);if(result2.unchanged.length>0)console.log(` Unchanged: ${result2.unchanged.join(", ")}`);for(let err of result2.errors)console.error(` Error (${err.name}): ${err.error}`);let total=result2.registered.length+result2.updated.length+result2.unchanged.length+result2.reactivated.length;console.log(`
770
- Sync complete: ${total} active agent(s), ${result2.archived.length} removed.`)}async function removeMissingAgents(discoveredNames,result2){try{let entries=await ls();for(let entry of entries){if(discoveredNames.has(entry.name))continue;if(entry.scope==="built-in")continue;if(!entry.dir||!entry.dir.includes("/agents/"))continue;if(await rm3(entry.name))result2.archived.push(entry.name)}}catch{}}async function syncSingleAgent(agent,result2,workspaceRoot){let repoPath=(agent.repoUrl?extractOrgRepo(agent.repoUrl):null)??agent.repoUrl??agent.dir,agentsMdPath=join25(agent.dir,"AGENTS.md"),content=readFileSync15(agentsMdPath,"utf-8"),fm=parseFrontmatter(content),_resolvedMeta;if(workspaceRoot){let ctx=buildResolveContext(workspaceRoot,agent.name);_resolvedMeta=computeResolvedMetadata(fm,ctx)}let resolved=await resolve3(agent.name),existing=resolved&&!resolved.builtin?resolved.entry:null,sdkConfig=fm.sdk,permissions=fm.permissions,disallowedTools=fm.disallowedTools,omniScopes=fm.omniScopes,hooks=fm.hooks;if(!existing){await add({name:agent.name,dir:agent.dir,repo:repoPath,promptMode:fm.promptMode??"append",model:fm.model,description:fm.description,color:fm.color,provider:fm.provider,permissions,disallowedTools,omniScopes,hooks,sdk:sdkConfig}),result2.registered.push(agent.name);return}let identityUpdate={dir:agent.dir,repo:repoPath,promptMode:fm.promptMode??"append",model:fm.model,description:fm.description,color:fm.color,provider:fm.provider,permissions,disallowedTools,omniScopes,hooks,sdk:sdkConfig},sdkChanged=JSON.stringify(existing.sdk)!==JSON.stringify(sdkConfig),permissionsChanged=JSON.stringify(existing.permissions)!==JSON.stringify(permissions),disallowedToolsChanged=JSON.stringify(existing.disallowedTools)!==JSON.stringify(disallowedTools),omniScopesChanged=JSON.stringify(existing.omniScopes)!==JSON.stringify(omniScopes),hooksChanged=JSON.stringify(existing.hooks)!==JSON.stringify(hooks);if(sdkChanged||permissionsChanged||disallowedToolsChanged||omniScopesChanged||hooksChanged||existing.repo!==repoPath||existing.dir!==agent.dir||existing.promptMode!==(fm.promptMode??"append")||existing.model!==fm.model||existing.description!==fm.description||existing.color!==fm.color||existing.provider!==fm.provider)await edit(agent.name,identityUpdate),result2.updated.push(agent.name);else result2.unchanged.push(agent.name)}async function syncSingleAgentByName(workspaceRoot,agentName){let agent=discoverSingleAgent(workspaceRoot,agentName);if(!agent)return"not-found";let result2={registered:[],updated:[],unchanged:[],archived:[],reactivated:[],healed:[],errors:[]};if(await syncSingleAgent(agent,result2,workspaceRoot),result2.registered.length>0)return"registered";if(result2.updated.length>0)return"updated";return"unchanged"}function watchAgentDirectory(workspaceRoot,options){let agentsDir=join25(workspaceRoot,"agents");if(!existsSync23(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=join25(agentsDir,name);if(existsSync23(agentDir)&&existsSync23(join25(agentDir,"AGENTS.md"))){let action=await syncSingleAgentByName(workspaceRoot,name);return action!=="unchanged"&&action!=="not-found"?action:null}if(!existsSync23(agentDir)){if(await rm3(name))return"removed"}return null}var INVALID_LITERALS;var init_agent_sync=__esm(()=>{init_agent_directory();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 execSync7}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 execSync7("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`
770
+ Sync complete: ${total} active agent(s), ${result2.archived.length} removed.`)}async function removeMissingAgents(discoveredNames,result2){try{let entries=await ls();for(let entry of entries){if(discoveredNames.has(entry.name))continue;if(entry.scope==="built-in")continue;if(!entry.dir||!entry.dir.includes("/agents/"))continue;let{removed}=await rm3(entry.name);if(removed)result2.archived.push(entry.name)}}catch{}}async function syncSingleAgent(agent,result2,workspaceRoot){let repoPath=(agent.repoUrl?extractOrgRepo(agent.repoUrl):null)??agent.repoUrl??agent.dir,agentsMdPath=join25(agent.dir,"AGENTS.md"),content=readFileSync15(agentsMdPath,"utf-8"),fm=parseFrontmatter(content),_resolvedMeta;if(workspaceRoot){let ctx=buildResolveContext(workspaceRoot,agent.name);_resolvedMeta=computeResolvedMetadata(fm,ctx)}let resolved=await resolve3(agent.name),existing=resolved&&!resolved.builtin?resolved.entry:null,sdkConfig=fm.sdk,permissions=fm.permissions,disallowedTools=fm.disallowedTools,omniScopes=fm.omniScopes,hooks=fm.hooks;if(!existing){await add({name:agent.name,dir:agent.dir,repo:repoPath,promptMode:fm.promptMode??"append",model:fm.model,description:fm.description,color:fm.color,provider:fm.provider,permissions,disallowedTools,omniScopes,hooks,sdk:sdkConfig}),result2.registered.push(agent.name);return}let identityUpdate={dir:agent.dir,repo:repoPath,promptMode:fm.promptMode??"append",model:fm.model,description:fm.description,color:fm.color,provider:fm.provider,permissions,disallowedTools,omniScopes,hooks,sdk:sdkConfig},sdkChanged=JSON.stringify(existing.sdk)!==JSON.stringify(sdkConfig),permissionsChanged=JSON.stringify(existing.permissions)!==JSON.stringify(permissions),disallowedToolsChanged=JSON.stringify(existing.disallowedTools)!==JSON.stringify(disallowedTools),omniScopesChanged=JSON.stringify(existing.omniScopes)!==JSON.stringify(omniScopes),hooksChanged=JSON.stringify(existing.hooks)!==JSON.stringify(hooks);if(sdkChanged||permissionsChanged||disallowedToolsChanged||omniScopesChanged||hooksChanged||existing.repo!==repoPath||existing.dir!==agent.dir||existing.promptMode!==(fm.promptMode??"append")||existing.model!==fm.model||existing.description!==fm.description||existing.color!==fm.color||existing.provider!==fm.provider)await edit(agent.name,identityUpdate),result2.updated.push(agent.name);else result2.unchanged.push(agent.name)}async function syncSingleAgentByName(workspaceRoot,agentName){let agent=discoverSingleAgent(workspaceRoot,agentName);if(!agent)return"not-found";let result2={registered:[],updated:[],unchanged:[],archived:[],reactivated:[],healed:[],errors:[]};if(await syncSingleAgent(agent,result2,workspaceRoot),result2.registered.length>0)return"registered";if(result2.updated.length>0)return"updated";return"unchanged"}function watchAgentDirectory(workspaceRoot,options){let agentsDir=join25(workspaceRoot,"agents");if(!existsSync23(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=join25(agentsDir,name);if(existsSync23(agentDir)&&existsSync23(join25(agentDir,"AGENTS.md"))){let action=await syncSingleAgentByName(workspaceRoot,name);return action!=="unchanged"&&action!=="not-found"?action:null}if(!existsSync23(agentDir)){let{removed}=await rm3(name);if(removed)return"removed"}return null}var INVALID_LITERALS;var init_agent_sync=__esm(()=>{init_agent_directory();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 execSync7}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 execSync7("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`
771
771
  SELECT t.id FROM tasks t
772
772
  JOIN projects p ON t.project_id = p.id
773
773
  WHERE p.name = ${projectName} AND t.seq = ${seq2}
@@ -3204,7 +3204,7 @@ ${indented}`}function formatHumanOutput(events,label){let lines=[];if(lines.push
3204
3204
  WHERE c.content ILIKE ${`%${query2}%`}
3205
3205
  ORDER BY c.timestamp DESC
3206
3206
  LIMIT ${limit}
3207
- `;if(options.json){console.log(JSON.stringify(rows,null,2));return}if(rows.length===0){console.log(`No results for "${query2}".`);return}console.log(""),console.log(`Search: "${query2}" (${rows.length} results)`),console.log("\u2500".repeat(60));for(let r of rows){let preview=String(r.content).replace(/\n/g," ").slice(0,100),agent=r.agent_id??"(unknown)",time=r.timestamp?new Date(r.timestamp).toLocaleTimeString():"??:??";console.log(` [${time}] ${agent} (${r.role}): ${preview}`)}console.log("")}init_agent_directory();init_genie_config2();import{resolve as resolvePath2}from"path";init_audit();init_genie_config2();async function resolveOmniApiUrl(){let envUrl=process.env.OMNI_API_URL;if(envUrl)return envUrl;return(await loadGenieConfig()).omni?.apiUrl??null}async function resolveOmniApiKey(){let envKey=process.env.OMNI_API_KEY;if(envKey)return envKey;return(await loadGenieConfig()).omni?.apiKey}async function registerAgentInOmni(agentName,options){let apiUrl=await resolveOmniApiUrl();if(!apiUrl)return null;let apiKey=await resolveOmniApiKey(),body={name:agentName,provider:"claude",model:options?.model,agentType:"assistant",capabilities:options?.roles??[],metadata:{source:"genie",sessionIsolation:{perPerson:!0,perChannel:!0},registeredAt:new Date().toISOString()}},traceId=generateTraceId();try{let headers={"Content-Type":"application/json","X-Trace-Id":traceId};if(apiKey)headers.Authorization=`Bearer ${apiKey}`;let response=await fetch(`${apiUrl}/api/v2/agents`,{method:"POST",headers,body:JSON.stringify(body),signal:AbortSignal.timeout(1e4)});if(!response.ok){let text=await response.text().catch(()=>"");return console.warn(`Warning: Omni registration failed (HTTP ${response.status}): ${text}`),recordAuditEvent("omni",agentName,"registration_error",getActor(),{traceId,status:response.status,error:text.slice(0,200)}).catch(()=>{}),null}let result2=await response.json();return recordAuditEvent("omni",agentName,"registration_success",getActor(),{traceId,omniAgentId:result2.data.id}).catch(()=>{}),result2.data.id}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);return console.warn(`Warning: Omni registration failed: ${message}`),recordAuditEvent("omni",agentName,"registration_error",getActor(),{traceId,error:message.slice(0,200)}).catch(()=>{}),null}}async function findOmniAgent(agentName){let apiUrl=await resolveOmniApiUrl();if(!apiUrl)return null;let apiKey=await resolveOmniApiKey(),traceId=generateTraceId();try{let headers={"X-Trace-Id":traceId};if(apiKey)headers.Authorization=`Bearer ${apiKey}`;let response=await fetch(`${apiUrl}/api/v2/agents?name=${encodeURIComponent(agentName)}`,{method:"GET",headers,signal:AbortSignal.timeout(1e4)});if(!response.ok)return null;return(await response.json()).data?.find((a)=>a.name===agentName&&a.isActive)?.id??null}catch{return null}}init_agent_directory();init_agent_sync();init_audit();init_builtin_agents();init_defaults();init_frontmatter();init_genie_config2();init_workspace();import{resolve as resolvePath}from"path";function registerDirNamespace(program2){let dir=program2.command("dir").description("Agent directory management"),addCmd=dir.command("add <name>").description("Register an agent in the directory").requiredOption("--dir <path>","Agent folder (CWD + AGENTS.md)").option("--repo <path>","Default git repo (overridden by team)").option("--prompt-mode <mode>","Prompt mode: append or system","append").option("--model <model>","Default model (sonnet, opus, codex)").option("--roles <roles...>","Built-in roles this agent can orchestrate").option("--permission-preset <preset>","Permission preset: full, read-only, chat-only").option("--allow <tools>",'Comma-separated tool allow list (e.g. "Read,Glob,Grep,Bash")').option("--bash-allow <patterns>","Comma-separated regex patterns for allowed bash commands").option("--global","Write to global directory instead of project");registerSdkFlags(addCmd),addCmd.action(async(name,options)=>{try{await handleDirAdd(name,options)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}}),dir.command("rm <name>").description("Remove an agent from the directory").option("--global","Remove from global directory instead of project").action(async(name,options)=>{try{let removed=await rm3(name,{global:options.global});if(recordAuditEvent("item",name,"item_removed",getActor(),{type:"agent",source:"dir_rm"}).catch(()=>{}),removed){let scope=options.global?"global":"project";console.log(`Agent "${name}" removed from ${scope} directory.`)}else console.error(`Agent "${name}" not found in directory.`),process.exit(1)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}}),dir.command("ls [name]").description("List all agents or show single entry details").option("--json","Output as JSON").option("--builtins","Include built-in roles and council members").option("--all","Include archived agents").action(async(name,options)=>{try{if(name)await showEntry2(name,options.json);else await listEntries2(options.json,options.builtins,options.all)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}});let editCmd=dir.command("edit <name>").description("Update an agent directory entry").option("--dir <path>","Agent folder (CWD + AGENTS.md)").option("--repo <path>","Default git repo").option("--prompt-mode <mode>","Prompt mode: append or system").option("--model <model>","Default model").option("--provider <provider>","AI provider: claude or codex").option("--color <color>","Display color for TUI").option("--description <desc>","Agent description").option("--roles <roles...>","Built-in roles this agent can orchestrate").option("--permission-preset <preset>","Permission preset: full, read-only, chat-only").option("--allow <tools>",'Comma-separated tool allow list (e.g. "Read,Glob,Grep,Bash")').option("--bash-allow <patterns>","Comma-separated regex patterns for allowed bash commands").option("--global","Edit in global directory instead of project");registerSdkFlags(editCmd),editCmd.action(async(name,options)=>{try{await handleEdit(name,options)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}}),dir.command("sync").description("Sync agents from workspace agents/ directory").action(async()=>{try{await handleDirSync()}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}}),dir.command("export <name>").description("Print full AGENTS.md frontmatter for an agent from PG state").option("--stdout","Print to stdout as raw YAML (default)").option("--json","Print resolved fields as nested JSON with declared/resolved/source").action(async(name,options)=>{try{await handleDirExport(name,options)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}async function handleDirAdd(name,options){let promptMode=validatePromptMode(options.promptMode),resolvedDir=resolvePath(options.dir);if(options.repo)validateRepoPath(options.repo);let permissions=buildPermissions(options.permissionPreset,options.allow,options.bashAllow),sdk=buildSdkConfig(options),entry=await add({name,dir:resolvedDir,repo:options.repo?resolvePath(options.repo):void 0,promptMode,model:options.model,roles:normalizeRoles(options.roles),...permissions&&{permissions},...sdk&&{sdk}},{global:options.global});recordAuditEvent("item",name,"item_registered",getActor(),{type:"agent",source:"dir_add"}).catch(()=>{});let scope=options.global?"global":"project";console.log(`Agent "${entry.name}" registered (${scope}).`),printEntry(entry)}async function handleEdit(name,options){let updates={};if(options.dir)updates.dir=resolvePath(options.dir);if(options.repo)updates.repo=resolvePath(options.repo);if(options.promptMode)updates.promptMode=validatePromptMode(options.promptMode);if(options.model)updates.model=options.model;if(options.provider)updates.provider=options.provider;if(options.color)updates.color=options.color;if(options.description)updates.description=options.description;if(options.roles)updates.roles=normalizeRoles(options.roles);let permissions=buildPermissions(options.permissionPreset,options.allow,options.bashAllow);if(permissions)updates.permissions=permissions;let sdk=buildSdkConfig(options);if(sdk)updates.sdk=sdk;if(Object.keys(updates).length===0)console.error("No fields to update. Provide at least one of: --dir, --repo, --prompt-mode, --model, --provider, --color, --description, --roles, --permission-preset, --allow, --bash-allow, --sdk-*"),process.exit(1);let entry=await edit(name,updates,{global:options.global});syncFrontmatterToDisk(entry,updates),recordAuditEvent("item",name,"item_updated",getActor(),{type:"agent",source:"dir_edit"}).catch(()=>{});let scope=options.global?"global":"project";console.log(`Agent "${name}" updated (${scope}).`),printEntry(entry)}async function handleDirSync(){let{findWorkspace:findWorkspace2}=await Promise.resolve().then(() => (init_workspace(),exports_workspace)),ws=findWorkspace2();if(!ws)console.error("Not in a genie workspace. Run `genie init` first."),process.exit(1);console.log(`Syncing agents from ${ws.root}/agents/...`);let result2=await syncAgentDirectory(ws.root);printSyncResult(result2)}async function handleDirExport(name,options){let entry=await get2(name);if(!entry)console.error(`Agent "${name}" not found in directory.`),process.exit(1);if(options.json){let ctx=buildDirResolveContext(name),output={name:entry.name};for(let field of RESOLVED_FIELDS){let declared=entry[field]??null,result2=resolveFieldWithSource(entry,field,ctx);output[field]={declared:declared??null,resolved:result2.value,source:result2.source}}console.log(JSON.stringify(output,null,2));return}let fm={};if(entry.name)fm.name=entry.name;if(entry.description)fm.description=entry.description;if(entry.model)fm.model=entry.model;if(entry.color)fm.color=entry.color;if(entry.promptMode)fm.promptMode=entry.promptMode;if(entry.provider)fm.provider=entry.provider;if(entry.sdk&&Object.keys(entry.sdk).length>0){let{serializeSdkConfig:serializeSdkConfig2}=await Promise.resolve().then(() => (init_frontmatter_writer(),exports_frontmatter_writer));fm.sdk=serializeSdkConfig2(entry.sdk)}let yamlStr=(await Promise.resolve().then(() => (init_js_yaml(),exports_js_yaml))).dump(fm,{lineWidth:-1,noRefs:!0,sortKeys:!1,quotingType:'"'});console.log(`---
3207
+ `;if(options.json){console.log(JSON.stringify(rows,null,2));return}if(rows.length===0){console.log(`No results for "${query2}".`);return}console.log(""),console.log(`Search: "${query2}" (${rows.length} results)`),console.log("\u2500".repeat(60));for(let r of rows){let preview=String(r.content).replace(/\n/g," ").slice(0,100),agent=r.agent_id??"(unknown)",time=r.timestamp?new Date(r.timestamp).toLocaleTimeString():"??:??";console.log(` [${time}] ${agent} (${r.role}): ${preview}`)}console.log("")}init_agent_directory();init_genie_config2();import{resolve as resolvePath2}from"path";init_audit();init_genie_config2();async function resolveOmniApiUrl(){let envUrl=process.env.OMNI_API_URL;if(envUrl)return envUrl;return(await loadGenieConfig()).omni?.apiUrl??null}async function resolveOmniApiKey(){let envKey=process.env.OMNI_API_KEY;if(envKey)return envKey;return(await loadGenieConfig()).omni?.apiKey}async function registerAgentInOmni(agentName,options){let apiUrl=await resolveOmniApiUrl();if(!apiUrl)return null;let apiKey=await resolveOmniApiKey(),body={name:agentName,provider:"claude",model:options?.model,agentType:"assistant",capabilities:options?.roles??[],metadata:{source:"genie",sessionIsolation:{perPerson:!0,perChannel:!0},registeredAt:new Date().toISOString()}},traceId=generateTraceId();try{let headers={"Content-Type":"application/json","X-Trace-Id":traceId};if(apiKey)headers.Authorization=`Bearer ${apiKey}`;let response=await fetch(`${apiUrl}/api/v2/agents`,{method:"POST",headers,body:JSON.stringify(body),signal:AbortSignal.timeout(1e4)});if(!response.ok){let text=await response.text().catch(()=>"");return console.warn(`Warning: Omni registration failed (HTTP ${response.status}): ${text}`),recordAuditEvent("omni",agentName,"registration_error",getActor(),{traceId,status:response.status,error:text.slice(0,200)}).catch(()=>{}),null}let result2=await response.json();return recordAuditEvent("omni",agentName,"registration_success",getActor(),{traceId,omniAgentId:result2.data.id}).catch(()=>{}),result2.data.id}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);return console.warn(`Warning: Omni registration failed: ${message}`),recordAuditEvent("omni",agentName,"registration_error",getActor(),{traceId,error:message.slice(0,200)}).catch(()=>{}),null}}async function findOmniAgent(agentName){let apiUrl=await resolveOmniApiUrl();if(!apiUrl)return null;let apiKey=await resolveOmniApiKey(),traceId=generateTraceId();try{let headers={"X-Trace-Id":traceId};if(apiKey)headers.Authorization=`Bearer ${apiKey}`;let response=await fetch(`${apiUrl}/api/v2/agents?name=${encodeURIComponent(agentName)}`,{method:"GET",headers,signal:AbortSignal.timeout(1e4)});if(!response.ok)return null;return(await response.json()).data?.find((a)=>a.name===agentName&&a.isActive)?.id??null}catch{return null}}init_agent_directory();init_agent_sync();init_audit();init_builtin_agents();init_defaults();init_frontmatter();init_genie_config2();init_workspace();import{resolve as resolvePath}from"path";function registerDirNamespace(program2){let dir=program2.command("dir").description("Agent directory management"),addCmd=dir.command("add <name>").description("Register an agent in the directory").requiredOption("--dir <path>","Agent folder (CWD + AGENTS.md)").option("--repo <path>","Default git repo (overridden by team)").option("--prompt-mode <mode>","Prompt mode: append or system","append").option("--model <model>","Default model (sonnet, opus, codex)").option("--roles <roles...>","Built-in roles this agent can orchestrate").option("--permission-preset <preset>","Permission preset: full, read-only, chat-only").option("--allow <tools>",'Comma-separated tool allow list (e.g. "Read,Glob,Grep,Bash")').option("--bash-allow <patterns>","Comma-separated regex patterns for allowed bash commands").option("--global","Write to global directory instead of project");registerSdkFlags(addCmd),addCmd.action(async(name,options)=>{try{await handleDirAdd(name,options)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}}),dir.command("rm <name>").description("Remove an agent from the directory").option("--global","Remove from global directory instead of project").option("--force","Also remove runtime/spawn rows sharing this role (id shapes: <team>-<role>, UUID)").action(async(name,options)=>{try{let result2=await rm3(name,{global:options.global,force:options.force});if(result2.removed){let scope=options.global?"global":"project";console.log(`Agent "${name}" removed from ${scope} directory.`),recordAuditEvent("item",name,"item_removed",getActor(),{type:"agent",source:"dir_rm"}).catch(()=>{})}else if(result2.message)console.error(result2.message),process.exit(1);else console.error(`Agent "${name}" not found in directory.`),process.exit(1)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}}),dir.command("ls [name]").description("List all agents or show single entry details").option("--json","Output as JSON").option("--builtins","Include built-in roles and council members").option("--all","Include archived agents").action(async(name,options)=>{try{if(name)await showEntry2(name,options.json);else await listEntries2(options.json,options.builtins,options.all)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}});let editCmd=dir.command("edit <name>").description("Update an agent directory entry").option("--dir <path>","Agent folder (CWD + AGENTS.md)").option("--repo <path>","Default git repo").option("--prompt-mode <mode>","Prompt mode: append or system").option("--model <model>","Default model").option("--provider <provider>","AI provider: claude or codex").option("--color <color>","Display color for TUI").option("--description <desc>","Agent description").option("--roles <roles...>","Built-in roles this agent can orchestrate").option("--permission-preset <preset>","Permission preset: full, read-only, chat-only").option("--allow <tools>",'Comma-separated tool allow list (e.g. "Read,Glob,Grep,Bash")').option("--bash-allow <patterns>","Comma-separated regex patterns for allowed bash commands").option("--global","Edit in global directory instead of project");registerSdkFlags(editCmd),editCmd.action(async(name,options)=>{try{await handleEdit(name,options)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}}),dir.command("sync").description("Sync agents from workspace agents/ directory").action(async()=>{try{await handleDirSync()}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}}),dir.command("export <name>").description("Print full AGENTS.md frontmatter for an agent from PG state").option("--stdout","Print to stdout as raw YAML (default)").option("--json","Print resolved fields as nested JSON with declared/resolved/source").action(async(name,options)=>{try{await handleDirExport(name,options)}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(`Error: ${message}`),process.exit(1)}})}async function handleDirAdd(name,options){let promptMode=validatePromptMode(options.promptMode),resolvedDir=resolvePath(options.dir);if(options.repo)validateRepoPath(options.repo);let permissions=buildPermissions(options.permissionPreset,options.allow,options.bashAllow),sdk=buildSdkConfig(options),entry=await add({name,dir:resolvedDir,repo:options.repo?resolvePath(options.repo):void 0,promptMode,model:options.model,roles:normalizeRoles(options.roles),...permissions&&{permissions},...sdk&&{sdk}},{global:options.global});recordAuditEvent("item",name,"item_registered",getActor(),{type:"agent",source:"dir_add"}).catch(()=>{});let scope=options.global?"global":"project";console.log(`Agent "${entry.name}" registered (${scope}).`),printEntry(entry)}async function handleEdit(name,options){let updates={};if(options.dir)updates.dir=resolvePath(options.dir);if(options.repo)updates.repo=resolvePath(options.repo);if(options.promptMode)updates.promptMode=validatePromptMode(options.promptMode);if(options.model)updates.model=options.model;if(options.provider)updates.provider=options.provider;if(options.color)updates.color=options.color;if(options.description)updates.description=options.description;if(options.roles)updates.roles=normalizeRoles(options.roles);let permissions=buildPermissions(options.permissionPreset,options.allow,options.bashAllow);if(permissions)updates.permissions=permissions;let sdk=buildSdkConfig(options);if(sdk)updates.sdk=sdk;if(Object.keys(updates).length===0)console.error("No fields to update. Provide at least one of: --dir, --repo, --prompt-mode, --model, --provider, --color, --description, --roles, --permission-preset, --allow, --bash-allow, --sdk-*"),process.exit(1);let entry=await edit(name,updates,{global:options.global});syncFrontmatterToDisk(entry,updates),recordAuditEvent("item",name,"item_updated",getActor(),{type:"agent",source:"dir_edit"}).catch(()=>{});let scope=options.global?"global":"project";console.log(`Agent "${name}" updated (${scope}).`),printEntry(entry)}async function handleDirSync(){let{findWorkspace:findWorkspace2}=await Promise.resolve().then(() => (init_workspace(),exports_workspace)),ws=findWorkspace2();if(!ws)console.error("Not in a genie workspace. Run `genie init` first."),process.exit(1);console.log(`Syncing agents from ${ws.root}/agents/...`);let result2=await syncAgentDirectory(ws.root);printSyncResult(result2)}async function handleDirExport(name,options){let entry=await get2(name);if(!entry)console.error(`Agent "${name}" not found in directory.`),process.exit(1);if(options.json){let ctx=buildDirResolveContext(name),output={name:entry.name};for(let field of RESOLVED_FIELDS){let declared=entry[field]??null,result2=resolveFieldWithSource(entry,field,ctx);output[field]={declared:declared??null,resolved:result2.value,source:result2.source}}console.log(JSON.stringify(output,null,2));return}let fm={};if(entry.name)fm.name=entry.name;if(entry.description)fm.description=entry.description;if(entry.model)fm.model=entry.model;if(entry.color)fm.color=entry.color;if(entry.promptMode)fm.promptMode=entry.promptMode;if(entry.provider)fm.provider=entry.provider;if(entry.sdk&&Object.keys(entry.sdk).length>0){let{serializeSdkConfig:serializeSdkConfig2}=await Promise.resolve().then(() => (init_frontmatter_writer(),exports_frontmatter_writer));fm.sdk=serializeSdkConfig2(entry.sdk)}let yamlStr=(await Promise.resolve().then(() => (init_js_yaml(),exports_js_yaml))).dump(fm,{lineWidth:-1,noRefs:!0,sortKeys:!1,quotingType:'"'});console.log(`---
3208
3208
  ${yamlStr}---`)}function buildDirResolveContext(agentName){let ctx={};try{let ws=findWorkspace();if(ws){let wsConfig=getWorkspaceConfig(ws.root);if(ctx.workspaceDefaults=wsConfig.agents?.defaults,agentName.includes("/")){let parentName=agentName.split("/")[0],{existsSync:existsSync27,readFileSync:readFileSync17}=__require("fs"),{join:join33}=__require("path"),parentAgentsMd=join33(ws.root,"agents",parentName,"AGENTS.md");if(existsSync27(parentAgentsMd)){let parentFm=parseFrontmatter(readFileSync17(parentAgentsMd,"utf-8"));ctx.parent={name:parentName,fields:parentFm}}}}}catch{}return ctx}function validateRepoPath(repo){if(repo.startsWith("/")||repo.startsWith("~/")||repo.startsWith("./")||repo.startsWith("../"))return;throw Error(`Invalid --repo value "${repo}". Must be a path (absolute "/...", home-relative "~/...", or dot-relative "./..." / "../..."). Got a bare word instead.`)}function validatePromptMode(mode){if(mode!=="system"&&mode!=="append")throw Error(`Invalid prompt mode "${mode}". Must be "append" or "system".`);return mode}function printEntry(entry){if(console.log(` Name: ${entry.name}`),console.log(` Dir: ${contractPath(entry.dir)}`),entry.repo)console.log(` Repo: ${contractPath(entry.repo)}`);if(console.log(` PromptMode: ${entry.promptMode}`),entry.model)console.log(` Model: ${entry.model}`);if(entry.provider)console.log(` Provider: ${entry.provider}`);if(entry.color)console.log(` Color: ${entry.color}`);if(entry.description)console.log(` Description: ${entry.description}`);if(entry.roles?.length)console.log(` Roles: ${entry.roles.join(", ")}`);if(entry.permissions?.preset)console.log(` Permissions: preset=${entry.permissions.preset}`);else if(entry.permissions?.allow){if(console.log(` Permissions: allow=${entry.permissions.allow.join(",")}`),entry.permissions.bashAllowPatterns?.length)console.log(` Bash Allow: ${entry.permissions.bashAllowPatterns.join(", ")}`)}if(entry.sdk)printSdkConfig(entry.sdk);console.log(` Registered: ${entry.registeredAt}`)}async function showEntry2(name,json2){let resolved=await resolve3(name);if(!resolved)console.error(`Agent "${name}" not found in directory or built-ins.`),process.exit(1);if(json2){console.log(JSON.stringify({...resolved.entry,builtin:resolved.builtin},null,2));return}if(resolved.builtin)console.log(`
3209
3209
  (built-in ${resolved.entry.registeredAt==="(built-in)"?"agent":"agent"})`);console.log(""),printEntry(resolved.entry),console.log("")}async function listEntries2(json2,includeBuiltins,_includeArchived){let entries=await ls();if(json2){listEntriesJson(entries,includeBuiltins);return}if(entries.length===0&&!includeBuiltins){console.log(`
3210
3210
  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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/genie",
3
- "version": "4.260418.6",
3
+ "version": "4.260418.7",
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.260418.6",
3
+ "version": "4.260418.7",
4
4
  "description": "Human-AI partnership for Claude Code. Share a terminal, orchestrate workers, evolve together. Brainstorm ideas, turn them into wishes, execute with /work, validate with /review, and ship as one team.",
5
5
  "author": {
6
6
  "name": "Namastex Labs"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genie-plugin",
3
- "version": "4.260418.6",
3
+ "version": "4.260418.7",
4
4
  "private": true,
5
5
  "description": "Runtime dependencies for genie bundled CLIs",
6
6
  "type": "module",