@automagik/genie 4.260429.33 → 4.260429.35

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
@@ -675,7 +675,7 @@ ${bin} set-option -w pane-active-border-style "fg=$COLOR"
675
675
  tell.location
676
676
  from (select lo_tell64($1) as location) tell
677
677
  ) seek
678
- `};return resolve3(lo),new Promise(async(r)=>finish=r);async function readable({highWaterMark=16384,start=0,end=1/0}={}){let max=end-start;return start&&await lo.seek(start),new Stream2.Readable({highWaterMark,async read(size){let l=size>max?size-max:size;max-=size;let[{data}]=await lo.read(l);if(this.push(data),data.length<size)this.push(null)}})}async function writable({highWaterMark=16384,start=0}={}){return start&&await lo.seek(start),new Stream2.Writable({highWaterMark,write(chunk,encoding,callback){lo.write(chunk).then(()=>callback(),callback)}})}}).catch(reject)})}var init_large=()=>{};var exports_src={};__export(exports_src,{default:()=>src_default});import os from"os";import fs from"fs";function Postgres(a,b2){let options=parseOptions(a,b2),subscribe=options.no_subscribe||Subscribe(Postgres,{...options}),ending=!1,queries=queue_default(),connecting=queue_default(),reserved=queue_default(),closed=queue_default(),ended=queue_default(),open3=queue_default(),busy=queue_default(),full=queue_default(),queues={connecting,reserved,closed,ended,open:open3,busy,full},connections=[...Array(options.max)].map(()=>connection_default(options,queues,{onopen,onend,onclose})),sql=Sql(handler);return Object.assign(sql,{get parameters(){return options.parameters},largeObject:largeObject.bind(null,sql),subscribe,CLOSE,END:CLOSE,PostgresError,options,reserve,listen,begin,close,end}),sql;function Sql(handler2){return handler2.debug=options.debug,Object.entries(options.types).reduce((acc,[name,type2])=>{return acc[name]=(x)=>new Parameter(x,type2.to),acc},typed),Object.assign(sql2,{types:typed,typed,unsafe,notify,array,json:json2,file}),sql2;function typed(value,type2){return new Parameter(value,type2)}function sql2(strings,...args){return strings&&Array.isArray(strings.raw)?new Query(strings,args,handler2,cancel):typeof strings==="string"&&!args.length?new Identifier(options.transform.column.to?options.transform.column.to(strings):strings):new Builder(strings,args)}function unsafe(string,args=[],options2={}){return arguments.length===2&&!Array.isArray(args)&&(options2=args,args=[]),new Query([string],args,handler2,cancel,{prepare:!1,...options2,simple:"simple"in options2?options2.simple:args.length===0})}function file(path2,args=[],options2={}){return arguments.length===2&&!Array.isArray(args)&&(options2=args,args=[]),new Query([],args,(query2)=>{fs.readFile(path2,"utf8",(err,string)=>{if(err)return query2.reject(err);query2.strings=[string],handler2(query2)})},cancel,{...options2,simple:"simple"in options2?options2.simple:args.length===0})}}async function listen(name,fn,onlisten){let listener={fn,onlisten},sql2=listen.sql||(listen.sql=Postgres({...options,max:1,idle_timeout:null,max_lifetime:null,fetch_types:!1,onclose(){Object.entries(listen.channels).forEach(([name2,{listeners}])=>{delete listen.channels[name2],Promise.all(listeners.map((l)=>listen(name2,l.fn,l.onlisten).catch(()=>{})))})},onnotify(c,x){c in listen.channels&&listen.channels[c].listeners.forEach((l)=>l.fn(x))}})),channels=listen.channels||(listen.channels={});if(name in channels){channels[name].listeners.push(listener);let result3=await channels[name].result;return listener.onlisten&&listener.onlisten(),{state:result3.state,unlisten}}channels[name]={result:sql2`listen ${sql2.unsafe('"'+name.replace(/"/g,'""')+'"')}`,listeners:[listener]};let result2=await channels[name].result;return listener.onlisten&&listener.onlisten(),{state:result2.state,unlisten};async function unlisten(){if(name in channels===!1)return;if(channels[name].listeners=channels[name].listeners.filter((x)=>x!==listener),channels[name].listeners.length)return;return delete channels[name],sql2`unlisten ${sql2.unsafe('"'+name.replace(/"/g,'""')+'"')}`}}async function notify(channel,payload){return await sql`select pg_notify(${channel}, ${""+payload})`}async function reserve(){let queue=queue_default(),c=open3.length?open3.shift():await new Promise((resolve3,reject)=>{let query={reserve:resolve3,reject};queries.push(query),closed.length&&connect(closed.shift(),query)});move(c,reserved),c.reserved=()=>queue.length?c.execute(queue.shift()):move(c,reserved),c.reserved.release=!0;let sql2=Sql(handler2);return sql2.release=()=>{c.reserved=null,onopen(c)},sql2;function handler2(q){c.queue===full?queue.push(q):c.execute(q)||move(c,full)}}async function begin(options2,fn){!fn&&(fn=options2,options2="");let queries2=queue_default(),savepoints=0,connection2,prepare=null;try{return await sql.unsafe("begin "+options2.replace(/[^a-z ]/ig,""),[],{onexecute}).execute(),await Promise.race([scope(connection2,fn),new Promise((_,reject)=>connection2.onclose=reject)])}catch(error){throw error}async function scope(c,fn2,name){let sql2=Sql(handler2);sql2.savepoint=savepoint,sql2.prepare=(x)=>prepare=x.replace(/[^a-z0-9$-_. ]/gi);let uncaughtError,result2;name&&await sql2`savepoint ${sql2(name)}`;try{if(result2=await new Promise((resolve3,reject)=>{let x=fn2(sql2);Promise.resolve(Array.isArray(x)?Promise.all(x):x).then(resolve3,reject)}),uncaughtError)throw uncaughtError}catch(e){throw await(name?sql2`rollback to ${sql2(name)}`:sql2`rollback`),e instanceof PostgresError&&e.code==="25P02"&&uncaughtError||e}if(!name)prepare?await sql2`prepare transaction '${sql2.unsafe(prepare)}'`:await sql2`commit`;return result2;function savepoint(name2,fn3){if(name2&&Array.isArray(name2.raw))return savepoint((sql3)=>sql3.apply(sql3,arguments));return arguments.length===1&&(fn3=name2,name2=null),scope(c,fn3,"s"+savepoints+++(name2?"_"+name2:""))}function handler2(q){q.catch((e)=>uncaughtError||(uncaughtError=e)),c.queue===full?queries2.push(q):c.execute(q)||move(c,full)}}function onexecute(c){connection2=c,move(c,reserved),c.reserved=()=>queries2.length?c.execute(queries2.shift()):move(c,reserved)}}function move(c,queue){return c.queue.remove(c),queue.push(c),c.queue=queue,queue===open3?c.idleTimer.start():c.idleTimer.cancel(),c}function json2(x){return new Parameter(x,3802)}function array(x,type2){if(!Array.isArray(x))return array(Array.from(arguments));return new Parameter(x,type2||(x.length?inferType(x)||25:0),options.shared.typeArrayMap)}function handler(query){if(ending)return query.reject(Errors.connection("CONNECTION_ENDED",options,options));if(open3.length)return go(open3.shift(),query);if(closed.length)return connect(closed.shift(),query);busy.length?go(busy.shift(),query):queries.push(query)}function go(c,query){return c.execute(query)?move(c,busy):move(c,full)}function cancel(query){return new Promise((resolve3,reject)=>{query.state?query.active?connection_default(options).cancel(query.state,resolve3,reject):query.cancelled={resolve:resolve3,reject}:(queries.remove(query),query.cancelled=!0,query.reject(Errors.generic("57014","canceling statement due to user request")),resolve3())})}async function end({timeout=null}={}){if(ending)return ending;await 1;let timer2;return ending=Promise.race([new Promise((r)=>timeout!==null&&(timer2=setTimeout(destroy,timeout*1000,r))),Promise.all(connections.map((c)=>c.end()).concat(listen.sql?listen.sql.end({timeout:0}):[],subscribe.sql?subscribe.sql.end({timeout:0}):[]))]).then(()=>clearTimeout(timer2))}async function close(){await Promise.all(connections.map((c)=>c.end()))}async function destroy(resolve3){await Promise.all(connections.map((c)=>c.terminate()));while(queries.length)queries.shift().reject(Errors.connection("CONNECTION_DESTROYED",options));resolve3()}function connect(c,query){return move(c,connecting),c.connect(query),c}function onend(c){move(c,ended)}function onopen(c){if(queries.length===0)return move(c,open3);let max=Math.ceil(queries.length/(connecting.length+1)),ready=!0;while(ready&&queries.length&&max-- >0){let query=queries.shift();if(query.reserve)return query.reserve(c);ready=c.execute(query)}ready?move(c,busy):move(c,full)}function onclose(c,e){move(c,closed),c.reserved=null,c.onclose&&(c.onclose(e),c.onclose=null),options.onclose&&options.onclose(c.id),queries.length&&connect(c,queries.shift())}}function parseOptions(a,b2){if(a&&a.shared)return a;let env=process.env,o=(!a||typeof a==="string"?b2:a)||{},{url,multihost}=parseUrl(a),query=[...url.searchParams].reduce((a2,[b3,c])=>(a2[b3]=c,a2),{}),host=o.hostname||o.host||multihost||url.hostname||env.PGHOST||"localhost",port=o.port||url.port||env.PGPORT||5432,user=o.user||o.username||url.username||env.PGUSERNAME||env.PGUSER||osUsername();o.no_prepare&&(o.prepare=!1),query.sslmode&&(query.ssl=query.sslmode,delete query.sslmode),"timeout"in o&&(console.log("The timeout option is deprecated, use idle_timeout instead"),o.idle_timeout=o.timeout),query.sslrootcert==="system"&&(query.ssl="verify-full");let ints=["idle_timeout","connect_timeout","max_lifetime","max_pipeline","backoff","keep_alive"],defaults={max:globalThis.Cloudflare?3:10,ssl:!1,sslnegotiation:null,idle_timeout:null,connect_timeout:30,max_lifetime,max_pipeline:100,backoff,keep_alive:60,prepare:!0,debug:!1,fetch_types:!0,publications:"alltables",target_session_attrs:null};return{host:Array.isArray(host)?host:host.split(",").map((x)=>x.split(":")[0]),port:Array.isArray(port)?port:host.split(",").map((x)=>parseInt(x.split(":")[1]||port)),path:o.path||host.indexOf("/")>-1&&host+"/.s.PGSQL."+port,database:o.database||o.db||(url.pathname||"").slice(1)||env.PGDATABASE||user,user,pass:o.pass||o.password||url.password||env.PGPASSWORD||"",...Object.entries(defaults).reduce((acc,[k,d])=>{let value=k in o?o[k]:(k in query)?query[k]==="disable"||query[k]==="false"?!1:query[k]:env["PG"+k.toUpperCase()]||d;return acc[k]=typeof value==="string"&&ints.includes(k)?+value:value,acc},{}),connection:{application_name:env.PGAPPNAME||"postgres.js",...o.connection,...Object.entries(query).reduce((acc,[k,v])=>((k in defaults)||(acc[k]=v),acc),{})},types:o.types||{},target_session_attrs:tsa(o,url,env),onnotice:o.onnotice,onnotify:o.onnotify,onclose:o.onclose,onparameter:o.onparameter,socket:o.socket,transform:parseTransform(o.transform||{undefined:void 0}),parameters:{},shared:{retries:0,typeArrayMap:{}},...mergeUserTypes(o.types)}}function tsa(o,url,env){let x=o.target_session_attrs||url.searchParams.get("target_session_attrs")||env.PGTARGETSESSIONATTRS;if(!x||["read-write","read-only","primary","standby","prefer-standby"].includes(x))return x;throw Error("target_session_attrs "+x+" is not supported")}function backoff(retries){return(0.5+Math.random()/2)*Math.min(3**retries/100,20)}function max_lifetime(){return 60*(30+Math.random()*30)}function parseTransform(x){return{undefined:x.undefined,column:{from:typeof x.column==="function"?x.column:x.column&&x.column.from,to:x.column&&x.column.to},value:{from:typeof x.value==="function"?x.value:x.value&&x.value.from,to:x.value&&x.value.to},row:{from:typeof x.row==="function"?x.row:x.row&&x.row.from,to:x.row&&x.row.to}}}function parseUrl(url){if(!url||typeof url!=="string")return{url:{searchParams:new Map}};let host=url;host=host.slice(host.indexOf("://")+3).split(/[?/]/)[0],host=decodeURIComponent(host.slice(host.indexOf("@")+1));let urlObj=new URL(url.replace(host,host.split(",")[0]));return{url:{username:decodeURIComponent(urlObj.username),password:decodeURIComponent(urlObj.password),host:urlObj.host,hostname:urlObj.hostname,port:urlObj.port,pathname:urlObj.pathname,searchParams:urlObj.searchParams},multihost:host.indexOf(",")>-1&&host}}function osUsername(){try{return os.userInfo().username}catch(_){return process.env.USERNAME||process.env.USER||process.env.LOGNAME}}var src_default;var init_src=__esm(()=>{init_types3();init_connection();init_query();init_queue();init_errors2();init_large();Object.assign(Postgres,{PostgresError,toPascal,pascal,toCamel,camel,toKebab,kebab,fromPascal,fromCamel,fromKebab,BigInt:{to:20,from:[20],parse:(x)=>BigInt(x),serialize:(x)=>x.toString()}});src_default=Postgres});var exports_db={};__export(exports_db,{shutdown:()=>shutdown,runRetention:()=>runRetention,resolveTcpPgPassword:()=>resolveTcpPgPassword,resolvePgserveSocketDir:()=>resolvePgserveSocketDir,resolvePgserveLibpqSocketPath:()=>resolvePgserveLibpqSocketPath,resolvePgserveDaemonPidPath:()=>resolvePgserveDaemonPidPath,resolvePgserveControlSocketPath:()=>resolvePgserveControlSocketPath,resolvePgserveAuthPassword:()=>resolvePgserveAuthPassword,resolveDatabaseName:()=>resolveDatabaseName,resetConnection:()=>resetConnection,probePgserveDaemon:()=>probePgserveDaemon,isSocketMode:()=>isSocketMode,isConnected:()=>isConnected,isAvailable:()=>isAvailable,getOrStartDaemon:()=>getOrStartDaemon,getLockfilePath:()=>getLockfilePath,getDataDir:()=>getDataDir,getConnection:()=>getConnection,getActivePort:()=>getActivePort,ensurePgserve:()=>ensurePgserve,checkRootGuard:()=>checkRootGuard,autoStartDaemon:()=>autoStartDaemon,__setSpawnDaemonForTest:()=>__setSpawnDaemonForTest,DB_NAME:()=>DB_NAME});import{execSync as execSync3,spawn}from"child_process";import{existsSync as existsSync13,mkdirSync as mkdirSync6,readFileSync as readFileSync9,renameSync,unlinkSync as unlinkSync3,writeFileSync as writeFileSync6}from"fs";import{createConnection}from"net";import{homedir as homedir11}from"os";import{join as join17}from"path";function resolvePgserveSocketDir(){let xdg=process.env.XDG_RUNTIME_DIR,base=xdg&&xdg.length>0?xdg:"/tmp";return join17(base,"pgserve")}function resolveDatabaseName(){let testDbName=process.env.GENIE_TEST_DB_NAME;if(testDbName&&testDbName.length>0)return testDbName;return DB_NAME}function resolvePgserveAuthPassword(){let password=process.env.PGPASSWORD;return password&&password.length>0?password:DB_NAME}function resolveTcpPgPassword(){return resolvePgserveAuthPassword()}function resolvePgserveLibpqSocketPath(){return join17(resolvePgserveSocketDir(),".s.PGSQL.5432")}function resolvePgserveControlSocketPath(){return join17(resolvePgserveSocketDir(),"control.sock")}function resolvePgserveDaemonPidPath(){return join17(resolvePgserveSocketDir(),"pgserve.pid")}function probePgserveDaemon(){let socketPresent=existsSync13(resolvePgserveLibpqSocketPath()),pid=liveDaemonPid(readDaemonPid(resolvePgserveDaemonPidPath()));if(socketPresent&&pid!==null)return{running:!0,pid,socketPresent:!0};if(!socketPresent&&pid===null)return{running:!1,pid:null,socketPresent:!1,reason:"no daemon"};return{running:!1,pid,socketPresent,reason:socketPresent?"socket present but pid stale":"pid alive but no socket"}}function readDaemonPid(pidPath){if(!existsSync13(pidPath))return null;try{let raw=readFileSync9(pidPath,"utf-8").trim(),parsed=Number.parseInt(raw,10);return Number.isInteger(parsed)&&parsed>0?parsed:null}catch{return null}}function liveDaemonPid(pid){if(pid===null)return null;try{return process.kill(pid,0),pid}catch(err){return err.code==="EPERM"?pid:null}}function findPgserveDaemonBin(){try{let resolved=__require.resolve("pgserve/bin/pgserve-wrapper.cjs");if(existsSync13(resolved))return resolved}catch{}let globalBin=join17(homedir11(),".bun","bin","pgserve");if(existsSync13(globalBin))return globalBin;try{let fromPath=execSync3("which pgserve",{encoding:"utf-8",timeout:3000}).trim();if(fromPath.length>0)return fromPath}catch{}return null}function sleep(ms){return new Promise((r)=>setTimeout(r,ms))}async function getOrStartDaemon(){if(process.env.GENIE_PG_DISABLE_AUTOSTART==="1")return probePgserveDaemon();let initial=probePgserveDaemon();if(initial.running)return initial;if(process.env.CI==="true"&&process.env.GENIE_PG_ALLOW_CI_AUTOSTART!=="1")throw Error("pgserve v2 daemon socket not present and CI=true. Either start `pgserve daemon` in the workflow or set GENIE_PG_ALLOW_CI_AUTOSTART=1 to opt in.");let rootErr=checkRootGuard();if(rootErr!==null)throw Error(rootErr);if(initial.reason==="socket present but pid stale"&&await isPgserveSocketAccepting())return{running:!0,pid:null,socketPresent:!0,reason:"socket accepts connections but pid file is stale"};if(daemonStartPromise)return await daemonStartPromise,probePgserveDaemon();daemonStartPromise=(async()=>{cleanPartialDaemonState(initial);let bin=findPgserveDaemonBin();if(bin===null)throw Error("pgserve binary not found. Install with `bun add pgserve@^2.0.0` (or `npm i pgserve@^2.0.0`), or start `pgserve daemon` manually before running genie.");mkdirSync6(resolvePgserveSocketDir(),{recursive:!0,mode:448}),spawn(bin,["daemon"],{detached:!0,stdio:"ignore",env:{...process.env}}).unref();let socketPath=resolvePgserveLibpqSocketPath(),timeout=Number(process.env.GENIE_PGSERVE_TIMEOUT)||16000,deadline=Date.now()+timeout;while(Date.now()<deadline){if(existsSync13(socketPath))return;await sleep(250)}throw Error(`pgserve v2 daemon did not bind ${socketPath} within ${Math.round(timeout/1000)}s. Try starting it manually: ${bin} daemon`)})();try{await daemonStartPromise}finally{daemonStartPromise=null}return probePgserveDaemon()}function cleanPartialDaemonState(initial){if(initial.reason==="pid alive but no socket"&&initial.pid!==null)unlinkIfPresent(resolvePgserveDaemonPidPath());if(initial.reason==="socket present but pid stale")removeStalePgserveSocketArtifacts()}async function isPgserveSocketAccepting(){let candidates=[resolvePgserveLibpqSocketPath(),resolvePgserveControlSocketPath()].filter((path2)=>existsSync13(path2));for(let path2 of candidates)if(await canConnectUnixSocket(path2))return!0;return!1}function canConnectUnixSocket(path2){return new Promise((resolve3)=>{let settled=!1,timer2=null,socket=null,finish=(ok)=>{if(settled)return;if(settled=!0,timer2)clearTimeout(timer2);socket?.removeAllListeners(),socket?.destroy(),resolve3(ok)};socket=createConnection(path2),timer2=setTimeout(()=>finish(!1),250),timer2.unref(),socket.once("connect",()=>finish(!0)),socket.once("error",()=>finish(!1))})}function removeStalePgserveSocketArtifacts(){for(let path2 of[resolvePgserveDaemonPidPath(),resolvePgserveLibpqSocketPath(),resolvePgserveControlSocketPath()])unlinkIfPresent(path2)}function unlinkIfPresent(path2){try{unlinkSync3(path2)}catch{}}function maskCredentials(url){return url.replace(/\/\/.*@/,"//***@")}function checkRootGuard(){if(process.getuid?.()!==0)return null;if(process.env.GENIE_ALLOW_ROOT==="1")return null;return"pgserve cannot start under uid 0 (root) \u2014 PostgreSQL refuses to run as root for security reasons. "+"Run genie as a non-root user, or set GENIE_ALLOW_ROOT=1 to attempt anyway. See: https://github.com/automagik-dev/genie/issues/1226"}function isPgAutostartDisabled(){let value=process.env.GENIE_PG_NO_AUTOSTART;return value!==void 0&&TRUTHY_ENV.has(value.trim().toLowerCase())}function selfHealPostgres(dataDir){try{execSync3(`pkill -9 -f "postgres.*${dataDir.replace(/\//g,"\\/")}" 2>/dev/null || true`,{stdio:"ignore",timeout:5000}),execSync3(`pkill -9 -f "pgserve.*${dataDir.replace(/\//g,"\\/")}" 2>/dev/null || true`,{stdio:"ignore",timeout:5000})}catch{}let pidFile=join17(dataDir,"postmaster.pid");if(existsSync13(pidFile))try{unlinkSync3(pidFile)}catch{}try{execSync3("ipcs -m 2>/dev/null | awk '$6 == 0 {print $2}' | xargs -I{} ipcrm -m {} 2>/dev/null || true",{stdio:"ignore",timeout:5000})}catch{}}function signalPgserveTree(child,signal){let pid=child.pid;if(pid===void 0){try{child.kill(signal)}catch{}return}try{if(process.platform==="win32")child.kill(signal);else process.kill(-pid,signal)}catch{try{child.kill(signal)}catch{}}}async function terminatePgserveTree(child){if(signalPgserveTree(child,"SIGTERM"),!await new Promise((resolve3)=>{if(child.exitCode!==null||child.signalCode!==null){resolve3(!0);return}let timer2=setTimeout(()=>resolve3(!1),1000);timer2.unref(),child.once("exit",()=>{clearTimeout(timer2),resolve3(!0)})}))signalPgserveTree(child,"SIGKILL")}function getPort(){let envPort=process.env.GENIE_PG_PORT;if(envPort){let parsed=Number.parseInt(envPort,10);if(!Number.isNaN(parsed)&&parsed>0&&parsed<65536)return parsed}return DEFAULT_PORT}async function isPostgresHealthy(port){try{return await Promise.race([(async()=>{let pg=(await Promise.resolve().then(() => (init_src(),exports_src))).default,probe=pg({host:DEFAULT_HOST,port,database:DB_NAME,username:DB_NAME,password:resolveTcpPgPassword(),max:1,connect_timeout:3,idle_timeout:1});try{return await probe`SELECT 1`,await probe.end({timeout:2}),!0}catch{try{await probe.end({timeout:1})}catch{}return!1}})(),new Promise((resolve3)=>{setTimeout(()=>resolve3(!1),4000).unref()})])}catch{return!1}}function readLockfile(){try{let content=readFileSync9(LOCKFILE_PATH,"utf-8").trim(),port=Number.parseInt(content,10);if(!Number.isNaN(port)&&port>0&&port<65536)return port}catch{}return null}function writeLockfile(port){try{mkdirSync6(GENIE_HOME,{recursive:!0});let tmpPath=`${LOCKFILE_PATH}.tmp.${process.pid}`;writeFileSync6(tmpPath,String(port),"utf-8"),renameSync(tmpPath,LOCKFILE_PATH)}catch{}}function removeLockfile(){try{unlinkSync3(LOCKFILE_PATH)}catch{}}async function runRetention(sql){if(retentionRan)return;try{await sql.unsafe(`
678
+ `};return resolve3(lo),new Promise(async(r)=>finish=r);async function readable({highWaterMark=16384,start=0,end=1/0}={}){let max=end-start;return start&&await lo.seek(start),new Stream2.Readable({highWaterMark,async read(size){let l=size>max?size-max:size;max-=size;let[{data}]=await lo.read(l);if(this.push(data),data.length<size)this.push(null)}})}async function writable({highWaterMark=16384,start=0}={}){return start&&await lo.seek(start),new Stream2.Writable({highWaterMark,write(chunk,encoding,callback){lo.write(chunk).then(()=>callback(),callback)}})}}).catch(reject)})}var init_large=()=>{};var exports_src={};__export(exports_src,{default:()=>src_default});import os from"os";import fs from"fs";function Postgres(a,b2){let options=parseOptions(a,b2),subscribe=options.no_subscribe||Subscribe(Postgres,{...options}),ending=!1,queries=queue_default(),connecting=queue_default(),reserved=queue_default(),closed=queue_default(),ended=queue_default(),open3=queue_default(),busy=queue_default(),full=queue_default(),queues={connecting,reserved,closed,ended,open:open3,busy,full},connections=[...Array(options.max)].map(()=>connection_default(options,queues,{onopen,onend,onclose})),sql=Sql(handler);return Object.assign(sql,{get parameters(){return options.parameters},largeObject:largeObject.bind(null,sql),subscribe,CLOSE,END:CLOSE,PostgresError,options,reserve,listen,begin,close,end}),sql;function Sql(handler2){return handler2.debug=options.debug,Object.entries(options.types).reduce((acc,[name,type2])=>{return acc[name]=(x)=>new Parameter(x,type2.to),acc},typed),Object.assign(sql2,{types:typed,typed,unsafe,notify,array,json:json2,file}),sql2;function typed(value,type2){return new Parameter(value,type2)}function sql2(strings,...args){return strings&&Array.isArray(strings.raw)?new Query(strings,args,handler2,cancel):typeof strings==="string"&&!args.length?new Identifier(options.transform.column.to?options.transform.column.to(strings):strings):new Builder(strings,args)}function unsafe(string,args=[],options2={}){return arguments.length===2&&!Array.isArray(args)&&(options2=args,args=[]),new Query([string],args,handler2,cancel,{prepare:!1,...options2,simple:"simple"in options2?options2.simple:args.length===0})}function file(path2,args=[],options2={}){return arguments.length===2&&!Array.isArray(args)&&(options2=args,args=[]),new Query([],args,(query2)=>{fs.readFile(path2,"utf8",(err,string)=>{if(err)return query2.reject(err);query2.strings=[string],handler2(query2)})},cancel,{...options2,simple:"simple"in options2?options2.simple:args.length===0})}}async function listen(name,fn,onlisten){let listener={fn,onlisten},sql2=listen.sql||(listen.sql=Postgres({...options,max:1,idle_timeout:null,max_lifetime:null,fetch_types:!1,onclose(){Object.entries(listen.channels).forEach(([name2,{listeners}])=>{delete listen.channels[name2],Promise.all(listeners.map((l)=>listen(name2,l.fn,l.onlisten).catch(()=>{})))})},onnotify(c,x){c in listen.channels&&listen.channels[c].listeners.forEach((l)=>l.fn(x))}})),channels=listen.channels||(listen.channels={});if(name in channels){channels[name].listeners.push(listener);let result3=await channels[name].result;return listener.onlisten&&listener.onlisten(),{state:result3.state,unlisten}}channels[name]={result:sql2`listen ${sql2.unsafe('"'+name.replace(/"/g,'""')+'"')}`,listeners:[listener]};let result2=await channels[name].result;return listener.onlisten&&listener.onlisten(),{state:result2.state,unlisten};async function unlisten(){if(name in channels===!1)return;if(channels[name].listeners=channels[name].listeners.filter((x)=>x!==listener),channels[name].listeners.length)return;return delete channels[name],sql2`unlisten ${sql2.unsafe('"'+name.replace(/"/g,'""')+'"')}`}}async function notify(channel,payload){return await sql`select pg_notify(${channel}, ${""+payload})`}async function reserve(){let queue=queue_default(),c=open3.length?open3.shift():await new Promise((resolve3,reject)=>{let query={reserve:resolve3,reject};queries.push(query),closed.length&&connect(closed.shift(),query)});move(c,reserved),c.reserved=()=>queue.length?c.execute(queue.shift()):move(c,reserved),c.reserved.release=!0;let sql2=Sql(handler2);return sql2.release=()=>{c.reserved=null,onopen(c)},sql2;function handler2(q){c.queue===full?queue.push(q):c.execute(q)||move(c,full)}}async function begin(options2,fn){!fn&&(fn=options2,options2="");let queries2=queue_default(),savepoints=0,connection2,prepare=null;try{return await sql.unsafe("begin "+options2.replace(/[^a-z ]/ig,""),[],{onexecute}).execute(),await Promise.race([scope(connection2,fn),new Promise((_,reject)=>connection2.onclose=reject)])}catch(error){throw error}async function scope(c,fn2,name){let sql2=Sql(handler2);sql2.savepoint=savepoint,sql2.prepare=(x)=>prepare=x.replace(/[^a-z0-9$-_. ]/gi);let uncaughtError,result2;name&&await sql2`savepoint ${sql2(name)}`;try{if(result2=await new Promise((resolve3,reject)=>{let x=fn2(sql2);Promise.resolve(Array.isArray(x)?Promise.all(x):x).then(resolve3,reject)}),uncaughtError)throw uncaughtError}catch(e){throw await(name?sql2`rollback to ${sql2(name)}`:sql2`rollback`),e instanceof PostgresError&&e.code==="25P02"&&uncaughtError||e}if(!name)prepare?await sql2`prepare transaction '${sql2.unsafe(prepare)}'`:await sql2`commit`;return result2;function savepoint(name2,fn3){if(name2&&Array.isArray(name2.raw))return savepoint((sql3)=>sql3.apply(sql3,arguments));return arguments.length===1&&(fn3=name2,name2=null),scope(c,fn3,"s"+savepoints+++(name2?"_"+name2:""))}function handler2(q){q.catch((e)=>uncaughtError||(uncaughtError=e)),c.queue===full?queries2.push(q):c.execute(q)||move(c,full)}}function onexecute(c){connection2=c,move(c,reserved),c.reserved=()=>queries2.length?c.execute(queries2.shift()):move(c,reserved)}}function move(c,queue){return c.queue.remove(c),queue.push(c),c.queue=queue,queue===open3?c.idleTimer.start():c.idleTimer.cancel(),c}function json2(x){return new Parameter(x,3802)}function array(x,type2){if(!Array.isArray(x))return array(Array.from(arguments));return new Parameter(x,type2||(x.length?inferType(x)||25:0),options.shared.typeArrayMap)}function handler(query){if(ending)return query.reject(Errors.connection("CONNECTION_ENDED",options,options));if(open3.length)return go(open3.shift(),query);if(closed.length)return connect(closed.shift(),query);busy.length?go(busy.shift(),query):queries.push(query)}function go(c,query){return c.execute(query)?move(c,busy):move(c,full)}function cancel(query){return new Promise((resolve3,reject)=>{query.state?query.active?connection_default(options).cancel(query.state,resolve3,reject):query.cancelled={resolve:resolve3,reject}:(queries.remove(query),query.cancelled=!0,query.reject(Errors.generic("57014","canceling statement due to user request")),resolve3())})}async function end({timeout=null}={}){if(ending)return ending;await 1;let timer2;return ending=Promise.race([new Promise((r)=>timeout!==null&&(timer2=setTimeout(destroy,timeout*1000,r))),Promise.all(connections.map((c)=>c.end()).concat(listen.sql?listen.sql.end({timeout:0}):[],subscribe.sql?subscribe.sql.end({timeout:0}):[]))]).then(()=>clearTimeout(timer2))}async function close(){await Promise.all(connections.map((c)=>c.end()))}async function destroy(resolve3){await Promise.all(connections.map((c)=>c.terminate()));while(queries.length)queries.shift().reject(Errors.connection("CONNECTION_DESTROYED",options));resolve3()}function connect(c,query){return move(c,connecting),c.connect(query),c}function onend(c){move(c,ended)}function onopen(c){if(queries.length===0)return move(c,open3);let max=Math.ceil(queries.length/(connecting.length+1)),ready=!0;while(ready&&queries.length&&max-- >0){let query=queries.shift();if(query.reserve)return query.reserve(c);ready=c.execute(query)}ready?move(c,busy):move(c,full)}function onclose(c,e){move(c,closed),c.reserved=null,c.onclose&&(c.onclose(e),c.onclose=null),options.onclose&&options.onclose(c.id),queries.length&&connect(c,queries.shift())}}function parseOptions(a,b2){if(a&&a.shared)return a;let env=process.env,o=(!a||typeof a==="string"?b2:a)||{},{url,multihost}=parseUrl(a),query=[...url.searchParams].reduce((a2,[b3,c])=>(a2[b3]=c,a2),{}),host=o.hostname||o.host||multihost||url.hostname||env.PGHOST||"localhost",port=o.port||url.port||env.PGPORT||5432,user=o.user||o.username||url.username||env.PGUSERNAME||env.PGUSER||osUsername();o.no_prepare&&(o.prepare=!1),query.sslmode&&(query.ssl=query.sslmode,delete query.sslmode),"timeout"in o&&(console.log("The timeout option is deprecated, use idle_timeout instead"),o.idle_timeout=o.timeout),query.sslrootcert==="system"&&(query.ssl="verify-full");let ints=["idle_timeout","connect_timeout","max_lifetime","max_pipeline","backoff","keep_alive"],defaults={max:globalThis.Cloudflare?3:10,ssl:!1,sslnegotiation:null,idle_timeout:null,connect_timeout:30,max_lifetime,max_pipeline:100,backoff,keep_alive:60,prepare:!0,debug:!1,fetch_types:!0,publications:"alltables",target_session_attrs:null};return{host:Array.isArray(host)?host:host.split(",").map((x)=>x.split(":")[0]),port:Array.isArray(port)?port:host.split(",").map((x)=>parseInt(x.split(":")[1]||port)),path:o.path||host.indexOf("/")>-1&&host+"/.s.PGSQL."+port,database:o.database||o.db||(url.pathname||"").slice(1)||env.PGDATABASE||user,user,pass:o.pass||o.password||url.password||env.PGPASSWORD||"",...Object.entries(defaults).reduce((acc,[k,d])=>{let value=k in o?o[k]:(k in query)?query[k]==="disable"||query[k]==="false"?!1:query[k]:env["PG"+k.toUpperCase()]||d;return acc[k]=typeof value==="string"&&ints.includes(k)?+value:value,acc},{}),connection:{application_name:env.PGAPPNAME||"postgres.js",...o.connection,...Object.entries(query).reduce((acc,[k,v])=>((k in defaults)||(acc[k]=v),acc),{})},types:o.types||{},target_session_attrs:tsa(o,url,env),onnotice:o.onnotice,onnotify:o.onnotify,onclose:o.onclose,onparameter:o.onparameter,socket:o.socket,transform:parseTransform(o.transform||{undefined:void 0}),parameters:{},shared:{retries:0,typeArrayMap:{}},...mergeUserTypes(o.types)}}function tsa(o,url,env){let x=o.target_session_attrs||url.searchParams.get("target_session_attrs")||env.PGTARGETSESSIONATTRS;if(!x||["read-write","read-only","primary","standby","prefer-standby"].includes(x))return x;throw Error("target_session_attrs "+x+" is not supported")}function backoff(retries){return(0.5+Math.random()/2)*Math.min(3**retries/100,20)}function max_lifetime(){return 60*(30+Math.random()*30)}function parseTransform(x){return{undefined:x.undefined,column:{from:typeof x.column==="function"?x.column:x.column&&x.column.from,to:x.column&&x.column.to},value:{from:typeof x.value==="function"?x.value:x.value&&x.value.from,to:x.value&&x.value.to},row:{from:typeof x.row==="function"?x.row:x.row&&x.row.from,to:x.row&&x.row.to}}}function parseUrl(url){if(!url||typeof url!=="string")return{url:{searchParams:new Map}};let host=url;host=host.slice(host.indexOf("://")+3).split(/[?/]/)[0],host=decodeURIComponent(host.slice(host.indexOf("@")+1));let urlObj=new URL(url.replace(host,host.split(",")[0]));return{url:{username:decodeURIComponent(urlObj.username),password:decodeURIComponent(urlObj.password),host:urlObj.host,hostname:urlObj.hostname,port:urlObj.port,pathname:urlObj.pathname,searchParams:urlObj.searchParams},multihost:host.indexOf(",")>-1&&host}}function osUsername(){try{return os.userInfo().username}catch(_){return process.env.USERNAME||process.env.USER||process.env.LOGNAME}}var src_default;var init_src=__esm(()=>{init_types3();init_connection();init_query();init_queue();init_errors2();init_large();Object.assign(Postgres,{PostgresError,toPascal,pascal,toCamel,camel,toKebab,kebab,fromPascal,fromCamel,fromKebab,BigInt:{to:20,from:[20],parse:(x)=>BigInt(x),serialize:(x)=>x.toString()}});src_default=Postgres});var exports_db={};__export(exports_db,{shutdown:()=>shutdown,runRetention:()=>runRetention,resolveTcpPgPassword:()=>resolveTcpPgPassword,resolvePgserveSocketDir:()=>resolvePgserveSocketDir,resolvePgserveLibpqSocketPath:()=>resolvePgserveLibpqSocketPath,resolvePgserveDaemonPidPath:()=>resolvePgserveDaemonPidPath,resolvePgserveControlSocketPath:()=>resolvePgserveControlSocketPath,resolvePgserveAuthPassword:()=>resolvePgserveAuthPassword,resolveDatabaseName:()=>resolveDatabaseName,resetConnection:()=>resetConnection,probePgserveDaemon:()=>probePgserveDaemon,isSocketMode:()=>isSocketMode,isConnected:()=>isConnected,isAvailable:()=>isAvailable,getOrStartDaemon:()=>getOrStartDaemon,getLockfilePath:()=>getLockfilePath,getDataDir:()=>getDataDir,getConnection:()=>getConnection,getActivePort:()=>getActivePort,ensurePgserve:()=>ensurePgserve,checkRootGuard:()=>checkRootGuard,autoStartDaemon:()=>autoStartDaemon,__setSpawnDaemonForTest:()=>__setSpawnDaemonForTest,DB_NAME:()=>DB_NAME});import{execSync as execSync3,spawn}from"child_process";import{existsSync as existsSync13,mkdirSync as mkdirSync6,readFileSync as readFileSync9,renameSync,unlinkSync as unlinkSync3,writeFileSync as writeFileSync6}from"fs";import{createConnection}from"net";import{homedir as homedir11}from"os";import{join as join17}from"path";function resolvePgserveSocketDir(){let xdg=process.env.XDG_RUNTIME_DIR,base=xdg&&xdg.length>0?xdg:"/tmp";return join17(base,"pgserve")}function resolveDatabaseName(){let testDbName=process.env.GENIE_TEST_DB_NAME;if(testDbName&&testDbName.length>0)return testDbName;return DB_NAME}function resolvePgserveAuthPassword(){let password=process.env.PGPASSWORD;return password&&password.length>0?password:DB_NAME}function resolveTcpPgPassword(){return resolvePgserveAuthPassword()}function resolvePgserveLibpqSocketPath(){return join17(resolvePgserveSocketDir(),".s.PGSQL.5432")}function resolvePgserveControlSocketPath(){return join17(resolvePgserveSocketDir(),"control.sock")}function resolvePgserveDaemonPidPath(){return join17(resolvePgserveSocketDir(),"pgserve.pid")}function probePgserveDaemon(){let socketPresent=existsSync13(resolvePgserveLibpqSocketPath()),pid=liveDaemonPid(readDaemonPid(resolvePgserveDaemonPidPath()));if(socketPresent&&pid!==null)return{running:!0,pid,socketPresent:!0};if(!socketPresent&&pid===null)return{running:!1,pid:null,socketPresent:!1,reason:"no daemon"};return{running:!1,pid,socketPresent,reason:socketPresent?"socket present but pid stale":"pid alive but no socket"}}function readDaemonPid(pidPath){if(!existsSync13(pidPath))return null;try{let raw=readFileSync9(pidPath,"utf-8").trim(),parsed=Number.parseInt(raw,10);return Number.isInteger(parsed)&&parsed>0?parsed:null}catch{return null}}function liveDaemonPid(pid){if(pid===null)return null;try{return process.kill(pid,0),pid}catch(err){return err.code==="EPERM"?pid:null}}function findPgserveDaemonBin(){try{let resolved=__require.resolve("pgserve/bin/pgserve-wrapper.cjs");if(existsSync13(resolved))return resolved}catch{}let globalBin=join17(homedir11(),".bun","bin","pgserve");if(existsSync13(globalBin))return globalBin;try{let fromPath=execSync3("which pgserve",{encoding:"utf-8",timeout:3000}).trim();if(fromPath.length>0)return fromPath}catch{}return null}function sleep(ms){return new Promise((r)=>setTimeout(r,ms))}async function getOrStartDaemon(){if(process.env.GENIE_PG_DISABLE_AUTOSTART==="1"||isPgAutostartDisabled()){let state=probePgserveDaemon();if(state.running)return state;throw Error("pgserve daemon unavailable and PG autostart is disabled")}let initial=probePgserveDaemon();if(initial.running)return initial;if(process.env.CI==="true"&&process.env.GENIE_PG_ALLOW_CI_AUTOSTART!=="1")throw Error("pgserve v2 daemon socket not present and CI=true. Either start `pgserve daemon` in the workflow or set GENIE_PG_ALLOW_CI_AUTOSTART=1 to opt in.");let rootErr=checkRootGuard();if(rootErr!==null)throw Error(rootErr);if(initial.reason==="socket present but pid stale"&&await isPgserveSocketAccepting())return{running:!0,pid:null,socketPresent:!0,reason:"socket accepts connections but pid file is stale"};if(daemonStartPromise)return await daemonStartPromise,probePgserveDaemon();daemonStartPromise=startPgserveDaemonOnce(initial);try{await daemonStartPromise}finally{daemonStartPromise=null}return probePgserveDaemon()}function cleanPartialDaemonState(initial){if(initial.reason==="pid alive but no socket"&&initial.pid!==null)unlinkIfPresent(resolvePgserveDaemonPidPath());if(initial.reason==="socket present but pid stale")removeStalePgserveSocketArtifacts()}async function isPgserveSocketAccepting(){let candidates=[resolvePgserveLibpqSocketPath(),resolvePgserveControlSocketPath()].filter((path2)=>existsSync13(path2));for(let path2 of candidates)if(await canConnectUnixSocket(path2))return!0;return!1}function canConnectUnixSocket(path2){return new Promise((resolve3)=>{let settled=!1,timer2=null,socket=null,finish=(ok)=>{if(settled)return;if(settled=!0,timer2)clearTimeout(timer2);socket?.removeAllListeners(),socket?.destroy(),resolve3(ok)};socket=createConnection(path2),timer2=setTimeout(()=>finish(!1),250),timer2.unref(),socket.once("connect",()=>finish(!0)),socket.once("error",()=>finish(!1))})}function removeStalePgserveSocketArtifacts(){for(let path2 of[resolvePgserveDaemonPidPath(),resolvePgserveLibpqSocketPath(),resolvePgserveControlSocketPath()])unlinkIfPresent(path2)}function unlinkIfPresent(path2){try{unlinkSync3(path2)}catch{}}async function startPgserveDaemonOnce(initial){if(cleanPartialDaemonState(initial),await tryEnsureDaemonWithSdk())return;let bin=requirePgserveDaemonBin();mkdirSync6(resolvePgserveSocketDir(),{recursive:!0,mode:448}),spawn(bin,["daemon","--data",DATA_DIR,"--log","warn"],{detached:!0,stdio:"ignore",env:{...process.env}}).unref(),await waitForDaemonSocket(bin)}function requirePgserveDaemonBin(){let bin=findPgserveDaemonBin();if(bin!==null)return bin;throw Error("pgserve binary not found. Install with `bun add pgserve@^2.0.2` (or `npm i pgserve@^2.0.2`), or start `pgserve daemon` manually before running genie.")}async function waitForDaemonSocket(bin){let socketPath=resolvePgserveLibpqSocketPath(),timeout=Number(process.env.GENIE_PGSERVE_TIMEOUT)||16000,deadline=Date.now()+timeout;while(Date.now()<deadline){if(existsSync13(socketPath))return;await sleep(250)}throw Error(`pgserve v2 daemon did not bind ${socketPath} within ${Math.round(timeout/1000)}s. Try starting it manually: ${bin} daemon`)}async function tryEnsureDaemonWithSdk(){let sdk;try{sdk=await import("pgserve")}catch{return!1}if(typeof sdk.ensureDaemon!=="function")return!1;let timeoutMs=Number(process.env.GENIE_PGSERVE_TIMEOUT)||16000,state=await sdk.ensureDaemon({dataDir:DATA_DIR,logLevel:"warn",timeoutMs,controlSocketDir:resolvePgserveSocketDir()});return Boolean(state.running&&(state.libpqSocketPresent??state.socketPresent??!0))}function maskCredentials(url){return url.replace(/\/\/.*@/,"//***@")}function checkRootGuard(){if(process.getuid?.()!==0)return null;if(process.env.GENIE_ALLOW_ROOT==="1")return null;return"pgserve cannot start under uid 0 (root) \u2014 PostgreSQL refuses to run as root for security reasons. "+"Run genie as a non-root user, or set GENIE_ALLOW_ROOT=1 to attempt anyway. See: https://github.com/automagik-dev/genie/issues/1226"}function isPgAutostartDisabled(){let value=process.env.GENIE_PG_NO_AUTOSTART;return value!==void 0&&TRUTHY_ENV.has(value.trim().toLowerCase())}function selfHealPostgres(dataDir){try{execSync3(`pkill -9 -f "postgres.*${dataDir.replace(/\//g,"\\/")}" 2>/dev/null || true`,{stdio:"ignore",timeout:5000}),execSync3(`pkill -9 -f "pgserve.*${dataDir.replace(/\//g,"\\/")}" 2>/dev/null || true`,{stdio:"ignore",timeout:5000})}catch{}let pidFile=join17(dataDir,"postmaster.pid");if(existsSync13(pidFile))try{unlinkSync3(pidFile)}catch{}try{execSync3("ipcs -m 2>/dev/null | awk '$6 == 0 {print $2}' | xargs -I{} ipcrm -m {} 2>/dev/null || true",{stdio:"ignore",timeout:5000})}catch{}}function signalPgserveTree(child,signal){let pid=child.pid;if(pid===void 0){try{child.kill(signal)}catch{}return}try{if(process.platform==="win32")child.kill(signal);else process.kill(-pid,signal)}catch{try{child.kill(signal)}catch{}}}async function terminatePgserveTree(child){if(signalPgserveTree(child,"SIGTERM"),!await new Promise((resolve3)=>{if(child.exitCode!==null||child.signalCode!==null){resolve3(!0);return}let timer2=setTimeout(()=>resolve3(!1),1000);timer2.unref(),child.once("exit",()=>{clearTimeout(timer2),resolve3(!0)})}))signalPgserveTree(child,"SIGKILL")}function getPort(){let envPort=process.env.GENIE_PG_PORT;if(envPort){let parsed=Number.parseInt(envPort,10);if(!Number.isNaN(parsed)&&parsed>0&&parsed<65536)return parsed}return DEFAULT_PORT}async function isPostgresHealthy(port){try{return await Promise.race([(async()=>{let pg=(await Promise.resolve().then(() => (init_src(),exports_src))).default,probe=pg({host:DEFAULT_HOST,port,database:DB_NAME,username:DB_NAME,password:resolveTcpPgPassword(),max:1,connect_timeout:3,idle_timeout:1});try{return await probe`SELECT 1`,await probe.end({timeout:2}),!0}catch{try{await probe.end({timeout:1})}catch{}return!1}})(),new Promise((resolve3)=>{setTimeout(()=>resolve3(!1),4000).unref()})])}catch{return!1}}function readLockfile(){try{let content=readFileSync9(LOCKFILE_PATH,"utf-8").trim(),port=Number.parseInt(content,10);if(!Number.isNaN(port)&&port>0&&port<65536)return port}catch{}return null}function writeLockfile(port){try{mkdirSync6(GENIE_HOME,{recursive:!0});let tmpPath=`${LOCKFILE_PATH}.tmp.${process.pid}`;writeFileSync6(tmpPath,String(port),"utf-8"),renameSync(tmpPath,LOCKFILE_PATH)}catch{}}function removeLockfile(){try{unlinkSync3(LOCKFILE_PATH)}catch{}}async function runRetention(sql){if(retentionRan)return;try{await sql.unsafe(`
679
679
  DELETE FROM heartbeats WHERE created_at < now() - interval '7 days';
