@automagik/genie 4.260429.7 → 4.260429.8

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
@@ -2482,9 +2482,10 @@ ${queryContent}`;let{messages:queryMessages}=state.provider.runQuery({agentId:se
2482
2482
  `);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=join55(home,"tui-launch.sh"),logsDir=join55(home,"logs"),crashLog=join55(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(`
2483
2483
  export `)}`,`exec ${bunPath} ${genieBin}`,""].join(`
2484
2484
  `);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(`
2485
- `).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:join56}=__require("path"),configPath2=join56(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{ensurePgserve:ensurePgserve2}=await Promise.resolve().then(() => (init_db(),exports_db)),port=await ensurePgserve2();console.log(` pgserve ready on port ${port}`);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}`)}}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=openSync4(path3,"wx",420);try{writeSync2(fd,payload)}finally{closeSync4(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})`),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 removePgservePortLockfile(){try{let lockfilePath=join55(genieHome3(),"pgserve.port");if(existsSync44(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(`
2485
+ `).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:join56}=__require("path"),configPath2=join56(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{ensurePgserve:ensurePgserve2}=await Promise.resolve().then(() => (init_db(),exports_db)),port=await ensurePgserve2();console.log(` pgserve ready on port ${port}`);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}`)}}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=openSync4(path3,"wx",420);try{writeSync2(fd,payload)}finally{closeSync4(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 removePgservePortLockfile(){try{let lockfilePath=join55(genieHome3(),"pgserve.port");if(existsSync44(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(`
2486
2486
  Shutting down genie serve...`),await stopHookSocketSafely(),await stopSchedulerHandles(),await stopOmniAndBrainServices(),killRegisteredServices(),!headless)killTuiSession();removePgservePortLockfile(),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)})}async function startForeground(headless){claimServePidOrExit(),removePgservePortLockfile();let{skipTui,mode}=resolveServeMode(headless);if(process.env.GENIE_IS_DAEMON="1",console.log(`genie serve starting (PID ${process.pid}, mode: ${mode})`),!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(`
2487
- 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){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",args=[process.argv[1]??"genie","serve","--foreground"];if(headless)args.push("--headless");let child=spawn4(bunPath,args,{detached:!0,stdio:"ignore",env:{...process.env,GENIE_IS_DAEMON:"1"}});if(child.unref(),child.pid)if(await new Promise((resolve10)=>setTimeout(resolve10,1000)),isProcessAlive(child.pid))console.log(`genie serve started (PID ${child.pid})`);else console.error("Error: genie serve exited immediately."),process.exit(1);else console.error("Error: failed to spawn genie serve"),process.exit(1)}function forceRemoveServePid(){try{unlinkSync11(servePidPath())}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 resolveBrainPortFromWorkspace(brain){try{let{findWorkspace:findWorkspace2}=(init_workspace(),__toCommonJS(exports_workspace)),ws=findWorkspace2();if(ws?.root&&brain.readServerInfo){let info=brain.readServerInfo(join55(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(),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=join55(genieHome3(),"scheduler.pid");if(existsSync44(schedulerPidPath)){let sPid=Number.parseInt(readFileSync26(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(`
2487
+ 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){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",args=[process.argv[1]??"genie","serve","--foreground"];if(headless)args.push("--headless");let child=spawn4(bunPath,args,{detached:!0,stdio:"ignore",env:{...process.env,GENIE_IS_DAEMON:"1"}});if(child.unref(),child.pid)if(await new Promise((resolve10)=>setTimeout(resolve10,1000)),isProcessAlive(child.pid))console.log(`genie serve started (PID ${child.pid})`);else console.error("Error: genie serve exited immediately."),process.exit(1);else console.error("Error: failed to spawn genie serve"),process.exit(1)}function forceRemoveServePid(){try{unlinkSync11(servePidPath())}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??join55(genieHome3(),"hook.sock")}function warnIfHookSocketMissing(){let sock=hookSocketPath();if(existsSync44(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(`
2488
+ `))}function printHookSocketStatus(){let sock=hookSocketPath();if(existsSync44(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(join55(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=join55(genieHome3(),"scheduler.pid");if(existsSync44(schedulerPidPath)){let sPid=Number.parseInt(readFileSync26(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(`
2488
2489
  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){if(process.env.GENIE_SKIP_PRECONDITIONS==="1")return;let{ensureServeReady:ensureServeReady2}=await Promise.resolve().then(() => (init_ensure_ready(),exports_ensure_ready)),report=await ensureServeReady2({autoFix});if(autoFix)return;if(!report.ok)console.error("genie serve start refused: one or more preconditions are not ok (--no-fix mode)."),process.exit(2)}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(await runStartPreconditions(autoFix),options.daemon)await startBackground(options.headless);else await startForeground(options.headless)}),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(`
2489
2490
  `)??[];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(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(`
2490
2491
  `):[],max=names.length+1,re=new RegExp(`^${baseName}-(\\d+)$`);for(let n of names){let m=n.match(re);if(m)max=Math.max(max,Number.parseInt(m[1],10)+1)}return max}function newAgentWindow(agentName){(async()=>{try{let{reconcileStaleSpawns:reconcileStaleSpawns2}=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry));await reconcileStaleSpawns2()}catch{}let{spawn:spawn5}=__require("child_process"),{join:join56,resolve:resolve10}=__require("path"),{existsSync:existsSync45}=__require("fs"),bunPath=process.execPath||"bun",genieBin=process.argv[1],wsRoot=process.env.GENIE_TUI_WORKSPACE,cwd;if(wsRoot){let parentName=agentName.includes("/")?agentName.slice(0,agentName.indexOf("/")):agentName,agentDir=resolve10(join56(wsRoot,"agents",parentName));if(existsSync45(agentDir))cwd=agentDir}let suffix=nextRoleSuffix(agentName),role=`${agentName}-${suffix}`,sessionName=agentName.replace(/\//g,"-"),args=["spawn",agentName,"--role",role,"--session",sessionName,"--new-window"];(genieBin&&genieBin!=="genie"?spawn5(bunPath,[genieBin,...args],{detached:!0,stdio:"ignore",cwd}):spawn5("genie",args,{detached:!0,stdio:"ignore",cwd})).unref()})()}var SESSION_NAME="genie-tui",TMUX_SOCKET="genie-tui",GENIE_AGENT_SOCKET="genie",TUI_TMUX_CONF,TMUX_BIN;var init_tmux2=__esm(()=>{init_ensure_tmux();TUI_TMUX_CONF=(()=>{let{existsSync:existsSync45}=__require("fs"),tuiConf=`${process.env.GENIE_HOME??`${process.env.HOME}/.genie`}/tui-tmux.conf`;return existsSync45(tuiConf)?tuiConf:"/dev/null"})(),TMUX_BIN=tmuxBin()});function s(orgId,path3){return`khal.${orgId}.genie.${path3}`}var GENIE_SUBJECTS;var init_subjects=__esm(()=>{GENIE_SUBJECTS={dashboard:{stats:(orgId)=>s(orgId,"dashboard.stats")},agents:{list:(orgId)=>s(orgId,"agents.list"),show:(orgId)=>s(orgId,"agents.show")},sessions:{list:(orgId)=>s(orgId,"sessions.list"),content:(orgId)=>s(orgId,"sessions.content"),search:(orgId)=>s(orgId,"sessions.search")},tasks:{list:(orgId)=>s(orgId,"tasks.list"),show:(orgId)=>s(orgId,"tasks.show")},boards:{list:(orgId)=>s(orgId,"boards.list"),show:(orgId)=>s(orgId,"boards.show")},costs:{summary:(orgId)=>s(orgId,"costs.summary"),sessions:(orgId)=>s(orgId,"costs.sessions"),tokens:(orgId)=>s(orgId,"costs.tokens"),efficiency:(orgId)=>s(orgId,"costs.efficiency")},schedules:{list:(orgId)=>s(orgId,"schedules.list"),history:(orgId)=>s(orgId,"schedules.history")},system:{health:(orgId)=>s(orgId,"system.health"),snapshots:(orgId)=>s(orgId,"system.snapshots"),tables:(orgId)=>s(orgId,"system.tables"),channels:(orgId)=>s(orgId,"system.channels")},settings:{get:(orgId)=>s(orgId,"settings.get"),set:(orgId)=>s(orgId,"settings.set"),templates:(orgId)=>s(orgId,"settings.templates"),templateSave:(orgId)=>s(orgId,"settings.templates.save"),skills:(orgId)=>s(orgId,"settings.skills"),rules:(orgId)=>s(orgId,"settings.rules"),workspace:(orgId)=>s(orgId,"settings.workspace"),testPg:(orgId)=>s(orgId,"settings.test_pg")},pty:{create:(orgId)=>s(orgId,"pty.create"),input:(orgId,sessionId)=>s(orgId,`pty.${sessionId}.input`),data:(orgId,sessionId)=>s(orgId,`pty.${sessionId}.data`),resize:(orgId,sessionId)=>s(orgId,`pty.${sessionId}.resize`),kill:(orgId,sessionId)=>s(orgId,`pty.${sessionId}.kill`)},fs:{list:(orgId)=>s(orgId,"fs.list"),read:(orgId)=>s(orgId,"fs.read"),write:(orgId)=>s(orgId,"fs.write")},approval:{resolve:(orgId)=>s(orgId,"approval.resolve"),list:(orgId)=>s(orgId,"approval.list")},events:{agentState:(orgId)=>s(orgId,"events.agent_state"),executorState:(orgId)=>s(orgId,"events.executor_state"),taskStage:(orgId)=>s(orgId,"events.task_stage"),runtime:(orgId)=>s(orgId,"events.runtime"),audit:(orgId)=>s(orgId,"events.audit"),message:(orgId)=>s(orgId,"events.message"),mailbox:(orgId)=>s(orgId,"events.mailbox"),taskDep:(orgId)=>s(orgId,"events.task_dep"),trigger:(orgId)=>s(orgId,"events.trigger"),approvalRequest:(orgId)=>s(orgId,"events.approval_request"),approvalResolved:(orgId)=>s(orgId,"events.approval_resolved")}}});function emit2(event){for(let handler of listeners)handler(event)}async function startListening(nats,orgId){if(listenersActive)return;if(listenersActive=!0,nats)natsConn=nats,natsOrgId=orgId??"default";let sql=await getConnection();for(let mapping of CHANNEL_MAP){let listener=await sql.listen(mapping.channel,(payload)=>{let parsed;try{parsed=JSON.parse(payload)}catch{parsed={raw:payload}}if(emit2({type:mapping.eventType,payload:parsed}),natsConn){let subject=mapping.natsSubject(natsOrgId);natsConn.publish(subject,sc.encode(JSON.stringify(parsed)))}});stopFns.push(()=>listener.unlisten())}}async function stopListening(){listenersActive=!1,natsConn=null,await Promise.allSettled(stopFns.map((fn)=>fn())),stopFns=[]}var import_nats4,listeners,natsConn=null,natsOrgId="default",sc,CHANNEL_MAP,listenersActive=!1,stopFns;var init_pg_bridge=__esm(()=>{init_db();init_subjects();import_nats4=__toESM(require_mod4(),1),listeners=new Set;sc=import_nats4.StringCodec(),CHANNEL_MAP=[{channel:"genie_agent_state",eventType:"agent-state-changed",natsSubject:GENIE_SUBJECTS.events.agentState},{channel:"genie_executor_state",eventType:"executor-state-changed",natsSubject:GENIE_SUBJECTS.events.executorState},{channel:"genie_task_stage",eventType:"task-stage-changed",natsSubject:GENIE_SUBJECTS.events.taskStage},{channel:"genie_runtime_event",eventType:"runtime-event",natsSubject:GENIE_SUBJECTS.events.runtime},{channel:"genie_audit_event",eventType:"audit-event",natsSubject:GENIE_SUBJECTS.events.audit},{channel:"genie_message",eventType:"message",natsSubject:GENIE_SUBJECTS.events.message},{channel:"genie_mailbox_delivery",eventType:"mailbox-delivery",natsSubject:GENIE_SUBJECTS.events.mailbox},{channel:"genie_task_dep",eventType:"task-dep-changed",natsSubject:GENIE_SUBJECTS.events.taskDep},{channel:"genie_trigger_due",eventType:"trigger-due",natsSubject:GENIE_SUBJECTS.events.trigger},{channel:"genie_approval_request",eventType:"approval-request",natsSubject:GENIE_SUBJECTS.events.approvalRequest},{channel:"genie_approval_resolved",eventType:"approval-resolved",natsSubject:GENIE_SUBJECTS.events.approvalResolved}],stopFns=[]});import{randomUUID as randomUUID10}from"crypto";function onPtyData(cb){dataCallback=cb}function onPtyExit(cb){exitCallback=cb}async function spawnForAgent(agentName,opts={}){let{buildClaudeCommand:buildClaudeCommand3}=await Promise.resolve().then(() => (init_provider_adapters(),exports_provider_adapters)),{createExecutor:createExecutor2}=await Promise.resolve().then(() => (init_executor_registry(),exports_executor_registry)),{findOrCreateAgent:findOrCreateAgent2,setCurrentExecutor:setCurrentExecutor2}=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry)),cols=opts.cols??120,rows=opts.rows??40,cwd=opts.cwd??process.cwd(),launch=buildClaudeCommand3({provider:"claude",team:"app",role:"engineer",name:agentName}),agent=await findOrCreateAgent2(agentName,"app","engineer"),executor=await createExecutor2(agent.id,"app-pty","process",{repoPath:cwd,state:"spawning",metadata:{command:launch.command,source:"genie-app"}});await setCurrentExecutor2(agent.id,executor.id);let env={...process.env,...launch.env,GENIE_APP_PTY:"true"},session=spawnPty(launch.command,{cwd,cols,rows,env,agentId:agent.id,executorId:executor.id,taskId:opts.taskId??null}),{updateExecutorState:updateExecutorState2}=await Promise.resolve().then(() => (init_executor_registry(),exports_executor_registry));return await updateExecutorState2(executor.id,"running"),session}function spawnBash(cwd){let shell=process.env.SHELL??"/bin/bash";return spawnPty(shell,{cwd:cwd??process.cwd(),cols:120,rows:40,env:process.env,agentId:null,executorId:null,taskId:null})}function writeTerminal(sessionId,data){let session=sessions.get(sessionId);if(!session||session.state!=="running")return!1;return session.pty.write(data),!0}function resizeTerminal(sessionId,cols,rows){let session=sessions.get(sessionId);if(!session||session.state!=="running")return!1;return session.pty.resize(cols,rows),session.cols=cols,session.rows=rows,!0}async function killTerminal(sessionId){let session=sessions.get(sessionId);if(!session)return!1;if(session.pty.kill(),session.state="exited",session.executorId)try{let{updateExecutorState:updateExecutorState2}=await Promise.resolve().then(() => (init_executor_registry(),exports_executor_registry));await updateExecutorState2(session.executorId,"terminated")}catch{}return sessions.delete(sessionId),!0}async function killAll(){let ids=[...sessions.keys()];await Promise.allSettled(ids.map((id)=>killTerminal(id)))}async function pipeStdout(stdout,sessionId,ptyHandle){let reader=stdout.getReader(),decoder=new TextDecoder;try{while(!0){let{done,value}=await reader.read();if(done)break;let text=decoder.decode(value);if(dataCallback)dataCallback(sessionId,text);if(ptyHandle.onData)ptyHandle.onData(text)}}catch{}}function onProcExit(sessionId,code,ptyHandle){let session=sessions.get(sessionId);if(session)session.state="exited";if(exitCallback)exitCallback(sessionId,code);if(ptyHandle.onExit)ptyHandle.onExit(code);handlePtyExit(sessionId,code)}function spawnPty(command,opts){let sessionId=randomUUID10(),ptyHandle;try{let bunPty=(()=>{throw new Error("Cannot require module "+"bun-pty");})(),parts=command.split(" "),raw=bunPty.spawn(parts,{cwd:opts.cwd,env:opts.env,cols:opts.cols,rows:opts.rows});ptyHandle={write:(data)=>raw.write(data),resize:(cols,rows)=>raw.resize(cols,rows),kill:()=>raw.kill(),onData:null,onExit:null},raw.onData=(data)=>{if(dataCallback)dataCallback(sessionId,data);if(ptyHandle.onData)ptyHandle.onData(data)},raw.onExit=(code)=>{let session2=sessions.get(sessionId);if(session2)session2.state="exited";if(exitCallback)exitCallback(sessionId,code);if(ptyHandle.onExit)ptyHandle.onExit(code);handlePtyExit(sessionId,code)}}catch{let parts=command.split(" "),proc=Bun.spawn(parts,{cwd:opts.cwd,env:opts.env,stdin:"pipe",stdout:"pipe",stderr:"pipe"});ptyHandle={write:(data)=>proc.stdin.write(data),resize:()=>{},kill:()=>proc.kill(),onData:null,onExit:null},pipeStdout(proc.stdout,sessionId,ptyHandle),proc.exited.then((code)=>onProcExit(sessionId,code,ptyHandle))}let session={id:sessionId,pty:ptyHandle,agentId:opts.agentId,executorId:opts.executorId,taskId:opts.taskId,command,state:"running",cols:opts.cols,rows:opts.rows,createdAt:new Date().toISOString()};return sessions.set(sessionId,session),session}function handlePtyExit(sessionId,code){let session=sessions.get(sessionId);if(!session?.executorId)return;(async()=>{try{let{updateExecutorState:updateExecutorState2}=await Promise.resolve().then(() => (init_executor_registry(),exports_executor_registry));await updateExecutorState2(session.executorId,code===0?"done":"error")}catch{}})()}var sessions,dataCallback=null,exitCallback=null;var init_pty=__esm(()=>{sessions=new Map});var exports_src_backend={};import{existsSync as existsSync45,readFileSync as readFileSync27,readdirSync as readdirSync10,writeFileSync as writeFileSync17}from"fs";import{homedir as homedir37}from"os";import{join as join56,resolve as resolve10}from"path";function findSkillsDir(){let genieHome4=process.env.GENIE_HOME??join56(homedir37(),".genie"),candidateDirs=[join56(process.cwd(),"skills"),join56(genieHome4,"..","skills")];for(let d of candidateDirs)if(existsSync45(d))return d;return null}function parseSkillMd(content,fallbackName){let descMatch=content.match(/^description:\s*["']?(.+?)["']?\s*$/m),description="";if(descMatch)description=descMatch[1].trim();else description=content.split(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/genie",
3
- "version": "4.260429.7",
3
+ "version": "4.260429.8",
4
4
  "description": "Collaborative terminal toolkit for human + AI workflows. NOTE: the npm distribution is being soft-deprecated — the canonical install is `curl -fsSL https://get.automagik.dev/genie | bash` (cosign + SLSA verified). See https://automagik.dev/genie/security/distribution-sovereignty",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genie",
3
- "version": "4.260429.7",
3
+ "version": "4.260429.8",
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.7",
3
+ "version": "4.260429.8",
4
4
  "private": true,
5
5
  "description": "Runtime dependencies for genie bundled CLIs",
6
6
  "type": "module",