680
680
  DELETE FROM machine_snapshots WHERE created_at < now() - interval '30 days';
681
681
  DELETE FROM audit_events WHERE entity_type LIKE 'otel_%' AND created_at < now() - interval '30 days';
@@ -2101,7 +2101,7 @@ Stopped following`),process.exit(0)}),await new Promise(()=>{});return}let conte
2101
2101
  [${time}] SYSTEM:`,entry2.text];default:return[]}}function formatFullConversation(entries){return entries.flatMap(formatTranscriptEntryForDisplay).join(`
2102
2102
  `)}async function findWorker(identifier){let worker=await get(identifier);if(worker)return worker;if(worker=await findByTask(identifier),worker)return worker;return(await list()).find((w)=>w.id.includes(identifier)||w.taskId?.includes(identifier)||w.taskTitle?.toLowerCase().includes(identifier.toLowerCase()))??null}async function resolveContext2(workerIdOrName,options){if(options.logFile)return{worker:{id:"direct",paneId:"",session:"",worktree:null,startedAt:new Date().toISOString(),state:"idle",lastStateChange:new Date().toISOString(),repoPath:process.cwd(),provider:"claude"},workerId:"direct",provider:"claude",duration:"N/A"};let worker=await findWorker(workerIdOrName);if(!worker)console.error(`Agent "${workerIdOrName}" not found. Run \`genie agent list\` to see agents.`),process.exit(1);let elapsed=getElapsedTime(worker);return{worker,workerId:worker.id,provider:worker.provider??"claude",branch:worker.worktree?`work/${worker.taskId}`:void 0,duration:elapsed.formatted}}function buildFilter2(options){let filter={},hasFilter=!1;if(options.last&&options.last>0)filter.last=options.last,hasFilter=!0;if(options.after)filter.since=options.after,hasFilter=!0;if(options.type)filter.roles=[options.type],hasFilter=!0;return hasFilter?filter:void 0}function filterSinceExchanges(entries,since){let userCount=0;for(let i2=entries.length-1;i2>=0;i2--)if(entries[i2].role==="user"){if(userCount++,userCount>=since)return entries.slice(i2)}return entries}async function loadEntries(ctx,options){let{readTranscript:readTranscript2,getProvider:getProvider3}=await Promise.resolve().then(() => exports_transcript);if(options.logFile)return(await getProvider3(ctx.worker)).readEntries(options.logFile);return readTranscript2(ctx.worker)}function filterEntries(entries,options){let{applyFilter:applyFilter2}=__toCommonJS(exports_transcript),filtered=options.since&&options.since>0?filterSinceExchanges(entries,options.since):entries,transcriptFilter=buildFilter2(options);if(transcriptFilter)filtered=applyFilter2(filtered,transcriptFilter);return filtered}function outputEntries(filtered,options){if(options.ndjson){for(let entry2 of filtered){let{raw:_raw,...rest}=entry2;console.log(JSON.stringify(options.raw?entry2:rest))}return!0}if(options.raw){for(let entry2 of filtered)console.log(JSON.stringify(entry2.raw));return!0}if(options.full)return console.log(formatFullConversation(filtered)),!0;return!1}async function historyCommand(workerIdOrName,options){let ctx=await resolveContext2(workerIdOrName,options),entries=await loadEntries(ctx,options);if(entries.length===0)console.error(`No transcript found for agent "${ctx.workerId}".`),process.exit(1);let filtered=filterEntries(entries,options);if(outputEntries(filtered,options))return;let events=extractEvents(filtered),toolCallCount=entries.filter((e)=>e.role==="tool_call").length,userMessageCount=entries.filter((e)=>e.role==="user").length,stats2={workerId:ctx.workerId,taskId:ctx.workerId,branch:ctx.branch,provider:ctx.provider,duration:ctx.duration,totalEntries:entries.length,compressedLines:events.length,compressionRatio:entries.length/Math.max(events.length,1),exchanges:userMessageCount,toolCalls:toolCallCount,status:detectStatus(entries)};if(options.json){console.log(JSON.stringify({stats:stats2,events},null,2));return}console.log(formatEventsForDisplay(events,stats2))}var init_history=__esm(()=>{init_agent_registry();init_term_format()});var exports_frontmatter_writer={};__export(exports_frontmatter_writer,{writeFrontmatter:()=>writeFrontmatter,serializeSdkConfig:()=>serializeSdkConfig});import{readFileSync as readFileSync25,writeFileSync as writeFileSync14}from"fs";function writeFrontmatter(filePath,updates){let content=readFileSync25(filePath,"utf-8"),{yamlObj,body}=splitFrontmatter(content),merged={...yamlObj,...stripUndefined(updates)},output=`---
2103
2103
  ${dump(merged,{lineWidth:-1,noRefs:!0,sortKeys:!1,quotingType:'"'})}---
2104
- ${body}`;writeFileSync14(filePath,output,"utf-8")}function serializeSdkConfig(sdk){let result2={};for(let[key,value]of Object.entries(sdk)){if(value===void 0||value===null)continue;if(Array.isArray(value)&&value.length===0)continue;if(typeof value==="object"&&!Array.isArray(value)&&Object.keys(value).length===0)continue;result2[key]=value}return result2}function splitFrontmatter(content){let match=content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);if(!match)return{yamlObj:{},body:content};let yamlStr=match[1],body=match[2],yamlObj={};try{let parsed=load(yamlStr);if(typeof parsed==="object"&&parsed!==null)yamlObj=parsed}catch{}return{yamlObj,body}}function stripUndefined(obj){let result2={};for(let[key,value]of Object.entries(obj))if(value!==void 0)result2[key]=value;return result2}var init_frontmatter_writer=__esm(()=>{init_js_yaml()});import{existsSync as existsSync40,realpathSync as realpathSync5}from"fs";import{homedir as homedir31}from"os";import{join as join48,resolve as resolve6}from"path";function getCwd(deps){return deps.cwd??process.cwd()}function getHomeDir(deps){return deps.homeDir??homedir31()}function getWorkspaceRoot(deps){if("workspaceRoot"in deps)return deps.workspaceRoot??null;return findWorkspace()?.root??null}function getConfig(deps){return deps.config??loadGenieConfigSync()}function expandHome(path3,homeDir){if(path3==="~")return homeDir;if(path3.startsWith("~/"))return join48(homeDir,path3.slice(2));return path3}function normalizeBrainVaultPath(path3,deps){return resolve6(getCwd(deps),expandHome(path3,getHomeDir(deps)))}function canonicalBrainVaultPath(path3,deps){let realpath=deps.realpath??realpathSync5;try{return realpath(path3)}catch{return resolve6(path3)}}function dedupeBrainVaultPaths(paths,deps={}){let seen=new Set,deduped=[];for(let path3 of paths){let canonical=canonicalBrainVaultPath(path3,deps);if(seen.has(canonical))continue;seen.add(canonical),deduped.push(canonical)}return deduped}function hasBrainJson(path3,deps){return(deps.exists??existsSync40)(join48(path3,"brain.json"))}function filterVaultsWithBrainJson(paths,source,deps){let warn=deps.warn??console.warn,label=source==="config"?"configured":source==="registry"?"registered":"legacy",valid=[];for(let path3 of paths){if(hasBrainJson(path3,deps)){valid.push(path3);continue}warn(` Brain server: skipped ${label} vault ${path3} (missing brain.json)`)}return valid}function normalizeAndDedupe(paths,deps){return dedupeBrainVaultPaths(paths.map((path3)=>normalizeBrainVaultPath(path3,deps)),deps)}function pushPathFromEntry(entry2,paths){let found=!1;for(let field of REGISTRY_PATH_FIELDS){let value=entry2[field];if(typeof value==="string"&&value.trim().length>0)paths.push(value),found=!0}return found}function isRegistryRecord(value){return Boolean(value)&&typeof value==="object"&&!Array.isArray(value)}function collectRegistryArray(values2,paths){for(let item of values2)collectRegistryPaths(item,paths)}function collectRegistryObject(entry2,paths){let foundPath=pushPathFromEntry(entry2,paths);for(let field of REGISTRY_COLLECTION_FIELDS)if(field in entry2)collectRegistryPaths(entry2[field],paths);if(!foundPath){for(let item of Object.values(entry2))if(item&&typeof item==="object")collectRegistryPaths(item,paths)}}function collectRegistryPaths(value,paths){if(typeof value==="string"){if(value.trim().length>0)paths.push(value);return}if(Array.isArray(value)){collectRegistryArray(value,paths);return}if(isRegistryRecord(value))collectRegistryObject(value,paths)}function countRegistryItems(value,fallback){if(Array.isArray(value))return value.length;if(!isRegistryRecord(value))return fallback;for(let field of REGISTRY_COLLECTION_FIELDS){let collection=value[field];if(Array.isArray(collection))return collection.length;if(isRegistryRecord(collection))return Object.keys(collection).length}return fallback}async function discoverRegisteredBrainVaultPaths(deps){let brain=deps.brain;if(!brain)return{paths:[],registryCount:0};let registryCalls=["listBrains","listBrainVaults","listVaults","listRegisteredBrains","listRegisteredBrainVaults","getBrainRegistry","readBrainRegistry"];for(let name of registryCalls){let read=brain[name];if(typeof read!=="function")continue;try{let result2=await read.call(brain),paths=[];if(collectRegistryPaths(result2,paths),paths.length>0)return{paths,registryCount:countRegistryItems(result2,paths.length)}}catch(err){let msg=err instanceof Error?err.message:String(err);(deps.warn??console.warn)(` Brain registry: ${name} failed: ${msg}`)}}return{paths:[],registryCount:0}}async function findLegacyBrainVault(deps={}){let cwd=getCwd(deps),homeDir=getHomeDir(deps),workspaceRoot=getWorkspaceRoot(deps),candidates=[workspaceRoot?join48(workspaceRoot,"brain"):void 0,cwd,join48(cwd,"brain"),join48(homeDir,"brain")].filter((path3)=>typeof path3==="string");for(let path3 of normalizeAndDedupe(candidates,deps))if(hasBrainJson(path3,deps))return path3;return null}async function findBrainVault(deps={}){return(await resolveBrainVaults(deps)).paths[0]??null}async function resolveBrainVaults(deps={}){let configuredPaths=getConfig(deps).brain?.paths;if(Array.isArray(configuredPaths)&&configuredPaths.length>0)return{source:"config",paths:filterVaultsWithBrainJson(normalizeAndDedupe(configuredPaths,deps),"config",deps)};let registered=await discoverRegisteredBrainVaultPaths(deps);if(registered.paths.length>0)return{source:"registry",paths:filterVaultsWithBrainJson(normalizeAndDedupe(registered.paths,deps),"registry",deps),registryCount:registered.registryCount};let legacyPath=await findLegacyBrainVault(deps);return{source:"legacy",paths:legacyPath?[legacyPath]:[]}}function normalizeStartupConcurrency(value){if(typeof value!=="number"||!Number.isFinite(value))return DEFAULT_BRAIN_START_CONCURRENCY;return Math.max(1,Math.floor(value))}async function allSettledBounded(items,concurrency,worker){let results=Array(items.length),nextIndex=0;async function runWorker(){while(!0){let index=nextIndex++;if(index>=items.length)return;try{results[index]={status:"fulfilled",value:await worker(items[index],index)}}catch(reason){results[index]={status:"rejected",reason}}}}return await Promise.allSettled(Array.from({length:Math.min(concurrency,items.length)},()=>runWorker())),results}function warnRegistryDrift(resolution,startedCount,resolvedCount,deps){if(resolution.source!=="registry")return;let expectedCount=resolution.registryCount??resolvedCount;if(startedCount===expectedCount)return;(deps.warn??console.warn)(` Brain server: registry drift: started ${startedCount}/${expectedCount} registered vault(s) (${resolvedCount} resolved valid path(s))`)}async function startResolvedBrainVaults(resolution,brain,geniePgPort,deps={}){let startEmbeddedBrainServer=brain.startEmbeddedBrainServer;if(!startEmbeddedBrainServer)return[];let warn=deps.warn??console.warn,log2=deps.log??console.log,handles=[],paths=dedupeBrainVaultPaths(resolution.paths,deps),concurrency=normalizeStartupConcurrency(deps.startupConcurrency),results=await allSettledBounded(paths,concurrency,async(brainPath)=>{let handle=await startEmbeddedBrainServer.call(brain,{brainPath,geniePgPort});return log2(` Brain server ready on port ${handle.port} (${brainPath})`),{brainPath,port:handle.port,stop:handle.stop}});for(let index=0;index<results.length;index++){let result2=results[index];if(result2.status==="fulfilled")handles.push(result2.value);else{let msg=result2.reason instanceof Error?result2.reason.message:String(result2.reason);warn(` Brain server: failed for ${paths[index]}: ${msg}`)}}return warnRegistryDrift(resolution,handles.length,paths.length,deps),handles}var REGISTRY_PATH_FIELDS,REGISTRY_COLLECTION_FIELDS,DEFAULT_BRAIN_START_CONCURRENCY=4;var init_brain_vaults=__esm(()=>{init_genie_config2();init_workspace();REGISTRY_PATH_FIELDS=["homePath","brainPath","vaultPath","path","root","dir"],REGISTRY_COLLECTION_FIELDS=["paths","brains","vaults","entries","items","registered"]});var exports_tui_disable={};__export(exports_tui_disable,{noticeTuiSkipped:()=>noticeTuiSkipped,isTuiDisabled:()=>isTuiDisabled});function isTuiDisabled(){let envVal=process.env.GENIE_TUI_DISABLE;if(envVal&&TRUTHY2.has(envVal.trim().toLowerCase()))return!0;if(process.argv.includes("--no-tui"))return!0;return!1}function noticeTuiSkipped(context){let reason=process.env.GENIE_TUI_DISABLE?"GENIE_TUI_DISABLE is set":"--no-tui flag present";console.error(`genie: TUI ${context} skipped (${reason}). See https://github.com/automagik-dev/genie for status of the upstream OpenTUI kqueue spin on macOS.`)}var TRUTHY2;var init_tui_disable=__esm(()=>{TRUTHY2=new Set(["1","true","yes","on"])});function parseDuration(input){let match=input.trim().match(DURATION_RE);if(!match)throw Error(`Invalid duration: "${input}". Expected format: 10m, 2h, 24h, 1d`);let value=Number.parseFloat(match[1]),unit=match[2].toLowerCase(),ms=value*{s:1000,sec:1000,m:60000,min:60000,h:3600000,hr:3600000,d:86400000,day:86400000}[unit];if(ms<=0)throw Error(`Duration must be positive: "${input}"`);return ms}function expandRange(range,step,min,max){if(step===0)throw Error("Cron step value cannot be 0");if(range==="*"){let out=[];for(let i2=min;i2<=max;i2+=step)out.push(i2);return out}if(range.includes("-")){let[start,end]=range.split("-").map(Number),out=[];for(let i2=start;i2<=end;i2+=step)out.push(i2);return out}return[Number.parseInt(range,10)]}function parseCronField(field,min,max){let values2=new Set;for(let part of field.split(",")){let stepMatch=part.match(/^(.+)\/(\d+)$/),step=stepMatch?Number.parseInt(stepMatch[2],10):1,range=stepMatch?stepMatch[1]:part;for(let v of expandRange(range,step,min,max))values2.add(v)}return[...values2].sort((a,b2)=>a-b2)}function getTimeParts(date,tz){if(!tz)return{month:date.getMonth()+1,dom:date.getDate(),dow:date.getDay(),hour:date.getHours(),minute:date.getMinutes()};let parts=new Intl.DateTimeFormat("en-US",{timeZone:tz,year:"numeric",month:"numeric",day:"numeric",hour:"numeric",minute:"numeric",weekday:"short",hour12:!1}).formatToParts(date),get3=(type2)=>Number(parts.find((p)=>p.type===type2)?.value??0),dayMap={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6},weekday=parts.find((p)=>p.type==="weekday")?.value??"Sun";return{month:get3("month"),dom:get3("day"),dow:dayMap[weekday]??0,hour:get3("hour")===24?0:get3("hour"),minute:get3("minute")}}function parseOpts(afterOrOpts){if(afterOrOpts instanceof Date)return{after:afterOrOpts};if(afterOrOpts)return{after:afterOrOpts.after,timezone:afterOrOpts.timezone};return{}}function advanceToNextDay(candidate,tz){candidate.setTime(candidate.getTime()+86400000);let tp=getTimeParts(candidate,tz);candidate.setTime(candidate.getTime()-tp.hour*3600000-tp.minute*60000)}function parseCronExpr(cronExpr){let parts=cronExpr.trim().split(/\s+/);if(parts.length<5)throw Error(`Invalid cron expression: "${cronExpr}"`);let[minField,hourField,domField,monthField,dowField]=parts;return{minutes:parseCronField(minField,0,59),hours:parseCronField(hourField,0,23),doms:parseCronField(domField,1,31),months:parseCronField(monthField,1,12),dows:parseCronField(dowField,0,6),domRestricted:domField!=="*",dowRestricted:dowField!=="*"}}function computeNextCronDue(cronExpr,afterOrOpts){let{after,timezone}=parseOpts(afterOrOpts),cron=parseCronExpr(cronExpr),candidate=new Date((after??new Date).getTime());candidate.setSeconds(0,0),candidate.setTime(candidate.getTime()+60000);let limit=new Date(candidate.getTime()+31622400000);while(candidate<=limit){let tp=getTimeParts(candidate,timezone);if(!cron.months.includes(tp.month)){advanceToNextDay(candidate,timezone);continue}if(!(cron.domRestricted&&cron.dowRestricted?cron.doms.includes(tp.dom)||cron.dows.includes(tp.dow):cron.doms.includes(tp.dom)&&cron.dows.includes(tp.dow))){advanceToNextDay(candidate,timezone);continue}if(!cron.hours.includes(tp.hour)){candidate.setTime(candidate.getTime()+3600000-tp.minute*60000);continue}if(cron.minutes.includes(tp.minute))return candidate;candidate.setTime(candidate.getTime()+60000)}throw Error(`No next cron occurrence found for "${cronExpr}" within 366 days`)}var DURATION_RE;var init_cron=__esm(()=>{DURATION_RE=/^(\d+(?:\.\d+)?)\s*(s|sec|m|min|h|hr|d|day)s?$/i});import{randomUUID as randomUUID7}from"crypto";function parseNotifyPayload(channel,raw){switch(channel){case"genie_task_stage":{let parts=raw.split(":");if(parts.length<3)return null;return{channel,eventType:"task.stage_change",payload:{taskId:parts[0],fromStage:parts[1],toStage:parts[2]},taskId:parts[0],summary:`Task ${parts[0]} moved from ${parts[1]} to ${parts[2]}`}}case"genie_executor_state":{let parts=raw.split(":");if(parts.length<4)return null;let eventType=parts[3]==="error"?"executor.error":"executor.state_change";return{channel,eventType,payload:{executorId:parts[0],agentId:parts[1],oldState:parts[2],newState:parts[3]},agentId:parts[1],summary:`${parts[1]} state: ${parts[2]} \u2192 ${parts[3]}`}}case"genie_message":{let parts=raw.split(":");if(parts.length<2)return null;return{channel,eventType:"task.comment",payload:{messageId:parts[0],conversationId:parts[1]},summary:`New message in conversation ${parts[1]}`}}case"genie_audit_event":{let parts=raw.split(":");if(parts.length<3)return null;return{channel,eventType:`${parts[0]}.${parts[2]}`,payload:{entityType:parts[0],entityId:parts[1],auditEventType:parts[2]},summary:`${parts[0]} ${parts[1]}: ${parts[2]}`}}default:return null}}function isActionableEvent(eventType){return ACTIONABLE_EVENTS.has(eventType)||eventType.startsWith("request.")}async function resolveTargetTeams(event){if(!isActionableEvent(event.eventType))return[];let active=(await listTeams()).filter((t)=>t.status==="in_progress");if(event.agentId){let aid=event.agentId;return active.filter((t)=>t.members.includes(aid)||t.leader===aid).map((t)=>t.name)}return active.map((t)=>t.name)}async function writeMailbox(repoPath,leader,message,traceId){try{await(await getConnection())`
2104
+ ${body}`;writeFileSync14(filePath,output,"utf-8")}function serializeSdkConfig(sdk){let result2={};for(let[key,value]of Object.entries(sdk)){if(value===void 0||value===null)continue;if(Array.isArray(value)&&value.length===0)continue;if(typeof value==="object"&&!Array.isArray(value)&&Object.keys(value).length===0)continue;result2[key]=value}return result2}function splitFrontmatter(content){let match=content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);if(!match)return{yamlObj:{},body:content};let yamlStr=match[1],body=match[2],yamlObj={};try{let parsed=load(yamlStr);if(typeof parsed==="object"&&parsed!==null)yamlObj=parsed}catch{}return{yamlObj,body}}function stripUndefined(obj){let result2={};for(let[key,value]of Object.entries(obj))if(value!==void 0)result2[key]=value;return result2}var init_frontmatter_writer=__esm(()=>{init_js_yaml()});import{existsSync as existsSync40,realpathSync as realpathSync5}from"fs";import{homedir as homedir31}from"os";import{join as join48,resolve as resolve6}from"path";function getCwd(deps){return deps.cwd??process.cwd()}function getHomeDir(deps){return deps.homeDir??homedir31()}function getWorkspaceRoot(deps){if("workspaceRoot"in deps)return deps.workspaceRoot??null;return findWorkspace()?.root??null}function getConfig(deps){return deps.config??loadGenieConfigSync()}function expandHome(path3,homeDir){if(path3==="~")return homeDir;if(path3.startsWith("~/"))return join48(homeDir,path3.slice(2));return path3}function normalizeBrainVaultPath(path3,deps){return resolve6(getCwd(deps),expandHome(path3,getHomeDir(deps)))}function canonicalBrainVaultPath(path3,deps){let realpath=deps.realpath??realpathSync5;try{return realpath(path3)}catch{return resolve6(path3)}}function dedupeBrainVaultPaths(paths,deps={}){let seen=new Set,deduped=[];for(let path3 of paths){let canonical=canonicalBrainVaultPath(path3,deps);if(seen.has(canonical))continue;seen.add(canonical),deduped.push(canonical)}return deduped}function hasBrainJson(path3,deps){return(deps.exists??existsSync40)(join48(path3,"brain.json"))}function filterVaultsWithBrainJson(paths,source,deps){let warn=deps.warn??console.warn,label=source==="config"?"configured":source==="registry"?"registered":"legacy",valid=[];for(let path3 of paths){if(hasBrainJson(path3,deps)){valid.push(path3);continue}warn(` Brain server: skipped ${label} vault ${path3} (missing brain.json)`)}return valid}function normalizeAndDedupe(paths,deps){return dedupeBrainVaultPaths(paths.map((path3)=>normalizeBrainVaultPath(path3,deps)),deps)}function pushPathFromEntry(entry2,paths){let found=!1;for(let field of REGISTRY_PATH_FIELDS){let value=entry2[field];if(typeof value==="string"&&value.trim().length>0)paths.push(value),found=!0}return found}function isRegistryRecord(value){return Boolean(value)&&typeof value==="object"&&!Array.isArray(value)}function collectRegistryArray(values2,paths){for(let item of values2)collectRegistryPaths(item,paths)}function collectRegistryObject(entry2,paths){let foundPath=pushPathFromEntry(entry2,paths);for(let field of REGISTRY_COLLECTION_FIELDS)if(field in entry2)collectRegistryPaths(entry2[field],paths);if(!foundPath){for(let item of Object.values(entry2))if(item&&typeof item==="object")collectRegistryPaths(item,paths)}}function collectRegistryPaths(value,paths){if(typeof value==="string"){if(value.trim().length>0)paths.push(value);return}if(Array.isArray(value)){collectRegistryArray(value,paths);return}if(isRegistryRecord(value))collectRegistryObject(value,paths)}function countRegistryItems(value,fallback){if(Array.isArray(value))return value.length;if(!isRegistryRecord(value))return fallback;for(let field of REGISTRY_COLLECTION_FIELDS){let collection=value[field];if(Array.isArray(collection))return collection.length;if(isRegistryRecord(collection))return Object.keys(collection).length}return fallback}async function discoverRegisteredBrainVaultPaths(deps){let brain=deps.brain;if(!brain)return{paths:[],registryCount:0};let registryCalls=["listBrains","listBrainVaults","listVaults","listRegisteredBrains","listRegisteredBrainVaults","getBrainRegistry","readBrainRegistry"];for(let name of registryCalls){let read=brain[name];if(typeof read!=="function")continue;try{let result2=await read.call(brain),paths=[];if(collectRegistryPaths(result2,paths),paths.length>0)return{paths,registryCount:countRegistryItems(result2,paths.length)}}catch(err){let msg=err instanceof Error?err.message:String(err);(deps.warn??console.warn)(` Brain registry: ${name} failed: ${msg}`)}}return{paths:[],registryCount:0}}async function findLegacyBrainVault(deps={}){let cwd=getCwd(deps),homeDir=getHomeDir(deps),workspaceRoot=getWorkspaceRoot(deps),candidates=[workspaceRoot?join48(workspaceRoot,"brain"):void 0,cwd,join48(cwd,"brain"),join48(homeDir,"brain")].filter((path3)=>typeof path3==="string");for(let path3 of normalizeAndDedupe(candidates,deps))if(hasBrainJson(path3,deps))return path3;return null}async function findBrainVault(deps={}){return(await resolveBrainVaults(deps)).paths[0]??null}async function resolveBrainVaults(deps={}){let configuredPaths=getConfig(deps).brain?.paths;if(Array.isArray(configuredPaths)&&configuredPaths.length>0)return{source:"config",paths:filterVaultsWithBrainJson(normalizeAndDedupe(configuredPaths,deps),"config",deps)};let registered=await discoverRegisteredBrainVaultPaths(deps);if(registered.paths.length>0)return{source:"registry",paths:filterVaultsWithBrainJson(normalizeAndDedupe(registered.paths,deps),"registry",deps),registryCount:registered.registryCount};let legacyPath=await findLegacyBrainVault(deps);return{source:"legacy",paths:legacyPath?[legacyPath]:[]}}function normalizeStartupConcurrency(value){if(typeof value!=="number"||!Number.isFinite(value))return DEFAULT_BRAIN_START_CONCURRENCY;return Math.max(1,Math.floor(value))}async function allSettledBounded(items,concurrency,worker){let results=Array(items.length),nextIndex=0;async function runWorker(){while(!0){let index=nextIndex++;if(index>=items.length)return;try{results[index]={status:"fulfilled",value:await worker(items[index],index)}}catch(reason){results[index]={status:"rejected",reason}}}}return await Promise.allSettled(Array.from({length:Math.min(concurrency,items.length)},()=>runWorker())),results}function warnRegistryDrift(resolution,startedCount,resolvedCount,deps){if(resolution.source!=="registry")return;let expectedCount=resolution.registryCount??resolvedCount;if(startedCount===expectedCount)return;(deps.warn??console.warn)(` Brain server: registry drift: started ${startedCount}/${expectedCount} registered vault(s) (${resolvedCount} resolved valid path(s))`)}async function startResolvedBrainVaults(resolution,brain,geniePgPort,deps={}){let startEmbeddedBrainServer=brain.startEmbeddedBrainServer;if(!startEmbeddedBrainServer)return[];let warn=deps.warn??console.warn,log2=deps.log??console.log,handles=[],paths=dedupeBrainVaultPaths(resolution.paths,deps),concurrency=normalizeStartupConcurrency(deps.startupConcurrency),results=await allSettledBounded(paths,concurrency,async(brainPath)=>{let handle=await startEmbeddedBrainServer.call(brain,{brainPath,geniePgPort});return log2(` Brain server ready on port ${handle.port} (${brainPath})`),{brainPath,port:handle.port,stop:handle.stop}});for(let index=0;index<results.length;index++){let result2=results[index];if(result2.status==="fulfilled")handles.push(result2.value);else{let msg=result2.reason instanceof Error?result2.reason.message:String(result2.reason);warn(` Brain server: failed for ${paths[index]}: ${msg}`)}}return warnRegistryDrift(resolution,handles.length,paths.length,deps),handles}var REGISTRY_PATH_FIELDS,REGISTRY_COLLECTION_FIELDS,DEFAULT_BRAIN_START_CONCURRENCY=4;var init_brain_vaults=__esm(()=>{init_genie_config2();init_workspace();REGISTRY_PATH_FIELDS=["homePath","brainPath","vaultPath","path","root","dir"],REGISTRY_COLLECTION_FIELDS=["paths","brains","vaults","entries","items","registered"]});var exports_tui_disable={};__export(exports_tui_disable,{noticeTuiSkipped:()=>noticeTuiSkipped,isTuiDisabled:()=>isTuiDisabled});function isTuiDisabled(){let envVal=process.env.GENIE_TUI_DISABLE;if(envVal&&TRUTHY2.has(envVal.trim().toLowerCase()))return!0;if(process.argv.includes("--no-tui"))return!0;return!1}function noticeTuiSkipped(context){let reason=process.env.GENIE_TUI_DISABLE?"GENIE_TUI_DISABLE is set":"--no-tui flag present";console.error(`genie: TUI ${context} skipped (${reason}). See https://github.com/automagik-dev/genie for status of the upstream OpenTUI kqueue spin on macOS.`)}var TRUTHY2;var init_tui_disable=__esm(()=>{TRUTHY2=new Set(["1","true","yes","on"])});var exports_service_registry={};__export(exports_service_registry,{unregisterService:()=>unregisterService,registerService:()=>registerService,reapDeadServices:()=>reapDeadServices,killAllServices:()=>killAllServices,getRegisteredServices:()=>getRegisteredServices,clearRegistry:()=>clearRegistry});function registerService(name,pid){registry.set(name,{pid,name,startedAt:new Date})}function unregisterService(name){registry.delete(name)}function getRegisteredServices(){return Array.from(registry.values())}function reapDeadServices(){let reaped=[];for(let[name,entry2]of registry)try{process.kill(entry2.pid,0)}catch{registry.delete(name),reaped.push(name)}return reaped}function killAllServices(){for(let[_name,entry2]of registry)try{process.kill(entry2.pid,"SIGTERM")}catch{registry.delete(_name)}let deadline=Date.now()+3000,checkInterval=200,stillAlive=()=>{for(let[,entry2]of registry)try{return process.kill(entry2.pid,0),!0}catch{}return!1};while(Date.now()<deadline&&stillAlive()){let waitUntil=Date.now()+checkInterval;while(Date.now()<waitUntil);}for(let[name,entry2]of registry){try{process.kill(entry2.pid,0),process.kill(entry2.pid,"SIGKILL")}catch{}registry.delete(name)}}function clearRegistry(){registry.clear()}var registry;var init_service_registry=__esm(()=>{registry=new Map});function parseDuration(input){let match=input.trim().match(DURATION_RE);if(!match)throw Error(`Invalid duration: "${input}". Expected format: 10m, 2h, 24h, 1d`);let value=Number.parseFloat(match[1]),unit=match[2].toLowerCase(),ms=value*{s:1000,sec:1000,m:60000,min:60000,h:3600000,hr:3600000,d:86400000,day:86400000}[unit];if(ms<=0)throw Error(`Duration must be positive: "${input}"`);return ms}function expandRange(range,step,min,max){if(step===0)throw Error("Cron step value cannot be 0");if(range==="*"){let out=[];for(let i2=min;i2<=max;i2+=step)out.push(i2);return out}if(range.includes("-")){let[start,end]=range.split("-").map(Number),out=[];for(let i2=start;i2<=end;i2+=step)out.push(i2);return out}return[Number.parseInt(range,10)]}function parseCronField(field,min,max){let values2=new Set;for(let part of field.split(",")){let stepMatch=part.match(/^(.+)\/(\d+)$/),step=stepMatch?Number.parseInt(stepMatch[2],10):1,range=stepMatch?stepMatch[1]:part;for(let v of expandRange(range,step,min,max))values2.add(v)}return[...values2].sort((a,b2)=>a-b2)}function getTimeParts(date,tz){if(!tz)return{month:date.getMonth()+1,dom:date.getDate(),dow:date.getDay(),hour:date.getHours(),minute:date.getMinutes()};let parts=new Intl.DateTimeFormat("en-US",{timeZone:tz,year:"numeric",month:"numeric",day:"numeric",hour:"numeric",minute:"numeric",weekday:"short",hour12:!1}).formatToParts(date),get3=(type2)=>Number(parts.find((p)=>p.type===type2)?.value??0),dayMap={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6},weekday=parts.find((p)=>p.type==="weekday")?.value??"Sun";return{month:get3("month"),dom:get3("day"),dow:dayMap[weekday]??0,hour:get3("hour")===24?0:get3("hour"),minute:get3("minute")}}function parseOpts(afterOrOpts){if(afterOrOpts instanceof Date)return{after:afterOrOpts};if(afterOrOpts)return{after:afterOrOpts.after,timezone:afterOrOpts.timezone};return{}}function advanceToNextDay(candidate,tz){candidate.setTime(candidate.getTime()+86400000);let tp=getTimeParts(candidate,tz);candidate.setTime(candidate.getTime()-tp.hour*3600000-tp.minute*60000)}function parseCronExpr(cronExpr){let parts=cronExpr.trim().split(/\s+/);if(parts.length<5)throw Error(`Invalid cron expression: "${cronExpr}"`);let[minField,hourField,domField,monthField,dowField]=parts;return{minutes:parseCronField(minField,0,59),hours:parseCronField(hourField,0,23),doms:parseCronField(domField,1,31),months:parseCronField(monthField,1,12),dows:parseCronField(dowField,0,6),domRestricted:domField!=="*",dowRestricted:dowField!=="*"}}function computeNextCronDue(cronExpr,afterOrOpts){let{after,timezone}=parseOpts(afterOrOpts),cron=parseCronExpr(cronExpr),candidate=new Date((after??new Date).getTime());candidate.setSeconds(0,0),candidate.setTime(candidate.getTime()+60000);let limit=new Date(candidate.getTime()+31622400000);while(candidate<=limit){let tp=getTimeParts(candidate,timezone);if(!cron.months.includes(tp.month)){advanceToNextDay(candidate,timezone);continue}if(!(cron.domRestricted&&cron.dowRestricted?cron.doms.includes(tp.dom)||cron.dows.includes(tp.dow):cron.doms.includes(tp.dom)&&cron.dows.includes(tp.dow))){advanceToNextDay(candidate,timezone);continue}if(!cron.hours.includes(tp.hour)){candidate.setTime(candidate.getTime()+3600000-tp.minute*60000);continue}if(cron.minutes.includes(tp.minute))return candidate;candidate.setTime(candidate.getTime()+60000)}throw Error(`No next cron occurrence found for "${cronExpr}" within 366 days`)}var DURATION_RE;var init_cron=__esm(()=>{DURATION_RE=/^(\d+(?:\.\d+)?)\s*(s|sec|m|min|h|hr|d|day)s?$/i});import{randomUUID as randomUUID7}from"crypto";function parseNotifyPayload(channel,raw){switch(channel){case"genie_task_stage":{let parts=raw.split(":");if(parts.length<3)return null;return{channel,eventType:"task.stage_change",payload:{taskId:parts[0],fromStage:parts[1],toStage:parts[2]},taskId:parts[0],summary:`Task ${parts[0]} moved from ${parts[1]} to ${parts[2]}`}}case"genie_executor_state":{let parts=raw.split(":");if(parts.length<4)return null;let eventType=parts[3]==="error"?"executor.error":"executor.state_change";return{channel,eventType,payload:{executorId:parts[0],agentId:parts[1],oldState:parts[2],newState:parts[3]},agentId:parts[1],summary:`${parts[1]} state: ${parts[2]} \u2192 ${parts[3]}`}}case"genie_message":{let parts=raw.split(":");if(parts.length<2)return null;return{channel,eventType:"task.comment",payload:{messageId:parts[0],conversationId:parts[1]},summary:`New message in conversation ${parts[1]}`}}case"genie_audit_event":{let parts=raw.split(":");if(parts.length<3)return null;return{channel,eventType:`${parts[0]}.${parts[2]}`,payload:{entityType:parts[0],entityId:parts[1],auditEventType:parts[2]},summary:`${parts[0]} ${parts[1]}: ${parts[2]}`}}default:return null}}function isActionableEvent(eventType){return ACTIONABLE_EVENTS.has(eventType)||eventType.startsWith("request.")}async function resolveTargetTeams(event){if(!isActionableEvent(event.eventType))return[];let active=(await listTeams()).filter((t)=>t.status==="in_progress");if(event.agentId){let aid=event.agentId;return active.filter((t)=>t.members.includes(aid)||t.leader===aid).map((t)=>t.name)}return active.map((t)=>t.name)}async function writeMailbox(repoPath,leader,message,traceId){try{await(await getConnection())`
2105
2105
  INSERT INTO mailbox (id, repo_path, "from", "to", body, trace_id, created_at)
2106
2106
  VALUES (${`mail-${traceId}`}, ${repoPath}, 'system', ${leader}, ${message}, ${traceId}, now())
2107
2107
  `}catch{try{await send(repoPath,"system",leader,message)}catch{}}}async function deliverToHierarchy(leader,teamName,message,traceId){let sql=await getConnection(),current=leader,visited=new Set([current]);for(;;){let reportsTo=(await sql`
@@ -2230,7 +2230,7 @@ ${body}`;writeFileSync14(filePath,output,"utf-8")}function serializeSdkConfig(sd
2230
2230
  `,failedCount++,deps.log({timestamp:now.toISOString(),level:"warn",event:"orphan_run_failed",run_id:run.id,worker_id:run.worker_id,dead_heartbeats:threshold})}if(failedCount>0)deps.log({timestamp:now.toISOString(),level:"info",event:"orphan_reconciliation_completed",failed_count:failedCount});return failedCount}async function collectMachineSnapshot(deps){let sql=await deps.getConnection(),now=deps.now(),snapshotId=deps.generateId(),workers=await deps.listWorkers(),activeWorkers=workers.filter((w)=>!["done","error","suspended"].includes(w.state)).length,teams=new Set(workers.filter((w)=>w.team).map((w)=>w.team)),tmuxSessions=await deps.countTmuxSessions(),cpuPercent=null,memoryMb=null;try{let mem=process.memoryUsage();memoryMb=Math.round(mem.rss/1024/1024)}catch{}try{let cpus=(await import("os")).cpus();if(cpus.length>0){let total=cpus.reduce((acc,cpu)=>{let t=Object.values(cpu.times).reduce((a,b2)=>a+b2,0);return acc+t-cpu.times.idle},0),totalAll=cpus.reduce((acc,cpu)=>acc+Object.values(cpu.times).reduce((a,b2)=>a+b2,0),0);cpuPercent=totalAll>0?Math.round(total/totalAll*100):null}}catch{}await sql`
2231
2231
  INSERT INTO machine_snapshots (id, active_workers, active_teams, tmux_sessions, cpu_percent, memory_mb, created_at)
2232
2232
  VALUES (${snapshotId}, ${activeWorkers}, ${teams.size}, ${tmuxSessions}, ${cpuPercent}, ${memoryMb}, ${now})
2233
- `,deps.log({timestamp:now.toISOString(),level:"debug",event:"machine_snapshot",active_workers:activeWorkers,active_teams:teams.size,tmux_sessions:tmuxSessions,cpu_percent:cpuPercent,memory_mb:memoryMb})}async function emitWorkerEvents(deps){let workers=await deps.listWorkers(),now=deps.now().toISOString(),currentIds=new Set;for(let worker of workers){currentIds.add(worker.id);let prev=previousWorkerStates.get(worker.id),repoPath=worker.repoPath??process.cwd();if(!prev)await deps.publishEvent(`genie.agent.${worker.id}.spawned`,{timestamp:now,kind:"state",agent:worker.id,team:worker.team,text:`Agent ${worker.id} spawned`,data:{state:worker.state},source:"registry"},repoPath);else if(prev.state!==worker.state){if(await deps.publishEvent(`genie.agent.${worker.id}.state`,{timestamp:now,kind:"state",agent:worker.id,team:worker.team,text:`Agent ${worker.id} state: ${prev.state} \u2192 ${worker.state}`,data:{previousState:prev.state,state:worker.state},source:"registry"},repoPath),worker.state==="done"&&worker.wishSlug&&worker.groupNumber!=null)await deps.publishEvent(`genie.wish.${worker.wishSlug}.group.${worker.groupNumber}.done`,{timestamp:now,kind:"system",agent:worker.id,team:worker.team,text:`Wish ${worker.wishSlug} group ${worker.groupNumber} completed by ${worker.id}`,data:{wishSlug:worker.wishSlug,groupNumber:worker.groupNumber},source:"registry"},repoPath)}previousWorkerStates.set(worker.id,{...worker})}for(let[id,prev]of previousWorkerStates)if(!currentIds.has(id))await deps.publishEvent(`genie.agent.${id}.killed`,{timestamp:now,kind:"state",agent:id,team:prev.team,text:`Agent ${id} killed`,data:{lastState:prev.state},source:"registry"},prev.repoPath??process.cwd()),previousWorkerStates.delete(id)}function _resetWorkerStatesForTesting(){previousWorkerStates.clear()}function startInboxWatcherIfEnabled(deps){let pollMs=getInboxPollIntervalMs();if(pollMs===0)return deps.log({timestamp:deps.now().toISOString(),level:"info",event:"inbox_watcher_disabled"}),null;return deps.log({timestamp:deps.now().toISOString(),level:"info",event:"inbox_watcher_started",poll_interval_ms:pollMs}),startInboxWatcher()}async function processMailboxRetryMessage(deps,msg,overrides={}){let deliverFn=overrides.deliverFn??(async(toWorker,messageId)=>{let{deliverToPane:deliverToPane2}=await Promise.resolve().then(() => (init_protocol_router(),exports_protocol_router));return deliverToPane2(toWorker,messageId)}),sendFn=overrides.sendFn??(async(repoPath2,from,to,body)=>{let{send:send2}=await Promise.resolve().then(() => (init_mailbox(),exports_mailbox));return send2(repoPath2,from,to,body)});if(await deliverFn(msg.to,msg.id)){deps.log({timestamp:deps.now().toISOString(),level:"info",event:"mailbox_delivery_retried",messageId:msg.id,to:msg.to});return}let rows=await(await deps.getConnection())`SELECT delivery_attempts, repo_path FROM mailbox WHERE id = ${msg.id} LIMIT 1`,attempts=rows[0]?.delivery_attempts??0;if(attempts<MAX_DELIVERY_ATTEMPTS)return;if(await markEscalated(msg.id),msg.from==="scheduler"){deps.log({timestamp:deps.now().toISOString(),level:"warn",event:"mailbox_delivery_escalation_dropped",reason:"already_escalated_by_scheduler",messageId:msg.id,to:msg.to,attempts});return}if(msg.body.startsWith("[escalation] ")){deps.log({timestamp:deps.now().toISOString(),level:"warn",event:"mailbox_delivery_escalation_dropped",reason:"body_prefix",messageId:msg.id,to:msg.to,attempts});return}if(msg.to===ESCALATION_RECIPIENT){deps.log({timestamp:deps.now().toISOString(),level:"warn",event:"mailbox_delivery_escalation_dropped",reason:"same_recipient",messageId:msg.id,to:msg.to,attempts});return}let repoPath=rows[0]?.repo_path;if(repoPath)await sendFn(repoPath,"scheduler",ESCALATION_RECIPIENT,`[escalation] Message ${msg.id} from "${msg.from}" to "${msg.to}" failed delivery after ${MAX_DELIVERY_ATTEMPTS} attempts. Body: "${msg.body.slice(0,200)}"`);deps.log({timestamp:deps.now().toISOString(),level:"warn",event:"mailbox_delivery_escalated",messageId:msg.id,to:msg.to,attempts})}function startDaemon(configOverrides,depsOverrides){let config=resolveConfig(configOverrides),deps={...createDefaultDeps(),...depsOverrides},daemonId=deps.generateId(),running2=!0,pollTimeout=null,pollResolve=null,listenConnection=null,heartbeatTimer=null,orphanTimer=null,leaseRecoveryTimer=null,agentResumeTimer=null,inboxWatcherHandle=null,captureFallbackTimer=null,eventRouterHandle=null,deliveryUnsub=null,deliveryRetryTimer=null,retentionTimer=null,stop=()=>{if(running2=!1,pollTimeout)clearTimeout(pollTimeout),pollTimeout=null;if(pollResolve)pollResolve(),pollResolve=null;if(heartbeatTimer)clearInterval(heartbeatTimer),heartbeatTimer=null;if(orphanTimer)clearInterval(orphanTimer),orphanTimer=null;if(leaseRecoveryTimer)clearInterval(leaseRecoveryTimer),leaseRecoveryTimer=null;if(agentResumeTimer)clearInterval(agentResumeTimer),agentResumeTimer=null;if(inboxWatcherHandle)stopInboxWatcher(inboxWatcherHandle),inboxWatcherHandle=null;if(listenConnection)listenConnection.end().catch(()=>{}),listenConnection=null;if(captureFallbackTimer)clearInterval(captureFallbackTimer),captureFallbackTimer=null;if(eventRouterHandle?.stop().catch(()=>{}),eventRouterHandle=null,deliveryRetryTimer)clearInterval(deliveryRetryTimer),deliveryRetryTimer=null;if(retentionTimer)clearInterval(retentionTimer),retentionTimer=null;if(deliveryUnsub)deliveryUnsub().catch(()=>{}),deliveryUnsub=null;Promise.resolve().then(() => (init_session_filewatch(),exports_session_filewatch)).then((m)=>m.stopFilewatch()).catch(()=>{}),Promise.resolve().then(() => (init_session_backfill(),exports_session_backfill)).then((m)=>m.stopBackfill()).catch(()=>{}),Promise.resolve().then(() => (init_db(),exports_db)).then(({getLockfilePath:getLockfilePath2})=>{try{__require("fs").unlinkSync(getLockfilePath2())}catch{}}).catch(()=>{})},processTriggers=async()=>{try{let claimed=await claimDueTriggers(deps,config,daemonId);if(claimed.length===0)return;if(claimed.length>config.jitterThreshold){let jitterMs=deps.jitter(config.maxJitterMs);deps.log({timestamp:deps.now().toISOString(),level:"info",event:"jitter_applied",count:claimed.length,jitter_ms:jitterMs}),await deps.sleep(jitterMs)}for(let trigger of claimed){if(!running2)break;await fireTrigger(deps,trigger,daemonId)}}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"process_cycle_error",error:message})}};async function setupListenNotify(d,onTrigger){try{let sql=await d.getConnection();return await sql.listen("genie_trigger_due",async()=>{if(!running2)return;await onTrigger()}),d.log({timestamp:d.now().toISOString(),level:"info",event:"listen_started",channel:"genie_trigger_due"}),sql}catch(err){let message=err instanceof Error?err.message:String(err);return d.log({timestamp:d.now().toISOString(),level:"warn",event:"listen_failed",error:message}),null}}function startLeaseRecoveryTimer(d,cfg,dId){return setInterval(async()=>{if(!running2)return;try{await reclaimExpiredLeases(d,dId)}catch(err){let message=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"error",event:"lease_recovery_error",error:message})}},cfg.leaseRecoveryIntervalMs)}function startOrphanTimer(d,cfg){return setInterval(async()=>{if(!running2)return;try{await reconcileOrphans(d,cfg)}catch(err){let message=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"error",event:"orphan_reconciliation_error",error:message})}},cfg.orphanCheckIntervalMs)}async function reconcileDeadPaneZombies(d){try{let{reconcileStaleSpawns:reconcileStaleSpawns2}=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry));await reconcileStaleSpawns2()}catch(err){let message=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"warn",event:"reconcile_stale_spawns_error",error:message})}}function startAgentResumeTimer(d,cfg,dId){return setInterval(async()=>{if(!running2)return;try{await reconcileDeadPaneZombies(d),await reconcileUnresumable(d),await runAgentRecoveryPass(d,dId,cfg)}catch(err){let message=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"error",event:"agent_resume_timer_error",error:message})}},cfg.leaseRecoveryIntervalMs)}async function startEventRouterSafe(d){try{let handle=await startEventRouter();return d.log({timestamp:d.now().toISOString(),level:"info",event:"event_router_started"}),handle}catch(err){let message=err instanceof Error?err.message:String(err);return d.log({timestamp:d.now().toISOString(),level:"warn",event:"event_router_start_failed",error:message}),null}}async function initSessionCapture(d,cfg){try{let captureSql=await d.getConnection(),{startFilewatch:startFilewatch2}=await Promise.resolve().then(() => (init_session_filewatch(),exports_session_filewatch)),{startBackfill:startBackfill2}=await Promise.resolve().then(() => (init_session_backfill(),exports_session_backfill)),{reconcileSubagentParents:reconcileSubagentParents2}=await Promise.resolve().then(() => (init_session_capture(),exports_session_capture));if(reconcileSubagentParents2(captureSql).then(({linked,metadataFilled})=>{if(linked>0||metadataFilled>0)d.log({timestamp:d.now().toISOString(),level:"info",event:"subagent_reconcile_on_start",linked,metadata_filled:metadataFilled})}).catch((err)=>{let msg=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"warn",event:"subagent_reconcile_on_start_failed",error:msg})}),!await startFilewatch2(captureSql)){let{ingestFileFull:ingestFileFull2,discoverAllJsonlFiles:discoverAllJsonlFiles2,buildWorkerMap:buildWorkerMap2}=await Promise.resolve().then(() => (init_session_capture(),exports_session_capture));d.log({timestamp:d.now().toISOString(),level:"warn",event:"filewatch_failed_fallback_polling"});let timer2=setInterval(async()=>{if(!running2)return;try{let files=await discoverAllJsonlFiles2(),workerMap=await buildWorkerMap2(captureSql);for(let f of files)await ingestFileFull2(captureSql,f.sessionId,f.jsonlPath,f.projectPath,0,{parentSessionId:f.parentSessionId,isSubagent:f.isSubagent,workerMap})}catch{}},cfg.heartbeatIntervalMs);return startBackfill2(captureSql).catch((err)=>{let msg=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"error",event:"backfill_error",error:msg})}),timer2}return startBackfill2(captureSql).catch((err)=>{let msg=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"error",event:"backfill_error",error:msg})}),null}catch(err){let message=err instanceof Error?err.message:String(err);return d.log({timestamp:d.now().toISOString(),level:"warn",event:"session_capture_init_failed",error:message}),null}}async function runHeartbeat(d){if(!running2)return;try{await collectHeartbeats(d),await collectMachineSnapshot(d),await emitWorkerEvents(d);try{let retSql=await d.getConnection();await retSql`DELETE FROM heartbeats WHERE created_at < now() - interval '7 days'`,await retSql`DELETE FROM machine_snapshots WHERE created_at < now() - interval '30 days'`,await retSql`DELETE FROM audit_events WHERE entity_type LIKE 'otel_%' AND created_at < now() - interval '30 days'`}catch{}}catch(err){let message=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"error",event:"heartbeat_error",error:message})}}let done=(async()=>{deps.log({timestamp:deps.now().toISOString(),level:"info",event:"daemon_started",daemon_id:daemonId,max_concurrent:config.maxConcurrent,poll_interval_ms:config.pollIntervalMs}),logReconcilerMode(deps,daemonId);try{await recoverOnStartup(deps,daemonId,config)}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"recovery_error",error:message})}listenConnection=await setupListenNotify(deps,processTriggers),heartbeatTimer=setInterval(()=>runHeartbeat(deps),config.heartbeatIntervalMs),orphanTimer=startOrphanTimer(deps,config),leaseRecoveryTimer=startLeaseRecoveryTimer(deps,config,daemonId),agentResumeTimer=startAgentResumeTimer(deps,config,daemonId),inboxWatcherHandle=startInboxWatcherIfEnabled(deps),eventRouterHandle=await startEventRouterSafe(deps);try{deliveryUnsub=await subscribeDelivery(async(toWorker,messageId)=>{try{let{deliverToPane:deliverToPane2}=await Promise.resolve().then(() => (init_protocol_router(),exports_protocol_router));await deliverToPane2(toWorker,messageId)}catch{}}),deps.log({timestamp:deps.now().toISOString(),level:"info",event:"mailbox_delivery_listen_started"})}catch{}deliveryRetryTimer=setInterval(async()=>{try{let retryable=await getRetryable(MAX_DELIVERY_ATTEMPTS);for(let msg of retryable)try{await processMailboxRetryMessage(deps,msg)}catch{}}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"mailbox_retry_error",error:message})}},60000);let RETENTION_INTERVAL_MS=3600000,runDaemonRetention=async()=>{try{let{getConnection:getConnection2,runRetention:runRetention2}=await Promise.resolve().then(() => (init_db(),exports_db)),sql=await getConnection2();await runRetention2(sql),deps.log({timestamp:deps.now().toISOString(),level:"debug",event:"retention_completed"})}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"retention_error",error:message})}};runDaemonRetention().catch(()=>{}),retentionTimer=setInterval(runDaemonRetention,RETENTION_INTERVAL_MS),captureFallbackTimer=await initSessionCapture(deps,config),await processTriggers();while(running2){if(await new Promise((resolve10)=>{pollResolve=resolve10,pollTimeout=setTimeout(resolve10,config.pollIntervalMs)}),pollResolve=null,!running2)break;await processTriggers()}deps.log({timestamp:deps.now().toISOString(),level:"info",event:"daemon_stopped",daemon_id:daemonId})})();return{stop,done,daemonId}}var ESCALATION_RECIPIENT="team-lead",MAX_DELIVERY_ATTEMPTS=3,TURN_AWARE_RECONCILER_FLAG="GENIE_RECONCILER_TURN_AWARE",RECOVERY_RETRY_DELAY_MS=60000,TURN_AWARE_RESUMABLE_STATES,RESUME_COOLDOWN_MS=60000,DEFAULT_MAX_RESUME_ATTEMPTS=3,INACTIVE_WORKER_STATES,TELEMETRY_STATES,previousWorkerStates;var init_scheduler_daemon=__esm(()=>{init_audit();init_cron();init_emit();init_event_router();init_inbox_watcher();init_mailbox();init_run_spec();init_should_resume();init_trace_context();TURN_AWARE_RESUMABLE_STATES=new Set(["working","permission","question"]);INACTIVE_WORKER_STATES=new Set(["done","error","suspended","spawning"]);TELEMETRY_STATES=new Set(["spawning","working","idle","permission","question","done","error","suspended"]);previousWorkerStates=new Map});var exports_service_registry={};__export(exports_service_registry,{unregisterService:()=>unregisterService,registerService:()=>registerService,reapDeadServices:()=>reapDeadServices,killAllServices:()=>killAllServices,getRegisteredServices:()=>getRegisteredServices,clearRegistry:()=>clearRegistry});function registerService(name,pid){registry.set(name,{pid,name,startedAt:new Date})}function unregisterService(name){registry.delete(name)}function getRegisteredServices(){return Array.from(registry.values())}function reapDeadServices(){let reaped=[];for(let[name,entry2]of registry)try{process.kill(entry2.pid,0)}catch{registry.delete(name),reaped.push(name)}return reaped}function killAllServices(){for(let[_name,entry2]of registry)try{process.kill(entry2.pid,"SIGTERM")}catch{registry.delete(_name)}let deadline=Date.now()+3000,checkInterval=200,stillAlive=()=>{for(let[,entry2]of registry)try{return process.kill(entry2.pid,0),!0}catch{}return!1};while(Date.now()<deadline&&stillAlive()){let waitUntil=Date.now()+checkInterval;while(Date.now()<waitUntil);}for(let[name,entry2]of registry){try{process.kill(entry2.pid,0),process.kill(entry2.pid,"SIGKILL")}catch{}registry.delete(name)}}function clearRegistry(){registry.clear()}var registry;var init_service_registry=__esm(()=>{registry=new Map});var SIGNAL_SEVERITY,SIGNAL_DRILLDOWN;var init_types4=__esm(()=>{SIGNAL_SEVERITY={"observability.recovery_anchor_at_risk":"critical","resume.lost_anchor":"warn","agents.zombie_storm":"warn","observability.partition.missing":"critical"},SIGNAL_DRILLDOWN={"observability.recovery_anchor_at_risk":"genie events timeline <executor-id>","resume.lost_anchor":"genie agent resume <name>","agents.zombie_storm":"genie prune --zombies","observability.partition.missing":"genie doctor --observability"}});class LostAnchorDetector{windows=new Map;lastFired=new Map;ingest(row,now=Date.now()){if(row.entity_type!=="agent")return null;if(row.event_type!=="resume.missing_session")return null;let agentId=row.entity_id,ts3=Date.parse(row.created_at);if(!Number.isFinite(ts3))return null;let cutoff=now-WINDOW_MS,fresh=(this.windows.get(agentId)??[]).filter((t)=>t>=cutoff);if(fresh.push(ts3),this.windows.set(agentId,fresh),fresh.length<THRESHOLD)return null;let lastFiredTs=this.lastFired.get(agentId);if(lastFiredTs!==void 0&&lastFiredTs>=cutoff)return null;return this.lastFired.set(agentId,now),{type:"resume.lost_anchor",subject:agentId,severity:SIGNAL_SEVERITY["resume.lost_anchor"],details:{window_ms:WINDOW_MS,threshold:THRESHOLD,events_in_window:fresh.length,latest_reason:row.details?.reason??null},triggeredAt:row.created_at}}reset(){this.windows.clear(),this.lastFired.clear()}}var WINDOW_MS=300000,THRESHOLD=3;var init_lost_anchor=__esm(()=>{init_types4()});async function detectPartitionMissing(deps={}){let collect=deps.collect??collectObservabilityHealth,now=(deps.now??(()=>new Date))(),report=await collect();if(report.partition_health!=="fail")return null;return{type:"observability.partition.missing",subject:"global",severity:SIGNAL_SEVERITY["observability.partition.missing"],details:{partition_count:report.partition_count,newest_partition:report.newest_partition,next_rotation_at:report.next_rotation_at},triggeredAt:now.toISOString()}}var init_partition_missing=__esm(()=>{init_observability_health();init_types4()});async function detectRecoveryAnchorAtRisk(row,deps){if(row.entity_type!=="executor")return null;if(row.event_type==="session.divergence_preserved")return{type:"observability.recovery_anchor_at_risk",subject:row.entity_id,severity:SIGNAL_SEVERITY["observability.recovery_anchor_at_risk"],details:{fingerprint:"divergence_preserved",stored_session_id:row.details?.stored_session_id??null,live_session_id:row.details?.live_session_id??null,executor_state:row.details?.executor_state??null},triggeredAt:row.created_at};if(row.event_type!=="session.reconciled")return null;let oldId=row.details?.old_session_id,newId2=row.details?.new_session_id;if(oldId==null||oldId===newId2)return null;let executor=await deps.getExecutor(row.entity_id);if(!executor)return null;if(!TERMINAL_EXECUTOR_STATES2.has(executor.state))return null;return{type:"observability.recovery_anchor_at_risk",subject:row.entity_id,severity:SIGNAL_SEVERITY["observability.recovery_anchor_at_risk"],details:{fingerprint:"legacy_reconciled",old_session_id:oldId,new_session_id:newId2,executor_state:executor.state},triggeredAt:row.created_at}}var TERMINAL_EXECUTOR_STATES2;var init_recovery_anchor=__esm(()=>{init_types4();TERMINAL_EXECUTOR_STATES2=new Set(["done","error","terminated"])});class ZombieStormDetector{window=[];lastFired=null;ingest(row,now=Date.now()){if(row.entity_type!=="worker")return null;if(row.event_type!=="state_changed")return null;if(row.details?.reason!=="dead_pane_zombie")return null;let ts3=Date.parse(row.created_at);if(!Number.isFinite(ts3))return null;let cutoff=now-WINDOW_MS2;while(this.window.length>0&&this.window[0]<cutoff)this.window.shift();if(this.window.push(ts3),this.window.length<=THRESHOLD2)return null;if(this.lastFired!==null&&this.lastFired>=cutoff)return null;return this.lastFired=now,{type:"agents.zombie_storm",subject:"global",severity:SIGNAL_SEVERITY["agents.zombie_storm"],details:{window_ms:WINDOW_MS2,threshold:THRESHOLD2,zombies_in_window:this.window.length,latest_agent:row.entity_id},triggeredAt:row.created_at}}reset(){this.window.length=0,this.lastFired=null}}var WINDOW_MS2=3600000,THRESHOLD2=5;var init_zombie_storm=__esm(()=>{init_types4()});var exports_derived_signals={};__export(exports_derived_signals,{startDerivedSignalsEngine:()=>startDerivedSignalsEngine,recordDerivedSignal:()=>recordDerivedSignal,listActiveDerivedSignals:()=>listActiveDerivedSignals,dispatch:()=>dispatch2,detectRecoveryAnchorAtRisk:()=>detectRecoveryAnchorAtRisk,detectPartitionMissing:()=>detectPartitionMissing,ZombieStormDetector:()=>ZombieStormDetector,SIGNAL_SEVERITY:()=>SIGNAL_SEVERITY,SIGNAL_DRILLDOWN:()=>SIGNAL_DRILLDOWN,LostAnchorDetector:()=>LostAnchorDetector});async function recordDerivedSignal(signal){await recordAuditEvent("derived_signal",signal.subject,signal.type,"derived-signals",{severity:signal.severity,triggered_at:signal.triggeredAt,...signal.details})}async function listActiveDerivedSignals(windowMs=3600000){let sinceMs=Date.now()-windowMs,since=new Date(sinceMs).toISOString(),rows=await queryAuditEvents({entity:"derived_signal",since,limit:200}),seen=new Set,out=[];for(let row of rows){if(row.entity_type!=="derived_signal")continue;let key=`${row.event_type}::${row.entity_id}`;if(seen.has(key))continue;seen.add(key);let details=row.details??{},severity=details.severity??"warn",triggeredAt=details.triggered_at??row.created_at;out.push({type:row.event_type,subject:row.entity_id,severity,details,triggeredAt})}return out}async function startDerivedSignalsEngine(){let lost=new LostAnchorDetector,zombie=new ZombieStormDetector,handle=await followAuditEvents({},(row)=>{dispatch2(row,{lost,zombie})});return{stop:async()=>{await handle.stop()}}}async function dispatch2(row,deps){let signals2=[];try{let sig=await detectRecoveryAnchorAtRisk(row,{getExecutor});if(sig)signals2.push(sig)}catch{}try{let sig=deps.lost.ingest(row);if(sig)signals2.push(sig)}catch{}try{let sig=deps.zombie.ingest(row);if(sig)signals2.push(sig)}catch{}for(let sig of signals2)await recordDerivedSignal(sig).catch(()=>{});return signals2}var init_derived_signals=__esm(()=>{init_audit();init_executor_registry();init_lost_anchor();init_partition_missing();init_recovery_anchor();init_zombie_storm();init_types4()});var exports_detectors={};__export(exports_detectors,{unregisterDetector:()=>unregisterDetector,registerDetector:()=>registerDetector,listDetectors:()=>listDetectors,__clearDetectorsForTests:()=>__clearDetectorsForTests});function registerDetector(module){validateModule(module),registry2.set(module.id,module)}function listDetectors(){return Array.from(registry2.values())}function unregisterDetector(id){return registry2.delete(id)}function __clearDetectorsForTests(){registry2.clear()}function validateModule(module){if(!module||typeof module!=="object")throw Error("registerDetector: module must be an object");if(typeof module.id!=="string"||!ID_RE.test(module.id))throw Error(`registerDetector: invalid id '${String(module.id)}' \u2014 must match ${ID_RE.source}`);if(typeof module.version!=="string"||!SEMVER_RE.test(module.version))throw Error(`registerDetector: invalid version '${String(module.version)}' for '${module.id}' \u2014 must be semver`);if(module.riskClass!=="low"&&module.riskClass!=="medium"&&module.riskClass!=="high")throw Error(`registerDetector: invalid riskClass for '${module.id}'`);if(typeof module.query!=="function")throw Error(`registerDetector: query must be a function on '${module.id}'`);if(typeof module.shouldFire!=="function")throw Error(`registerDetector: shouldFire must be a function on '${module.id}'`);if(typeof module.render!=="function")throw Error(`registerDetector: render must be a function on '${module.id}'`)}var registry2,SEMVER_RE,ID_RE;var init_detectors=__esm(()=>{registry2=new Map;SEMVER_RE=/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/,ID_RE=/^[a-z0-9][a-z0-9._-]{0,127}$/});import{statSync as statSync9}from"fs";function createBackfillNoWorktreeDetector(opts){let exists=opts?.exists??defaultWorktreeExistsCheck,version=opts?.version??"0.1.0",defaultQuery=async()=>{return await(await getConnection())`
2233
+ `,deps.log({timestamp:now.toISOString(),level:"debug",event:"machine_snapshot",active_workers:activeWorkers,active_teams:teams.size,tmux_sessions:tmuxSessions,cpu_percent:cpuPercent,memory_mb:memoryMb})}async function emitWorkerEvents(deps){let workers=await deps.listWorkers(),now=deps.now().toISOString(),currentIds=new Set;for(let worker of workers){currentIds.add(worker.id);let prev=previousWorkerStates.get(worker.id),repoPath=worker.repoPath??process.cwd();if(!prev)await deps.publishEvent(`genie.agent.${worker.id}.spawned`,{timestamp:now,kind:"state",agent:worker.id,team:worker.team,text:`Agent ${worker.id} spawned`,data:{state:worker.state},source:"registry"},repoPath);else if(prev.state!==worker.state){if(await deps.publishEvent(`genie.agent.${worker.id}.state`,{timestamp:now,kind:"state",agent:worker.id,team:worker.team,text:`Agent ${worker.id} state: ${prev.state} \u2192 ${worker.state}`,data:{previousState:prev.state,state:worker.state},source:"registry"},repoPath),worker.state==="done"&&worker.wishSlug&&worker.groupNumber!=null)await deps.publishEvent(`genie.wish.${worker.wishSlug}.group.${worker.groupNumber}.done`,{timestamp:now,kind:"system",agent:worker.id,team:worker.team,text:`Wish ${worker.wishSlug} group ${worker.groupNumber} completed by ${worker.id}`,data:{wishSlug:worker.wishSlug,groupNumber:worker.groupNumber},source:"registry"},repoPath)}previousWorkerStates.set(worker.id,{...worker})}for(let[id,prev]of previousWorkerStates)if(!currentIds.has(id))await deps.publishEvent(`genie.agent.${id}.killed`,{timestamp:now,kind:"state",agent:id,team:prev.team,text:`Agent ${id} killed`,data:{lastState:prev.state},source:"registry"},prev.repoPath??process.cwd()),previousWorkerStates.delete(id)}function _resetWorkerStatesForTesting(){previousWorkerStates.clear()}function startInboxWatcherIfEnabled(deps){let pollMs=getInboxPollIntervalMs();if(pollMs===0)return deps.log({timestamp:deps.now().toISOString(),level:"info",event:"inbox_watcher_disabled"}),null;return deps.log({timestamp:deps.now().toISOString(),level:"info",event:"inbox_watcher_started",poll_interval_ms:pollMs}),startInboxWatcher()}async function processMailboxRetryMessage(deps,msg,overrides={}){let deliverFn=overrides.deliverFn??(async(toWorker,messageId)=>{let{deliverToPane:deliverToPane2}=await Promise.resolve().then(() => (init_protocol_router(),exports_protocol_router));return deliverToPane2(toWorker,messageId)}),sendFn=overrides.sendFn??(async(repoPath2,from,to,body)=>{let{send:send2}=await Promise.resolve().then(() => (init_mailbox(),exports_mailbox));return send2(repoPath2,from,to,body)});if(await deliverFn(msg.to,msg.id)){deps.log({timestamp:deps.now().toISOString(),level:"info",event:"mailbox_delivery_retried",messageId:msg.id,to:msg.to});return}let rows=await(await deps.getConnection())`SELECT delivery_attempts, repo_path FROM mailbox WHERE id = ${msg.id} LIMIT 1`,attempts=rows[0]?.delivery_attempts??0;if(attempts<MAX_DELIVERY_ATTEMPTS)return;if(await markEscalated(msg.id),msg.from==="scheduler"){deps.log({timestamp:deps.now().toISOString(),level:"warn",event:"mailbox_delivery_escalation_dropped",reason:"already_escalated_by_scheduler",messageId:msg.id,to:msg.to,attempts});return}if(msg.body.startsWith("[escalation] ")){deps.log({timestamp:deps.now().toISOString(),level:"warn",event:"mailbox_delivery_escalation_dropped",reason:"body_prefix",messageId:msg.id,to:msg.to,attempts});return}if(msg.to===ESCALATION_RECIPIENT){deps.log({timestamp:deps.now().toISOString(),level:"warn",event:"mailbox_delivery_escalation_dropped",reason:"same_recipient",messageId:msg.id,to:msg.to,attempts});return}let repoPath=rows[0]?.repo_path;if(repoPath)await sendFn(repoPath,"scheduler",ESCALATION_RECIPIENT,`[escalation] Message ${msg.id} from "${msg.from}" to "${msg.to}" failed delivery after ${MAX_DELIVERY_ATTEMPTS} attempts. Body: "${msg.body.slice(0,200)}"`);deps.log({timestamp:deps.now().toISOString(),level:"warn",event:"mailbox_delivery_escalated",messageId:msg.id,to:msg.to,attempts})}function startDaemon(configOverrides,depsOverrides){let config=resolveConfig(configOverrides),deps={...createDefaultDeps(),...depsOverrides},daemonId=deps.generateId(),running2=!0,pollTimeout=null,pollResolve=null,listenConnection=null,heartbeatTimer=null,orphanTimer=null,leaseRecoveryTimer=null,agentResumeTimer=null,inboxWatcherHandle=null,captureFallbackTimer=null,eventRouterHandle=null,deliveryUnsub=null,deliveryRetryTimer=null,retentionTimer=null,stop=()=>{if(running2=!1,pollTimeout)clearTimeout(pollTimeout),pollTimeout=null;if(pollResolve)pollResolve(),pollResolve=null;if(heartbeatTimer)clearInterval(heartbeatTimer),heartbeatTimer=null;if(orphanTimer)clearInterval(orphanTimer),orphanTimer=null;if(leaseRecoveryTimer)clearInterval(leaseRecoveryTimer),leaseRecoveryTimer=null;if(agentResumeTimer)clearInterval(agentResumeTimer),agentResumeTimer=null;if(inboxWatcherHandle)stopInboxWatcher(inboxWatcherHandle),inboxWatcherHandle=null;if(listenConnection)listenConnection.end().catch(()=>{}),listenConnection=null;if(captureFallbackTimer)clearInterval(captureFallbackTimer),captureFallbackTimer=null;if(eventRouterHandle?.stop().catch(()=>{}),eventRouterHandle=null,deliveryRetryTimer)clearInterval(deliveryRetryTimer),deliveryRetryTimer=null;if(retentionTimer)clearInterval(retentionTimer),retentionTimer=null;if(deliveryUnsub)deliveryUnsub().catch(()=>{}),deliveryUnsub=null;Promise.resolve().then(() => (init_session_filewatch(),exports_session_filewatch)).then((m)=>m.stopFilewatch()).catch(()=>{}),Promise.resolve().then(() => (init_session_backfill(),exports_session_backfill)).then((m)=>m.stopBackfill()).catch(()=>{}),Promise.resolve().then(() => (init_db(),exports_db)).then(({getLockfilePath:getLockfilePath2})=>{try{__require("fs").unlinkSync(getLockfilePath2())}catch{}}).catch(()=>{})},processTriggers=async()=>{try{let claimed=await claimDueTriggers(deps,config,daemonId);if(claimed.length===0)return;if(claimed.length>config.jitterThreshold){let jitterMs=deps.jitter(config.maxJitterMs);deps.log({timestamp:deps.now().toISOString(),level:"info",event:"jitter_applied",count:claimed.length,jitter_ms:jitterMs}),await deps.sleep(jitterMs)}for(let trigger of claimed){if(!running2)break;await fireTrigger(deps,trigger,daemonId)}}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"process_cycle_error",error:message})}};async function setupListenNotify(d,onTrigger){try{let sql=await d.getConnection();return await sql.listen("genie_trigger_due",async()=>{if(!running2)return;await onTrigger()}),d.log({timestamp:d.now().toISOString(),level:"info",event:"listen_started",channel:"genie_trigger_due"}),sql}catch(err){let message=err instanceof Error?err.message:String(err);return d.log({timestamp:d.now().toISOString(),level:"warn",event:"listen_failed",error:message}),null}}function startLeaseRecoveryTimer(d,cfg,dId){return setInterval(async()=>{if(!running2)return;try{await reclaimExpiredLeases(d,dId)}catch(err){let message=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"error",event:"lease_recovery_error",error:message})}},cfg.leaseRecoveryIntervalMs)}function startOrphanTimer(d,cfg){return setInterval(async()=>{if(!running2)return;try{await reconcileOrphans(d,cfg)}catch(err){let message=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"error",event:"orphan_reconciliation_error",error:message})}},cfg.orphanCheckIntervalMs)}async function reconcileDeadPaneZombies(d){try{let{reconcileStaleSpawns:reconcileStaleSpawns2}=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry));await reconcileStaleSpawns2()}catch(err){let message=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"warn",event:"reconcile_stale_spawns_error",error:message})}}function startAgentResumeTimer(d,cfg,dId){return setInterval(async()=>{if(!running2)return;try{await reconcileDeadPaneZombies(d),await reconcileUnresumable(d),await runAgentRecoveryPass(d,dId,cfg)}catch(err){let message=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"error",event:"agent_resume_timer_error",error:message})}},cfg.leaseRecoveryIntervalMs)}async function startEventRouterSafe(d){try{let handle=await startEventRouter();return d.log({timestamp:d.now().toISOString(),level:"info",event:"event_router_started"}),handle}catch(err){let message=err instanceof Error?err.message:String(err);return d.log({timestamp:d.now().toISOString(),level:"warn",event:"event_router_start_failed",error:message}),null}}async function initSessionCapture(d,cfg){try{let captureSql=await d.getConnection(),{startFilewatch:startFilewatch2}=await Promise.resolve().then(() => (init_session_filewatch(),exports_session_filewatch)),{startBackfill:startBackfill2}=await Promise.resolve().then(() => (init_session_backfill(),exports_session_backfill)),{reconcileSubagentParents:reconcileSubagentParents2}=await Promise.resolve().then(() => (init_session_capture(),exports_session_capture));if(reconcileSubagentParents2(captureSql).then(({linked,metadataFilled})=>{if(linked>0||metadataFilled>0)d.log({timestamp:d.now().toISOString(),level:"info",event:"subagent_reconcile_on_start",linked,metadata_filled:metadataFilled})}).catch((err)=>{let msg=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"warn",event:"subagent_reconcile_on_start_failed",error:msg})}),!await startFilewatch2(captureSql)){let{ingestFileFull:ingestFileFull2,discoverAllJsonlFiles:discoverAllJsonlFiles2,buildWorkerMap:buildWorkerMap2}=await Promise.resolve().then(() => (init_session_capture(),exports_session_capture));d.log({timestamp:d.now().toISOString(),level:"warn",event:"filewatch_failed_fallback_polling"});let timer2=setInterval(async()=>{if(!running2)return;try{let files=await discoverAllJsonlFiles2(),workerMap=await buildWorkerMap2(captureSql);for(let f of files)await ingestFileFull2(captureSql,f.sessionId,f.jsonlPath,f.projectPath,0,{parentSessionId:f.parentSessionId,isSubagent:f.isSubagent,workerMap})}catch{}},cfg.heartbeatIntervalMs);return startBackfill2(captureSql).catch((err)=>{let msg=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"error",event:"backfill_error",error:msg})}),timer2}return startBackfill2(captureSql).catch((err)=>{let msg=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"error",event:"backfill_error",error:msg})}),null}catch(err){let message=err instanceof Error?err.message:String(err);return d.log({timestamp:d.now().toISOString(),level:"warn",event:"session_capture_init_failed",error:message}),null}}async function runHeartbeat(d){if(!running2)return;try{await collectHeartbeats(d),await collectMachineSnapshot(d),await emitWorkerEvents(d);try{let retSql=await d.getConnection();await retSql`DELETE FROM heartbeats WHERE created_at < now() - interval '7 days'`,await retSql`DELETE FROM machine_snapshots WHERE created_at < now() - interval '30 days'`,await retSql`DELETE FROM audit_events WHERE entity_type LIKE 'otel_%' AND created_at < now() - interval '30 days'`}catch{}}catch(err){let message=err instanceof Error?err.message:String(err);d.log({timestamp:d.now().toISOString(),level:"error",event:"heartbeat_error",error:message})}}let done=(async()=>{deps.log({timestamp:deps.now().toISOString(),level:"info",event:"daemon_started",daemon_id:daemonId,max_concurrent:config.maxConcurrent,poll_interval_ms:config.pollIntervalMs}),logReconcilerMode(deps,daemonId);try{await recoverOnStartup(deps,daemonId,config)}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"recovery_error",error:message})}listenConnection=await setupListenNotify(deps,processTriggers),heartbeatTimer=setInterval(()=>runHeartbeat(deps),config.heartbeatIntervalMs),orphanTimer=startOrphanTimer(deps,config),leaseRecoveryTimer=startLeaseRecoveryTimer(deps,config,daemonId),agentResumeTimer=startAgentResumeTimer(deps,config,daemonId),inboxWatcherHandle=startInboxWatcherIfEnabled(deps),eventRouterHandle=await startEventRouterSafe(deps);try{deliveryUnsub=await subscribeDelivery(async(toWorker,messageId)=>{try{let{deliverToPane:deliverToPane2}=await Promise.resolve().then(() => (init_protocol_router(),exports_protocol_router));await deliverToPane2(toWorker,messageId)}catch{}}),deps.log({timestamp:deps.now().toISOString(),level:"info",event:"mailbox_delivery_listen_started"})}catch{}deliveryRetryTimer=setInterval(async()=>{try{let retryable=await getRetryable(MAX_DELIVERY_ATTEMPTS);for(let msg of retryable)try{await processMailboxRetryMessage(deps,msg)}catch{}}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"mailbox_retry_error",error:message})}},60000);let RETENTION_INTERVAL_MS=3600000,runDaemonRetention=async()=>{try{let{getConnection:getConnection2,runRetention:runRetention2}=await Promise.resolve().then(() => (init_db(),exports_db)),sql=await getConnection2();await runRetention2(sql),deps.log({timestamp:deps.now().toISOString(),level:"debug",event:"retention_completed"})}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"retention_error",error:message})}};runDaemonRetention().catch(()=>{}),retentionTimer=setInterval(runDaemonRetention,RETENTION_INTERVAL_MS),captureFallbackTimer=await initSessionCapture(deps,config),await processTriggers();while(running2){if(await new Promise((resolve10)=>{pollResolve=resolve10,pollTimeout=setTimeout(resolve10,config.pollIntervalMs)}),pollResolve=null,!running2)break;await processTriggers()}deps.log({timestamp:deps.now().toISOString(),level:"info",event:"daemon_stopped",daemon_id:daemonId})})();return{stop,done,daemonId}}var ESCALATION_RECIPIENT="team-lead",MAX_DELIVERY_ATTEMPTS=3,TURN_AWARE_RECONCILER_FLAG="GENIE_RECONCILER_TURN_AWARE",RECOVERY_RETRY_DELAY_MS=60000,TURN_AWARE_RESUMABLE_STATES,RESUME_COOLDOWN_MS=60000,DEFAULT_MAX_RESUME_ATTEMPTS=3,INACTIVE_WORKER_STATES,TELEMETRY_STATES,previousWorkerStates;var init_scheduler_daemon=__esm(()=>{init_audit();init_cron();init_emit();init_event_router();init_inbox_watcher();init_mailbox();init_run_spec();init_should_resume();init_trace_context();TURN_AWARE_RESUMABLE_STATES=new Set(["working","permission","question"]);INACTIVE_WORKER_STATES=new Set(["done","error","suspended","spawning"]);TELEMETRY_STATES=new Set(["spawning","working","idle","permission","question","done","error","suspended"]);previousWorkerStates=new Map});var SIGNAL_SEVERITY,SIGNAL_DRILLDOWN;var init_types4=__esm(()=>{SIGNAL_SEVERITY={"observability.recovery_anchor_at_risk":"critical","resume.lost_anchor":"warn","agents.zombie_storm":"warn","observability.partition.missing":"critical"},SIGNAL_DRILLDOWN={"observability.recovery_anchor_at_risk":"genie events timeline <executor-id>","resume.lost_anchor":"genie agent resume <name>","agents.zombie_storm":"genie prune --zombies","observability.partition.missing":"genie doctor --observability"}});class LostAnchorDetector{windows=new Map;lastFired=new Map;ingest(row,now=Date.now()){if(row.entity_type!=="agent")return null;if(row.event_type!=="resume.missing_session")return null;let agentId=row.entity_id,ts3=Date.parse(row.created_at);if(!Number.isFinite(ts3))return null;let cutoff=now-WINDOW_MS,fresh=(this.windows.get(agentId)??[]).filter((t)=>t>=cutoff);if(fresh.push(ts3),this.windows.set(agentId,fresh),fresh.length<THRESHOLD)return null;let lastFiredTs=this.lastFired.get(agentId);if(lastFiredTs!==void 0&&lastFiredTs>=cutoff)return null;return this.lastFired.set(agentId,now),{type:"resume.lost_anchor",subject:agentId,severity:SIGNAL_SEVERITY["resume.lost_anchor"],details:{window_ms:WINDOW_MS,threshold:THRESHOLD,events_in_window:fresh.length,latest_reason:row.details?.reason??null},triggeredAt:row.created_at}}reset(){this.windows.clear(),this.lastFired.clear()}}var WINDOW_MS=300000,THRESHOLD=3;var init_lost_anchor=__esm(()=>{init_types4()});async function detectPartitionMissing(deps={}){let collect=deps.collect??collectObservabilityHealth,now=(deps.now??(()=>new Date))(),report=await collect();if(report.partition_health!=="fail")return null;return{type:"observability.partition.missing",subject:"global",severity:SIGNAL_SEVERITY["observability.partition.missing"],details:{partition_count:report.partition_count,newest_partition:report.newest_partition,next_rotation_at:report.next_rotation_at},triggeredAt:now.toISOString()}}var init_partition_missing=__esm(()=>{init_observability_health();init_types4()});async function detectRecoveryAnchorAtRisk(row,deps){if(row.entity_type!=="executor")return null;if(row.event_type==="session.divergence_preserved")return{type:"observability.recovery_anchor_at_risk",subject:row.entity_id,severity:SIGNAL_SEVERITY["observability.recovery_anchor_at_risk"],details:{fingerprint:"divergence_preserved",stored_session_id:row.details?.stored_session_id??null,live_session_id:row.details?.live_session_id??null,executor_state:row.details?.executor_state??null},triggeredAt:row.created_at};if(row.event_type!=="session.reconciled")return null;let oldId=row.details?.old_session_id,newId2=row.details?.new_session_id;if(oldId==null||oldId===newId2)return null;let executor=await deps.getExecutor(row.entity_id);if(!executor)return null;if(!TERMINAL_EXECUTOR_STATES2.has(executor.state))return null;return{type:"observability.recovery_anchor_at_risk",subject:row.entity_id,severity:SIGNAL_SEVERITY["observability.recovery_anchor_at_risk"],details:{fingerprint:"legacy_reconciled",old_session_id:oldId,new_session_id:newId2,executor_state:executor.state},triggeredAt:row.created_at}}var TERMINAL_EXECUTOR_STATES2;var init_recovery_anchor=__esm(()=>{init_types4();TERMINAL_EXECUTOR_STATES2=new Set(["done","error","terminated"])});class ZombieStormDetector{window=[];lastFired=null;ingest(row,now=Date.now()){if(row.entity_type!=="worker")return null;if(row.event_type!=="state_changed")return null;if(row.details?.reason!=="dead_pane_zombie")return null;let ts3=Date.parse(row.created_at);if(!Number.isFinite(ts3))return null;let cutoff=now-WINDOW_MS2;while(this.window.length>0&&this.window[0]<cutoff)this.window.shift();if(this.window.push(ts3),this.window.length<=THRESHOLD2)return null;if(this.lastFired!==null&&this.lastFired>=cutoff)return null;return this.lastFired=now,{type:"agents.zombie_storm",subject:"global",severity:SIGNAL_SEVERITY["agents.zombie_storm"],details:{window_ms:WINDOW_MS2,threshold:THRESHOLD2,zombies_in_window:this.window.length,latest_agent:row.entity_id},triggeredAt:row.created_at}}reset(){this.window.length=0,this.lastFired=null}}var WINDOW_MS2=3600000,THRESHOLD2=5;var init_zombie_storm=__esm(()=>{init_types4()});var exports_derived_signals={};__export(exports_derived_signals,{startDerivedSignalsEngine:()=>startDerivedSignalsEngine,recordDerivedSignal:()=>recordDerivedSignal,listActiveDerivedSignals:()=>listActiveDerivedSignals,dispatch:()=>dispatch2,detectRecoveryAnchorAtRisk:()=>detectRecoveryAnchorAtRisk,detectPartitionMissing:()=>detectPartitionMissing,ZombieStormDetector:()=>ZombieStormDetector,SIGNAL_SEVERITY:()=>SIGNAL_SEVERITY,SIGNAL_DRILLDOWN:()=>SIGNAL_DRILLDOWN,LostAnchorDetector:()=>LostAnchorDetector});async function recordDerivedSignal(signal){await recordAuditEvent("derived_signal",signal.subject,signal.type,"derived-signals",{severity:signal.severity,triggered_at:signal.triggeredAt,...signal.details})}async function listActiveDerivedSignals(windowMs=3600000){let sinceMs=Date.now()-windowMs,since=new Date(sinceMs).toISOString(),rows=await queryAuditEvents({entity:"derived_signal",since,limit:200}),seen=new Set,out=[];for(let row of rows){if(row.entity_type!=="derived_signal")continue;let key=`${row.event_type}::${row.entity_id}`;if(seen.has(key))continue;seen.add(key);let details=row.details??{},severity=details.severity??"warn",triggeredAt=details.triggered_at??row.created_at;out.push({type:row.event_type,subject:row.entity_id,severity,details,triggeredAt})}return out}async function startDerivedSignalsEngine(){let lost=new LostAnchorDetector,zombie=new ZombieStormDetector,handle=await followAuditEvents({},(row)=>{dispatch2(row,{lost,zombie})});return{stop:async()=>{await handle.stop()}}}async function dispatch2(row,deps){let signals2=[];try{let sig=await detectRecoveryAnchorAtRisk(row,{getExecutor});if(sig)signals2.push(sig)}catch{}try{let sig=deps.lost.ingest(row);if(sig)signals2.push(sig)}catch{}try{let sig=deps.zombie.ingest(row);if(sig)signals2.push(sig)}catch{}for(let sig of signals2)await recordDerivedSignal(sig).catch(()=>{});return signals2}var init_derived_signals=__esm(()=>{init_audit();init_executor_registry();init_lost_anchor();init_partition_missing();init_recovery_anchor();init_zombie_storm();init_types4()});var exports_detectors={};__export(exports_detectors,{unregisterDetector:()=>unregisterDetector,registerDetector:()=>registerDetector,listDetectors:()=>listDetectors,__clearDetectorsForTests:()=>__clearDetectorsForTests});function registerDetector(module){validateModule(module),registry2.set(module.id,module)}function listDetectors(){return Array.from(registry2.values())}function unregisterDetector(id){return registry2.delete(id)}function __clearDetectorsForTests(){registry2.clear()}function validateModule(module){if(!module||typeof module!=="object")throw Error("registerDetector: module must be an object");if(typeof module.id!=="string"||!ID_RE.test(module.id))throw Error(`registerDetector: invalid id '${String(module.id)}' \u2014 must match ${ID_RE.source}`);if(typeof module.version!=="string"||!SEMVER_RE.test(module.version))throw Error(`registerDetector: invalid version '${String(module.version)}' for '${module.id}' \u2014 must be semver`);if(module.riskClass!=="low"&&module.riskClass!=="medium"&&module.riskClass!=="high")throw Error(`registerDetector: invalid riskClass for '${module.id}'`);if(typeof module.query!=="function")throw Error(`registerDetector: query must be a function on '${module.id}'`);if(typeof module.shouldFire!=="function")throw Error(`registerDetector: shouldFire must be a function on '${module.id}'`);if(typeof module.render!=="function")throw Error(`registerDetector: render must be a function on '${module.id}'`)}var registry2,SEMVER_RE,ID_RE;var init_detectors=__esm(()=>{registry2=new Map;SEMVER_RE=/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/,ID_RE=/^[a-z0-9][a-z0-9._-]{0,127}$/});import{statSync as statSync9}from"fs";function createBackfillNoWorktreeDetector(opts){let exists=opts?.exists??defaultWorktreeExistsCheck,version=opts?.version??"0.1.0",defaultQuery=async()=>{return await(await getConnection())`
2234
2234
  SELECT name, status, worktree_path
2235
2235
  FROM teams
2236
2236
  WHERE status = 'in_progress'
@@ -2502,10 +2502,10 @@ ${queryContent}`;let{messages:queryMessages}=state.provider.runQuery({agentId:se
2502
2502
  `);applyTuiStyle(),setupTuiKeybindings();try{execSync10(tuiTmux(`select-pane -t ${panes[0]}`),{stdio:"ignore"})}catch{}return{leftPane:panes[0],rightPane:panes[1]||panes[0]}}function sendTuiLaunchScript(leftPane,rightPane,workspaceRoot){let home=genieHome3(),bunPath=process.execPath||"bun",genieBin=process.argv[1]||"genie",scriptPath=join56(home,"tui-launch.sh"),logsDir=join56(home,"logs"),crashLog=join56(logsDir,"tui-crash.log"),envVars=["GENIE_TUI_PANE=left",`GENIE_TUI_RIGHT=${rightPane}`];if(workspaceRoot)envVars.push(`GENIE_TUI_WORKSPACE=${workspaceRoot}`);let content=["#!/bin/sh",`mkdir -p '${logsDir}'`,`exec 2>> '${crashLog}'`,`printf -- '--- tui-launch %s pid=%s ---\\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$$" >&2`,`export ${envVars.join(`
2503
2503
  export `)}`,`exec ${bunPath} ${genieBin}`,""].join(`
2504
2504
  `);writeFileSync16(scriptPath,content,{mode:493});try{execSync10(tuiTmux(`send-keys -t '${leftPane}' '${scriptPath}' Enter`),{stdio:"ignore"})}catch{}}function killTuiSession(){try{execSync10(tuiTmux("kill-server"),{stdio:"ignore"})}catch{}}function listAgentSessions(){try{return execSync10(genieTmuxCmd("list-sessions -F '#{session_name}'"),{encoding:"utf-8"}).trim().split(`
2505
- `).filter(Boolean)}catch{return[]}}function isServeRunning(){let entry2=readServePid();return entry2!==null&&isProcessAlive(entry2.pid)}async function autoStartServe(){if(isStoppingLockActive()){console.log("genie serve is shutting down \u2014 skipping auto-start.");return}if(isServeRunning())return;let bunPath=process.execPath??"bun",genieBin=process.argv[1]??"genie",{spawn:spawnChild}=await import("child_process");spawnChild(bunPath,[genieBin,"serve","--foreground"],{detached:!0,stdio:"ignore",env:{...process.env,GENIE_IS_DAEMON:"1"}}).unref();let deadline=Date.now()+15000;while(Date.now()<deadline)if(await new Promise((resolve10)=>setTimeout(resolve10,500)),isServeRunning()&&isTuiSessionReady())return;if(!isServeRunning())throw Error("genie serve failed to start within 15s. Run `genie serve` manually.")}function isTuiSessionReady(){try{return execSync10(tuiTmux(`has-session -t ${TUI_SESSION}`),{stdio:"ignore"}),!0}catch{return!1}}function ensureTuiSession(workspaceRoot){if(isTuiDisabled()){noticeTuiSkipped("session ensure");return}if(isTuiSessionReady())return;let{leftPane,rightPane}=startTuiTmuxServer();sendTuiLaunchScript(leftPane,rightPane,workspaceRoot)}async function startAgentSync(){try{let{findWorkspace:findWorkspace2,genieHome:genieHome4}=(init_workspace(),__toCommonJS(exports_workspace)),ws=findWorkspace2();if(!ws){let{join:join57}=__require("path"),configPath2=join57(genieHome4(),"config.json");return console.warn(` Agent sync: DISABLED \u2014 no workspace found from cwd or ${configPath2}`),console.warn(" Fix: `cd <workspace> && genie serve restart`, or run `genie init` to bootstrap one"),null}let{syncAgentDirectory:syncAgentDirectory2,watchAgentDirectory:watchAgentDirectory2}=await Promise.resolve().then(() => (init_agent_sync(),exports_agent_sync)),syncResult=await syncAgentDirectory2(ws.root);if(syncResult.registered.length+syncResult.updated.length>0)console.log(` Agent sync: ${syncResult.registered.length} registered, ${syncResult.updated.length} updated (workspace: ${ws.root})`);else console.log(` Agent sync: up to date (workspace: ${ws.root})`);if(syncResult.errors.length>0){console.warn(` Agent sync: ${syncResult.errors.length} error(s) \u2014 these agents were NOT registered:`);for(let e of syncResult.errors)console.warn(` ${e.name}: ${e.error}`)}let watcher2=watchAgentDirectory2(ws.root,{onSync:(name,action)=>{console.log(` [agent-watcher] ${name}: ${action}`)}});if(watcher2)console.log(" Agent watcher started (watching agents/ directory)");else console.warn(" Agent watcher: FAILED to start \u2014 new agents will not be auto-registered");return watcher2}catch(err){let msg=err instanceof Error?err.message:String(err);return console.error(` Agent sync failed: ${msg}`),null}}async function startPgserve(){console.log(" Starting pgserve...");try{let{getOrStartDaemon:getOrStartDaemon2,resolvePgserveLibpqSocketPath:resolvePgserveLibpqSocketPath2}=await Promise.resolve().then(() => (init_db(),exports_db)),daemon=await getOrStartDaemon2();console.log(` pgserve ready at ${resolvePgserveLibpqSocketPath2()}${daemon.pid?` (pid ${daemon.pid})`:""}`)}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(` pgserve failed: ${msg}`),process.env.GENIE_PG_NO_AUTOSTART="1",console.error(" pgserve retries disabled for this serve process; fix pgserve and restart `genie serve`.")}}async function startScheduler(){console.log(" Starting scheduler daemon...");try{let{startDaemon:startDaemon2}=await Promise.resolve().then(() => (init_scheduler_daemon(),exports_scheduler_daemon));handles.schedulerHandle=startDaemon2(),console.log(" Scheduler started (includes event-router + inbox-watcher)");try{let{registerService:registerService2}=await Promise.resolve().then(() => (init_service_registry(),exports_service_registry));registerService2("scheduler",process.pid)}catch{}}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(` Scheduler failed: ${msg}`)}try{let{startDerivedSignalsEngine:startDerivedSignalsEngine2}=await Promise.resolve().then(() => (init_derived_signals(),exports_derived_signals));handles.derivedSignals=await startDerivedSignalsEngine2(),console.log(" Derived-signal rule engine subscribed")}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(` Derived-signal engine failed: ${msg}`)}}function claimServePidOrExit(){let path3=servePidPath();mkdirSync18(genieHome3(),{recursive:!0});let startTime=getProcessStartTime(process.pid)??"unknown",payload=`${process.pid}:${startTime}`;for(let attempt=0;attempt<2;attempt++)try{let fd=openSync5(path3,"wx",420);try{writeSync2(fd,payload)}finally{closeSync5(fd)}return}catch(err){if(err.code!=="EEXIST")throw err;let existing=readServePid();if(existing&&existing.startTime!==null&&isProcessAlive(existing.pid))console.log(`genie serve already running (PID ${existing.pid})`),warnIfHookSocketMissing(),process.exit(0);forceRemoveServePid()}console.error("Could not claim serve.pid after 2 attempts \u2014 another genie serve is racing this one. "+"Wait a moment and retry, or run `genie serve status`."),process.exit(1)}function resolveServeMode(headless){let tuiDisabled=isTuiDisabled();if(tuiDisabled&&!headless)noticeTuiSkipped("serve");return{skipTui:Boolean(headless)||tuiDisabled,mode:headless?"headless":tuiDisabled?"no-tui":"full"}}async function loadBrainStartupConfig(deps){return deps.loadConfig?.()??(await Promise.resolve().then(() => (init_genie_config2(),exports_genie_config))).loadGenieConfigSync()}async function importBrainForStartup(deps){if(deps.importBrain)return deps.importBrain();return import("@khal-os/brain")}async function getBrainStartupPgPort(deps){return deps.getActivePort?.()??(await Promise.resolve().then(() => (init_db(),exports_db))).getActivePort()}function assignBrainHandles(deps,brainHandles){if(deps.setBrainHandles){deps.setBrainHandles(brainHandles);return}handles.brainHandles=brainHandles}function isMissingBrainModule(message){return message.includes("Cannot find")||message.includes("not found")||message.includes("MODULE_NOT_FOUND")}async function startBrainServer(deps,config,log2,warn){let brain=await importBrainForStartup(deps);if(!brain.startEmbeddedBrainServer)return[];let pgPort=await getBrainStartupPgPort(deps);if(!pgPort)return log2(" Brain server: pgserve not available (skipped)"),[];let resolveVaults=deps.resolveVaults??resolveBrainVaults,startVaults=deps.startVaults??startResolvedBrainVaults,resolution=await resolveVaults({brain,config,warn});if(resolution.paths.length===0)return log2(` Brain server: no ${resolution.source} brain vaults found (skipped)`),[];log2(` Starting brain server (${resolution.paths.length} ${resolution.source} vault(s))...`);let brainHandles=await startVaults(resolution,brain,pgPort,{warn,log:log2});if(assignBrainHandles(deps,brainHandles),brainHandles.length===0)log2(" Brain server: no vaults started");return brainHandles}async function startBrainServerIfEnabled(deps={}){let config=await loadBrainStartupConfig(deps),brainEmbedded=config.brain?.embedded!==!1,log2=deps.log??console.log,warn=deps.warn??console.warn;if(!brainEmbedded)return log2(" Brain server: skipped (brain.embedded=false \u2014 managed externally)"),[];try{return await startBrainServer(deps,config,log2,warn)}catch(err){let msg=err instanceof Error?err.message:String(err);if(isMissingBrainModule(msg))return[];return warn(` Brain server: failed: ${msg}`),[]}}function logAgentSessionInfo(){let sessions=listAgentSessions();if(sessions.length>0)console.log(` Agent server (-L genie): ${sessions.length} sessions`);else console.log(" Agent server (-L genie): no sessions yet (created on first spawn)")}function startTuiSessionIfEnabled(skipTui){if(skipTui)return;console.log(" Setting up TUI session...");let{leftPane,rightPane}=startTuiTmuxServer(),ws=(()=>{try{let{findWorkspace:findWorkspace2}=(init_workspace(),__toCommonJS(exports_workspace));return findWorkspace2()}catch{return null}})();sendTuiLaunchScript(leftPane,rightPane,ws?.root),console.log(" TUI server ready (session: genie-tui)")}async function startDetectorSchedulerSafely(){try{await Promise.resolve().then(() => (init_built_in(),exports_built_in));let{start:startDetectorScheduler}=await Promise.resolve().then(() => (init_detector_scheduler(),exports_detector_scheduler)),{listDetectors:listDetectors2}=await Promise.resolve().then(() => (init_detectors(),exports_detectors));handles.detectorScheduler=startDetectorScheduler();let registered=listDetectors2().map((d)=>d.id);console.log(` Detector scheduler started (measurement only, 60s \xB1 5s cadence) \u2014 registered: [${registered.join(", ")}]`)}catch(err){let msg=err instanceof Error?err.message:String(err);console.warn(` Detector scheduler: failed \u2014 ${msg}`)}}async function startExecutorReadEndpointSafely(){try{let{startExecutorReadEndpoint:startExecutorReadEndpoint2,getExecutorReadPort:getExecutorReadPort2}=await Promise.resolve().then(() => (init_executor_read(),exports_executor_read));if(await startExecutorReadEndpoint2())console.log(` Executor read endpoint ready on port ${getExecutorReadPort2()}`)}catch(err){let msg=err instanceof Error?err.message:String(err);console.warn(` Executor read endpoint: failed \u2014 ${msg}`)}}async function startOmniApprovalHandlerSafely(){try{let{startOmniApprovalHandler:startOmniApprovalHandler2}=await Promise.resolve().then(() => (init_omni_approval_handler(),exports_omni_approval_handler)),handler=await startOmniApprovalHandler2();if(handler)handles.omniApprovalHandler=handler,console.log(" Omni approval handler started")}catch{}}async function startOmniBridgeSafely(){let{OmniBridge:OmniBridge2}=await Promise.resolve().then(() => (init_omni_bridge(),exports_omni_bridge)),bridge=new OmniBridge2({natsUrl:process.env.GENIE_NATS_URL??"localhost:4222",maxConcurrent:Number(process.env.GENIE_MAX_CONCURRENT??"20"),idleTimeoutMs:Number(process.env.GENIE_IDLE_TIMEOUT_MS??"900000")});try{await bridge.start(),handles.omniBridge=bridge,console.log(" Omni bridge started")}catch(err){let msg=err instanceof Error?err.message:String(err);if(process.env.GENIE_OMNI_REQUIRED==="1")console.error(` Omni bridge: FAILED \u2014 ${msg}`),process.exit(1);console.warn(` Omni bridge: degraded \u2014 ${msg}; set GENIE_OMNI_REQUIRED=1 to make this fatal`)}}async function stopSchedulerHandles(){handles.agentWatcher?.close();let schedulerHandle=handles.schedulerHandle;if(schedulerHandle){schedulerHandle.stop();try{await schedulerHandle.done}catch{}handles.schedulerHandle=null}if(handles.detectorScheduler)handles.detectorScheduler.stop(),handles.detectorScheduler=null;if(handles.derivedSignals)await handles.derivedSignals.stop().catch(()=>{}),handles.derivedSignals=null}async function stopOmniAndBrainServices(){if(handles.omniApprovalHandler)await handles.omniApprovalHandler.stop().catch(()=>{}),handles.omniApprovalHandler=null;if(handles.omniBridge)await handles.omniBridge.stop().catch(()=>{}),handles.omniBridge=null;if(Promise.resolve().then(() => (init_executor_read(),exports_executor_read)).then((m)=>m.stopExecutorReadEndpoint().catch(()=>{})),handles.brainHandles.length>0){for(let handle of handles.brainHandles)await handle.stop().catch(()=>{});handles.brainHandles=[]}}function killRegisteredServices(){try{let{killAllServices:killAllServices2}=(init_service_registry(),__toCommonJS(exports_service_registry));killAllServices2()}catch{}}function removeLegacyPgservePortLockfileIfForcedTcp(){if(process.env.GENIE_PG_FORCE_TCP!=="1")return;try{let lockfilePath=join56(genieHome3(),"pgserve.port");if(existsSync45(lockfilePath))unlinkSync11(lockfilePath)}catch{}}function sigKillRegisteredServices(){try{let{getRegisteredServices:getRegisteredServices2}=(init_service_registry(),__toCommonJS(exports_service_registry));for(let svc of getRegisteredServices2())try{process.kill(svc.pid,"SIGKILL")}catch{}}catch{}}async function startHookSocketSafely(){try{let{startHookSocket:startHookSocket2}=await Promise.resolve().then(() => (init_hook_socket(),exports_hook_socket));handles.hookSocket=await startHookSocket2()}catch(err){console.warn(` Hook socket: DISABLED \u2014 ${err.message}`),handles.hookSocket=null}}async function stopHookSocketSafely(){if(!handles.hookSocket)return;try{await handles.hookSocket.stop()}catch{}handles.hookSocket=null}function buildShutdownFn(headless){let shutdownStarted=!1;return{shutdown:async()=>{if(shutdownStarted)return;if(shutdownStarted=!0,console.log(`
2505
+ `).filter(Boolean)}catch{return[]}}function isServeRunning(){let entry2=readServePid();return entry2!==null&&isProcessAlive(entry2.pid)}async function autoStartServe(){if(isStoppingLockActive()){console.log("genie serve is shutting down \u2014 skipping auto-start.");return}if(isServeRunning())return;let bunPath=process.execPath??"bun",genieBin=process.argv[1]??"genie",{spawn:spawnChild}=await import("child_process");spawnChild(bunPath,[genieBin,"serve","--foreground"],{detached:!0,stdio:"ignore",env:{...process.env,GENIE_IS_DAEMON:"1"}}).unref();let deadline=Date.now()+15000;while(Date.now()<deadline)if(await new Promise((resolve10)=>setTimeout(resolve10,500)),isServeRunning()&&isTuiSessionReady())return;if(!isServeRunning())throw Error("genie serve failed to start within 15s. Run `genie serve` manually.")}function isTuiSessionReady(){try{return execSync10(tuiTmux(`has-session -t ${TUI_SESSION}`),{stdio:"ignore"}),!0}catch{return!1}}function ensureTuiSession(workspaceRoot){if(isTuiDisabled()){noticeTuiSkipped("session ensure");return}if(isTuiSessionReady())return;let{leftPane,rightPane}=startTuiTmuxServer();sendTuiLaunchScript(leftPane,rightPane,workspaceRoot)}async function startAgentSync(){try{let{findWorkspace:findWorkspace2,genieHome:genieHome4}=(init_workspace(),__toCommonJS(exports_workspace)),ws=findWorkspace2();if(!ws){let{join:join57}=__require("path"),configPath2=join57(genieHome4(),"config.json");return console.warn(` Agent sync: DISABLED \u2014 no workspace found from cwd or ${configPath2}`),console.warn(" Fix: `cd <workspace> && genie serve restart`, or run `genie init` to bootstrap one"),null}let{syncAgentDirectory:syncAgentDirectory2,watchAgentDirectory:watchAgentDirectory2}=await Promise.resolve().then(() => (init_agent_sync(),exports_agent_sync)),syncResult=await syncAgentDirectory2(ws.root);if(syncResult.registered.length+syncResult.updated.length>0)console.log(` Agent sync: ${syncResult.registered.length} registered, ${syncResult.updated.length} updated (workspace: ${ws.root})`);else console.log(` Agent sync: up to date (workspace: ${ws.root})`);if(syncResult.errors.length>0){console.warn(` Agent sync: ${syncResult.errors.length} error(s) \u2014 these agents were NOT registered:`);for(let e of syncResult.errors)console.warn(` ${e.name}: ${e.error}`)}let watcher2=watchAgentDirectory2(ws.root,{onSync:(name,action)=>{console.log(` [agent-watcher] ${name}: ${action}`)}});if(watcher2)console.log(" Agent watcher started (watching agents/ directory)");else console.warn(" Agent watcher: FAILED to start \u2014 new agents will not be auto-registered");return watcher2}catch(err){let msg=err instanceof Error?err.message:String(err);return console.error(` Agent sync failed: ${msg}`),null}}async function startPgserve(){console.log(" Starting pgserve daemon...");try{let{getDataDir:getDataDir2,getOrStartDaemon:getOrStartDaemon2,resolvePgserveSocketDir:resolvePgserveSocketDir2}=await Promise.resolve().then(() => (init_db(),exports_db)),state=await getOrStartDaemon2(),pid=state.pid?`, pid ${state.pid}`:"";console.log(` pgserve daemon ready on ${resolvePgserveSocketDir2()} (data: ${getDataDir2()}${pid})`);try{let{registerService:registerService2}=await Promise.resolve().then(() => (init_service_registry(),exports_service_registry));registerService2("pgserve-owner",process.pid)}catch{}}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(` pgserve failed: ${msg}`),process.env.GENIE_PG_NO_AUTOSTART="1",process.env.GENIE_PG_DISABLE_AUTOSTART="1",console.error(" pgserve retries disabled for this serve process; fix pgserve and restart `genie serve`.")}}async function startScheduler(){console.log(" Starting scheduler daemon...");try{let{startDaemon:startDaemon2}=await Promise.resolve().then(() => (init_scheduler_daemon(),exports_scheduler_daemon));handles.schedulerHandle=startDaemon2(),console.log(" Scheduler started (includes event-router + inbox-watcher)");try{let{registerService:registerService2}=await Promise.resolve().then(() => (init_service_registry(),exports_service_registry));registerService2("scheduler",process.pid)}catch{}}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(` Scheduler failed: ${msg}`)}try{let{startDerivedSignalsEngine:startDerivedSignalsEngine2}=await Promise.resolve().then(() => (init_derived_signals(),exports_derived_signals));handles.derivedSignals=await startDerivedSignalsEngine2(),console.log(" Derived-signal rule engine subscribed")}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(` Derived-signal engine failed: ${msg}`)}}function claimServePidOrExit(){let path3=servePidPath();mkdirSync18(genieHome3(),{recursive:!0});let startTime=getProcessStartTime(process.pid)??"unknown",payload=`${process.pid}:${startTime}`;for(let attempt=0;attempt<2;attempt++)try{let fd=openSync5(path3,"wx",420);try{writeSync2(fd,payload)}finally{closeSync5(fd)}return}catch(err){if(err.code!=="EEXIST")throw err;let existing=readServePid();if(existing&&existing.startTime!==null&&isProcessAlive(existing.pid))console.log(`genie serve already running (PID ${existing.pid})`),warnIfHookSocketMissing(),process.exit(0);forceRemoveServePid()}console.error("Could not claim serve.pid after 2 attempts \u2014 another genie serve is racing this one. "+"Wait a moment and retry, or run `genie serve status`."),process.exit(1)}function resolveServeMode(headless){let tuiDisabled=isTuiDisabled();if(tuiDisabled&&!headless)noticeTuiSkipped("serve");return{skipTui:Boolean(headless)||tuiDisabled,mode:headless?"headless":tuiDisabled?"no-tui":"full"}}async function loadBrainStartupConfig(deps){return deps.loadConfig?.()??(await Promise.resolve().then(() => (init_genie_config2(),exports_genie_config))).loadGenieConfigSync()}async function importBrainForStartup(deps){if(deps.importBrain)return deps.importBrain();return import("@khal-os/brain")}async function getBrainStartupPgPort(deps){return deps.getActivePort?.()??(await Promise.resolve().then(() => (init_db(),exports_db))).getActivePort()}function assignBrainHandles(deps,brainHandles){if(deps.setBrainHandles){deps.setBrainHandles(brainHandles);return}handles.brainHandles=brainHandles}function isMissingBrainModule(message){return message.includes("Cannot find")||message.includes("not found")||message.includes("MODULE_NOT_FOUND")}async function startBrainServer(deps,config,log2,warn){let brain=await importBrainForStartup(deps);if(!brain.startEmbeddedBrainServer)return[];let pgPort=await getBrainStartupPgPort(deps);if(!pgPort)return log2(" Brain server: pgserve not available (skipped)"),[];let resolveVaults=deps.resolveVaults??resolveBrainVaults,startVaults=deps.startVaults??startResolvedBrainVaults,resolution=await resolveVaults({brain,config,warn});if(resolution.paths.length===0)return log2(` Brain server: no ${resolution.source} brain vaults found (skipped)`),[];log2(` Starting brain server (${resolution.paths.length} ${resolution.source} vault(s))...`);let brainHandles=await startVaults(resolution,brain,pgPort,{warn,log:log2});if(assignBrainHandles(deps,brainHandles),brainHandles.length===0)log2(" Brain server: no vaults started");return brainHandles}async function startBrainServerIfEnabled(deps={}){let config=await loadBrainStartupConfig(deps),brainEmbedded=config.brain?.embedded!==!1,log2=deps.log??console.log,warn=deps.warn??console.warn;if(!brainEmbedded)return log2(" Brain server: skipped (brain.embedded=false \u2014 managed externally)"),[];try{return await startBrainServer(deps,config,log2,warn)}catch(err){let msg=err instanceof Error?err.message:String(err);if(isMissingBrainModule(msg))return[];return warn(` Brain server: failed: ${msg}`),[]}}function logAgentSessionInfo(){let sessions=listAgentSessions();if(sessions.length>0)console.log(` Agent server (-L genie): ${sessions.length} sessions`);else console.log(" Agent server (-L genie): no sessions yet (created on first spawn)")}function startTuiSessionIfEnabled(skipTui){if(skipTui)return;console.log(" Setting up TUI session...");let{leftPane,rightPane}=startTuiTmuxServer(),ws=(()=>{try{let{findWorkspace:findWorkspace2}=(init_workspace(),__toCommonJS(exports_workspace));return findWorkspace2()}catch{return null}})();sendTuiLaunchScript(leftPane,rightPane,ws?.root),console.log(" TUI server ready (session: genie-tui)")}async function startDetectorSchedulerSafely(){try{await Promise.resolve().then(() => (init_built_in(),exports_built_in));let{start:startDetectorScheduler}=await Promise.resolve().then(() => (init_detector_scheduler(),exports_detector_scheduler)),{listDetectors:listDetectors2}=await Promise.resolve().then(() => (init_detectors(),exports_detectors));handles.detectorScheduler=startDetectorScheduler();let registered=listDetectors2().map((d)=>d.id);console.log(` Detector scheduler started (measurement only, 60s \xB1 5s cadence) \u2014 registered: [${registered.join(", ")}]`)}catch(err){let msg=err instanceof Error?err.message:String(err);console.warn(` Detector scheduler: failed \u2014 ${msg}`)}}async function startExecutorReadEndpointSafely(){try{let{startExecutorReadEndpoint:startExecutorReadEndpoint2,getExecutorReadPort:getExecutorReadPort2}=await Promise.resolve().then(() => (init_executor_read(),exports_executor_read));if(await startExecutorReadEndpoint2())console.log(` Executor read endpoint ready on port ${getExecutorReadPort2()}`)}catch(err){let msg=err instanceof Error?err.message:String(err);console.warn(` Executor read endpoint: failed \u2014 ${msg}`)}}async function startOmniApprovalHandlerSafely(){try{let{startOmniApprovalHandler:startOmniApprovalHandler2}=await Promise.resolve().then(() => (init_omni_approval_handler(),exports_omni_approval_handler)),handler=await startOmniApprovalHandler2();if(handler)handles.omniApprovalHandler=handler,console.log(" Omni approval handler started")}catch{}}async function startOmniBridgeSafely(){let{OmniBridge:OmniBridge2}=await Promise.resolve().then(() => (init_omni_bridge(),exports_omni_bridge)),bridge=new OmniBridge2({natsUrl:process.env.GENIE_NATS_URL??"localhost:4222",maxConcurrent:Number(process.env.GENIE_MAX_CONCURRENT??"20"),idleTimeoutMs:Number(process.env.GENIE_IDLE_TIMEOUT_MS??"900000")});try{await bridge.start(),handles.omniBridge=bridge,console.log(" Omni bridge started")}catch(err){let msg=err instanceof Error?err.message:String(err);if(process.env.GENIE_OMNI_REQUIRED==="1")console.error(` Omni bridge: FAILED \u2014 ${msg}`),process.exit(1);console.warn(` Omni bridge: degraded \u2014 ${msg}; set GENIE_OMNI_REQUIRED=1 to make this fatal`)}}async function stopSchedulerHandles(){handles.agentWatcher?.close();let schedulerHandle=handles.schedulerHandle;if(schedulerHandle){schedulerHandle.stop();try{await schedulerHandle.done}catch{}handles.schedulerHandle=null}if(handles.detectorScheduler)handles.detectorScheduler.stop(),handles.detectorScheduler=null;if(handles.derivedSignals)await handles.derivedSignals.stop().catch(()=>{}),handles.derivedSignals=null}async function stopOmniAndBrainServices(){if(handles.omniApprovalHandler)await handles.omniApprovalHandler.stop().catch(()=>{}),handles.omniApprovalHandler=null;if(handles.omniBridge)await handles.omniBridge.stop().catch(()=>{}),handles.omniBridge=null;if(Promise.resolve().then(() => (init_executor_read(),exports_executor_read)).then((m)=>m.stopExecutorReadEndpoint().catch(()=>{})),handles.brainHandles.length>0){for(let handle of handles.brainHandles)await handle.stop().catch(()=>{});handles.brainHandles=[]}}function killRegisteredServices(){try{let{killAllServices:killAllServices2}=(init_service_registry(),__toCommonJS(exports_service_registry));killAllServices2()}catch{}}function removeLegacyPgservePortLockfileIfForcedTcp(){if(process.env.GENIE_PG_FORCE_TCP!=="1")return;try{let lockfilePath=join56(genieHome3(),"pgserve.port");if(existsSync45(lockfilePath))unlinkSync11(lockfilePath)}catch{}}function sigKillRegisteredServices(){try{let{getRegisteredServices:getRegisteredServices2}=(init_service_registry(),__toCommonJS(exports_service_registry));for(let svc of getRegisteredServices2())try{process.kill(svc.pid,"SIGKILL")}catch{}}catch{}}async function startHookSocketSafely(){try{let{startHookSocket:startHookSocket2}=await Promise.resolve().then(() => (init_hook_socket(),exports_hook_socket));handles.hookSocket=await startHookSocket2()}catch(err){console.warn(` Hook socket: DISABLED \u2014 ${err.message}`),handles.hookSocket=null}}async function stopHookSocketSafely(){if(!handles.hookSocket)return;try{await handles.hookSocket.stop()}catch{}handles.hookSocket=null}function buildShutdownFn(headless){let shutdownStarted=!1;return{shutdown:async()=>{if(shutdownStarted)return;if(shutdownStarted=!0,console.log(`
2506
2506
  Shutting down genie serve...`),await stopHookSocketSafely(),await stopSchedulerHandles(),await stopOmniAndBrainServices(),killRegisteredServices(),!headless)killTuiSession();removeLegacyPgservePortLockfileIfForcedTcp(),removeServePid(),console.log("genie serve stopped.")},hasStarted:()=>shutdownStarted}}function installGracefulExitHandlers(shutdown2,hasStarted){let gracefulExit=(exitCode)=>{if(hasStarted())return;let forceTimer=setTimeout(()=>{console.error("Graceful shutdown timeout (10s). Force-killing remaining processes."),sigKillRegisteredServices(),removeServePid(),process.exit(1)},1e4);forceTimer.unref(),shutdown2().catch(()=>{}).finally(()=>{clearTimeout(forceTimer),removeServePid(),process.exit(exitCode)})};process.on("SIGTERM",()=>gracefulExit(143)),process.on("SIGINT",()=>gracefulExit(130)),process.on("SIGHUP",()=>gracefulExit(129)),process.on("exit",()=>{removeServePid()}),process.on("uncaughtException",(err)=>{console.error("Uncaught exception in genie serve:",err),gracefulExit(1)})}function writeStartupStatus(status){let statusPath=process.env.GENIE_SERVE_STARTUP_STATUS;if(!statusPath)return;try{mkdirSync18(dirname14(statusPath),{recursive:!0}),writeFileSync16(statusPath,`${JSON.stringify(status)}
2507
2507
  `,"utf-8")}catch{}}function readStartupStatus(statusPath){try{let parsed=JSON.parse(readFileSync27(statusPath,"utf-8"));if(typeof parsed.ok!=="boolean")return null;return{ok:parsed.ok,code:typeof parsed.code==="number"?parsed.code:void 0,lines:Array.isArray(parsed.lines)?parsed.lines.filter((line)=>typeof line==="string"):void 0}}catch{return null}}async function waitForStartupStatus(statusPath,childPid,timeoutMs){let deadline=Date.now()+timeoutMs;while(Date.now()<deadline){let status=readStartupStatus(statusPath);if(status)return status;if(!isProcessAlive(childPid))return{ok:!1,code:1};await new Promise((resolve10)=>setTimeout(resolve10,100))}return null}function exitBackgroundStartFailed(){console.error("Error: genie serve exited immediately."),process.exit(1)}function exitStartupStatusFailure(status){for(let line of status.lines??[])console.error(line);process.exit(status.code??1)}function exitStartupStatusMissing(childPid){console.error("Error: genie serve did not report startup precondition status within 16s.");try{process.kill(childPid,"SIGTERM")}catch{}process.exit(1)}async function confirmBackgroundStarted(childPid,startupStatusPath){if(startupStatusPath){let status=await waitForStartupStatus(startupStatusPath,childPid,16000);if(forceRemovePath(startupStatusPath),status?.ok===!1)exitStartupStatusFailure(status);if(status?.ok!==!0)exitStartupStatusMissing(childPid);if(!isProcessAlive(childPid))exitBackgroundStartFailed();console.log(`genie serve started (PID ${childPid})`);return}if(await new Promise((resolve10)=>setTimeout(resolve10,1000)),!isProcessAlive(childPid))exitBackgroundStartFailed();console.log(`genie serve started (PID ${childPid})`)}async function startForeground(headless,autoFix=!0){claimServePidOrExit(),removeLegacyPgservePortLockfileIfForcedTcp();let{skipTui,mode}=resolveServeMode(headless);process.env.GENIE_IS_DAEMON="1",console.log(`genie serve starting (PID ${process.pid}, mode: ${mode})`);let preconditionLines=[],preconditionLog=process.env.GENIE_SERVE_STARTUP_STATUS?(line)=>{preconditionLines.push(line),console.log(line)}:void 0;try{if(!await runStartPreconditions(autoFix,preconditionLog))writeStartupStatus({ok:!1,code:2,lines:preconditionLines}),removeServePid(),process.exit(2)}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(`genie serve start preconditions failed: ${msg}`),writeStartupStatus({ok:!1,code:1,lines:[...preconditionLines,`genie serve start preconditions failed: ${msg}`]}),removeServePid(),process.exit(1)}if(writeStartupStatus({ok:!0}),!skipTui)await ensureTmux();if(await startPgserve(),await startBrainServerIfEnabled(),!headless)logAgentSessionInfo();handles.agentWatcher=await startAgentSync(),startTuiSessionIfEnabled(skipTui),await startScheduler(),await startDetectorSchedulerSafely(),await startExecutorReadEndpointSafely(),await startOmniApprovalHandlerSafely(),await startOmniBridgeSafely(),await startHookSocketSafely(),console.log(`
2508
- genie serve is running (${mode}). ${headless?"Send SIGTERM to stop.":"Press Ctrl+C to stop."}`);let{shutdown:shutdown2,hasStarted}=buildShutdownFn(headless);if(installGracefulExitHandlers(shutdown2,hasStarted),handles.schedulerHandle)await handles.schedulerHandle.done;else await new Promise(()=>{});removeServePid()}async function startBackground(headless,autoFix=!0){let existingEntry=readServePid();if(existingEntry&&isProcessAlive(existingEntry.pid))console.log(`genie serve already running (PID ${existingEntry.pid})`),process.exit(0);if(existingEntry)forceRemoveServePid();let bunPath=process.execPath??"bun",genieBin=process.argv[1]??"genie",startupStatusPath=autoFix?void 0:serveStartupStatusPath(),args=[genieBin,"serve","--foreground"];if(headless)args.push("--headless");if(!autoFix)args.push("--no-fix");let child=spawn4(bunPath,args,{detached:!0,stdio:"ignore",env:{...process.env,GENIE_IS_DAEMON:"1",...startupStatusPath?{GENIE_SERVE_STARTUP_STATUS:startupStatusPath}:{}}});if(child.unref(),child.pid)await confirmBackgroundStarted(child.pid,startupStatusPath);else console.error("Error: failed to spawn genie serve"),process.exit(1)}function forceRemoveServePid(){forceRemovePath(servePidPath())}function forceRemovePath(path3){try{unlinkSync11(path3)}catch{}}async function stopServe(){let entry2=readServePid();if(!entry2){console.log("genie serve is not running (no PID file).");return}writeStoppingLockSync();try{let pid=entry2.pid;if(!isProcessAlive(pid)){console.log(`Stale PID file (PID ${pid} not running). Cleaning up.`),forceRemoveServePid(),killTuiSession();return}console.log(`Stopping genie serve (PID ${pid})...`);try{process.kill(-pid,"SIGTERM")}catch{try{process.kill(pid,"SIGTERM")}catch{}}let deadline=Date.now()+1e4;while(Date.now()<deadline&&isProcessAlive(pid))await new Promise((resolve10)=>setTimeout(resolve10,250));if(isProcessAlive(pid)){console.log("Did not stop within 10s. Sending SIGKILL.");try{process.kill(-pid,"SIGKILL")}catch{try{process.kill(pid,"SIGKILL")}catch{}}}killTuiSession(),forceRemoveServePid(),console.log("genie serve stopped.")}finally{clearStoppingLock()}}async function printPgserveHealth(){try{let{isAvailable:isAvailable2,getActivePort:getActivePort2}=await Promise.resolve().then(() => (init_db(),exports_db)),dbOk=await isAvailable2();console.log(` pgserve: ${dbOk?`healthy (port ${getActivePort2()})`:"unreachable"}`)}catch{console.log(" pgserve: unavailable")}}function hookSocketPath(){return process.env.GENIE_HOOK_SOCK??join56(genieHome3(),"hook.sock")}function warnIfHookSocketMissing(){let sock=hookSocketPath();if(existsSync45(sock))return;let lines=[` WARNING: hook UDS not found at ${sock}.`," Daemon-mode hook dispatch is INACTIVE \u2014 every hook will fall back"," to the legacy F1 bun-fork path (hookify-perf-foundation gains lost)."," Remediation: `genie serve stop && genie serve start` to refresh the"," daemon and re-create the socket."];console.warn(lines.join(`
2508
+ genie serve is running (${mode}). ${headless?"Send SIGTERM to stop.":"Press Ctrl+C to stop."}`);let{shutdown:shutdown2,hasStarted}=buildShutdownFn(headless);if(installGracefulExitHandlers(shutdown2,hasStarted),handles.schedulerHandle)await handles.schedulerHandle.done;else await new Promise(()=>{});removeServePid()}async function startBackground(headless,autoFix=!0){let existingEntry=readServePid();if(existingEntry&&isProcessAlive(existingEntry.pid))console.log(`genie serve already running (PID ${existingEntry.pid})`),process.exit(0);if(existingEntry)forceRemoveServePid();let bunPath=process.execPath??"bun",genieBin=process.argv[1]??"genie",startupStatusPath=autoFix?void 0:serveStartupStatusPath(),args=[genieBin,"serve","--foreground"];if(headless)args.push("--headless");if(!autoFix)args.push("--no-fix");let child=spawn4(bunPath,args,{detached:!0,stdio:"ignore",env:{...process.env,GENIE_IS_DAEMON:"1",...startupStatusPath?{GENIE_SERVE_STARTUP_STATUS:startupStatusPath}:{}}});if(child.unref(),child.pid)await confirmBackgroundStarted(child.pid,startupStatusPath);else console.error("Error: failed to spawn genie serve"),process.exit(1)}function forceRemoveServePid(){forceRemovePath(servePidPath())}function forceRemovePath(path3){try{unlinkSync11(path3)}catch{}}async function stopServe(){let entry2=readServePid();if(!entry2){console.log("genie serve is not running (no PID file).");return}writeStoppingLockSync();try{let pid=entry2.pid;if(!isProcessAlive(pid)){console.log(`Stale PID file (PID ${pid} not running). Cleaning up.`),forceRemoveServePid(),killTuiSession();return}console.log(`Stopping genie serve (PID ${pid})...`);try{process.kill(-pid,"SIGTERM")}catch{try{process.kill(pid,"SIGTERM")}catch{}}let deadline=Date.now()+1e4;while(Date.now()<deadline&&isProcessAlive(pid))await new Promise((resolve10)=>setTimeout(resolve10,250));if(isProcessAlive(pid)){console.log("Did not stop within 10s. Sending SIGKILL.");try{process.kill(-pid,"SIGKILL")}catch{try{process.kill(pid,"SIGKILL")}catch{}}}killTuiSession(),forceRemoveServePid(),console.log("genie serve stopped.")}finally{clearStoppingLock()}}async function printPgserveHealth(){try{let{isAvailable:isAvailable2,getActivePort:getActivePort2,isSocketMode:isSocketMode2,resolvePgserveSocketDir:resolvePgserveSocketDir2}=await Promise.resolve().then(() => (init_db(),exports_db)),dbOk=await isAvailable2(),where=isSocketMode2()?`socket ${resolvePgserveSocketDir2()}`:`port ${getActivePort2()}`;console.log(` pgserve: ${dbOk?`healthy (${where})`:"unreachable"}`)}catch{console.log(" pgserve: unavailable")}}function hookSocketPath(){return process.env.GENIE_HOOK_SOCK??join56(genieHome3(),"hook.sock")}function warnIfHookSocketMissing(){let sock=hookSocketPath();if(existsSync45(sock))return;let lines=[` WARNING: hook UDS not found at ${sock}.`," Daemon-mode hook dispatch is INACTIVE \u2014 every hook will fall back"," to the legacy F1 bun-fork path (hookify-perf-foundation gains lost)."," Remediation: `genie serve stop && genie serve start` to refresh the"," daemon and re-create the socket."];console.warn(lines.join(`
2509
2509
  `))}function printHookSocketStatus(){let sock=hookSocketPath();if(existsSync45(sock))console.log(` hook UDS: listening at ${sock}`);else console.log(` hook UDS: MISSING at ${sock} (F1 fallback active \u2014 see #1490)`)}function resolveBrainPortFromWorkspace(brain){try{let{findWorkspace:findWorkspace2}=(init_workspace(),__toCommonJS(exports_workspace)),ws=findWorkspace2();if(ws?.root&&brain.readServerInfo){let info=brain.readServerInfo(join56(ws.root,"brain"));if(info?.port)return info.port}}catch{}return null}async function probeBrainHealth(brainPort){try{let resp=await fetch(`http://127.0.0.1:${brainPort}/healthz`);console.log(resp.ok?` brain: running (port ${brainPort})`:` brain: unhealthy (port ${brainPort}, status ${resp.status})`)}catch{console.log(` brain: stopped (port ${brainPort} unreachable)`)}}async function printBrainStatus(){try{let brain=await import("@khal-os/brain");if(handles.brainHandles.length>0){for(let handle of handles.brainHandles)await probeBrainHealth(handle.port);return}let brainPort=resolveBrainPortFromWorkspace(brain);if(brainPort)await probeBrainHealth(brainPort);else console.log(" brain: stopped")}catch{console.log(" brain: not installed")}}async function printPgserveStatus(){await printPgserveHealth(),printHookSocketStatus(),await printBrainStatus()}function printTmuxStatus(){let agentRunning=isGenieTmuxRunning(),sessions=agentRunning?listAgentSessions():[];if(console.log(` tmux -L genie: ${agentRunning?`running (${sessions.length} sessions)`:"stopped"}`),sessions.length>0)console.log(` ${sessions.join(", ")}`);let tuiReady=isTuiSessionReady();console.log(` tmux -L genie-tui: ${tuiReady?"running":"stopped"}`)}async function printDaemonStatus(serveRunning){try{let schedulerPidPath=join56(genieHome3(),"scheduler.pid");if(existsSync45(schedulerPidPath)){let sPid=Number.parseInt(readFileSync27(schedulerPidPath,"utf-8").trim(),10),sAlive=!Number.isNaN(sPid)&&isProcessAlive(sPid);console.log(` scheduler: ${sAlive?`running (PID ${sPid})`:"stopped"}`)}else if(serveRunning)console.log(" scheduler: integrated (in-process)");else console.log(" scheduler: stopped")}catch{console.log(" scheduler: unknown")}try{let{getInboxPollIntervalMs:getInboxPollIntervalMs2}=await Promise.resolve().then(() => (init_inbox_watcher(),exports_inbox_watcher)),pollMs=getInboxPollIntervalMs2();if(pollMs===0)console.log(" inbox: disabled");else console.log(` inbox: ${serveRunning?"watching":"stopped"} (poll ${pollMs/1000}s)`)}catch{console.log(" inbox: unavailable")}}async function printBridgeStatus(){try{let{getBridgeStatus:getBridgeStatus2}=await Promise.resolve().then(() => (init_bridge_status(),exports_bridge_status)),res=await getBridgeStatus2();if(res.state==="running"&&res.pong){let uptimeSec=Math.round(res.pong.uptimeMs/1000),latency=res.latencyMs??0;console.log(` omni-bridge: running (pid ${res.pong.pid}, uptime ${uptimeSec}s, ping ${latency}ms)`)}else if(res.state==="stale")console.log(` omni-bridge: stale \u2014 ${res.detail}`);else console.log(" omni-bridge: stopped")}catch{console.log(" omni-bridge: unavailable")}}async function statusServe(){let entry2=readServePid(),running2=entry2!==null&&isProcessAlive(entry2.pid);if(console.log(`
2510
2510
  Genie Serve`),console.log("\u2500".repeat(50)),console.log(` Status: ${running2?"running":"stopped"}`),running2&&entry2)console.log(` PID: ${entry2.pid}`);await printPgserveStatus(),printTmuxStatus(),await printDaemonStatus(running2),await printBridgeStatus(),console.log(` PID file: ${servePidPath()}`),console.log("")}async function runStartPreconditions(autoFix,log2){if(process.env.GENIE_SKIP_PRECONDITIONS==="1")return!0;let{ensureServeReady:ensureServeReady2}=await Promise.resolve().then(() => (init_ensure_ready(),exports_ensure_ready)),report=await ensureServeReady2({autoFix,deps:log2?{log:log2}:void 0});if(autoFix)return!0;if(!report.ok){if(log2)log2("genie serve start refused: one or more preconditions are not ok (--no-fix mode).");else console.error("genie serve start refused: one or more preconditions are not ok (--no-fix mode).");return!1}return!0}function registerServeCommands(program2){let serve=program2.command("serve").description("Start all genie infrastructure (pgserve, tmux, scheduler)");serve.command("start",{isDefault:!0}).description("Start genie serve").option("--daemon","Run in background").option("--foreground","Run in foreground (default)").option("--headless","Run without TUI (services only: pgserve, scheduler, inbox-watcher)").option("--no-fix","Refuse to start when any precondition is not ok (default: auto-fix)").action(async(options)=>{let autoFix=options.fix!==!1;if(options.daemon)await startBackground(options.headless,autoFix);else await startForeground(options.headless,autoFix)}),serve.command("stop").description("Stop genie serve and all services").action(async()=>{await stopServe()}),serve.command("status").description("Show service health").action(async()=>{await statusServe()})}var STOPPING_LOCK_TTL_MS=30000,TUI_SESSION="genie-tui",NAV_WIDTH=30,TUI_STYLE,handles;var init_serve=__esm(()=>{init_genie_tokens();init_brain_vaults();init_ensure_tmux();init_process_identity();init_tmux_wrapper();init_tui_disable();TUI_STYLE={activeBorder:palette.borderActive,inactiveBorder:palette.border};handles={schedulerHandle:null,agentWatcher:null,brainHandles:[],omniApprovalHandler:null,omniBridge:null,detectorScheduler:null,derivedSignals:null,hookSocket:null}});var exports_tmux2={};__export(exports_tmux2,{newAgentWindow:()=>newAgentWindow,hasProjectSession:()=>hasProjectSession,attachTuiSession:()=>attachTuiSession,attachProjectWindow:()=>attachProjectWindow});import{spawnSync as spawnSync6}from"child_process";function runTuiTmux(args,stdio="ignore"){return spawnSync6(TMUX_BIN,["-L",TMUX_SOCKET,"-f",TUI_TMUX_CONF,...args],{stdio})}function runTuiTmuxOutput(args){let result2=spawnSync6(TMUX_BIN,["-L",TMUX_SOCKET,"-f",TUI_TMUX_CONF,...args],{encoding:"utf-8"});return result2.status===0?result2.stdout.trim():null}function runAgentTmux(args,stdio="ignore"){return spawnSync6(TMUX_BIN,["-L",GENIE_AGENT_SOCKET,...args],{stdio})}function shellQuote3(value){return`'${value.replace(/'/g,"'\\''")}'`}function buildAttachLoop(targetSession){return`while true; do TMUX='' ${[TMUX_BIN,"-L",GENIE_AGENT_SOCKET,"attach-session","-t",targetSession].map(shellQuote3).join(" ")} 2>/dev/null; sleep 0.3; done`}function resolveRightPane(rightPane){if(runTuiTmux(["display-message","-t",rightPane,"-p",""]).status===0)return rightPane;let panes=runTuiTmuxOutput(["list-panes","-t",`${SESSION_NAME}:0`,"-F","#{pane_id}"])?.split(`
2511
2511
  `)??[];return panes[1]||panes[0]||rightPane}function hasProjectSession(targetSession){return runAgentTmux(["has-session","-t",targetSession]).status===0}function attachProjectWindow(rightPane,targetSession,windowIndex){if(targetSession===SESSION_NAME)return;let pane=resolveRightPane(rightPane);if(!hasProjectSession(targetSession))return;if(windowIndex!==void 0)runAgentTmux(["select-window","-t",`${targetSession}:${windowIndex}`]);runAgentTmux(["set-option","-t",targetSession,"status","off"]),runTuiTmux(["respawn-pane","-k","-t",pane,"sh","-lc",buildAttachLoop(targetSession)]),runTuiTmux(["select-pane","-t",`${SESSION_NAME}:0.0`])}function attachTuiSession(){if(runTuiTmux(["select-pane","-t",`${SESSION_NAME}:0.0`]),process.env.TMUX)runTuiTmux(["switch-client","-t",SESSION_NAME],"inherit");else runTuiTmux(["attach-session","-t",SESSION_NAME],"inherit")}function nextRoleSuffix(baseName){let sessionName=baseName.replace(/\//g,"-"),output=spawnSync6(TMUX_BIN,["-L",GENIE_AGENT_SOCKET,"list-windows","-t",`=${sessionName}`,"-F","#{window_name}"],{encoding:"utf-8"}),names=output.status===0?output.stdout.trim().split(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/genie",
3
- "version": "4.260429.33",
3
+ "version": "4.260429.35",
4
4
  "description": "Collaborative terminal toolkit for human + AI workflows. NOTE: the npm distribution is being soft-deprecated — the canonical install is `curl -fsSL https://get.automagik.dev/genie | bash` (cosign + SLSA verified). See https://automagik.dev/genie/security/distribution-sovereignty",
5
5
  "type": "module",
6
6
  "bin": {
@@ -58,7 +58,7 @@
58
58
  "ignore": "7.0.5",
59
59
  "js-yaml": "4.1.1",
60
60
  "nats": "2.29.3",
61
- "pgserve": "^2.0.0",
61
+ "pgserve": "^2.0.2",
62
62
  "postgres": "3.4.9",
63
63
  "react": "19.2.5",
64
64
  "react-dom": "19.2.5",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genie",
3
- "version": "4.260429.33",
3
+ "version": "4.260429.35",
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.260429.33",
3
+ "version": "4.260429.35",
4
4
  "private": true,
5
5
  "description": "Runtime dependencies for genie bundled CLIs",
6
6
  "type": "module",