@gencode/cli 0.8.9 → 0.8.10

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @gencode/cli
2
2
 
3
+ ## 0.8.10
4
+
5
+ ### Patch Changes
6
+
7
+ - 61997a5: Fix encrypted history migration being permanently skipped when `.aimax` contains only log files
8
+
9
+ When `--encrypt-sessions` is disabled and `.aimax.enc` exists with encrypted history, the CLI now correctly migrates data to plaintext `.aimax` even if the logger has already created `app.log` or `errors.log` in that directory. Previously, these incidental log files caused the migration to be silently skipped, making encrypted history permanently inaccessible until the log files were manually removed.
10
+
3
11
  ## 0.8.9
4
12
 
5
13
  ### Patch Changes
package/dist/bin.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{a as e,i as t,r as n,t as r}from"./program-BTLD1DwI.js";function i(){globalThis.getPkgPath||(globalThis.getPkgPath=()=>`@wizard/aimax`)}i();const a=Date.now(),o=process.env.AIMAX_DATA_DIR,s=process.argv.includes(`run`)&&process.argv.includes(`--encrypt-sessions`);o&&!s&&n(o),t.info(`AIMax CLI starting (pid=${process.pid})`,{dataDir:o,encryptedRun:s,loggerDeferred:!!(o&&s)}),r().parseAsync(process.argv).catch(e=>{t.error(`Unexpected error: ${e.message}`),process.exit(1)}).finally(()=>{let n=Date.now()-a;return t.info(`AIMax CLI exited (total uptime: ${n}ms)`),e()});export{};
2
+ import{a as e,i as t,r as n,t as r}from"./program-C2WFt_WL.js";function i(){globalThis.getPkgPath||(globalThis.getPkgPath=()=>`@wizard/aimax`)}i();const a=Date.now(),o=process.env.AIMAX_DATA_DIR,s=process.argv.includes(`run`)&&process.argv.includes(`--encrypt-sessions`);o&&!s&&n(o),t.info(`AIMax CLI starting (pid=${process.pid})`,{dataDir:o,encryptedRun:s,loggerDeferred:!!(o&&s)}),r().parseAsync(process.argv).catch(e=>{t.error(`Unexpected error: ${e.message}`),process.exit(1)}).finally(()=>{let n=Date.now()-a;return t.info(`AIMax CLI exited (total uptime: ${n}ms)`),e()});export{};
@@ -0,0 +1,15 @@
1
+ import{createRequire as e}from"node:module";import{Command as t}from"commander";import{GoalConflictError as n,applyCliGoalBeforeRun as r,bootstrapMountLayout as i,buildAimaxGoalCliHelpExtra as a,buildResumeNarration as o,clearPendingUiTool as s,createBuiltinMemoryProvider as c,deleteGoal as l,ensureBootstrapMountLayout as u,exportSession as d,formatApprovalResolution as f,formatClarifyResolution as p,formatReviewResolution as m,hasBootstrapSentinel as h,initializePluginSystem as g,inspectSession as _,listAvailableSlashCommands as v,listSessionSummaries as ee,loadPendingHitl as te,loadPendingUiTool as ne,loadSkillsWithPluginDirs as re,loadTranscript as ie,normalizePluginsConfig as ae,normalizeSessionStoreName as y,readGoal as b,resolveGoalObjective as oe,resolveMemoryProvider as se,resolvePendingHitl as ce,resolvePendingUiTool as le,rewriteTranscript as ue,runAgent as x,updateGoal as de,writeGoal as fe}from"@gencode/agents";import{formatTaskForDisplay as pe,isAgentDiagnosticEvent as me,isHitlTool as he,parseMatchedTextToResolution as ge,parseTextToResolution as _e}from"@gencode/shared";import S from"node:fs/promises";import C from"node:fs";import w from"node:path";import ve from"node:os";import{execFile as ye,execFileSync as be}from"node:child_process";import xe from"log4js";import Se from"gensign-node";import{fileURLToPath as Ce}from"node:url";import{addAgent as we,addBinding as Te,getAgentConfig as T,listAgents as Ee,listBindings as De,loadAgentsConfig as E,normalizeAgentId as Oe,removeAgent as ke,removeBindings as Ae,resolveAgentDir as je,resolveDefaultAgentId as D,updateAgentIdentity as Me}from"@gencode/agents/config";import{randomUUID as Ne}from"node:crypto";function Pe(e){if(typeof e==`string`)return e;let t=JSON.stringify(e);return t===void 0?String(e):t}function Fe(e){process.stdout.write(e)}function O(e){process.stdout.write(e+`
2
+ `)}function k(e){process.stderr.write(e+`
3
+ `)}function A(e){switch(e.type){case`start`:O(`\n[start] ${e.message}`);break;case`text`:Fe(e.text);break;case`stream_text_delta`:Fe(e.text);break;case`bootstrap`:O(`\n[bootstrap:${e.phase}] ${e.dataDir}`);break;case`session_reset`:O(`\n[session:${e.action}] ${e.message}`);break;case`tool_start`:O(`\n[tool:${e.name}] ${JSON.stringify(e.input??{})}`);break;case`tool_end`:{let t=Pe(e.output);O(`[tool:${e.name}] ${e.isError?`ERROR`:`OK`} ${t.slice(0,200)}`);break}case`compaction`:O(`\n[compaction${e.layer?`:${e.layer}`:``}] ${e.reason}${e.strategy?` (${e.strategy})`:``}`);break;case`skill_used`:O(`\n[skill] ${e.skillName} agent=${e.agent} task=${e.taskId}`);break;case`custom`:O(`\n[plugin:${e.pluginId}] ${e.name}${e.label?` ${e.label}`:``}${e.data?` ${JSON.stringify(e.data)}`:``}`);break;case`error`:k(`\n[error] ${e.message}`);break;case`diagnostic`:break;case`subagent_spawn`:O(`\n[subagent:spawn]${e.label?` "${e.label}"`:``} ${pe(e.task)}`);break;case`subagent_complete`:O(`[subagent:${e.status}] ${pe(e.task)}`);break;case`hitl_requested`:if(O(`\n[hitl:${e.request.kind}] ${e.request.title}`),O(` prompt: ${e.request.prompt}`),O(` requestId: ${e.request.requestId}`),e.request.input.mode===`choice`)for(let t of e.request.input.choices)O(` - [${t.id}] ${t.label}`);break;case`hitl_resumed`:O(`\n[hitl:resumed] requestId=${e.requestId} action=${e.resolution.action}`);break;case`hitl_expired`:O(`\n[hitl:expired] requestId=${e.requestId} reason=${e.reason}`);break;case`hitl_cancelled`:O(`\n[hitl:cancelled] requestId=${e.requestId}${e.reason?` reason=${e.reason}`:``}`);break;case`ui_tool_request`:O(`\n[ui-tool:${e.request.toolName}] ${e.request.outputSchema.title}`),O(` requestId: ${e.request.requestId}`),O(` toolCallId: ${e.request.toolCallId}`);break;case`ui_tool_result`:O(`\n[ui-tool:resumed] requestId=${e.requestId} tool=${e.toolName}`);break}}function Ie(e,t){if(t===`json`){e&&O(JSON.stringify(e,null,2));return}O(`
4
+ `),O(`session: ${e.sessionId}`),O(`duration: ${e.durationMs}ms`),O(`tokens: input=${e.usage.input} output=${e.usage.output} total=${e.usage.total}`),e.context&&(O(`context: ${e.context.snapshotPath}`),O(`tool-results: ${e.context.toolResultsDir}`)),e.error&&k(`error: ${e.error}`)}function Le(e,t){if(t===`json`){O(JSON.stringify(e,null,2));return}if(e.length===0){O(`No sessions found.`);return}for(let t of e){let e=t.createdAt?new Date(t.createdAt).toLocaleString():`unknown`,n=t.goalStatus?` [GOAL:${t.goalStatus}]`:` [GOAL:—]`;O(`${t.id} ${e} [${t.channel}]${n} ${t.title}`)}}function Re(e,t){if(t===`json`){O(JSON.stringify(e,null,2));return}O(`session: ${e.id}`),e.metadata&&(O(`title: ${e.metadata.title}`),O(`channel: ${e.metadata.channel}`),O(`created: ${e.metadata.createdAt}`),O(`updated: ${e.metadata.updatedAt}`)),O(`transcript: ${e.transcriptPath}`),O(`entries: ${e.transcriptEntryCount}`),O(`context: ${e.contextSnapshotPath}`),O(`session-memory: ${e.sessionMemoryPath}`),O(`collapse-log: ${e.collapseLogPath}`),O(`read-states: ${e.readStateCount}`),O(`tool-results: ${e.toolResultRefCount}`),O(`tool-results-dir: ${e.toolResultsDir}`)}function ze(e,t){if(t===`json`){O(JSON.stringify(e,null,2));return}O(`session: ${e.id}`),O(`transcript: ${e.paths.transcriptPath}`),O(`context: ${e.paths.contextSnapshotPath}`),O(`session-memory: ${e.paths.sessionMemoryPath}`),O(`collapse-log: ${e.paths.collapseLogPath}`),O(`tool-results-dir: ${e.paths.toolResultsDir}`),O(`transcript-entries: ${e.transcript.length}`),O(`read-states: ${e.context.readStates.length}`),O(`tool-results: ${e.context.toolResults.length}`),O(`collapse-spans: ${e.context.compaction.collapseSpans.length}`)}function Be(e,t){if(t===`json`){O(JSON.stringify(e,null,2));return}O(`Bootstrap completed.`),O(`dataDir: ${e.dataDir}`),O(`created dirs: ${e.createdDirs.length}`),O(`created files: ${e.createdFiles.length}`),O(`skipped dirs: ${e.skippedDirs.length}`),O(`skipped files: ${e.skippedFiles.length}`)}function Ve(e){let t=new Intl.DateTimeFormat(`en-CA`,{timeZone:`Asia/Shanghai`,year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1}).formatToParts(e);return Object.fromEntries(t.map(e=>[e.type,e.value]))}function He(e=new Date){let t=Ve(e),n=String(e.getMilliseconds()).padStart(3,`0`);return`${t.year}-${t.month}-${t.day} ${t.hour}:${t.minute}:${t.second}.${n}`}let j=function(e){return e.INFO=`INFO`,e.ERROR=`ERROR`,e.WARN=`WARN`,e}({}),M=null;function Ue(){return He()}function We(e){if(!e)return``;let t=Object.entries(e).filter(([,e])=>e!==void 0).map(([e,t])=>`${e}=${Ge(t)}`);return t.length>0?` ${t.join(` `)}`:``}function Ge(e){return JSON.stringify(Ke(e,new WeakSet))??`undefined`}function Ke(e,t){return typeof e==`bigint`?e.toString():e==null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`?e:e instanceof Error?{name:e.name,message:e.message,stack:e.stack}:typeof e!=`object`&&typeof e!=`function`?String(e):t.has(e)?`[Circular]`:(t.add(e),Array.isArray(e)?e.map(e=>Ke(e,t)):Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0).map(([e,n])=>[e,Ke(n,t)])))}function qe(e){return w.join(e,`.aimax`)}function Je(e){return{appLogPath:w.join(e,`app.log`),errorLogPath:w.join(e,`errors.log`)}}function Ye(e){let{appLogPath:t,errorLogPath:n}=Je(e);xe.configure({appenders:{appFile:{type:`file`,filename:t,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`messagePassThrough`}},errorFile:{type:`file`,filename:n,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`messagePassThrough`}},errorsOnly:{type:`logLevelFilter`,appender:`errorFile`,level:`error`,maxLevel:`fatal`}},categories:{default:{appenders:[`appFile`,`errorsOnly`],level:`info`}}})}function Xe(e,t,n){return`[${Ue()}] [${e}] ${t}${We(n)}`}function Ze(e,t,n){process.stderr.write(`${Xe(e,t,n)}\n`)}function Qe(e,t,n){if(!M){Ze(e,t,n);return}let r=Xe(e,t,n),i=xe.getLogger();if(e===j.ERROR){i.error(r);return}if(e===j.WARN){i.warn(r);return}i.info(r)}function N(e){let t=qe(e);C.mkdirSync(t,{recursive:!0}),Ye(t),M={dataDir:e,logDir:t}}function $e(){return M?{...M}:null}async function et(){await xe.shutdown()}const P={info:(e,t)=>Qe(j.INFO,e,t),warn:(e,t)=>Qe(j.WARN,e,t),error:(e,t)=>Qe(j.ERROR,e,t)};var F=class{startTime;name;constructor(e){this.name=e,this.startTime=Date.now()}end(){let e=Date.now()-this.startTime;return P.info(`${this.name} completed in ${e}ms`),e}};const tt=`.aimax`,nt=`${tt}.pre-gocryptfs.`,rt=[`app.log`,`errors.log`],it=[`fusermount3`,`fusermount`,`umount`],at=[{command:`fusermount3`,args:[`-u`],label:`fusermount3 -u`},{command:`fusermount3`,args:[`-uz`],label:`fusermount3 -uz`},{command:`fusermount`,args:[`-u`],label:`fusermount -u`},{command:`fusermount`,args:[`-uz`],label:`fusermount -uz`},{command:`umount`,args:[],label:`umount`},{command:`umount`,args:[`-l`],label:`umount -l`}];function ot(e){return w.join(e,`.aimax.enc`)}function st(e){return w.join(e,tt)}function ct(e){return w.join(e,`${nt}${process.pid}.${Date.now()}`)}function lt(e){return w.join(e,`${tt}.plaintext-restore.${process.pid}.${Date.now()}`)}function ut(e){return e.replace(/\\([0-7]{3})/g,(e,t)=>String.fromCharCode(Number.parseInt(t,8)))}async function I(e){try{let t=await pt.read(),n=w.resolve(e);for(let e of t.split(`
5
+ `)){if(!e.trim())continue;let t=e.split(` `);if(t.length>=5&&w.resolve(ut(t[4]??``))===n)return!0}return!1}catch{return!1}}function dt(e){try{let t=C.readFileSync(`/proc/self/mountinfo`,`utf-8`),n=w.resolve(e);for(let e of t.split(`
6
+ `)){if(!e.trim())continue;let t=e.split(` `);if(t.length>=5&&w.resolve(ut(t[4]??``))===n)return!0}return!1}catch{return!1}}async function ft(){return await S.readFile(`/proc/self/mountinfo`,`utf-8`)}const pt={read:ft};async function L(e){try{return await S.stat(e),!0}catch(e){if(e.code===`ENOENT`)return!1;throw e}}async function R(e){await S.mkdir(e,{recursive:!0})}async function mt(e){if(await R(e),(await S.readdir(e)).length>0)throw Error(`Refusing to mount encrypted .aimax over non-empty directory: ${e}. Clear stale plaintext files or disable --encrypt-sessions for this run.`)}async function z(e){return await L(e)?(await S.readdir(e)).length===0:!0}async function B(e){if(await L(e))return(await S.readdir(e)).length}async function ht(e){return await L(e)?(await S.readdir(e)).some(e=>!rt.some(t=>e.startsWith(t))):!1}async function gt(e){let t=await S.readdir(e);for(let n of t)rt.some(e=>n.startsWith(e))&&await S.rm(w.join(e,n),{force:!0}).catch(()=>{})}async function _t(e){if(!await L(w.join(e,`gocryptfs.conf`)))throw Error(`Encrypted .aimax directory exists but is not initialized: ${e}. Remove the incomplete .aimax.enc directory or restore it from backup before retrying --encrypt-sessions.`)}async function vt(e){return(await S.readdir(e,{withFileTypes:!0})).filter(e=>e.isDirectory()&&e.name.startsWith(nt)).map(t=>w.join(e,t.name)).sort()}async function V(e,t){if(!await L(t))return null;let n=ct(e);return P.info(`--encrypt-sessions moving plaintext .aimax aside before migration`,{plainDir:t,backupDir:n}),await S.rename(t,n),n}async function H(e,t,n){P.info(`--encrypt-sessions copying plaintext backup into encrypted mount`,{backupDir:e,plainDir:t,force:n}),await S.cp(e,t,{recursive:!0,force:n})}async function yt(e,t){if(e.length===0)return[];await R(t);let n=[];for(let r of e)await L(r)&&(await H(r,t,!0),await S.rm(r,{recursive:!0,force:!0}),P.info(`--encrypt-sessions restored interrupted plaintext backup after failed migration`,{backupDir:r,plainDir:t}),n.push(r));return n}async function bt(e){let t=ot(e),n=st(e),r=await L(t);if(!r)return;let i=r&&await L(w.join(t,`gocryptfs.conf`)),a=await L(n),o=a?await I(n):!1,s=await z(n);if(P.info(`plaintext .aimax restore check for disabled --encrypt-sessions`,{dataDir:e,encryptedDir:t,plainDir:n,encryptedDirExists:r,encryptedDirInitialized:i,plainDirExists:a,plainDirMountPoint:o,plainDirEntryCount:await B(n)}),!i){P.warn(`plaintext .aimax restore skipped because .aimax.enc is not initialized`,{encryptedDir:t,plainDir:n}),await R(n);return}if(o){P.warn(`plaintext .aimax restore skipped because .aimax is already a mount point`,{plainDir:n,encryptedDir:t});return}if(await ht(n)){P.info(`plaintext .aimax restore skipped because plaintext .aimax already contains data`,{plainDir:n,encryptedDir:t,plainDirEntryCount:await B(n)});return}s||(P.info(`plaintext .aimax clearing ephemeral files before restore`,{plainDir:n,encryptedDir:t,plainDirEntryCount:await B(n)}),await gt(n));try{await Ct()}catch(e){P.warn(`plaintext .aimax restore unavailable; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e),plainDir:n,encryptedDir:t}),await R(n);return}let c=lt(e),l=!1;try{await mt(n),await wt(t,n),l=!0,await S.rm(c,{recursive:!0,force:!0}),await R(c),await S.cp(n,c,{recursive:!0,force:!0}),P.info(`plaintext .aimax restore copied encrypted history to staging directory`,{plainDir:n,encryptedDir:t,restoreDir:c,restoredEntryCount:await B(c)}),await Et(n),l=!1,await S.rm(n,{recursive:!0,force:!0}),await S.rename(c,n),P.info(`plaintext .aimax restore completed for disabled --encrypt-sessions`,{plainDir:n,encryptedDir:t})}catch(e){l&&await Et(n).catch(e=>{P.warn(`plaintext .aimax restore failed to unmount during rollback`,{error:e instanceof Error?e.message:String(e),plainDir:n,encryptedDir:t})}),await S.rm(c,{recursive:!0,force:!0}).catch(()=>{}),await R(n).catch(()=>{}),P.warn(`plaintext .aimax restore failed; continuing with existing plaintext .aimax`,{error:e instanceof Error?e.message:String(e),plainDir:n,encryptedDir:t})}}async function xt(e){let t=w.join(ve.tmpdir(),`aimax-gocryptfs-pass.${process.pid}.${Date.now()}`);await S.writeFile(t,`wizard_aimax@2026
7
+ `,{mode:384});try{return await e(t)}finally{await S.rm(t,{force:!0})}}async function St(e){let t=e.includes(`-init`)?`init`:`mount`;P.info(`--encrypt-sessions starting gocryptfs ${t}`);try{await At(`gocryptfs`,e),P.info(`--encrypt-sessions completed gocryptfs ${t}`)}catch(n){let r=n instanceof Error?n.message:String(n);throw P.warn(`--encrypt-sessions failed gocryptfs ${t}`,{error:r}),Error(`gocryptfs ${e.join(` `)} failed: ${r}`)}}async function Ct(){P.info(`--encrypt-sessions checking encryption dependencies`),await Mt(`gocryptfs`,`required for --encrypt-sessions`),P.info(`--encrypt-sessions dependency available`,{command:`gocryptfs`});for(let e of it)if(await jt(e)){P.info(`--encrypt-sessions unmount dependency available`,{command:e});return}throw Error(`--encrypt-sessions requires one of ${it.join(`, `)} to be installed for secure unmount cleanup.`)}async function wt(e,t){P.info(`--encrypt-sessions mounting encrypted .aimax`,{encryptedDir:e,plainDir:t}),await xt(async n=>{await St([`-q`,`-passfile`,n,e,t])})}async function Tt(e){P.info(`--encrypt-sessions initializing encrypted .aimax directory`,{encryptedDir:e}),await xt(async t=>{await St([`-q`,`-init`,`-passfile`,t,e])})}async function Et(e){let t=[];P.info(`--encrypt-sessions unmounting encrypted .aimax`,{plainDir:e});for(let n of at)try{if(P.info(`--encrypt-sessions attempting encrypted .aimax unmount`,{command:n.label,plainDir:e}),await At(n.command,[...n.args,e]),!await I(e)){P.info(`--encrypt-sessions unmounted encrypted .aimax`,{command:n.label,plainDir:e});return}let r=`${n.label} returned success but ${e} is still mounted`;t.push(r),P.warn(`--encrypt-sessions unmount command returned success but mountpoint remains`,{command:n.label,plainDir:e})}catch(r){let i=Nt(n.label,r);t.push(i),P.warn(`--encrypt-sessions unmount attempt failed`,{command:n.label,plainDir:e,error:r instanceof Error?r.message:String(r)})}throw Error(`Failed to unmount ${e}: ${t.join(`; `)}`)}function Dt(e){for(let t of at)try{if(be(t.command,[...t.args,e],{stdio:`ignore`}),!dt(e))return}catch{}}function Ot(e){let t=!1,n=()=>{t||(t=!0,Dt(e))},r=()=>n(),i=()=>{n(),process.exit(130)},a=()=>{n(),process.exit(143)};return process.once(`exit`,r),process.once(`SIGINT`,i),process.once(`SIGTERM`,a),{release(){process.removeListener(`exit`,r),process.removeListener(`SIGINT`,i),process.removeListener(`SIGTERM`,a)}}}async function kt(e){let t=ot(e),n=st(e),r=await L(n),i=await L(t),a=i&&await L(w.join(t,`gocryptfs.conf`)),o=r?await I(n):!1;P.info(`--encrypt-sessions preparing encrypted .aimax mount`,{dataDir:e,encryptedDir:t,plainDir:n,plainDirExists:r,encryptedDirExists:i,encryptedDirInitialized:a,plainDirMountPoint:o,plainDirEntryCount:await B(n),encryptedDirEntryCount:await B(t)});let s=()=>({mounted:!1,plainDir:n,encryptedDir:t,async cleanup(){}});try{await Ct()}catch(e){return P.warn(`--encrypt-sessions is unavailable; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e)}),await R(n),s()}if(await I(n))return P.warn(`--encrypt-sessions found existing .aimax mount; continuing without taking ownership`,{plainDir:n}),s();let c=null,l=[],u=null,d=null,f=!1;try{if(l=await vt(e),l.length>0&&P.warn(`--encrypt-sessions found interrupted pre-gocryptfs migration backups`,{count:l.length}),!await L(t))if(P.info(`--encrypt-sessions encrypted .aimax directory does not exist; starting first-time migration`,{encryptedDir:t,plainDir:n,resumedBackupCount:l.length}),l.length>0?u=await V(e,n):c=await V(e,n),await R(t),await Tt(t),await R(n),await wt(t,n),f=!0,d=Ot(n),P.info(`--encrypt-sessions mounted encrypted .aimax`,{plainDir:n,encryptedDir:t}),l.length>0){for(let e of l)await H(e,n,!0);u&&=(await H(u,n,!1),await S.rm(u,{recursive:!0,force:!0}),P.info(`--encrypt-sessions removed residual plaintext backup after migration`,{backupDir:u}),null);for(let e of l)await S.rm(e,{recursive:!0,force:!0}),P.info(`--encrypt-sessions removed resumed plaintext migration backup`,{backupDir:e});l=[]}else c&&=(await H(c,n,!0),await S.rm(c,{recursive:!0,force:!0}),P.info(`--encrypt-sessions removed plaintext migration backup`,{backupDir:c}),null);else if(P.info(`--encrypt-sessions encrypted .aimax directory exists; mounting existing encrypted data`,{encryptedDir:t,plainDir:n,resumedBackupCount:l.length,plainDirEntryCount:await B(n)}),await _t(t),l.length>0?u=await V(e,n):await z(n)||(c=await V(e,n)),await mt(n),await wt(t,n),f=!0,d=Ot(n),P.info(`--encrypt-sessions mounted encrypted .aimax`,{plainDir:n,encryptedDir:t}),l.length>0){for(let e of l)await H(e,n,!0);u&&=(await H(u,n,!1),await S.rm(u,{recursive:!0,force:!0}),P.info(`--encrypt-sessions removed residual plaintext backup after migration`,{backupDir:u}),null);for(let e of l)await S.rm(e,{recursive:!0,force:!0}),P.info(`--encrypt-sessions removed resumed plaintext migration backup`,{backupDir:e});l=[]}else c&&=(await H(c,n,!0),await S.rm(c,{recursive:!0,force:!0}),P.info(`--encrypt-sessions removed plaintext migration backup`,{backupDir:c}),null);return P.info(`--encrypt-sessions prepared encrypted .aimax mount result`,{mounted:f,plainDir:n,encryptedDir:t,plainDirMountPoint:await I(n),plainDirEntryCount:await B(n),encryptedDirEntryCount:await B(t)}),{mounted:f,plainDir:n,encryptedDir:t,async cleanup(){if(d?.release(),!f){P.info(`--encrypt-sessions cleanup skipped because encrypted .aimax is not mounted`,{plainDir:n,encryptedDir:t});return}f=!1,P.info(`--encrypt-sessions cleanup started`,{plainDir:n,encryptedDir:t});try{await Et(n),P.info(`--encrypt-sessions cleanup completed`,{plainDir:n,encryptedDir:t})}catch(e){P.warn(`--encrypt-sessions failed to unmount encrypted .aimax; continuing shutdown`,{error:e instanceof Error?e.message:String(e)})}}}}catch(e){d?.release(),f&&await Et(n).catch(e=>{P.warn(`--encrypt-sessions failed to unmount during mount rollback`,{error:e instanceof Error?e.message:String(e),plainDir:n,encryptedDir:t})}),c&&await L(c)&&await z(n)&&(await S.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await S.rename(c,n).catch(()=>{}),P.info(`--encrypt-sessions restored plaintext backup after failed migration`,{backupDir:c,plainDir:n})),u&&await L(u)&&await z(n)&&(await S.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await S.rename(u,n).catch(()=>{}),P.info(`--encrypt-sessions restored residual plaintext backup after failed migration`,{backupDir:u,plainDir:n}));let r=await yt(l,n).catch(e=>(P.warn(`--encrypt-sessions failed to restore interrupted plaintext backups after failed migration`,{error:e instanceof Error?e.message:String(e),plainDir:n,backupCount:l.length}),[]));return l=l.filter(e=>!r.includes(e)),P.warn(`--encrypt-sessions failed; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e),mountedBeforeFailure:f,plainDir:n,encryptedDir:t,backupDir:c,residualPlainBackupDir:u,resumedBackupCount:l.length}),await R(n),s()}}async function U(e,t,n){if(!t.encryptSessions)return await bt(e),n();P.info(`--encrypt-sessions wrapper starting encrypted .aimax preparation`,{dataDir:e});let r=await kt(e);P.info(`--encrypt-sessions wrapper prepared encrypted .aimax state`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir});try{return P.info(`--encrypt-sessions wrapper entering protected operation`,{dataDir:e,mounted:r.mounted}),await n(r)}finally{P.info(`--encrypt-sessions wrapper starting cleanup`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir}),await r.cleanup(),P.info(`--encrypt-sessions wrapper finished cleanup`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir})}}async function At(e,t){await new Promise((n,r)=>{ye(e,t,{encoding:`utf-8`},e=>{if(e){r(e);return}n()})})}async function jt(e){try{return await At(`sh`,[`-c`,`command -v "${e}" >/dev/null 2>&1`]),!0}catch{return!1}}async function Mt(e,t){if(!await jt(e))throw Error(`--encrypt-sessions requires ${e}: ${t}.`)}function Nt(e,t){return`${e} failed: ${t instanceof Error?t.message:String(t)}`}function Pt(e){e.command(`bootstrap`).description(`Initialize the data directory with required directories and templates`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{Be(await U(e.dataDir,e,async()=>i(e.dataDir)),t)}catch(e){k(`Error bootstrapping data directory: ${e.message}`),process.exit(1)}})}function Ft(e){return Se.sm4_encrypt_ecb(e)}function It(e){return Ft(e)}function Lt(e={}){let t=Rt(e.apiFormat??process.env.AIMAX_API_FORMAT),n=e.baseUrl??process.env.AIMAX_BASE_URL,r=process.env.AIMAX_AUTH_TOKEN,i=e.authToken?It(e.authToken):r?It(r):e.apiKey??process.env.AIMAX_API_KEY,a=e.model??process.env.AIMAX_MODEL,o=[];if(n||o.push(`--base-url / AIMAX_BASE_URL`),i||o.push(`--api-key / AIMAX_API_KEY`),a||o.push(`--model / AIMAX_MODEL`),o.length>0)throw Error(`Missing required LLM configuration: ${o.join(`, `)}`);return{apiFormat:t,baseUrl:n,apiKey:i,model:a,contextWindow:e.contextWindow??(process.env.AIMAX_CONTEXT_WINDOW?Number(process.env.AIMAX_CONTEXT_WINDOW):void 0),flashModel:e.flashModel??process.env.AIMAX_FLASH_MODEL}}function Rt(e){if(!e||e===`openai-completions`||e===`anthropic-messages`)return e;throw Error(`Unsupported LLM API format: ${e}`)}function zt(e,t){return t?w.resolve(t):w.join(e,`.aimax`,`plugins.json`)}async function W(e,t){let n=zt(e,t);try{let e=await S.readFile(n,`utf-8`);return JSON.parse(e)}catch(e){if(e.code===`ENOENT`)return;throw e}}async function G(e,t,n){let r=zt(e,n);await S.mkdir(w.dirname(r),{recursive:!0}),await S.writeFile(r,JSON.stringify(t,null,2),`utf-8`)}function K(e){return typeof e==`object`&&!!e}function Bt(e){return K(e)&&e.type===`text`&&typeof e.text==`string`&&(e.textSignature===void 0||typeof e.textSignature==`string`)}function Vt(e){return K(e)&&e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`}function Ht(e){return K(e)&&e.type===`thinking`&&typeof e.thinking==`string`&&(e.thinkingSignature===void 0||typeof e.thinkingSignature==`string`)&&(e.redacted===void 0||typeof e.redacted==`boolean`)}function Ut(e){return K(e)&&e.type===`toolCall`&&typeof e.id==`string`&&typeof e.name==`string`&&K(e.arguments)&&(e.thoughtSignature===void 0||typeof e.thoughtSignature==`string`)}function Wt(e){return typeof e==`string`||Array.isArray(e)&&e.every(e=>Bt(e)||Vt(e))}function Gt(e){return Array.isArray(e)&&e.every(e=>Bt(e)||Ht(e)||Ut(e))}function Kt(e){return K(e)&&typeof e.input==`number`&&typeof e.output==`number`&&typeof e.cacheRead==`number`&&typeof e.cacheWrite==`number`&&typeof e.totalTokens==`number`&&K(e.cost)&&typeof e.cost.input==`number`&&typeof e.cost.output==`number`&&typeof e.cost.cacheRead==`number`&&typeof e.cost.cacheWrite==`number`&&typeof e.cost.total==`number`}function qt(e){return!K(e)||typeof e.role!=`string`?!1:e.role===`user`?Wt(e.content):e.role===`assistant`?Gt(e.content)&&typeof e.api==`string`&&typeof e.provider==`string`&&typeof e.model==`string`&&Kt(e.usage)&&(e.stopReason===`stop`||e.stopReason===`length`||e.stopReason===`toolUse`||e.stopReason===`error`||e.stopReason===`aborted`)&&(e.errorMessage===void 0||typeof e.errorMessage==`string`):e.role===`toolResult`?typeof e.toolCallId==`string`&&typeof e.toolName==`string`&&Array.isArray(e.content)&&e.content.every(e=>Bt(e)||Vt(e))&&typeof e.isError==`boolean`:!1}async function Jt(e){let t;try{t=await S.readFile(e,`utf-8`)}catch(e){throw Error(`Failed to read message file: ${e.message}`)}let n;try{n=JSON.parse(t)}catch(e){throw Error(`Invalid JSON in message file: ${e.message}`)}let r=Array.isArray(n)?n:[n];if(r.length===0||!r.every(e=>qt(e)))throw Error(`Message file must contain one Message object or an array of Message objects`);return r}async function Yt(e){if(!!e.message==!!e.fromFile)throw Error(`Exactly one of --message or --from-file must be provided`);return e.fromFile?{kind:`messages`,messages:await Jt(e.fromFile)}:{kind:`text`,message:e.message}}var Xt=class{constructor(e){this.sinks=e}async send(e){await Promise.allSettled(this.sinks.map(async t=>{await t.send(e)}))}async close(){await Promise.allSettled(this.sinks.map(async e=>{await e.close()}))}},Zt=class{constructor(e){this.url=e}async send(e){await this.post(this.toPayload(e))}async close(){}async post(e){let t=Date.now(),n=Qt(e);P.info(`sending callback event`,{callbackUrl:this.url,...n});let r=new AbortController,i=!1,a=setTimeout(()=>{i=!0,r.abort()},5e3);try{let a=await fetch(this.url,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e),signal:r.signal}),o=Date.now()-t;if(!a.ok){P.error(`callback event failed`,{callbackUrl:this.url,httpStatus:a.status,durationMs:o,timedOut:i,...n});return}P.info(`callback event delivered`,{callbackUrl:this.url,httpStatus:a.status,durationMs:o,...n})}catch(e){let r=Date.now()-t;P.error(`callback event failed`,{callbackUrl:this.url,error:e instanceof Error?e.message:String(e),durationMs:r,timedOut:i,...n})}finally{clearTimeout(a)}}toPayload(e){switch(e.type){case`start`:return e;case`progress`:return e;case`done`:return e;case`error`:return e;case`session_reset`:return e;case`hitl`:return e;case`title_updated`:return e;default:{let t=e;throw Error(`Unsupported callback event: ${JSON.stringify(t)}`)}}}};function Qt(e){return{eventType:e.type,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,progressType:e.type===`progress`?e.event.type:void 0}}function $t(e,t){if(t.kind===`none`)return e;let n=new URL(e);return n.searchParams.set(`authToken`,t.token),n.toString()}const en=5e3,tn=5e3;function nn(){let e=globalThis.WebSocket;if(!e)throw Error(`WebSocket is not available in this runtime`);return e}function rn(e){return e?{kind:`query_token`,token:e}:{kind:`none`}}function an(e,t,n){if(typeof e.once==`function`){e.once(t,n);return}if(typeof e.addEventListener==`function`&&typeof e.removeEventListener==`function`){let r=(...i)=>{e.removeEventListener?.(t,r),n(...i)};e.addEventListener(t,r);return}throw Error(`WebSocket does not support one-time listener registration for "${t}"`)}function on(e,t,n){if(typeof e.on==`function`){e.on(t,n);return}if(typeof e.addEventListener==`function`){e.addEventListener(t,n);return}throw Error(`WebSocket does not support listener registration for "${t}"`)}var sn=class{socket=null;connectPromise=null;enabled=!0;textSequence=0;constructor(e,t,n){this.url=e,this.events=t,this.authToken=n}async send(e){let t=this.toEnvelope(e);if(!(!t||!this.enabled))try{await cn(this.ensureConnected(),en,`WebSocket connection timed out after ${en}ms`);let e=nn();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){P.warn(`websocket sink disabled after send failure`,{url:this.url,error:e instanceof Error?e.message:String(e)}),this.enabled=!1}}async sendTextDelta(e){if(!this.enabled||!this.events.has(`text`))return;this.textSequence+=1;let t={type:`text`,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,timestamp:new Date().toISOString(),sequence:this.textSequence,delta:e.text};try{await cn(this.ensureConnected(),en,`WebSocket connection timed out after ${en}ms`);let e=nn();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){P.warn(`websocket sink disabled after text delta send failure`,{url:this.url,error:e instanceof Error?e.message:String(e)}),this.enabled=!1}}async close(){this.enabled=!1;let e=this.socket;if(this.socket=null,this.connectPromise=null,!e)return;let t=nn();if(e.readyState!==t.CLOSED)try{await cn(new Promise(t=>{an(e,`close`,()=>t()),e.close()}),tn,`WebSocket close timed out after ${tn}ms`)}catch(e){P.warn(`websocket sink close timed out`,{url:this.url,error:e instanceof Error?e.message:String(e)})}}async ensureConnected(){if(!this.enabled)return;let e=nn();if(this.socket&&this.socket.readyState===e.OPEN)return;if(this.connectPromise){await this.connectPromise;return}let t=new e($t(this.url,rn(this.authToken)));this.connectPromise=new Promise((e,n)=>{an(t,`open`,()=>{this.socket=t,on(t,`close`,()=>{this.socket===t&&(this.socket=null)}),e()}),an(t,`error`,e=>{n(e)})});try{await this.connectPromise}finally{this.connectPromise=null}}toEnvelope(e){let t=new Date().toISOString();switch(e.type){case`start`:return this.events.has(`start`)?{...e,timestamp:t}:null;case`done`:return this.events.has(`done`)?{...e,timestamp:t}:null;case`error`:return this.events.has(`error`)?{...e,timestamp:t}:null;case`hitl`:return this.events.has(`hitl`)?{...e,timestamp:t}:null;case`title_updated`:return this.events.has(`title_updated`)?{type:`title_updated`,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,timestamp:t,title:e.title}:null;case`session_reset`:return null;case`progress`:return e.event.type===`text`?this.events.has(`text`)?(this.textSequence+=1,{type:`text`,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,timestamp:t,sequence:this.textSequence,delta:e.event.text}):null:e.event.type===`stream_text_delta`||!this.events.has(`progress`)?null:{type:`progress`,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,timestamp:t,event:e.event};default:{let t=e;throw Error(`Unsupported stream event: ${JSON.stringify(t)}`)}}}};function cn(e,t,n){return new Promise((r,i)=>{let a=setTimeout(()=>i(Error(n)),t);e.then(e=>{clearTimeout(a),r(e)},e=>{clearTimeout(a),i(e)})})}function ln(e){let t=e.trim();if(!t)throw Error(`Goal objective cannot be empty`);return t}function un(e,t){if(t.action===`unchanged`)return null;if(t.action===`created`||t.action===`replaced`)return t.action;if(e?.status!==t.goal.status)switch(t.goal.status){case`active`:return e?.status===`paused`?`resumed`:`updated`;case`paused`:return`paused`;case`complete`:return`completed`;case`budget_limited`:return`budget_limited`;default:return`updated`}return`updated`}function dn(e){let t=un(e.before,e.result);return t?{type:`goal_updated`,sessionId:e.sessionId,action:t,goalId:e.result.goal.goalId,goalStatus:e.result.goal.status}:null}function fn(e){let t=e?.packageRoot??pn(),n=w.join(t,`models`),r=w.join(n,...`Xenova/bge-small-zh-v1.5`.split(`/`));if(C.existsSync(w.join(r,`config.json`)))return n}function pn(){let e=w.dirname(Ce(import.meta.url));return w.basename(e)===`src`||w.basename(e)===`dist`?w.resolve(e,`..`):e}const mn=[`start`,`text`,`done`,`error`,`hitl`],hn=[`off`,`gate`,`dry_run`,`write`];function gn(e){if(!e?.trim())return new Set(mn);let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean),n=new Set([`start`,`text`,`progress`,`done`,`error`,`hitl`,`title_updated`]),r=new Set;for(let e of t){if(!n.has(e))throw Error(`Invalid stream event: ${e}. Must be one of start,text,progress,done,error,hitl`);r.add(e)}return r.size>0?r:new Set(mn)}function _n(e){if(e.disableTopicSegmentation===!0||process.env.AIMAX_DISABLE_TOPIC_SEGMENTATION===`true`)return{enabled:!1};let t=fn();return t?{embeddingModelDir:t}:void 0}function vn(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir or AIMAX_DATA_DIR`);return t}function yn(e){return e?.trim()||void 0}function bn(e){let t=(e.systemAgentsDir??process.env.AIMAX_SYSTEM_AGENTS_DIR)?.trim();if(t){if(!w.isAbsolute(t)){let n=e.systemAgentsDir===void 0?`AIMAX_SYSTEM_AGENTS_DIR`:`--system-agents-dir`;throw Error(`Invalid ${n}: ${t}. Path must be absolute.`)}return t}}function xn(e){return e?y(e):void 0}function Sn(e){if(!e?.trim())return[];let t=e.split(`,`).map(e=>e.trim()).filter(Boolean),n=new Set,r=[];for(let e of t){if(!w.isAbsolute(e))throw Error(`Invalid --skillsLoadPaths entry: ${e}. Each path must be absolute.`);n.has(e)||(n.add(e),r.push(e))}return r}function Cn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if([`true`,`1`,`yes`,`on`].includes(n))return!0;if([`false`,`0`,`no`,`off`].includes(n))return!1;throw Error(`Invalid ${t}: ${e}. Must be true or false.`)}}function wn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(hn.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function Tn(e){let t=e.autoSkillsLoadEnabled===void 0?Cn(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):Cn(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?wn(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):wn(e.autoSkillsReviewMode,`--auto-skills-review-mode`),r={};return t!==void 0&&(r.load={enabled:t}),n!==void 0&&(r.review={mode:n}),r.load||r.review?r:void 0}function En(e,t){if(e.inputText&&t){let n=_e(e.inputText,t);return n.submittedBy={userId:e.user,channel:e.channel??`IM`},n}if(!e.inputJson&&!e.inputText)throw Error(`Either --input-json or --input-text must be provided for the resume command`);try{let t=JSON.parse(e.inputJson);return{requestId:e.requestId,sessionId:e.sessionId,action:t.action??`submit`,values:t.values,submittedBy:t.submittedBy,idempotencyKey:t.idempotencyKey,submittedAt:t.submittedAt??new Date().toISOString()}}catch(e){throw Error(`Invalid --input-json: ${e.message}`)}}function Dn(e,t){if(!e.inputJson)throw Error(`UI tool resume requires --input-json`);try{let n=JSON.parse(e.inputJson),r=n&&typeof n==`object`&&`values`in n&&n.values&&typeof n.values==`object`&&!Array.isArray(n.values)?n.values:n;return{requestId:t.request.requestId,sessionId:t.sessionId,toolCallId:t.request.toolCallId,toolName:t.request.toolName,values:r,submittedAt:new Date().toISOString()}}catch(e){throw Error(`Invalid --input-json: ${e.message}`)}}async function On(e){let t=await ie(e.dataDir,e.sessionId,{storeName:e.sessionStoreName,encryptSessions:e.encryptSessions});for(let n=t.length-1;n>=0;--n){let r=t[n];if(r?.role!==`assistant`||!Array.isArray(r.toolCalls))continue;let i=r.toolCalls.find(t=>t.id===e.toolCallId&&t.name===e.toolName);if(i)return i.arguments}}async function kn(e){let t=vn(e),n=e.channel??`WEB`,r=Lt({apiFormat:e.apiFormat,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel});return{dataDir:t,systemAgentsDir:bn(e),channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,skillsLoadPaths:Sn(e.skillsLoadPaths),autoSkills:Tn(e)}}function An(e){let t=[],n=null;return e.callbackUrl&&t.push(new Zt(e.callbackUrl)),e.streamUrl&&(n=new sn(e.streamUrl,gn(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new Xt(t),websocketSink:n}}async function jn(e){let{dataDir:t,sessionId:n,sessionStoreName:r,toolCallId:i,toolName:a,resolution:o,encryptSessions:s}=e;if(!i||!a||!he(a))return;let c=(e,t)=>{switch(e){case`request_approval`:return f(t);case`clarify`:return p(t);case`request_review`:return m(t);default:return JSON.stringify({action:t.action,values:t.values})}};await ue(t,n,e=>{let t=e.findIndex(e=>e.role===`tool_result`&&e.toolCallId===i&&e.toolName===a);if(t===-1)return e;let n=e.slice(0,t+1);return n[t]={...n[t],content:c(a,o),isError:!1},n},{storeName:r,encryptSessions:s})}async function Mn(e){let{dataDir:t,sessionId:n,sessionStoreName:r,result:i,encryptSessions:a}=e;await ue(t,n,e=>{let t=e.findIndex(e=>e.role===`assistant`&&Array.isArray(e.toolCalls)&&e.toolCalls.some(e=>e.id===i.toolCallId&&e.name===i.toolName));if(t===-1)return e;let n=e.slice(0,t+1);return n.push({role:`tool_result`,toolCallId:i.toolCallId,toolName:i.toolName,content:JSON.stringify({submitted:!0,values:i.values}),isError:!1,timestamp:i.submittedAt}),n},{storeName:r,encryptSessions:a})}async function Nn(e){let t=vn(e);await U(t,e,async()=>{N(t);let i=new F(`resume command`),a=null;try{let t=await kn(e),o=xn(e.sessionStore),c=null;if(e.goal||e.goalFile){let i;i=e.goalFile?await S.readFile(e.goalFile,`utf-8`):e.goal;let a=ln(i),s=e.tokenBudget===void 0?void 0:e.tokenBudget===`0`||e.tokenBudget===``?null:Number(e.tokenBudget);s!=null&&(Number.isNaN(s)||s<=0)&&(k(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));try{let n=await b(t.dataDir,e.sessionId,{storeName:o}),i=await r({dataDir:t.dataDir,sessionId:e.sessionId,objective:a,tokenBudget:s,force:e.force,storeName:o});c=dn({sessionId:e.sessionId,before:n,result:i})}catch(e){throw e instanceof n&&(k(e.message),k(`Existing: ${e.existingObjectivePreview}`),process.exit(2)),e}}P.info(`resume command started`,{sessionId:e.sessionId,requestId:e.requestId,channel:t.channel,dataDir:t.dataDir});let l=await te(t.dataDir,e.sessionId,{storeName:o,encryptSessions:e.encryptSessions}),u=l?null:await ne(t.dataDir,e.sessionId,{storeName:o,encryptSessions:e.encryptSessions});if(!l&&!u)throw Error(`No pending HITL or UI tool request found for session "${e.sessionId}"`);if(l){if(l.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${l.request.requestId}", got "${e.requestId}"`);if(l.status===`expired`)throw Error(`HITL request has expired`);if(l.status===`cancelled`)throw Error(`HITL request has been cancelled`)}else if(u){if(u.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${u.request.requestId}", got "${e.requestId}"`);if(u.status!==`pending`)throw Error(`UI tool request is already "${u.status}", cannot resume`)}if(l){let n=En(e,l.request),r=await ce({dataDir:t.dataDir,sessionStoreName:o,sessionId:e.sessionId,requestId:e.requestId,resolution:n}),s=r.state;if(!s)throw Error(`Resolved HITL state was not persisted`);let u=Pn(n,s.request.kind);await jn({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:o,toolCallId:s.toolContext?.toolCallId,toolName:s.toolContext?.toolName,resolution:n,encryptSessions:e.encryptSessions});let d=An(e);a=d.sink;let f=e.sessionId,p=async n=>{if(f=n.sessionId??f,!me(n)){if(n.type===`stream_text_delta`){t.format===`text`&&A(n),await d.websocketSink?.sendTextDelta({sessionId:f,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}t.format===`text`&&A(n),await a?.send({sessionId:f,channel:t.channel,messageId:e.messageId,user:e.user,type:`progress`,event:n})}};c&&await p(c),await p({type:`hitl_resumed`,requestId:e.requestId,resolution:n,sessionId:e.sessionId}),`idempotentReplay`in r&&r.idempotentReplay&&(P.info(`resume command treated as idempotent replay`,{sessionId:e.sessionId,requestId:e.requestId,idempotencyKey:n.idempotencyKey}),Ie({sessionId:e.sessionId,text:`Resume request already processed.`,usage:{input:0,output:0,total:0},durationMs:0},t.format),i.end(),process.exit(0));let m=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,h=await W(t.dataDir,m),g;try{g=await x({dataDir:t.dataDir,projectDir:yn(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:o,sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,message:u,encryptSessions:e.encryptSessions??!1,topicSegmentation:_n(e),hitlResume:{request:s.request,resolution:n,checkpoint:s.checkpoint,toolContext:s.toolContext},plugins:h?{config:h,dataDir:t.dataDir,workspaceDir:w.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:h.llmAllowlist}:void 0,onProgress:p})}finally{}g.error?await a?.send({sessionId:g.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`error`,message:g.error}):await a?.send({sessionId:g.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`done`,result:{text:g.text,usage:g.usage,durationMs:g.durationMs,error:g.error,paused:g.paused,uiToolPending:g.uiToolPending}}),Ie(g,t.format),g.error?P.error(`resume command failed: ${g.error}`):P.info(`resume command succeeded`),i.end(),process.exit(g.error?1:0);return}let d=Dn(e,u);if(!await le(t.dataDir,e.sessionId,e.requestId,d,{storeName:o,encryptSessions:e.encryptSessions}))throw Error(`UI tool resume validation failed`);await Mn({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:o,result:d,encryptSessions:e.encryptSessions});let f=An(e);a=f.sink;let p=e.sessionId,m=async n=>{if(p=n.sessionId??p,!me(n)){if(n.type===`stream_text_delta`){t.format===`text`&&A(n),await f.websocketSink?.sendTextDelta({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}if(t.format===`text`&&A(n),n.type===`start`){await a?.send({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,type:`start`,message:n.message});return}await a?.send({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,type:`progress`,event:n})}},h=await On({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:o,toolCallId:d.toolCallId,toolName:d.toolName,encryptSessions:e.encryptSessions});c&&await m(c),await m({type:`tool_end`,sessionId:e.sessionId,toolCallId:d.toolCallId,name:d.toolName,input:h,output:JSON.stringify({submitted:!0,values:d.values}),isError:!1});let g=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,_=await W(t.dataDir,g),v=await x({dataDir:t.dataDir,projectDir:yn(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:o,sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,message:`[UI_TOOL_RESUME]
8
+ The pending UI tool result has been written into the transcript. Continue from the latest tool result without repeating the same form request.`,encryptSessions:e.encryptSessions??!1,topicSegmentation:_n(e),uiToolResume:d,plugins:_?{config:_,dataDir:t.dataDir,workspaceDir:w.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:_.llmAllowlist}:void 0,onProgress:m});await s(t.dataDir,e.sessionId,{storeName:o,encryptSessions:e.encryptSessions}),v.error?await a?.send({sessionId:v.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`error`,message:v.error}):await a?.send({sessionId:v.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`done`,result:{text:v.text,usage:v.usage,durationMs:v.durationMs,error:v.error,paused:v.paused,uiToolPending:v.uiToolPending}}),Ie(v,t.format),v.error?P.error(`resume command failed: ${v.error}`):P.info(`resume command succeeded`),i.end(),process.exit(v.error?1:0)}catch(t){let n=t;a&&(n.message.includes(`expired`)&&await a.send({sessionId:e.sessionId,channel:e.channel??`WEB`,messageId:e.messageId,user:e.user,type:`progress`,event:{type:`hitl_expired`,sessionId:e.sessionId,requestId:e.requestId,reason:n.message}}),n.message.includes(`cancelled`)&&await a.send({sessionId:e.sessionId,channel:e.channel??`WEB`,messageId:e.messageId,user:e.user,type:`progress`,event:{type:`hitl_cancelled`,sessionId:e.sessionId,requestId:e.requestId,reason:n.message}}),await a.send({sessionId:e.sessionId,channel:e.channel??`WEB`,messageId:e.messageId,user:e.user,type:`error`,message:`Resume failed: ${n.message}`})),P.error(`resume command error: ${n.message}`),k(`Fatal: ${n.message}`),i.end(),process.exit(1)}finally{await a?.close()}})}function Pn(e,t){return o(e,t)}function Fn(e){e.command(`resume`).description(`Resume a paused HITL session with user input`).requiredOption(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--project-dir <path>`,`Current project directory used as the default cwd context`).option(`--system-agents-dir <path>`,`System agent definition directory (overrides AIMAX_SYSTEM_AGENTS_DIR, default: /aimax/agents)`).requiredOption(`-s, --session-id <id>`,`Session ID to resume`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).requiredOption(`--request-id <id>`,`HITL request ID to resolve`).option(`--input-json <json>`,`JSON string with the resolution (action, values, etc.)`).option(`--input-text <text>`,`Plain text response for IM channels without rich UI (e.g. '同意', '拒绝')`).option(`--skillsLoadPaths <paths>`,`Comma-separated absolute skill load paths`).option(`--auto-skills-load-enabled <boolean>`,`Enable learned auto-skill loading for the main agent (overrides AIMAX_AUTO_SKILLS_LOAD_ENABLED)`).option(`--auto-skills-review-mode <mode>`,`Auto-skill review mode: off, gate, dry_run, or write (overrides AIMAX_AUTO_SKILLS_REVIEW_MODE)`).option(`--message-id <id>`,`Message ID for correlating events`).option(`--user <id>`,`User identifier propagated to external callback and stream payloads`).option(`-c, --channel <channel>`,`Channel name (default: WEB)`,`WEB`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-format <format>`,`LLM API format: openai-completions or anthropic-messages (overrides AIMAX_API_FORMAT)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY)`).option(`--auth-token <token>`,`Auth token used to generate the API key`).option(`--model <name>`,`LLM model name (overrides AIMAX_MODEL)`).option(`--context-window <n>`,`LLM context window size`).option(`--callback-url <url>`,`HTTP callback URL for progress events`).option(`--stream-url <url>`,`WebSocket URL for streaming text events`).option(`--stream-auth-token <token>`,`Auth token for WebSocket streaming`).option(`--stream-events <list>`,`Comma-separated stream events`).option(`--timeout <ms>`,`Execution timeout in milliseconds`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--plugins-config <path>`,`Plugins config file path`).option(`--goal <text>`,`Set or replace the thread goal objective before resuming`).option(`--goal-file <path>`,`Read goal objective from a file`).option(`--token-budget <n>`,`Token budget for the goal (positive integer, or 0 for unlimited)`).option(`--force`,`Replace existing goal with a different objective`).option(`--encrypt-sessions`,`Enable encryption for the .aimax data directory`).option(`--disable-topic-segmentation`,`Disable smart topic segmentation for this resume run`).action(async e=>{await Nn(e)})}const In=[`start`,`text`,`done`,`error`],Ln=[`off`,`gate`,`dry_run`,`write`];function Rn(e){if(!e?.trim())return new Set(In);let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean),n=new Set([`start`,`text`,`progress`,`done`,`error`,`hitl`,`title_updated`]),r=new Set;for(let e of t){if(!n.has(e))throw Error(`Invalid stream event: ${e}. Must be one of start,text,progress,done,error,hitl,title_updated`);r.add(e)}return r.size>0?r:new Set(In)}function zn(e){if(e.disableTopicSegmentation===!0||process.env.AIMAX_DISABLE_TOPIC_SEGMENTATION===`true`)return{enabled:!1};let t=fn();return t?{embeddingModelDir:t}:void 0}function Bn(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir option or AIMAX_DATA_DIR environment variable`);return t}function Vn(e){return e?.trim()||void 0}function Hn(e){let t=(e.systemAgentsDir??process.env.AIMAX_SYSTEM_AGENTS_DIR)?.trim();if(t){if(!w.isAbsolute(t)){let n=e.systemAgentsDir===void 0?`AIMAX_SYSTEM_AGENTS_DIR`:`--system-agents-dir`;throw Error(`Invalid ${n}: ${t}. Path must be absolute.`)}return t}}function Un(e){return e?.trim()||void 0}function Wn(e){return e??`WEB`}function Gn(e){return e?y(e):void 0}function Kn(e){if(!e?.trim())return[];let t=e.split(`,`).map(e=>e.trim()).filter(Boolean),n=new Set,r=[];for(let e of t){if(!w.isAbsolute(e))throw Error(`Invalid --skillsLoadPaths entry: ${e}. Each path must be absolute.`);n.has(e)||(n.add(e),r.push(e))}return r}function qn(e){let t=``;for(let n=0;n<e.length;n+=1){let r=e[n];if(r===`\\`&&n+1<e.length){let r=e[n+1];if(r===`,`||r===`\\`||r===`=`){t+=r,n+=1;continue}}t+=r}return t}function Jn(e){let t=[],n=``;for(let r=0;r<e.length;r+=1){let i=e[r];if(i===`\\`&&r+1<e.length){let t=e[r+1];if(t===`,`||t===`\\`){n+=t,r+=1;continue}}if(i===`,`){t.push(n),n=``;continue}n+=i}return t.push(n),t}function Yn(e){if(!e?.trim())return{};let t=[],n=new Set;for(let r of Jn(e)){let e=r.trim();if(!e)continue;let i=e.indexOf(`=`);if(i<=0)throw Error(`Invalid --env entry: ${e}. Expected KEY=VALUE (use \\= to embed an equals sign in the value).`);let a=e.slice(0,i).trim(),o=e.slice(i+1).trim();if(!a)throw Error(`Invalid --env entry: ${e}. Key must not be empty.`);if(n.has(a))throw Error(`Invalid --env entry: duplicate key ${a}.`);n.add(a),t.push([a,qn(o)])}return Object.fromEntries(t)}function Xn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if([`true`,`1`,`yes`,`on`].includes(n))return!0;if([`false`,`0`,`no`,`off`].includes(n))return!1;throw Error(`Invalid ${t}: ${e}. Must be true or false.`)}}function Zn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(Ln.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function Qn(e){let t=e.autoSkillsLoadEnabled===void 0?Xn(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):Xn(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?Zn(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):Zn(e.autoSkillsReviewMode,`--auto-skills-review-mode`),r={};return t!==void 0&&(r.load={enabled:t}),n!==void 0&&(r.review={mode:n}),r.load||r.review?r:void 0}function $n(e,t){return e.length<=t?e:t<=3?e.slice(0,t):`${e.slice(0,t-3)}...`}function er(e,t){if(t<=0)return[``];let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n.length>0?n:[``]}function tr(e,t,n=78){let r=Math.max(0,n-4),i=e?e.length+2:0,a=Math.max(r,i,...t.map(e=>e.length)),o=a+2,s=e?` ${$n(e,Math.max(0,a-2))} `:``,c=e?`┌${s}${`─`.repeat(Math.max(0,o-s.length))}┐`:`┌${`─`.repeat(o)}┐`,l=`└${`─`.repeat(o)}┘`;return[c,...t.flatMap(e=>er(e,a).map(e=>`│ ${e.padEnd(a,` `)} │`)),l].join(`
9
+ `)}function nr(e){return e.kind===`text`?`inline message (${e.message.length} chars)`:`message file (${e.messages.length} messages)`}function q(e,t=`-`){return e==null||e===``?t:String(e)}function rr(e){return e?`set`:`unset`}function ir(e){return e?`true`:`false`}function ar(e,t){let n=Gn(e.sessionStore)??`sessions`,r=t.timeoutMs===void 0?`default`:`${t.timeoutMs}`,i=e.callbackUrl?`enabled`:`disabled`,a=e.streamUrl?`enabled`:`disabled`,o=nr(t.input),s=t.input.kind===`text`?`inline`:e.fromFile??`file`,c=He(),l=zn(e)?.enabled===!1?`disabled`:`enabled`,u=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,d=[...Rn(e.streamEvents)].join(`,`),f=t.autoSkills?.load?.enabled,p=t.autoSkills?.review?.mode,m=e.tokenBudget===`0`?`unlimited`:q(e.tokenBudget),h=e.env?Object.keys(Yn(e.env)):[],g=h.length===0?`-`:`${h.length} key${h.length===1?``:`s`}`;return{banner:tr(void 0,[`AIMax CLI`,`Stateless Agent Runner`]),contextBox:tr(`Run Context`,[`time : ${c}`,`dataDir : ${t.dataDir}`,`projectDir : ${Vn(e.projectDir)??`-`}`,`systemAgents : ${t.systemAgentsDir??`/aimax/agents`}`,`agent : ${Un(e.agent)??`-`}`,`channel : ${t.channel}`,`user : ${e.user??`-`}`,`message : ${e.message===void 0?`-`:`inline (${e.message.length} chars)`}`,`fromFile : ${q(e.fromFile)}`,`input : ${o}`,`skillsPaths : ${t.skillsLoadPaths.length>0?t.skillsLoadPaths.join(`,`):`-`}`,`autoSkillLoad: ${f===void 0?`-`:String(f)}`,`autoSkillRev : ${p??`-`}`,`sessionId : ${e.sessionId??`new`}`,`sessionStore : ${n}`,`messageId : ${e.messageId??`-`}`,`workspace : ${w.join(t.dataDir,`workspace`)}`,`baseUrl : ${t.llm.baseUrl}`,`apiKey : ${rr(e.apiKey)}`,`authToken : ${rr(e.authToken)}`,`model : ${t.llm.model}`,`contextWindow: ${q(t.llm.contextWindow)}`,`flashModel : ${q(t.llm.flashModel)}`,`callbackUrl : ${q(e.callbackUrl)}`,`streamUrl : ${q(e.streamUrl)}`,`streamAuth : ${rr(e.streamAuthToken)}`,`streamEvents : ${d}`,`output : ${t.format}`,`callback : ${i}`,`websocket : ${a}`,`timeoutMs : ${r}`,`pluginsConfig: ${q(u)}`,`env : ${g}`,`goal : ${e.goal===void 0?`-`:`inline (${e.goal.length} chars)`}`,`goalFile : ${q(e.goalFile)}`,`tokenBudget : ${m}`,`force : ${ir(e.force)}`,`resumeReqId : ${q(e.resumeRequestId)}`,`resumeInput : ${e.resumeInputJson===void 0?`-`:`inline (${e.resumeInputJson.length} chars)`}`,`resumeFile : ${q(e.resumeFromFile)}`,`encryptSess : ${ir(e.encryptSessions)}`,`topicSegment : ${l}`]),logContext:{time:c,channel:t.channel,user:e.user,dataDir:t.dataDir,projectDir:Vn(e.projectDir),systemAgentsDir:t.systemAgentsDir,agent:Un(e.agent),workspaceDir:w.join(t.dataDir,`workspace`),sessionId:e.sessionId??`new`,sessionStore:n,messageId:e.messageId,hasMessage:e.message!==void 0,fromFile:e.fromFile,skillsLoadPaths:t.skillsLoadPaths.join(`,`)||void 0,autoSkillsLoadEnabled:f,autoSkillsReviewMode:p,baseUrl:t.llm.baseUrl,hasApiKey:!!e.apiKey,hasAuthToken:!!e.authToken,model:t.llm.model,contextWindow:t.llm.contextWindow,flashModel:t.llm.flashModel,callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,hasStreamAuthToken:!!e.streamAuthToken,streamEvents:d,output:t.format,hasCallback:!!e.callbackUrl,hasStream:!!e.streamUrl,timeoutMs:t.timeoutMs,pluginsConfig:u,envKeys:h.length>0?h.join(`,`):void 0,hasGoal:e.goal!==void 0,goalFile:e.goalFile,tokenBudget:m===`-`?void 0:m,force:!!e.force,resumeRequestId:e.resumeRequestId,hasResumeInputJson:e.resumeInputJson!==void 0,resumeFromFile:e.resumeFromFile,encryptSessions:!!e.encryptSessions,topicSegmentation:l,inputKind:t.input.kind,inputSource:s,inputSummary:o}}}async function or(e,t){let n=Bn(e),r=Wn(e.channel),i=Lt({apiFormat:e.apiFormat,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel});return{dataDir:n,systemAgentsDir:Hn(e),channel:r,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:i,input:t,skillsLoadPaths:Kn(e.skillsLoadPaths),autoSkills:Qn(e)}}function sr(e){if(e.kind===`text`)return e.message;if(e.messages.length!==1)return null;let[t]=e.messages;if(t.role!==`user`)return null;if(typeof t.content==`string`)return t.content;if(t.content.length===0)return null;let n=[];for(let e of t.content){if(e.type!==`text`)return null;n.push(e.text)}return n.join(`
10
+ `)}async function cr(e,t){if(!e.sessionId)return null;let n=sr(t);if(!n)return null;let r=await te(Bn(e),e.sessionId,{storeName:Gn(e.sessionStore),encryptSessions:e.encryptSessions});return!r||r.status!==`pending`||!ge(n,r.request)?null:{requestId:r.request.requestId,inputText:n}}function lr(e){let t=[],n=null;return e.callbackUrl&&t.push(new Zt(e.callbackUrl)),e.streamUrl&&(n=new sn(e.streamUrl,Rn(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new Xt(t),websocketSink:n}}async function J(e,t){P.info(`dispatching external event`,Or(t)),await e.sink.send(t)}function ur(e){let t={sessionId:e.sessionId,messageId:e.messageId,parentSessionId:e.parentSessionId,depth:e.depth,scope:e.scope,phase:e.phase,...e.details};if(e.level===`error`){P.error(e.message,t);return}if(e.level===`warn`){P.warn(e.message,t);return}P.info(e.message,t)}function dr(e,t,n,r,i){return{sink:e,websocketSink:t,channel:n,defaultMessageId:r,user:i}}function fr(e){let t=new AbortController,n=n=>{P.warn(`run abort signal received`,{signal:n,uptimeMs:Math.round(process.uptime()*1e3),alreadyAborted:t.signal.aborted,...e?.()}),t.abort()},r=()=>n(`SIGTERM`),i=()=>n(`SIGINT`);return process.once(`SIGTERM`,r),process.once(`SIGINT`,i),{controller:t,cleanup:()=>{process.off(`SIGTERM`,r),process.off(`SIGINT`,i)}}}function pr(e){return{activeSessionId:e??`pending`,finalResult:null}}function mr(e,t){e.activeSessionId=t.sessionId??e.activeSessionId}function hr(e,t){return e.messageId??t}async function gr(e,t,n){if(!await h(e.dataDir)){if(await _r(t,e.format,n.activeSessionId,e.dataDir,`checking`),(await u(e.dataDir)).performedBootstrap){await _r(t,e.format,n.activeSessionId,e.dataDir,`initializing`),await _r(t,e.format,n.activeSessionId,e.dataDir,`initialized`);return}await _r(t,e.format,n.activeSessionId,e.dataDir,`ready`)}}async function _r(e,t,n,r,i){let a={type:`bootstrap`,phase:i,dataDir:r};t===`text`&&A(a),await J(e,{sessionId:n,channel:e.channel,messageId:e.defaultMessageId,user:e.user,type:`progress`,event:a})}function vr(e,t,n){return async r=>{if(mr(n,r),me(r)){ur(r);return}if(r.type===`stream_text_delta`){e.format===`text`&&A(r),await t.websocketSink?.sendTextDelta({sessionId:n.activeSessionId,channel:e.channel,messageId:hr(r,t.defaultMessageId),user:t.user,text:r.text});return}e.format===`text`&&A(r);let i=hr(r,t.defaultMessageId);if(r.type===`hitl_requested`){await J(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`hitl`,request:r.request}),await J(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r});return}if(r.type===`start`){await J(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`start`,message:r.message});return}if(r.type===`session_reset`){await J(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`session_reset`,action:r.action,previousSessionId:r.previousSessionId,message:r.message});return}await J(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r})}}function yr(e,t,n,r,i,a){let o={dataDir:t.dataDir,projectDir:Vn(e.projectDir),systemAgentsDir:t.systemAgentsDir,agentPolicy:Un(e.agent)?{requestedAgentName:Un(e.agent)}:void 0,sessionStoreName:Gn(e.sessionStore),sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,abortSignal:n.signal,pendingGoal:a,encryptSessions:e.encryptSessions??!1,topicSegmentation:zn(e),env:Yn(e.env),plugins:i?{config:i,dataDir:t.dataDir,workspaceDir:w.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:i.llmAllowlist}:void 0,onProgress:r};return t.input.kind===`messages`?{...o,messages:t.input.messages}:{...o,message:t.input.message}}async function br(e,t,n,r){if(t.activeSessionId=r.sessionId,t.finalResult=r,r.error){await J(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:r.error});return}await J(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`done`,result:{text:r.text,usage:r.usage,durationMs:r.durationMs,error:r.error,paused:r.paused}})}async function xr(e,t,n,r){await J(e,{sessionId:t.finalResult?.sessionId??t.activeSessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:`Fatal: ${r.message}`})}function Sr(e,t){let n=ar(e,t);P.info([`run command started`,n.banner,n.contextBox].join(`
11
+ `),n.logContext),t.format===`text`&&(O(n.banner),O(``),O(n.contextBox),O(``))}function Cr(e,t,n){return Ie(t,n),t.error?P.error(`run command failed: ${t.error}`):P.info(`run command succeeded`),e.end(),t.error?1:0}function wr(e){let t=$e();if(!t)return;let n=`[${He()}] [ERROR] ${e}\n`;try{C.appendFileSync(w.join(t.logDir,`app.log`),n),C.appendFileSync(w.join(t.logDir,`errors.log`),n)}catch{}}async function Tr(e,t){let n=`run command error: ${t.message}`;P.error(n),wr(n),k(`Fatal: ${t.message}`),e.end(),await et(),process.exit(1)}async function Er(e){if(e.resumeInputJson&&e.resumeFromFile)throw Error(`--resume-input-json and --resume-from-file are mutually exclusive`);if(!e.resumeFromFile)return e.resumeInputJson;try{return await S.readFile(e.resumeFromFile,`utf-8`)}catch(e){throw Error(`Failed to read resume input file: ${e.message}`)}}async function Dr(e){let t=Bn(e);await U(t,e,async i=>{N(t),e.encryptSessions&&P.info(`--encrypt-sessions run mount state after logger initialization`,{dataDir:t,mounted:i?.mounted??!1,plainDir:i?.plainDir,encryptedDir:i?.encryptedDir});let a=new F(`run command`),o=await Er(e);if(e.resumeRequestId||o||e.resumeFromFile){if(!e.sessionId||!e.resumeRequestId||!o)throw Error(`--session-id, --resume-request-id, and exactly one of --resume-input-json or --resume-from-file must be provided together`);await Nn({dataDir:e.dataDir,projectDir:e.projectDir,systemAgentsDir:e.systemAgentsDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:e.resumeRequestId,inputJson:o,channel:e.channel,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow,flashModel:e.flashModel,callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamAuthToken:e.streamAuthToken,streamEvents:e.streamEvents,timeout:e.timeout,output:e.output,pluginsConfig:e.pluginsConfig,skillsLoadPaths:e.skillsLoadPaths,autoSkillsLoadEnabled:e.autoSkillsLoadEnabled,autoSkillsReviewMode:e.autoSkillsReviewMode,messageId:e.messageId,user:e.user,goal:e.goal,goalFile:e.goalFile,tokenBudget:e.tokenBudget,force:e.force,encryptSessions:e.encryptSessions,disableTopicSegmentation:e.disableTopicSegmentation});return}let s;try{s=await Yt({message:e.message,fromFile:e.fromFile})}catch(e){await Tr(a,e);return}let c=await cr(e,s);if(c){await Nn({dataDir:e.dataDir,projectDir:e.projectDir,systemAgentsDir:e.systemAgentsDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:c.requestId,inputText:c.inputText,channel:e.channel,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow,flashModel:e.flashModel,callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamAuthToken:e.streamAuthToken,streamEvents:e.streamEvents,timeout:e.timeout,output:e.output,pluginsConfig:e.pluginsConfig,skillsLoadPaths:e.skillsLoadPaths,autoSkillsLoadEnabled:e.autoSkillsLoadEnabled,autoSkillsReviewMode:e.autoSkillsReviewMode,messageId:e.messageId,user:e.user,goal:e.goal,goalFile:e.goalFile,tokenBudget:e.tokenBudget,force:e.force,encryptSessions:e.encryptSessions,disableTopicSegmentation:e.disableTopicSegmentation});return}let l=e.channel??`WEB`,u=pr(e.sessionId),{controller:d,cleanup:f}=fr(()=>({activeSessionId:u.activeSessionId,finalSessionId:u.finalResult?.sessionId,messageId:e.messageId,channel:l,user:e.user})),p=null;try{let t=await or(e,s);l=t.channel,Sr(e,t);let i=lr(e);p=i.sink,P.info(`external sink configured`,{callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamEvents:e.streamEvents});let o=dr(p,i.websocketSink,t.channel,e.messageId,e.user);await gr(t,o,u);let c,f=null;if(e.goal||e.goalFile){let i;i=e.goalFile?await S.readFile(e.goalFile,`utf-8`):e.goal;let a=ln(i),o=Gn(e.sessionStore),s=e.tokenBudget===void 0?void 0:e.tokenBudget===`0`||e.tokenBudget===``?null:Number(e.tokenBudget);s!=null&&(Number.isNaN(s)||s<=0)&&(k(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));try{if(e.sessionId){let n=await b(t.dataDir,e.sessionId,{storeName:o}),i=await r({dataDir:t.dataDir,sessionId:e.sessionId,objective:a,tokenBudget:s,force:e.force,storeName:o});f=dn({sessionId:e.sessionId,before:n,result:i})}else c={objective:a,tokenBudget:s??null}}catch(e){throw e instanceof n&&(k(e.message),k(`Existing: ${e.existingObjectivePreview}`),process.exit(2)),e}}let m=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,h=await W(t.dataDir,m),g=vr(t,o,u);f&&await g(f);let _=await x(yr(e,t,d,g,h,c));await br(o,u,e.messageId,_),process.exitCode=Cr(a,_,t.format)}catch(t){let n=t;p&&await xr(dr(p,null,l,e.messageId,e.user),u,e.messageId,n),await Tr(a,n)}finally{await p?.close(),f()}})}function Or(e){return{eventType:e.type,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,progressType:e.type===`progress`?e.event.type:void 0,textLength:e.type===`done`?e.result.text.length:void 0,hasError:e.type===`error`?!0:e.type===`done`?!!e.result.error:void 0}}function kr(e){e.command(`run`).description(`Run an agent task`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--project-dir <path>`,`Current project directory used as the default cwd context`).option(`--system-agents-dir <path>`,`System agent definition directory (overrides AIMAX_SYSTEM_AGENTS_DIR, default: /aimax/agents)`).option(`--agent <name>`,`Custom agent name to run as the root agent`).option(`--user <id>`,`User identifier propagated to external callback and stream payloads`).option(`--message <text>`,`User message to send to the agent`).option(`--from-file <path>`,`Load structured Message JSON from a file`).option(`--skillsLoadPaths <paths>`,`Comma-separated absolute skill load paths`).option(`--auto-skills-load-enabled <boolean>`,`Enable learned auto-skill loading for the main agent (overrides AIMAX_AUTO_SKILLS_LOAD_ENABLED)`).option(`--auto-skills-review-mode <mode>`,`Auto-skill review mode: off, gate, dry_run, or write (overrides AIMAX_AUTO_SKILLS_REVIEW_MODE)`).option(`-s, --session-id <id>`,`Resume an existing session by ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`--message-id <id>`,`Message ID for correlating events`).option(`-c, --channel <channel>`,`Channel name (default: WEB)`,`WEB`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-format <format>`,`LLM API format: openai-completions or anthropic-messages (overrides AIMAX_API_FORMAT)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY)`).option(`--auth-token <token>`,`Auth token used to generate the API key (highest priority)`).option(`--model <name>`,`LLM model name (overrides AIMAX_MODEL)`).option(`--context-window <n>`,`LLM context window size`).option(`--flash-model <name>`,`Flash model for lightweight tasks like title generation (overrides AIMAX_FLASH_MODEL)`).option(`--callback-url <url>`,`HTTP callback URL for progress events`).option(`--stream-url <url>`,`WebSocket URL for streaming text events`).option(`--stream-auth-token <token>`,`Auth token for WebSocket streaming`).option(`--stream-events <list>`,`Comma-separated stream events: start,text,progress,done,error`).option(`--timeout <ms>`,`Execution timeout in milliseconds`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--plugins-config <path>`,`Plugins config file path`).option(`--env <kvlist>`,`Session-scoped env vars injected into the run. Comma-separated KEY=VALUE pairs. Backslash-escape "," and "=" inside values. Available to plugins via api.runtime.session.env and merged into child process environments spawned by the exec/process tools.`).option(`--goal <text>`,`Set or replace the thread goal objective before running`).option(`--goal-file <path>`,`Read goal objective from a file`).option(`--token-budget <n>`,`Token budget for the goal (positive integer, or 0 for unlimited)`).option(`--force`,`Replace existing goal with a different objective`).option(`--resume-request-id <id>`,`Resume a pending HITL request from aimax run`).option(`--resume-input-json <json>`,`Structured HITL resume payload used with --resume-request-id`).option(`--resume-from-file <path>`,`Load structured HITL resume payload from a file (alternative to --resume-input-json)`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).option(`--disable-topic-segmentation`,`Disable smart topic segmentation for this run`).action(async e=>{await Dr(e)})}function Ar(e){e.command(`sessions`).description(`List or inspect sessions for a data directory`).argument(`[action]`,`Action: list (default) | inspect | export`).option(`-d, --data-dir <path>`,`Data directory path`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`-c, --channel <channel>`,`Filter by channel type: H5 | WEB | KLPA | TASK | CRON | EIP_ASSISTANT`).option(`-s, --session-id <id>`,`Session ID for inspect/export`).option(`--output <format>`,`Output format: text or json`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async(e,t,n)=>{let r=n.opts(),i=e??`list`,a=i===`export`?r.output===`text`?`text`:`json`:r.output===`json`?`json`:`text`;r.dataDir||(k(`error: required option '-d, --data-dir <path>' not specified`),process.exit(1)),r.channel&&r.channel!==`H5`&&r.channel!==`WEB`&&r.channel!==`KLPA`&&r.channel!==`TASK`&&r.channel!==`CRON`&&r.channel!==`EIP_ASSISTANT`&&(k(`Invalid channel: ${r.channel}. Must be 'H5', 'WEB', 'KLPA', 'TASK', 'CRON', or 'EIP_ASSISTANT'`),process.exit(1));try{await U(r.dataDir,r,async()=>{let e=r.sessionStore?y(r.sessionStore):void 0;if(i===`list`){Le(await ee(r.dataDir,r.channel,{storeName:e}),a);return}if(r.sessionId||(k(`error: required option '-s, --session-id <id>' not specified`),process.exit(1)),i===`inspect`){Re(await _(r.dataDir,r.sessionId,{storeName:e}),a);return}if(i===`export`){ze(await d(r.dataDir,r.sessionId,{storeName:e}),a);return}k(`Invalid sessions action: ${i}. Must be 'list', 'inspect', or 'export'`),process.exit(1)})}catch(e){k(`${i===`inspect`?`Error inspecting session`:i===`export`?`Error exporting session`:`Error listing sessions`}: ${e.message}`),process.exit(1)}})}function jr(e){return w.join(e,`workspace`)}function Mr(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function Nr(e,t){let n=[];n.push(`backend: ${e.backend}`),n.push(`provider: ${e.provider}${e.model?` (${e.model})`:``}`);let r=typeof e.custom?.providerSource==`string`?e.custom.providerSource:void 0,i=typeof e.custom?.providerId==`string`?e.custom.providerId:void 0,a=typeof e.custom?.pluginId==`string`?e.custom.pluginId:void 0;r&&n.push(`provider_source: ${r}`),i&&n.push(`provider_id: ${i}`),a&&n.push(`plugin_id: ${a}`),typeof e.files==`number`&&n.push(`files: ${e.files}`),typeof e.chunks==`number`&&n.push(`chunks: ${e.chunks}`),typeof e.dirty==`boolean`&&n.push(`dirty: ${e.dirty}`),e.dbPath&&n.push(`db: ${e.dbPath}`),e.sources?.length&&n.push(`sources: ${e.sources.join(`, `)}`),t&&(e.fts&&(n.push(`fts: enabled=${e.fts.enabled} available=${e.fts.available}`),e.fts.error&&n.push(`fts_error: ${e.fts.error}`)),e.vector&&(n.push(`vector: enabled=${e.vector.enabled} available=${e.vector.available??`unknown`}`),e.vector.dims&&n.push(`vector_dims: ${e.vector.dims}`),e.vector.loadError&&n.push(`vector_error: ${e.vector.loadError}`)),e.cache&&n.push(`cache: enabled=${e.cache.enabled} entries=${e.cache.entries??0}`));let o=Array.isArray(e.custom?.cliWarnings)?e.custom.cliWarnings.filter(e=>typeof e==`string`&&e.length>0):[];for(let e of o)n.push(`warning: ${e}`);return n.join(`
12
+ `)}function Pr(e){let t=e.level===`error`?`plugin error`:`plugin warning`;return e.pluginId?`${t} (${e.pluginId}): ${e.message}`:`${t}: ${e.message}`}function Fr(e){if(!e||e===`cli`)return`cli`;if(e===`cron`)return`cron`;throw Error(`Unsupported dream trigger: ${e}. Expected "cli" or "cron".`)}async function Ir(e){let t=[],n;try{n=await W(e.dataDir,e.pluginsConfig)}catch(e){t.push(`failed to load plugins config: ${e.message}`)}if(!e.shouldInitialize&&!n)return{warnings:t};try{let r=g({config:n,dataDir:e.dataDir,workspaceDir:jr(e.dataDir),bundledDir:Mr()});return t.push(...r.diagnostics.map(Pr)),{pluginSystem:r,warnings:t}}catch(e){return t.push(`failed to initialize plugin system: ${e.message}`),{warnings:t}}}async function Lr(e){let t=w.join(e.dataDir,`.aimax`),{pluginSystem:n,warnings:r}=await Ir({dataDir:e.dataDir,pluginsConfig:e.pluginsConfig,shouldInitialize:!!(e.requirePluginSystem||e.provider||e.providerPlugin)}),i=n?.normalizedConfig.slots.memory,a=e.providerPlugin?.trim()||(e.provider?void 0:i),o=se({providerId:e.provider,pluginId:a,dataDir:e.dataDir,memoryDir:t});return o?{provider:o.provider,providerId:o.registration.id,pluginId:o.registration.pluginId,providerOrigin:`plugin`,warnings:r,pluginSystem:n}:((a||e.provider)&&r.push(`requested memory provider was not resolved; falling back to builtin provider`),{provider:c({dataDir:e.dataDir,memoryDir:t},{includeSessions:e.includeSessions}),providerId:`builtin`,providerOrigin:`builtin`,warnings:r,pluginSystem:n})}function Rr(e,t,n){let r={...e.custom??{},providerSource:t.providerOrigin,providerId:t.providerId,pluginId:t.pluginId,cliWarnings:t.warnings},i={...e,custom:r};return n&&t.providerOrigin===`plugin`?i.custom={...r,note:`deep probe details are provider-defined for plugin memory providers`}:n&&(i.custom={...r,note:`deep probe is only supported by builtin provider`}),i}function zr(e){let t=e.command(`memory`).description(`Manage semantic memory indexing and search`),n=e=>e.option(`--plugins-config <path>`,`Plugins config file path`);n(t.command(`status`)).description(`Show memory index status`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--deep`,`Probe embedding/vector availability`).option(`--index`,`Run a refresh before reporting status`).option(`--include-sessions`,`Include session transcripts in indexing`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--verbose`,`Verbose output`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{await U(e.dataDir,e,async()=>{let n=await Lr({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,pluginsConfig:e.pluginsConfig,includeSessions:e.includeSessions});e.index&&n.provider.sync&&await n.provider.sync(`cli-status`);let r=Rr(n.provider.status(),n,e.deep);O(t===`json`?JSON.stringify(r,null,2):Nr(r,e.deep))})}catch(e){k(`Error getting memory status: ${e.message}`),process.exit(1)}}),n(t.command(`index`)).description(`Reindex memory files`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--include-sessions`,`Include session transcripts in indexing`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--rebuild`,`Force full rebuild from Markdown source`).option(`--verbose`,`Verbose output`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{try{await U(e.dataDir,e,async()=>{let t=await Lr({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,pluginsConfig:e.pluginsConfig,includeSessions:e.includeSessions}),n;if(t.provider.sync&&(await t.provider.sync(e.rebuild?`cli-rebuild`:`cli-index`),n=t.provider.status().custom?.lastRebuildSummary),t.warnings.length>0)for(let e of t.warnings)k(`Warning: ${e}`);e.verbose&&n&&O(JSON.stringify(n,null,2)),O(e.rebuild?`Memory index rebuilt.`:`Memory index refreshed.`)})}catch(e){k(`Error indexing memory: ${e.message}`),process.exit(1)}}),n(t.command(`search [query]`)).description(`Search semantic memory`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--query <text>`,`Search query`).option(`--include-sessions`,`Include session transcripts in search`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async(e,t)=>{let n=t.output===`json`?`json`:`text`,r=t.query?.trim()||e?.trim();r||(k(`Query is required: provide [query] or --query <text>`),process.exit(1));try{await U(t.dataDir,t,async()=>{let e=await(await Lr({dataDir:t.dataDir,provider:t.provider,providerPlugin:t.providerPlugin,pluginsConfig:t.pluginsConfig,includeSessions:t.includeSessions})).provider.search(r);if(n===`json`){O(JSON.stringify(e,null,2));return}if(e.length===0){O(`No results found for: ${r}`);return}O(e.map(e=>{let t=`${e.path}:${e.startLine}-${e.endLine} (${e.score.toFixed(4)}) ${e.snippet}`;return e.citation?`${t}\n${e.citation}`:t}).join(`
13
+ `))})}catch(e){k(`Error searching memory: ${e.message}`),process.exit(1)}}),n(t.command(`dream`)).description(`Trigger Dream Gate host hook for memory plugins`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--trigger <mode>`,`Dream Gate trigger mode: cli (default) or cron`,`cli`).option(`--dry-run`,`Return hook results without plugin-side mutation`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{await U(e.dataDir,e,async()=>{let n=Fr(e.trigger),r=await Lr({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,pluginsConfig:e.pluginsConfig,requirePluginSystem:!0}),i=r.pluginSystem?await r.pluginSystem.registry.hooks.dispatch(`dream_gate`,{dataDir:e.dataDir,memoryDir:w.join(e.dataDir,`.aimax`),providerId:r.providerId,pluginId:r.pluginId,trigger:n,dryRun:!!e.dryRun},{workspaceDir:jr(e.dataDir)}):[],a={ok:!0,trigger:n,providerSource:r.providerOrigin,providerId:r.providerId,pluginId:r.pluginId,resultCount:i.length,results:i,warnings:r.warnings};if(t===`json`){O(JSON.stringify(a,null,2));return}O(`trigger: ${a.trigger}`),O(`provider_source: ${a.providerSource}`),O(`provider_id: ${a.providerId}`),a.pluginId&&O(`plugin_id: ${a.pluginId}`),O(`result_count: ${a.resultCount}`),a.results.length===0?O(`note: no dream_gate hook registered`):O(`results: ${JSON.stringify(a.results)}`);for(let e of a.warnings)O(`warning: ${e}`)})}catch(e){k(`Error running dream gate: ${e.message}`),process.exit(1)}})}function Br(e){return`${e.match.accountId?`${e.match.channel}:${e.match.accountId}`:e.match.channel} -> ${e.agentId}`}function Vr(e){return async t=>{let n=await E(t),r=Ee(n),i=De(n);if(D(n),e.json){console.log(JSON.stringify({agents:r,bindings:i},null,2));return}console.log(`Agents:`);for(let e of r){let n=e.default?` (default)`:``,r=e.name&&e.name!==e.id?`${e.id}${n} (${e.name})`:`${e.id}${n}`;if(console.log(` - ${r}`),e.identity?.emoji||e.identity?.name){let t=[e.identity.emoji,e.identity.name].filter(Boolean).join(` `);console.log(` Identity: ${t}`)}let a=je(t,e.id);if(console.log(` Agent dir: ${a}`),e.model){let t=typeof e.model==`string`?e.model:e.model.primary;console.log(` Model: ${t}`)}let o=i.filter(t=>t.agentId===e.id);if(o.length>0){console.log(` Routing rules:`);for(let e of o)console.log(` - ${Br(e)}`)}}}}function Hr(e,t){return async n=>{T(await E(n),Oe(e))&&(console.error(`Agent "${e}" already exists.`),process.exit(1)),await we(n,{id:e,name:t.name,model:t.model,default:t.default})||(console.error(`Agent "${e}" already exists.`),process.exit(1));let r=je(n,e);console.log(`Agent "${e}" added successfully.`),console.log(` Agent dir: ${r}`)}}function Ur(e){return async t=>{let n=T(await E(t),Oe(e));n||(console.error(`Agent "${e}" not found.`),process.exit(1)),n.default===!0&&(console.error(`Cannot delete default agent "${e}".`),process.exit(1)),await ke(t,e)||(console.error(`Failed to delete agent "${e}".`),process.exit(1)),console.log(`Agent "${e}" deleted.`)}}function Wr(e){return async t=>{let n=await E(t),r=e.agent??D(n);T(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),(!e.bind||e.bind.length===0)&&(console.error(`Please specify --bind <channel>[:<account>]`),process.exit(1));for(let n of e.bind){let[e,...i]=n.split(`:`),a=i.join(`:`),o=[`H5`,`WEB`,`KLPA`,`TASK`,`CRON`,`EIP_ASSISTANT`];o.includes(e)||(console.error(`Invalid channel: ${e}`),console.error(`Valid channels: ${o.join(`, `)}`),process.exit(1)),await Te(t,{agentId:r,match:{channel:e,accountId:a||void 0}}),console.log(`Binding added: ${n} -> ${r}`)}}}function Gr(e){return async t=>{let n=await E(t),r=e.agent??D(n);if(T(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),e.all){let e=await Ae(t,r,`*`);console.log(`Removed ${e} binding(s) for agent "${r}".`)}else if(e.bind&&e.bind.length>0){let n=0;for(let i of e.bind){let[e,...a]=i.split(`:`),o=await Ae(t,r,e,a.join(`:`)||void 0);o>0?(console.log(`Binding removed: ${i} -> ${r}`),n+=o):console.log(`No binding found: ${i} -> ${r}`)}}else console.error(`Please specify --bind <channel>[:<account>] or --all`),process.exit(1)}}function Kr(e){return async t=>{let n=De(await E(t));if(e.agent&&(n=n.filter(t=>t.agentId===e.agent)),e.json){console.log(JSON.stringify(n,null,2));return}if(n.length===0){console.log(`No bindings configured.`);return}console.log(`Routing bindings:`);for(let e of n)console.log(` ${Br(e)}`)}}function qr(e){return async t=>{let n=await E(t),r=e.agent??D(n);T(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),await Me(t,r,{name:e.name,emoji:e.emoji,avatar:e.avatar})||(console.error(`Failed to update identity for agent "${r}".`),process.exit(1)),console.log(`Identity updated for agent "${r}".`)}}function Jr(e,t){let n=e.command(`agents`).description(`Manage agents`),r=e=>e.option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`);r(n.command(`list`).description(`List all configured agents`).option(`-j, --json`,`Output as JSON`).option(`-b, --bindings`,`Show detailed binding rules`)).action(async e=>{let n=t();await U(n,e,async()=>{await Vr(e)(n)})}),r(n.command(`add <id>`).description(`Add a new agent`).option(`-n, --name <name>`,`Display name`).option(`-m, --model <model>`,`Model identifier`).option(`--default`,`Mark as default agent`)).action(async(e,n)=>{let r=t();await U(r,n,async()=>{await Hr(e,n)(r)})}),r(n.command(`delete <id>`).description(`Delete an agent`)).action(async(e,n)=>{let r=t();await U(r,n,async()=>{await Ur(e)(r)})}),r(n.command(`bind`).description(`Bind a channel to an agent`).option(`-a, --agent <id>`,`Target agent ID`).option(`-b, --bind <channel...>`,`Channel binding (e.g., WEB, KLPA:ops)`)).action(async e=>{let n=t();await U(n,e,async()=>{await Wr(e)(n)})}),r(n.command(`unbind`).description(`Unbind a channel from an agent`).option(`-a, --agent <id>`,`Target agent ID`).option(`-b, --bind <channel...>`,`Channel binding to remove`).option(`--all`,`Remove all bindings for the agent`)).action(async e=>{let n=t();await U(n,e,async()=>{await Gr(e)(n)})}),r(n.command(`bindings`).description(`List routing bindings`).option(`-a, --agent <id>`,`Filter by agent ID`).option(`-j, --json`,`Output as JSON`)).action(async e=>{let n=t();await U(n,e,async()=>{await Kr(e)(n)})}),r(n.command(`set-identity`).description(`Set agent identity`).option(`-a, --agent <id>`,`Target agent ID`).option(`-n, --name <name>`,`Agent name`).option(`-e, --emoji <emoji>`,`Agent emoji`).option(`--avatar <path>`,`Avatar path`)).action(async e=>{let n=t();await U(n,e,async()=>{await qr(e)(n)})})}function Y(e){return w.join(e,`workspace`)}function X(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function Yr(e){if(e.length===0){O(`No plugins discovered.`);return}for(let t of e){let e=t.status.padEnd(8,` `);O(`${t.id} ${e} ${t.origin} ${t.source}`)}}function Xr(e){O(`id: ${e.id}`),O(`status: ${e.status}`),O(`origin: ${e.origin}`),O(`source: ${e.source}`),O(`enabled: ${e.enabled}`),e.error&&O(`error: ${e.error}`),O(`tools: ${e.toolCount}`),O(`hooks: ${e.hookCount}`),e.skills.length>0&&O(`skills: ${e.skills.join(`, `)}`)}function Zr(e){return Array.from(new Set((e??[]).map(e=>e.trim()).filter(Boolean)))}function Qr(e){if(e.length===0){O(`LLM allowlist is empty.`);return}for(let t of e)O(t)}function $r(e,t){let n=e.command(`plugins`).description(`Manage AIMax plugins`),r=e=>e.option(`--plugins-config <path>`,`Plugins config file path`),i=e=>e.option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`);i(r(n.command(`list`))).description(`List discovered plugins`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await U(n,e,async()=>{Yr(g({config:await W(n,e.pluginsConfig),dataDir:n,workspaceDir:Y(n),bundledDir:X()}).registry.plugins)})}),i(r(n.command(`info`))).description(`Show plugin details`).argument(`<id>`,`Plugin id`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await U(r,n,async()=>{let t=g({config:await W(r,n.pluginsConfig),dataDir:r,workspaceDir:Y(r),bundledDir:X()}).registry.plugins.find(t=>t.id===e);t||(k(`Plugin not found: ${e}`),process.exit(1)),Xr(t)})}),i(r(n.command(`enable`))).description(`Enable a plugin`).argument(`<id>`,`Plugin id`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await U(r,n,async()=>{let t=await W(r,n.pluginsConfig)??{},i=ae(t);g({config:t,dataDir:r,workspaceDir:Y(r),bundledDir:X()}).registry.plugins.some(t=>t.id===e)||(k(`Plugin not found: ${e}`),process.exit(1)),await G(r,{...t,entries:{...t.entries,[e]:{...t.entries?.[e]??{},enabled:!0}}},n.pluginsConfig),O(`Enabled ${e}`),i.allow.length>0&&!i.allow.includes(e)&&O(`Note: plugins.allow is set; add this plugin id to allowlist if needed.`)})}),i(r(n.command(`disable`))).description(`Disable a plugin`).argument(`<id>`,`Plugin id`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await U(r,n,async()=>{let t=await W(r,n.pluginsConfig)??{};g({config:t,dataDir:r,workspaceDir:Y(r),bundledDir:X()}).registry.plugins.some(t=>t.id===e)||(k(`Plugin not found: ${e}`),process.exit(1)),await G(r,{...t,entries:{...t.entries,[e]:{...t.entries?.[e]??{},enabled:!1}}},n.pluginsConfig),O(`Disabled ${e}`)})}),i(r(n.command(`doctor`))).description(`Validate plugin configuration`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await U(n,e,async()=>{let t=g({config:await W(n,e.pluginsConfig),dataDir:n,workspaceDir:Y(n),bundledDir:X()});if(t.diagnostics.length===0){O(`No plugin issues detected.`);return}for(let e of t.diagnostics)O(`${e.level===`error`?`ERROR`:`WARN`}${e.pluginId?` ${e.pluginId}`:``}: ${e.message}`);t.diagnostics.some(e=>e.level===`error`)&&process.exit(1)})});let a=n.command(`llm-allow`).description(`Manage plugin LLM allowlist`);i(r(a.command(`list`))).description(`List LLM allowlist entries`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await U(n,e,async()=>{Qr(Zr((await W(n,e.pluginsConfig))?.llmAllowlist))})}),i(r(a.command(`add`))).description(`Add entries to the LLM allowlist (plugin id or tool name)`).argument(`<entry...>`,`Plugin id or tool name`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await U(r,n,async()=>{let t=await W(r,n.pluginsConfig)??{},i=Zr([...t.llmAllowlist??[],...e]);await G(r,{...t,llmAllowlist:i},n.pluginsConfig),O(`LLM allowlist updated (${i.length} entries).`)})}),i(r(a.command(`remove`))).description(`Remove entries from the LLM allowlist`).argument(`<entry...>`,`Plugin id or tool name`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await U(r,n,async()=>{let t=await W(r,n.pluginsConfig)??{},i=new Set(e.map(e=>e.trim()).filter(Boolean)),a=Zr(t.llmAllowlist).filter(e=>!i.has(e));await G(r,{...t,llmAllowlist:a},n.pluginsConfig),O(`LLM allowlist updated (${a.length} entries).`)})}),i(r(a.command(`clear`))).description(`Clear the LLM allowlist`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await U(n,e,async()=>{await G(n,{...await W(n,e.pluginsConfig)??{},llmAllowlist:[]},e.pluginsConfig),O(`LLM allowlist cleared.`)})})}function ei(e){e.command(`commands`).description(`List available slash commands for a data directory`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{await U(e.dataDir,e,async()=>{let n=v(await re(e.dataDir,[]));if(t===`json`){O(JSON.stringify(n,null,2));return}O(`Commands`),O(` builtin: ${n.builtin.map(e=>e.name).join(` | `)}`),n.skillCommands.length>0?O(` skills: ${n.skillCommands.map(e=>e.name).join(` | `)}`):O(` skills: (none)`)})}catch(e){k(`Error listing commands: ${e.message}`),process.exit(1)}})}function Z(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir option or AIMAX_DATA_DIR environment variable`);return t}function Q(e){if(!e.sessionId)throw Error(`Session ID is required (--session-id or -s)`);return e.sessionId}function $(e){return e?y(e):void 0}async function ti(e){let t={storeName:e.sessionStoreName},n=e.objective.trim(),r=await b(e.dataDir,e.sessionId,t);if(!r||(await oe(e.dataDir,e.sessionId,r,t)).trim()!==n)return fe(e.dataDir,e.sessionId,{goalId:Ne(),objective:n,status:`active`,tokenBudget:e.tokenBudget??null,tokensUsed:0,timeUsedSeconds:0},{...t,eventSource:`cli`});if(r.status===`complete`)return r;let i={};return r.status===`paused`&&(i.status=`active`),e.tokenBudget!==void 0&&e.tokenBudget!==r.tokenBudget&&(i.tokenBudget=e.tokenBudget),Object.keys(i).length===0?r:await de(e.dataDir,e.sessionId,i,{...t,eventSource:`cli`})}async function ni(e,t){let n=Z(t),r=Q(t),i=$(t.sessionStore),a=e.trim();a||(k(`error: objective cannot be empty`),process.exit(1));let o=t.tokenBudget===void 0||t.tokenBudget===`0`||t.tokenBudget===``?null:Number(t.tokenBudget);o!==null&&(Number.isNaN(o)||o<=0)&&(k(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));let s=await ti({dataDir:n,sessionId:r,sessionStoreName:i,objective:a,tokenBudget:o});O(JSON.stringify({goal:s},null,2))}async function ri(e){let t=Z(e),n=Q(e),r=$(e.sessionStore),i=await b(t,n,{storeName:r});if(!i){O(JSON.stringify({goal:null},null,2));return}let a=await oe(t,n,i,{storeName:r});O(JSON.stringify({goal:{...i,objective:a}},null,2))}async function ii(e){let t=Z(e),n=Q(e),r=$(e.sessionStore),i=await b(t,n,{storeName:r});i||(k(`error: no goal exists for this session`),process.exit(1)),i.status===`complete`&&(k(`error: cannot pause a completed goal`),process.exit(1));let a=await de(t,n,{status:`paused`},{storeName:r,eventSource:`cli`});O(JSON.stringify({goal:a},null,2))}async function ai(e){let t=Z(e),n=Q(e),r=$(e.sessionStore),i=await b(t,n,{storeName:r});if(i||(k(`error: no goal exists for this session`),process.exit(1)),i.status===`complete`&&(k(`error: cannot resume a completed goal`),process.exit(1)),i.status===`budget_limited`&&(k(`error: cannot resume a budget-limited goal; clear or replace it instead`),process.exit(1)),i.status===`active`){O(JSON.stringify({goal:i},null,2));return}let a=await de(t,n,{status:`active`},{storeName:r,eventSource:`cli`});O(JSON.stringify({goal:a},null,2))}async function oi(e){let t=await l(Z(e),Q(e),{storeName:$(e.sessionStore),eventSource:`cli`});O(JSON.stringify({cleared:t},null,2))}function si(e){let t=e.command(`goal`).description(`Manage thread goals for a session`).addHelpText(`after`,a());t.command(`set <objective>`).description(`Set or replace the thread goal (creates new goalId)`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).requiredOption(`-s, --session-id <id>`,`Session ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`--token-budget <n>`,`Optional token budget (positive integer, or 0 for unlimited)`).action(async(e,t)=>{try{await ni(e,t)}catch(e){k(`error: ${e.message}`),process.exit(1)}}),t.command(`get`).description(`Get the current goal as JSON`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).requiredOption(`-s, --session-id <id>`,`Session ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).action(async e=>{try{await ri(e)}catch(e){k(`error: ${e.message}`),process.exit(1)}}),t.command(`pause`).description(`Pause the current goal`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).requiredOption(`-s, --session-id <id>`,`Session ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).action(async e=>{try{await ii(e)}catch(e){k(`error: ${e.message}`),process.exit(1)}}),t.command(`resume`).description(`Resume a paused goal`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).requiredOption(`-s, --session-id <id>`,`Session ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).action(async e=>{try{await ai(e)}catch(e){k(`error: ${e.message}`),process.exit(1)}}),t.command(`clear`).description(`Clear the current goal`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).requiredOption(`-s, --session-id <id>`,`Session ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).action(async e=>{try{await oi(e)}catch(e){k(`error: ${e.message}`),process.exit(1)}})}const ci=[`progress`,`error`,`hitl`];function li(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir or AIMAX_DATA_DIR`);return t}function ui(e){if(!e?.trim())return new Set(ci);let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean),n=new Set([`start`,`text`,`progress`,`done`,`error`,`hitl`,`title_updated`]),r=new Set;for(let e of t){if(!n.has(e))throw Error(`Invalid stream event: ${e}. Must be one of start,text,progress,done,error,hitl`);r.add(e)}return r.size>0?r:new Set(ci)}function di(e){return e?y(e):void 0}function fi(e){let t=[];return e.callbackUrl&&t.push(new Zt(e.callbackUrl)),e.streamUrl&&t.push(new sn(e.streamUrl,ui(e.streamEvents),e.streamAuthToken)),new Xt(t)}async function pi(e){let t=li(e);await U(t,e,async()=>{N(t);let n=new F(`cancel command`),r=e.channel??`WEB`,i=e.output===`json`?`json`:`text`,a=fi(e),o=di(e.sessionStore);try{let s=await te(t,e.sessionId,{storeName:o});if(!s)throw Error(`No pending HITL request found for session "${e.sessionId}"`);let c=e.requestId??s.request.requestId;if(s.request.requestId!==c)throw Error(`Request ID mismatch: pending is "${s.request.requestId}", got "${c}"`);if(!(await ce({dataDir:t,sessionStoreName:o,sessionId:e.sessionId,requestId:c,resolution:{requestId:c,sessionId:e.sessionId,action:`cancel`,submittedAt:new Date().toISOString(),submittedBy:{channel:r}}})).state)throw Error(`Failed to cancel HITL request`);let l={type:`hitl_cancelled`,sessionId:e.sessionId,requestId:c,reason:e.reason??`cancelled by operator`};i===`text`&&A(l),await a.send({type:`progress`,sessionId:e.sessionId,channel:r,messageId:e.messageId,event:l}),n.end(),process.exit(0)}catch(t){let i=t;await a.send({type:`error`,sessionId:e.sessionId,channel:r,messageId:e.messageId,message:i.message}),P.error(`cancel command error: ${i.message}`),k(`Fatal: ${i.message}`),n.end(),process.exit(1)}finally{await a.close()}})}function mi(e){e.command(`cancel`).description(`Cancel a pending HITL request`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).requiredOption(`-s, --session-id <id>`,`Session ID containing the pending HITL request`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`--request-id <id>`,`HITL request ID to cancel`).option(`--reason <text>`,`Human-readable cancel reason`).option(`-c, --channel <channel>`,`Channel type (default: WEB)`,`WEB`).option(`--callback-url <url>`,`HTTP callback URL for progress events`).option(`--stream-url <url>`,`WebSocket URL for streaming text events`).option(`--stream-auth-token <token>`,`Auth token for WebSocket streaming`).option(`--stream-events <list>`,`Comma-separated stream events`).option(`--message-id <id>`,`Message ID for correlating events`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{await pi(e)})}function hi(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir option or AIMAX_DATA_DIR environment variable`);return t}function gi(e){return e.query?.trim()||void 0}function _i(e){if(!e)return;let t=Number(e);if(!Number.isFinite(t)||t<=0)throw Error(`--timeout must be a positive number of milliseconds`);return t}function vi(e){if(!e)return;let t=Number(e);if(!Number.isInteger(t)||t<=0)throw Error(`--max-tokens must be a positive integer`);return t}async function yi(e){if(e.filePath){if(!w.isAbsolute(e.filePath))throw Error(`--file-path must be an absolute path`);try{await S.access(e.filePath)}catch(e){throw Error(`Failed to access --file-path: ${e.message}`)}return{source:`file`,filePath:e.filePath}}let t=e.content;if(!t||!t.trim())throw Error(`Either --file-path or --content must be provided`);return{source:`content`,content:t}}async function bi(e){let t=null;try{let n=hi(e);N(n),t=new F(`summarize command`);let r=gi(e),i=await yi(e),a=Lt({apiFormat:e.apiFormat,baseUrl:e.baseUrl,apiKey:e.apiKey,model:e.model,contextWindow:2e5}),o=_i(e.timeout),s=vi(e.maxTokens);P.info(`summarize command started`,{dataDir:n,source:i.source,filePath:i.source===`file`?i.filePath:void 0,queryLength:r?.length,contentLength:i.source===`content`?i.content.length:void 0,timeoutMs:o,maxTokens:s});let c=await x({dataDir:n,channel:`WEB`,message:xi(i,r),llm:{...a,maxTokens:s},timeoutMs:o});O(c.text.trim()),P.info(`summarize command succeeded`,{source:i.source,summaryLength:c.text.length,durationMs:c.durationMs}),t.end()}catch(e){P.error(`summarize command error: ${e.message}`),k(`Fatal: ${e.message}`),t?.end(),process.exit(1)}}function xi(e,t){return e.source===`file`?[t?`Summarize exactly one file for the query below.`:`Summarize exactly one file.`,`Read only the absolute file path provided here. Do not search, browse, read other files, execute commands, modify files, or perform any other processing.`,`Return only the summary text.`,``,...t?[`Query:\n${t}`,``]:[],`Input source: file`,`File path: ${e.filePath}`].join(`
14
+ `):[t?`Summarize the provided content for the query below.`:`Summarize the provided content.`,t?`Use only the provided content and query. Do not search, browse, read files, execute commands, modify files, or perform any other processing.`:`Use only the provided content. Do not search, browse, read files, execute commands, modify files, or perform any other processing.`,`Return only the summary text.`,``,...t?[`Query:\n${t}`,``]:[],`Input source: content`,`Source content:`,`<source>`,e.content,`</source>`].join(`
15
+ `)}function Si(e){e.command(`summarize`).description(`Summarize one absolute file path or inline content`).option(`--file-path <path>`,`Absolute file path to summarize`).option(`--content <text>`,`Inline text content to summarize when --file-path is not provided`).option(`--query <text>`,`Optional search target or current description to focus the summary`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-format <format>`,`LLM API format: openai-completions or anthropic-messages (overrides AIMAX_API_FORMAT)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY)`).option(`--model <name>`,`LLM model name (overrides AIMAX_MODEL)`).option(`--timeout <ms>`,`Execution timeout in milliseconds`).option(`--max-tokens <number>`,`Maximum number of tokens for model output`).action(async e=>{await bi(e)})}const Ci=e(import.meta.url)(`../package.json`);function wi(){return process.env.AIMAX_DATA_DIR||process.cwd()}function Ti(){let e=new t;return e.name(`aimax`).description(`AIMax CLI — runs agent tasks in a containerized environment`).version(Ci.version),kr(e),Fn(e),si(e),mi(e),Ar(e),Si(e),ei(e),Pt(e),zr(e),Jr(e,wi),$r(e,wi),e}export{et as a,P as i,wi as n,N as r,Ti as t};
package/dist/program.js CHANGED
@@ -1 +1 @@
1
- import{n as e,t}from"./program-BTLD1DwI.js";export{t as createProgram,e as getDataDir};
1
+ import{n as e,t}from"./program-C2WFt_WL.js";export{t as createProgram,e as getDataDir};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gencode/cli",
3
- "version": "0.8.9",
3
+ "version": "0.8.10",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "aimax": "./dist/bin.js"
@@ -1,15 +0,0 @@
1
- import{createRequire as e}from"node:module";import{Command as t}from"commander";import{GoalConflictError as n,applyCliGoalBeforeRun as r,bootstrapMountLayout as i,buildAimaxGoalCliHelpExtra as a,buildResumeNarration as o,clearPendingUiTool as s,createBuiltinMemoryProvider as c,deleteGoal as l,ensureBootstrapMountLayout as u,exportSession as d,formatApprovalResolution as f,formatClarifyResolution as p,formatReviewResolution as m,hasBootstrapSentinel as h,initializePluginSystem as g,inspectSession as _,listAvailableSlashCommands as v,listSessionSummaries as ee,loadPendingHitl as te,loadPendingUiTool as ne,loadSkillsWithPluginDirs as re,loadTranscript as ie,normalizePluginsConfig as ae,normalizeSessionStoreName as y,readGoal as b,resolveGoalObjective as oe,resolveMemoryProvider as se,resolvePendingHitl as ce,resolvePendingUiTool as le,rewriteTranscript as ue,runAgent as de,updateGoal as fe,writeGoal as pe}from"@gencode/agents";import{formatTaskForDisplay as me,isAgentDiagnosticEvent as he,isHitlTool as ge,parseMatchedTextToResolution as _e,parseTextToResolution as ve}from"@gencode/shared";import x from"node:fs/promises";import S from"node:fs";import C from"node:path";import ye from"node:os";import{execFile as be,execFileSync as xe}from"node:child_process";import Se from"log4js";import Ce from"gensign-node";import{fileURLToPath as we}from"node:url";import{addAgent as Te,addBinding as Ee,getAgentConfig as w,listAgents as De,listBindings as Oe,loadAgentsConfig as T,normalizeAgentId as ke,removeAgent as Ae,removeBindings as je,resolveAgentDir as Me,resolveDefaultAgentId as Ne,updateAgentIdentity as Pe}from"@gencode/agents/config";import{randomUUID as Fe}from"node:crypto";function Ie(e){if(typeof e==`string`)return e;let t=JSON.stringify(e);return t===void 0?String(e):t}function Le(e){process.stdout.write(e)}function E(e){process.stdout.write(e+`
2
- `)}function D(e){process.stderr.write(e+`
3
- `)}function O(e){switch(e.type){case`start`:E(`\n[start] ${e.message}`);break;case`text`:Le(e.text);break;case`stream_text_delta`:Le(e.text);break;case`bootstrap`:E(`\n[bootstrap:${e.phase}] ${e.dataDir}`);break;case`session_reset`:E(`\n[session:${e.action}] ${e.message}`);break;case`tool_start`:E(`\n[tool:${e.name}] ${JSON.stringify(e.input??{})}`);break;case`tool_end`:{let t=Ie(e.output);E(`[tool:${e.name}] ${e.isError?`ERROR`:`OK`} ${t.slice(0,200)}`);break}case`compaction`:E(`\n[compaction${e.layer?`:${e.layer}`:``}] ${e.reason}${e.strategy?` (${e.strategy})`:``}`);break;case`skill_used`:E(`\n[skill] ${e.skillName} agent=${e.agent} task=${e.taskId}`);break;case`custom`:E(`\n[plugin:${e.pluginId}] ${e.name}${e.label?` ${e.label}`:``}${e.data?` ${JSON.stringify(e.data)}`:``}`);break;case`error`:D(`\n[error] ${e.message}`);break;case`diagnostic`:break;case`subagent_spawn`:E(`\n[subagent:spawn]${e.label?` "${e.label}"`:``} ${me(e.task)}`);break;case`subagent_complete`:E(`[subagent:${e.status}] ${me(e.task)}`);break;case`hitl_requested`:if(E(`\n[hitl:${e.request.kind}] ${e.request.title}`),E(` prompt: ${e.request.prompt}`),E(` requestId: ${e.request.requestId}`),e.request.input.mode===`choice`)for(let t of e.request.input.choices)E(` - [${t.id}] ${t.label}`);break;case`hitl_resumed`:E(`\n[hitl:resumed] requestId=${e.requestId} action=${e.resolution.action}`);break;case`hitl_expired`:E(`\n[hitl:expired] requestId=${e.requestId} reason=${e.reason}`);break;case`hitl_cancelled`:E(`\n[hitl:cancelled] requestId=${e.requestId}${e.reason?` reason=${e.reason}`:``}`);break;case`ui_tool_request`:E(`\n[ui-tool:${e.request.toolName}] ${e.request.outputSchema.title}`),E(` requestId: ${e.request.requestId}`),E(` toolCallId: ${e.request.toolCallId}`);break;case`ui_tool_result`:E(`\n[ui-tool:resumed] requestId=${e.requestId} tool=${e.toolName}`);break}}function Re(e,t){if(t===`json`){e&&E(JSON.stringify(e,null,2));return}E(`
4
- `),E(`session: ${e.sessionId}`),E(`duration: ${e.durationMs}ms`),E(`tokens: input=${e.usage.input} output=${e.usage.output} total=${e.usage.total}`),e.context&&(E(`context: ${e.context.snapshotPath}`),E(`tool-results: ${e.context.toolResultsDir}`)),e.error&&D(`error: ${e.error}`)}function ze(e,t){if(t===`json`){E(JSON.stringify(e,null,2));return}if(e.length===0){E(`No sessions found.`);return}for(let t of e){let e=t.createdAt?new Date(t.createdAt).toLocaleString():`unknown`,n=t.goalStatus?` [GOAL:${t.goalStatus}]`:` [GOAL:—]`;E(`${t.id} ${e} [${t.channel}]${n} ${t.title}`)}}function Be(e,t){if(t===`json`){E(JSON.stringify(e,null,2));return}E(`session: ${e.id}`),e.metadata&&(E(`title: ${e.metadata.title}`),E(`channel: ${e.metadata.channel}`),E(`created: ${e.metadata.createdAt}`),E(`updated: ${e.metadata.updatedAt}`)),E(`transcript: ${e.transcriptPath}`),E(`entries: ${e.transcriptEntryCount}`),E(`context: ${e.contextSnapshotPath}`),E(`session-memory: ${e.sessionMemoryPath}`),E(`collapse-log: ${e.collapseLogPath}`),E(`read-states: ${e.readStateCount}`),E(`tool-results: ${e.toolResultRefCount}`),E(`tool-results-dir: ${e.toolResultsDir}`)}function Ve(e,t){if(t===`json`){E(JSON.stringify(e,null,2));return}E(`session: ${e.id}`),E(`transcript: ${e.paths.transcriptPath}`),E(`context: ${e.paths.contextSnapshotPath}`),E(`session-memory: ${e.paths.sessionMemoryPath}`),E(`collapse-log: ${e.paths.collapseLogPath}`),E(`tool-results-dir: ${e.paths.toolResultsDir}`),E(`transcript-entries: ${e.transcript.length}`),E(`read-states: ${e.context.readStates.length}`),E(`tool-results: ${e.context.toolResults.length}`),E(`collapse-spans: ${e.context.compaction.collapseSpans.length}`)}function He(e,t){if(t===`json`){E(JSON.stringify(e,null,2));return}E(`Bootstrap completed.`),E(`dataDir: ${e.dataDir}`),E(`created dirs: ${e.createdDirs.length}`),E(`created files: ${e.createdFiles.length}`),E(`skipped dirs: ${e.skippedDirs.length}`),E(`skipped files: ${e.skippedFiles.length}`)}function Ue(e){let t=new Intl.DateTimeFormat(`en-CA`,{timeZone:`Asia/Shanghai`,year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1}).formatToParts(e);return Object.fromEntries(t.map(e=>[e.type,e.value]))}function We(e=new Date){let t=Ue(e),n=String(e.getMilliseconds()).padStart(3,`0`);return`${t.year}-${t.month}-${t.day} ${t.hour}:${t.minute}:${t.second}.${n}`}let k=function(e){return e.INFO=`INFO`,e.ERROR=`ERROR`,e.WARN=`WARN`,e}({}),A=null;function Ge(){return We()}function Ke(e){if(!e)return``;let t=Object.entries(e).filter(([,e])=>e!==void 0).map(([e,t])=>`${e}=${qe(t)}`);return t.length>0?` ${t.join(` `)}`:``}function qe(e){return JSON.stringify(Je(e,new WeakSet))??`undefined`}function Je(e,t){return typeof e==`bigint`?e.toString():e==null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`?e:e instanceof Error?{name:e.name,message:e.message,stack:e.stack}:typeof e!=`object`&&typeof e!=`function`?String(e):t.has(e)?`[Circular]`:(t.add(e),Array.isArray(e)?e.map(e=>Je(e,t)):Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0).map(([e,n])=>[e,Je(n,t)])))}function Ye(e){return C.join(e,`.aimax`)}function Xe(e){return{appLogPath:C.join(e,`app.log`),errorLogPath:C.join(e,`errors.log`)}}function Ze(e){let{appLogPath:t,errorLogPath:n}=Xe(e);Se.configure({appenders:{appFile:{type:`file`,filename:t,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`messagePassThrough`}},errorFile:{type:`file`,filename:n,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`messagePassThrough`}},errorsOnly:{type:`logLevelFilter`,appender:`errorFile`,level:`error`,maxLevel:`fatal`}},categories:{default:{appenders:[`appFile`,`errorsOnly`],level:`info`}}})}function Qe(e,t,n){return`[${Ge()}] [${e}] ${t}${Ke(n)}`}function $e(e,t,n){process.stderr.write(`${Qe(e,t,n)}\n`)}function et(e,t,n){if(!A){$e(e,t,n);return}let r=Qe(e,t,n),i=Se.getLogger();if(e===k.ERROR){i.error(r);return}if(e===k.WARN){i.warn(r);return}i.info(r)}function j(e){let t=Ye(e);S.mkdirSync(t,{recursive:!0}),Ze(t),A={dataDir:e,logDir:t}}function tt(){return A?{...A}:null}async function nt(){await Se.shutdown()}const M={info:(e,t)=>et(k.INFO,e,t),warn:(e,t)=>et(k.WARN,e,t),error:(e,t)=>et(k.ERROR,e,t)};var rt=class{startTime;name;constructor(e){this.name=e,this.startTime=Date.now()}end(){let e=Date.now()-this.startTime;return M.info(`${this.name} completed in ${e}ms`),e}};const it=`.aimax`,at=`${it}.pre-gocryptfs.`,ot=[`fusermount3`,`fusermount`,`umount`],st=[{command:`fusermount3`,args:[`-u`],label:`fusermount3 -u`},{command:`fusermount3`,args:[`-uz`],label:`fusermount3 -uz`},{command:`fusermount`,args:[`-u`],label:`fusermount -u`},{command:`fusermount`,args:[`-uz`],label:`fusermount -uz`},{command:`umount`,args:[],label:`umount`},{command:`umount`,args:[`-l`],label:`umount -l`}];function ct(e){return C.join(e,`.aimax.enc`)}function lt(e){return C.join(e,it)}function ut(e){return C.join(e,`${at}${process.pid}.${Date.now()}`)}function dt(e){return C.join(e,`${it}.plaintext-restore.${process.pid}.${Date.now()}`)}function ft(e){return e.replace(/\\([0-7]{3})/g,(e,t)=>String.fromCharCode(Number.parseInt(t,8)))}async function N(e){try{let t=await ht.read(),n=C.resolve(e);for(let e of t.split(`
5
- `)){if(!e.trim())continue;let t=e.split(` `);if(t.length>=5&&C.resolve(ft(t[4]??``))===n)return!0}return!1}catch{return!1}}function pt(e){try{let t=S.readFileSync(`/proc/self/mountinfo`,`utf-8`),n=C.resolve(e);for(let e of t.split(`
6
- `)){if(!e.trim())continue;let t=e.split(` `);if(t.length>=5&&C.resolve(ft(t[4]??``))===n)return!0}return!1}catch{return!1}}async function mt(){return await x.readFile(`/proc/self/mountinfo`,`utf-8`)}const ht={read:mt};async function P(e){try{return await x.stat(e),!0}catch(e){if(e.code===`ENOENT`)return!1;throw e}}async function F(e){await x.mkdir(e,{recursive:!0})}async function gt(e){if(await F(e),(await x.readdir(e)).length>0)throw Error(`Refusing to mount encrypted .aimax over non-empty directory: ${e}. Clear stale plaintext files or disable --encrypt-sessions for this run.`)}async function I(e){return await P(e)?(await x.readdir(e)).length===0:!0}async function L(e){if(await P(e))return(await x.readdir(e)).length}async function _t(e){if(!await P(C.join(e,`gocryptfs.conf`)))throw Error(`Encrypted .aimax directory exists but is not initialized: ${e}. Remove the incomplete .aimax.enc directory or restore it from backup before retrying --encrypt-sessions.`)}async function vt(e){return(await x.readdir(e,{withFileTypes:!0})).filter(e=>e.isDirectory()&&e.name.startsWith(at)).map(t=>C.join(e,t.name)).sort()}async function yt(e,t){if(!await P(t))return null;let n=ut(e);return M.info(`--encrypt-sessions moving plaintext .aimax aside before migration`,{plainDir:t,backupDir:n}),await x.rename(t,n),n}async function R(e,t,n){M.info(`--encrypt-sessions copying plaintext backup into encrypted mount`,{backupDir:e,plainDir:t,force:n}),await x.cp(e,t,{recursive:!0,force:n})}async function bt(e,t){if(e.length===0)return[];await F(t);let n=[];for(let r of e)await P(r)&&(await R(r,t,!0),await x.rm(r,{recursive:!0,force:!0}),M.info(`--encrypt-sessions restored interrupted plaintext backup after failed migration`,{backupDir:r,plainDir:t}),n.push(r));return n}async function xt(e){let t=ct(e),n=lt(e),r=await P(t);if(!r)return;let i=r&&await P(C.join(t,`gocryptfs.conf`)),a=await P(n),o=a?await N(n):!1,s=await I(n);if(M.info(`plaintext .aimax restore check for disabled --encrypt-sessions`,{dataDir:e,encryptedDir:t,plainDir:n,encryptedDirExists:r,encryptedDirInitialized:i,plainDirExists:a,plainDirMountPoint:o,plainDirEntryCount:await L(n)}),!i){M.warn(`plaintext .aimax restore skipped because .aimax.enc is not initialized`,{encryptedDir:t,plainDir:n}),await F(n);return}if(o){M.warn(`plaintext .aimax restore skipped because .aimax is already a mount point`,{plainDir:n,encryptedDir:t});return}if(!s){M.info(`plaintext .aimax restore skipped because plaintext .aimax already contains data`,{plainDir:n,encryptedDir:t,plainDirEntryCount:await L(n)});return}try{await wt()}catch(e){M.warn(`plaintext .aimax restore unavailable; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e),plainDir:n,encryptedDir:t}),await F(n);return}let c=dt(e),l=!1;try{await gt(n),await Tt(t,n),l=!0,await x.rm(c,{recursive:!0,force:!0}),await F(c),await x.cp(n,c,{recursive:!0,force:!0}),M.info(`plaintext .aimax restore copied encrypted history to staging directory`,{plainDir:n,encryptedDir:t,restoreDir:c,restoredEntryCount:await L(c)}),await Dt(n),l=!1,await x.rm(n,{recursive:!0,force:!0}),await x.rename(c,n),M.info(`plaintext .aimax restore completed for disabled --encrypt-sessions`,{plainDir:n,encryptedDir:t})}catch(e){l&&await Dt(n).catch(e=>{M.warn(`plaintext .aimax restore failed to unmount during rollback`,{error:e instanceof Error?e.message:String(e),plainDir:n,encryptedDir:t})}),await x.rm(c,{recursive:!0,force:!0}).catch(()=>{}),await F(n).catch(()=>{}),M.warn(`plaintext .aimax restore failed; continuing with existing plaintext .aimax`,{error:e instanceof Error?e.message:String(e),plainDir:n,encryptedDir:t})}}async function St(e){let t=C.join(ye.tmpdir(),`aimax-gocryptfs-pass.${process.pid}.${Date.now()}`);await x.writeFile(t,`wizard_aimax@2026
7
- `,{mode:384});try{return await e(t)}finally{await x.rm(t,{force:!0})}}async function Ct(e){let t=e.includes(`-init`)?`init`:`mount`;M.info(`--encrypt-sessions starting gocryptfs ${t}`);try{await jt(`gocryptfs`,e),M.info(`--encrypt-sessions completed gocryptfs ${t}`)}catch(n){let r=n instanceof Error?n.message:String(n);throw M.warn(`--encrypt-sessions failed gocryptfs ${t}`,{error:r}),Error(`gocryptfs ${e.join(` `)} failed: ${r}`)}}async function wt(){M.info(`--encrypt-sessions checking encryption dependencies`),await Nt(`gocryptfs`,`required for --encrypt-sessions`),M.info(`--encrypt-sessions dependency available`,{command:`gocryptfs`});for(let e of ot)if(await Mt(e)){M.info(`--encrypt-sessions unmount dependency available`,{command:e});return}throw Error(`--encrypt-sessions requires one of ${ot.join(`, `)} to be installed for secure unmount cleanup.`)}async function Tt(e,t){M.info(`--encrypt-sessions mounting encrypted .aimax`,{encryptedDir:e,plainDir:t}),await St(async n=>{await Ct([`-q`,`-passfile`,n,e,t])})}async function Et(e){M.info(`--encrypt-sessions initializing encrypted .aimax directory`,{encryptedDir:e}),await St(async t=>{await Ct([`-q`,`-init`,`-passfile`,t,e])})}async function Dt(e){let t=[];M.info(`--encrypt-sessions unmounting encrypted .aimax`,{plainDir:e});for(let n of st)try{if(M.info(`--encrypt-sessions attempting encrypted .aimax unmount`,{command:n.label,plainDir:e}),await jt(n.command,[...n.args,e]),!await N(e)){M.info(`--encrypt-sessions unmounted encrypted .aimax`,{command:n.label,plainDir:e});return}let r=`${n.label} returned success but ${e} is still mounted`;t.push(r),M.warn(`--encrypt-sessions unmount command returned success but mountpoint remains`,{command:n.label,plainDir:e})}catch(r){let i=Pt(n.label,r);t.push(i),M.warn(`--encrypt-sessions unmount attempt failed`,{command:n.label,plainDir:e,error:r instanceof Error?r.message:String(r)})}throw Error(`Failed to unmount ${e}: ${t.join(`; `)}`)}function Ot(e){for(let t of st)try{if(xe(t.command,[...t.args,e],{stdio:`ignore`}),!pt(e))return}catch{}}function kt(e){let t=!1,n=()=>{t||(t=!0,Ot(e))},r=()=>n(),i=()=>{n(),process.exit(130)},a=()=>{n(),process.exit(143)};return process.once(`exit`,r),process.once(`SIGINT`,i),process.once(`SIGTERM`,a),{release(){process.removeListener(`exit`,r),process.removeListener(`SIGINT`,i),process.removeListener(`SIGTERM`,a)}}}async function At(e){let t=ct(e),n=lt(e),r=await P(n),i=await P(t),a=i&&await P(C.join(t,`gocryptfs.conf`)),o=r?await N(n):!1;M.info(`--encrypt-sessions preparing encrypted .aimax mount`,{dataDir:e,encryptedDir:t,plainDir:n,plainDirExists:r,encryptedDirExists:i,encryptedDirInitialized:a,plainDirMountPoint:o,plainDirEntryCount:await L(n),encryptedDirEntryCount:await L(t)});let s=()=>({mounted:!1,plainDir:n,encryptedDir:t,async cleanup(){}});try{await wt()}catch(e){return M.warn(`--encrypt-sessions is unavailable; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e)}),await F(n),s()}if(await N(n))return M.warn(`--encrypt-sessions found existing .aimax mount; continuing without taking ownership`,{plainDir:n}),s();let c=null,l=[],u=null,d=null,f=!1;try{if(l=await vt(e),l.length>0&&M.warn(`--encrypt-sessions found interrupted pre-gocryptfs migration backups`,{count:l.length}),!await P(t))if(M.info(`--encrypt-sessions encrypted .aimax directory does not exist; starting first-time migration`,{encryptedDir:t,plainDir:n,resumedBackupCount:l.length}),l.length>0?u=await yt(e,n):c=await yt(e,n),await F(t),await Et(t),await F(n),await Tt(t,n),f=!0,d=kt(n),M.info(`--encrypt-sessions mounted encrypted .aimax`,{plainDir:n,encryptedDir:t}),l.length>0){for(let e of l)await R(e,n,!0);u&&=(await R(u,n,!1),await x.rm(u,{recursive:!0,force:!0}),M.info(`--encrypt-sessions removed residual plaintext backup after migration`,{backupDir:u}),null);for(let e of l)await x.rm(e,{recursive:!0,force:!0}),M.info(`--encrypt-sessions removed resumed plaintext migration backup`,{backupDir:e});l=[]}else c&&=(await R(c,n,!0),await x.rm(c,{recursive:!0,force:!0}),M.info(`--encrypt-sessions removed plaintext migration backup`,{backupDir:c}),null);else if(M.info(`--encrypt-sessions encrypted .aimax directory exists; mounting existing encrypted data`,{encryptedDir:t,plainDir:n,resumedBackupCount:l.length,plainDirEntryCount:await L(n)}),await _t(t),l.length>0?u=await yt(e,n):await I(n)||(c=await yt(e,n)),await gt(n),await Tt(t,n),f=!0,d=kt(n),M.info(`--encrypt-sessions mounted encrypted .aimax`,{plainDir:n,encryptedDir:t}),l.length>0){for(let e of l)await R(e,n,!0);u&&=(await R(u,n,!1),await x.rm(u,{recursive:!0,force:!0}),M.info(`--encrypt-sessions removed residual plaintext backup after migration`,{backupDir:u}),null);for(let e of l)await x.rm(e,{recursive:!0,force:!0}),M.info(`--encrypt-sessions removed resumed plaintext migration backup`,{backupDir:e});l=[]}else c&&=(await R(c,n,!0),await x.rm(c,{recursive:!0,force:!0}),M.info(`--encrypt-sessions removed plaintext migration backup`,{backupDir:c}),null);return M.info(`--encrypt-sessions prepared encrypted .aimax mount result`,{mounted:f,plainDir:n,encryptedDir:t,plainDirMountPoint:await N(n),plainDirEntryCount:await L(n),encryptedDirEntryCount:await L(t)}),{mounted:f,plainDir:n,encryptedDir:t,async cleanup(){if(d?.release(),!f){M.info(`--encrypt-sessions cleanup skipped because encrypted .aimax is not mounted`,{plainDir:n,encryptedDir:t});return}f=!1,M.info(`--encrypt-sessions cleanup started`,{plainDir:n,encryptedDir:t});try{await Dt(n),M.info(`--encrypt-sessions cleanup completed`,{plainDir:n,encryptedDir:t})}catch(e){M.warn(`--encrypt-sessions failed to unmount encrypted .aimax; continuing shutdown`,{error:e instanceof Error?e.message:String(e)})}}}}catch(e){d?.release(),f&&await Dt(n).catch(e=>{M.warn(`--encrypt-sessions failed to unmount during mount rollback`,{error:e instanceof Error?e.message:String(e),plainDir:n,encryptedDir:t})}),c&&await P(c)&&await I(n)&&(await x.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await x.rename(c,n).catch(()=>{}),M.info(`--encrypt-sessions restored plaintext backup after failed migration`,{backupDir:c,plainDir:n})),u&&await P(u)&&await I(n)&&(await x.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await x.rename(u,n).catch(()=>{}),M.info(`--encrypt-sessions restored residual plaintext backup after failed migration`,{backupDir:u,plainDir:n}));let r=await bt(l,n).catch(e=>(M.warn(`--encrypt-sessions failed to restore interrupted plaintext backups after failed migration`,{error:e instanceof Error?e.message:String(e),plainDir:n,backupCount:l.length}),[]));return l=l.filter(e=>!r.includes(e)),M.warn(`--encrypt-sessions failed; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e),mountedBeforeFailure:f,plainDir:n,encryptedDir:t,backupDir:c,residualPlainBackupDir:u,resumedBackupCount:l.length}),await F(n),s()}}async function z(e,t,n){if(!t.encryptSessions)return await xt(e),n();M.info(`--encrypt-sessions wrapper starting encrypted .aimax preparation`,{dataDir:e});let r=await At(e);M.info(`--encrypt-sessions wrapper prepared encrypted .aimax state`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir});try{return M.info(`--encrypt-sessions wrapper entering protected operation`,{dataDir:e,mounted:r.mounted}),await n(r)}finally{M.info(`--encrypt-sessions wrapper starting cleanup`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir}),await r.cleanup(),M.info(`--encrypt-sessions wrapper finished cleanup`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir})}}async function jt(e,t){await new Promise((n,r)=>{be(e,t,{encoding:`utf-8`},e=>{if(e){r(e);return}n()})})}async function Mt(e){try{return await jt(`sh`,[`-c`,`command -v "${e}" >/dev/null 2>&1`]),!0}catch{return!1}}async function Nt(e,t){if(!await Mt(e))throw Error(`--encrypt-sessions requires ${e}: ${t}.`)}function Pt(e,t){return`${e} failed: ${t instanceof Error?t.message:String(t)}`}function Ft(e){e.command(`bootstrap`).description(`Initialize the data directory with required directories and templates`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{He(await z(e.dataDir,e,async()=>i(e.dataDir)),t)}catch(e){D(`Error bootstrapping data directory: ${e.message}`),process.exit(1)}})}function It(e){return Ce.sm4_encrypt_ecb(e)}function Lt(e){return It(e)}function Rt(e={}){let t=zt(e.apiFormat??process.env.AIMAX_API_FORMAT),n=e.baseUrl??process.env.AIMAX_BASE_URL,r=process.env.AIMAX_AUTH_TOKEN,i=e.authToken?Lt(e.authToken):r?Lt(r):e.apiKey??process.env.AIMAX_API_KEY,a=e.model??process.env.AIMAX_MODEL,o=[];if(n||o.push(`--base-url / AIMAX_BASE_URL`),i||o.push(`--api-key / AIMAX_API_KEY`),a||o.push(`--model / AIMAX_MODEL`),o.length>0)throw Error(`Missing required LLM configuration: ${o.join(`, `)}`);return{apiFormat:t,baseUrl:n,apiKey:i,model:a,contextWindow:e.contextWindow??(process.env.AIMAX_CONTEXT_WINDOW?Number(process.env.AIMAX_CONTEXT_WINDOW):void 0),flashModel:e.flashModel??process.env.AIMAX_FLASH_MODEL}}function zt(e){if(!e||e===`openai-completions`||e===`anthropic-messages`)return e;throw Error(`Unsupported LLM API format: ${e}`)}function Bt(e,t){return t?C.resolve(t):C.join(e,`.aimax`,`plugins.json`)}async function B(e,t){let n=Bt(e,t);try{let e=await x.readFile(n,`utf-8`);return JSON.parse(e)}catch(e){if(e.code===`ENOENT`)return;throw e}}async function V(e,t,n){let r=Bt(e,n);await x.mkdir(C.dirname(r),{recursive:!0}),await x.writeFile(r,JSON.stringify(t,null,2),`utf-8`)}function H(e){return typeof e==`object`&&!!e}function Vt(e){return H(e)&&e.type===`text`&&typeof e.text==`string`&&(e.textSignature===void 0||typeof e.textSignature==`string`)}function Ht(e){return H(e)&&e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`}function Ut(e){return H(e)&&e.type===`thinking`&&typeof e.thinking==`string`&&(e.thinkingSignature===void 0||typeof e.thinkingSignature==`string`)&&(e.redacted===void 0||typeof e.redacted==`boolean`)}function Wt(e){return H(e)&&e.type===`toolCall`&&typeof e.id==`string`&&typeof e.name==`string`&&H(e.arguments)&&(e.thoughtSignature===void 0||typeof e.thoughtSignature==`string`)}function Gt(e){return typeof e==`string`||Array.isArray(e)&&e.every(e=>Vt(e)||Ht(e))}function Kt(e){return Array.isArray(e)&&e.every(e=>Vt(e)||Ut(e)||Wt(e))}function qt(e){return H(e)&&typeof e.input==`number`&&typeof e.output==`number`&&typeof e.cacheRead==`number`&&typeof e.cacheWrite==`number`&&typeof e.totalTokens==`number`&&H(e.cost)&&typeof e.cost.input==`number`&&typeof e.cost.output==`number`&&typeof e.cost.cacheRead==`number`&&typeof e.cost.cacheWrite==`number`&&typeof e.cost.total==`number`}function Jt(e){return!H(e)||typeof e.role!=`string`?!1:e.role===`user`?Gt(e.content):e.role===`assistant`?Kt(e.content)&&typeof e.api==`string`&&typeof e.provider==`string`&&typeof e.model==`string`&&qt(e.usage)&&(e.stopReason===`stop`||e.stopReason===`length`||e.stopReason===`toolUse`||e.stopReason===`error`||e.stopReason===`aborted`)&&(e.errorMessage===void 0||typeof e.errorMessage==`string`):e.role===`toolResult`?typeof e.toolCallId==`string`&&typeof e.toolName==`string`&&Array.isArray(e.content)&&e.content.every(e=>Vt(e)||Ht(e))&&typeof e.isError==`boolean`:!1}async function Yt(e){let t;try{t=await x.readFile(e,`utf-8`)}catch(e){throw Error(`Failed to read message file: ${e.message}`)}let n;try{n=JSON.parse(t)}catch(e){throw Error(`Invalid JSON in message file: ${e.message}`)}let r=Array.isArray(n)?n:[n];if(r.length===0||!r.every(e=>Jt(e)))throw Error(`Message file must contain one Message object or an array of Message objects`);return r}async function Xt(e){if(!!e.message==!!e.fromFile)throw Error(`Exactly one of --message or --from-file must be provided`);return e.fromFile?{kind:`messages`,messages:await Yt(e.fromFile)}:{kind:`text`,message:e.message}}var Zt=class{constructor(e){this.sinks=e}async send(e){await Promise.allSettled(this.sinks.map(async t=>{await t.send(e)}))}async close(){await Promise.allSettled(this.sinks.map(async e=>{await e.close()}))}},Qt=class{constructor(e){this.url=e}async send(e){await this.post(this.toPayload(e))}async close(){}async post(e){let t=Date.now(),n=$t(e);M.info(`sending callback event`,{callbackUrl:this.url,...n});let r=new AbortController,i=!1,a=setTimeout(()=>{i=!0,r.abort()},5e3);try{let a=await fetch(this.url,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e),signal:r.signal}),o=Date.now()-t;if(!a.ok){M.error(`callback event failed`,{callbackUrl:this.url,httpStatus:a.status,durationMs:o,timedOut:i,...n});return}M.info(`callback event delivered`,{callbackUrl:this.url,httpStatus:a.status,durationMs:o,...n})}catch(e){let r=Date.now()-t;M.error(`callback event failed`,{callbackUrl:this.url,error:e instanceof Error?e.message:String(e),durationMs:r,timedOut:i,...n})}finally{clearTimeout(a)}}toPayload(e){switch(e.type){case`start`:return e;case`progress`:return e;case`done`:return e;case`error`:return e;case`session_reset`:return e;case`hitl`:return e;case`title_updated`:return e;default:{let t=e;throw Error(`Unsupported callback event: ${JSON.stringify(t)}`)}}}};function $t(e){return{eventType:e.type,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,progressType:e.type===`progress`?e.event.type:void 0}}function en(e,t){if(t.kind===`none`)return e;let n=new URL(e);return n.searchParams.set(`authToken`,t.token),n.toString()}const U=5e3,tn=5e3;function W(){let e=globalThis.WebSocket;if(!e)throw Error(`WebSocket is not available in this runtime`);return e}function nn(e){return e?{kind:`query_token`,token:e}:{kind:`none`}}function rn(e,t,n){if(typeof e.once==`function`){e.once(t,n);return}if(typeof e.addEventListener==`function`&&typeof e.removeEventListener==`function`){let r=(...i)=>{e.removeEventListener?.(t,r),n(...i)};e.addEventListener(t,r);return}throw Error(`WebSocket does not support one-time listener registration for "${t}"`)}function an(e,t,n){if(typeof e.on==`function`){e.on(t,n);return}if(typeof e.addEventListener==`function`){e.addEventListener(t,n);return}throw Error(`WebSocket does not support listener registration for "${t}"`)}var on=class{socket=null;connectPromise=null;enabled=!0;textSequence=0;constructor(e,t,n){this.url=e,this.events=t,this.authToken=n}async send(e){let t=this.toEnvelope(e);if(!(!t||!this.enabled))try{await sn(this.ensureConnected(),U,`WebSocket connection timed out after ${U}ms`);let e=W();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){M.warn(`websocket sink disabled after send failure`,{url:this.url,error:e instanceof Error?e.message:String(e)}),this.enabled=!1}}async sendTextDelta(e){if(!this.enabled||!this.events.has(`text`))return;this.textSequence+=1;let t={type:`text`,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,timestamp:new Date().toISOString(),sequence:this.textSequence,delta:e.text};try{await sn(this.ensureConnected(),U,`WebSocket connection timed out after ${U}ms`);let e=W();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){M.warn(`websocket sink disabled after text delta send failure`,{url:this.url,error:e instanceof Error?e.message:String(e)}),this.enabled=!1}}async close(){this.enabled=!1;let e=this.socket;if(this.socket=null,this.connectPromise=null,!e)return;let t=W();if(e.readyState!==t.CLOSED)try{await sn(new Promise(t=>{rn(e,`close`,()=>t()),e.close()}),tn,`WebSocket close timed out after ${tn}ms`)}catch(e){M.warn(`websocket sink close timed out`,{url:this.url,error:e instanceof Error?e.message:String(e)})}}async ensureConnected(){if(!this.enabled)return;let e=W();if(this.socket&&this.socket.readyState===e.OPEN)return;if(this.connectPromise){await this.connectPromise;return}let t=new e(en(this.url,nn(this.authToken)));this.connectPromise=new Promise((e,n)=>{rn(t,`open`,()=>{this.socket=t,an(t,`close`,()=>{this.socket===t&&(this.socket=null)}),e()}),rn(t,`error`,e=>{n(e)})});try{await this.connectPromise}finally{this.connectPromise=null}}toEnvelope(e){let t=new Date().toISOString();switch(e.type){case`start`:return this.events.has(`start`)?{...e,timestamp:t}:null;case`done`:return this.events.has(`done`)?{...e,timestamp:t}:null;case`error`:return this.events.has(`error`)?{...e,timestamp:t}:null;case`hitl`:return this.events.has(`hitl`)?{...e,timestamp:t}:null;case`title_updated`:return this.events.has(`title_updated`)?{type:`title_updated`,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,timestamp:t,title:e.title}:null;case`session_reset`:return null;case`progress`:return e.event.type===`text`?this.events.has(`text`)?(this.textSequence+=1,{type:`text`,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,timestamp:t,sequence:this.textSequence,delta:e.event.text}):null:e.event.type===`stream_text_delta`||!this.events.has(`progress`)?null:{type:`progress`,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,timestamp:t,event:e.event};default:{let t=e;throw Error(`Unsupported stream event: ${JSON.stringify(t)}`)}}}};function sn(e,t,n){return new Promise((r,i)=>{let a=setTimeout(()=>i(Error(n)),t);e.then(e=>{clearTimeout(a),r(e)},e=>{clearTimeout(a),i(e)})})}function cn(e){let t=e.trim();if(!t)throw Error(`Goal objective cannot be empty`);return t}function ln(e,t){if(t.action===`unchanged`)return null;if(t.action===`created`||t.action===`replaced`)return t.action;if(e?.status!==t.goal.status)switch(t.goal.status){case`active`:return e?.status===`paused`?`resumed`:`updated`;case`paused`:return`paused`;case`complete`:return`completed`;case`budget_limited`:return`budget_limited`;default:return`updated`}return`updated`}function un(e){let t=ln(e.before,e.result);return t?{type:`goal_updated`,sessionId:e.sessionId,action:t,goalId:e.result.goal.goalId,goalStatus:e.result.goal.status}:null}function dn(e){let t=e?.packageRoot??fn(),n=C.join(t,`models`),r=C.join(n,...`Xenova/bge-small-zh-v1.5`.split(`/`));if(S.existsSync(C.join(r,`config.json`)))return n}function fn(){let e=C.dirname(we(import.meta.url));return C.basename(e)===`src`||C.basename(e)===`dist`?C.resolve(e,`..`):e}const pn=[`start`,`text`,`done`,`error`,`hitl`],mn=[`off`,`gate`,`dry_run`,`write`];function hn(e){if(!e?.trim())return new Set(pn);let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean),n=new Set([`start`,`text`,`progress`,`done`,`error`,`hitl`,`title_updated`]),r=new Set;for(let e of t){if(!n.has(e))throw Error(`Invalid stream event: ${e}. Must be one of start,text,progress,done,error,hitl`);r.add(e)}return r.size>0?r:new Set(pn)}function gn(e){if(e.disableTopicSegmentation===!0||process.env.AIMAX_DISABLE_TOPIC_SEGMENTATION===`true`)return{enabled:!1};let t=dn();return t?{embeddingModelDir:t}:void 0}function _n(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir or AIMAX_DATA_DIR`);return t}function vn(e){return e?.trim()||void 0}function yn(e){let t=(e.systemAgentsDir??process.env.AIMAX_SYSTEM_AGENTS_DIR)?.trim();if(t){if(!C.isAbsolute(t)){let n=e.systemAgentsDir===void 0?`AIMAX_SYSTEM_AGENTS_DIR`:`--system-agents-dir`;throw Error(`Invalid ${n}: ${t}. Path must be absolute.`)}return t}}function bn(e){return e?y(e):void 0}function xn(e){if(!e?.trim())return[];let t=e.split(`,`).map(e=>e.trim()).filter(Boolean),n=new Set,r=[];for(let e of t){if(!C.isAbsolute(e))throw Error(`Invalid --skillsLoadPaths entry: ${e}. Each path must be absolute.`);n.has(e)||(n.add(e),r.push(e))}return r}function Sn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if([`true`,`1`,`yes`,`on`].includes(n))return!0;if([`false`,`0`,`no`,`off`].includes(n))return!1;throw Error(`Invalid ${t}: ${e}. Must be true or false.`)}}function Cn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(mn.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function wn(e){let t=e.autoSkillsLoadEnabled===void 0?Sn(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):Sn(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?Cn(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):Cn(e.autoSkillsReviewMode,`--auto-skills-review-mode`),r={};return t!==void 0&&(r.load={enabled:t}),n!==void 0&&(r.review={mode:n}),r.load||r.review?r:void 0}function Tn(e,t){if(e.inputText&&t){let n=ve(e.inputText,t);return n.submittedBy={userId:e.user,channel:e.channel??`IM`},n}if(!e.inputJson&&!e.inputText)throw Error(`Either --input-json or --input-text must be provided for the resume command`);try{let t=JSON.parse(e.inputJson);return{requestId:e.requestId,sessionId:e.sessionId,action:t.action??`submit`,values:t.values,submittedBy:t.submittedBy,idempotencyKey:t.idempotencyKey,submittedAt:t.submittedAt??new Date().toISOString()}}catch(e){throw Error(`Invalid --input-json: ${e.message}`)}}function En(e,t){if(!e.inputJson)throw Error(`UI tool resume requires --input-json`);try{let n=JSON.parse(e.inputJson),r=n&&typeof n==`object`&&`values`in n&&n.values&&typeof n.values==`object`&&!Array.isArray(n.values)?n.values:n;return{requestId:t.request.requestId,sessionId:t.sessionId,toolCallId:t.request.toolCallId,toolName:t.request.toolName,values:r,submittedAt:new Date().toISOString()}}catch(e){throw Error(`Invalid --input-json: ${e.message}`)}}async function Dn(e){let t=await ie(e.dataDir,e.sessionId,{storeName:e.sessionStoreName,encryptSessions:e.encryptSessions});for(let n=t.length-1;n>=0;--n){let r=t[n];if(r?.role!==`assistant`||!Array.isArray(r.toolCalls))continue;let i=r.toolCalls.find(t=>t.id===e.toolCallId&&t.name===e.toolName);if(i)return i.arguments}}async function On(e){let t=_n(e),n=e.channel??`WEB`,r=Rt({apiFormat:e.apiFormat,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel});return{dataDir:t,systemAgentsDir:yn(e),channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,skillsLoadPaths:xn(e.skillsLoadPaths),autoSkills:wn(e)}}function kn(e){let t=[],n=null;return e.callbackUrl&&t.push(new Qt(e.callbackUrl)),e.streamUrl&&(n=new on(e.streamUrl,hn(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new Zt(t),websocketSink:n}}async function An(e){let{dataDir:t,sessionId:n,sessionStoreName:r,toolCallId:i,toolName:a,resolution:o,encryptSessions:s}=e;if(!i||!a||!ge(a))return;let c=(e,t)=>{switch(e){case`request_approval`:return f(t);case`clarify`:return p(t);case`request_review`:return m(t);default:return JSON.stringify({action:t.action,values:t.values})}};await ue(t,n,e=>{let t=e.findIndex(e=>e.role===`tool_result`&&e.toolCallId===i&&e.toolName===a);if(t===-1)return e;let n=e.slice(0,t+1);return n[t]={...n[t],content:c(a,o),isError:!1},n},{storeName:r,encryptSessions:s})}async function jn(e){let{dataDir:t,sessionId:n,sessionStoreName:r,result:i,encryptSessions:a}=e;await ue(t,n,e=>{let t=e.findIndex(e=>e.role===`assistant`&&Array.isArray(e.toolCalls)&&e.toolCalls.some(e=>e.id===i.toolCallId&&e.name===i.toolName));if(t===-1)return e;let n=e.slice(0,t+1);return n.push({role:`tool_result`,toolCallId:i.toolCallId,toolName:i.toolName,content:JSON.stringify({submitted:!0,values:i.values}),isError:!1,timestamp:i.submittedAt}),n},{storeName:r,encryptSessions:a})}async function Mn(e){let t=_n(e);await z(t,e,async()=>{j(t);let i=new rt(`resume command`),a=null;try{let t=await On(e),o=bn(e.sessionStore),c=null;if(e.goal||e.goalFile){let i;i=e.goalFile?await x.readFile(e.goalFile,`utf-8`):e.goal;let a=cn(i),s=e.tokenBudget===void 0?void 0:e.tokenBudget===`0`||e.tokenBudget===``?null:Number(e.tokenBudget);s!=null&&(Number.isNaN(s)||s<=0)&&(D(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));try{let n=await b(t.dataDir,e.sessionId,{storeName:o}),i=await r({dataDir:t.dataDir,sessionId:e.sessionId,objective:a,tokenBudget:s,force:e.force,storeName:o});c=un({sessionId:e.sessionId,before:n,result:i})}catch(e){throw e instanceof n&&(D(e.message),D(`Existing: ${e.existingObjectivePreview}`),process.exit(2)),e}}M.info(`resume command started`,{sessionId:e.sessionId,requestId:e.requestId,channel:t.channel,dataDir:t.dataDir});let l=await te(t.dataDir,e.sessionId,{storeName:o,encryptSessions:e.encryptSessions}),u=l?null:await ne(t.dataDir,e.sessionId,{storeName:o,encryptSessions:e.encryptSessions});if(!l&&!u)throw Error(`No pending HITL or UI tool request found for session "${e.sessionId}"`);if(l){if(l.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${l.request.requestId}", got "${e.requestId}"`);if(l.status===`expired`)throw Error(`HITL request has expired`);if(l.status===`cancelled`)throw Error(`HITL request has been cancelled`)}else if(u){if(u.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${u.request.requestId}", got "${e.requestId}"`);if(u.status!==`pending`)throw Error(`UI tool request is already "${u.status}", cannot resume`)}if(l){let n=Tn(e,l.request),r=await ce({dataDir:t.dataDir,sessionStoreName:o,sessionId:e.sessionId,requestId:e.requestId,resolution:n}),s=r.state;if(!s)throw Error(`Resolved HITL state was not persisted`);let u=Nn(n,s.request.kind);await An({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:o,toolCallId:s.toolContext?.toolCallId,toolName:s.toolContext?.toolName,resolution:n,encryptSessions:e.encryptSessions});let d=kn(e);a=d.sink;let f=e.sessionId,p=async n=>{if(f=n.sessionId??f,!he(n)){if(n.type===`stream_text_delta`){t.format===`text`&&O(n),await d.websocketSink?.sendTextDelta({sessionId:f,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}t.format===`text`&&O(n),await a?.send({sessionId:f,channel:t.channel,messageId:e.messageId,user:e.user,type:`progress`,event:n})}};c&&await p(c),await p({type:`hitl_resumed`,requestId:e.requestId,resolution:n,sessionId:e.sessionId}),`idempotentReplay`in r&&r.idempotentReplay&&(M.info(`resume command treated as idempotent replay`,{sessionId:e.sessionId,requestId:e.requestId,idempotencyKey:n.idempotencyKey}),Re({sessionId:e.sessionId,text:`Resume request already processed.`,usage:{input:0,output:0,total:0},durationMs:0},t.format),i.end(),process.exit(0));let m=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,h=await B(t.dataDir,m),g;try{g=await de({dataDir:t.dataDir,projectDir:vn(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:o,sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,message:u,encryptSessions:e.encryptSessions??!1,topicSegmentation:gn(e),hitlResume:{request:s.request,resolution:n,checkpoint:s.checkpoint,toolContext:s.toolContext},plugins:h?{config:h,dataDir:t.dataDir,workspaceDir:C.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:h.llmAllowlist}:void 0,onProgress:p})}finally{}g.error?await a?.send({sessionId:g.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`error`,message:g.error}):await a?.send({sessionId:g.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`done`,result:{text:g.text,usage:g.usage,durationMs:g.durationMs,error:g.error,paused:g.paused,uiToolPending:g.uiToolPending}}),Re(g,t.format),g.error?M.error(`resume command failed: ${g.error}`):M.info(`resume command succeeded`),i.end(),process.exit(g.error?1:0);return}let d=En(e,u);if(!await le(t.dataDir,e.sessionId,e.requestId,d,{storeName:o,encryptSessions:e.encryptSessions}))throw Error(`UI tool resume validation failed`);await jn({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:o,result:d,encryptSessions:e.encryptSessions});let f=kn(e);a=f.sink;let p=e.sessionId,m=async n=>{if(p=n.sessionId??p,!he(n)){if(n.type===`stream_text_delta`){t.format===`text`&&O(n),await f.websocketSink?.sendTextDelta({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}if(t.format===`text`&&O(n),n.type===`start`){await a?.send({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,type:`start`,message:n.message});return}await a?.send({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,type:`progress`,event:n})}},h=await Dn({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:o,toolCallId:d.toolCallId,toolName:d.toolName,encryptSessions:e.encryptSessions});c&&await m(c),await m({type:`tool_end`,sessionId:e.sessionId,toolCallId:d.toolCallId,name:d.toolName,input:h,output:JSON.stringify({submitted:!0,values:d.values}),isError:!1});let g=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,_=await B(t.dataDir,g),v=await de({dataDir:t.dataDir,projectDir:vn(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:o,sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,message:`[UI_TOOL_RESUME]
8
- The pending UI tool result has been written into the transcript. Continue from the latest tool result without repeating the same form request.`,encryptSessions:e.encryptSessions??!1,topicSegmentation:gn(e),uiToolResume:d,plugins:_?{config:_,dataDir:t.dataDir,workspaceDir:C.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:_.llmAllowlist}:void 0,onProgress:m});await s(t.dataDir,e.sessionId,{storeName:o,encryptSessions:e.encryptSessions}),v.error?await a?.send({sessionId:v.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`error`,message:v.error}):await a?.send({sessionId:v.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`done`,result:{text:v.text,usage:v.usage,durationMs:v.durationMs,error:v.error,paused:v.paused,uiToolPending:v.uiToolPending}}),Re(v,t.format),v.error?M.error(`resume command failed: ${v.error}`):M.info(`resume command succeeded`),i.end(),process.exit(v.error?1:0)}catch(t){let n=t;a&&(n.message.includes(`expired`)&&await a.send({sessionId:e.sessionId,channel:e.channel??`WEB`,messageId:e.messageId,user:e.user,type:`progress`,event:{type:`hitl_expired`,sessionId:e.sessionId,requestId:e.requestId,reason:n.message}}),n.message.includes(`cancelled`)&&await a.send({sessionId:e.sessionId,channel:e.channel??`WEB`,messageId:e.messageId,user:e.user,type:`progress`,event:{type:`hitl_cancelled`,sessionId:e.sessionId,requestId:e.requestId,reason:n.message}}),await a.send({sessionId:e.sessionId,channel:e.channel??`WEB`,messageId:e.messageId,user:e.user,type:`error`,message:`Resume failed: ${n.message}`})),M.error(`resume command error: ${n.message}`),D(`Fatal: ${n.message}`),i.end(),process.exit(1)}finally{await a?.close()}})}function Nn(e,t){return o(e,t)}function Pn(e){e.command(`resume`).description(`Resume a paused HITL session with user input`).requiredOption(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--project-dir <path>`,`Current project directory used as the default cwd context`).option(`--system-agents-dir <path>`,`System agent definition directory (overrides AIMAX_SYSTEM_AGENTS_DIR, default: /aimax/agents)`).requiredOption(`-s, --session-id <id>`,`Session ID to resume`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).requiredOption(`--request-id <id>`,`HITL request ID to resolve`).option(`--input-json <json>`,`JSON string with the resolution (action, values, etc.)`).option(`--input-text <text>`,`Plain text response for IM channels without rich UI (e.g. '同意', '拒绝')`).option(`--skillsLoadPaths <paths>`,`Comma-separated absolute skill load paths`).option(`--auto-skills-load-enabled <boolean>`,`Enable learned auto-skill loading for the main agent (overrides AIMAX_AUTO_SKILLS_LOAD_ENABLED)`).option(`--auto-skills-review-mode <mode>`,`Auto-skill review mode: off, gate, dry_run, or write (overrides AIMAX_AUTO_SKILLS_REVIEW_MODE)`).option(`--message-id <id>`,`Message ID for correlating events`).option(`--user <id>`,`User identifier propagated to external callback and stream payloads`).option(`-c, --channel <channel>`,`Channel name (default: WEB)`,`WEB`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-format <format>`,`LLM API format: openai-completions or anthropic-messages (overrides AIMAX_API_FORMAT)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY)`).option(`--auth-token <token>`,`Auth token used to generate the API key`).option(`--model <name>`,`LLM model name (overrides AIMAX_MODEL)`).option(`--context-window <n>`,`LLM context window size`).option(`--callback-url <url>`,`HTTP callback URL for progress events`).option(`--stream-url <url>`,`WebSocket URL for streaming text events`).option(`--stream-auth-token <token>`,`Auth token for WebSocket streaming`).option(`--stream-events <list>`,`Comma-separated stream events`).option(`--timeout <ms>`,`Execution timeout in milliseconds`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--plugins-config <path>`,`Plugins config file path`).option(`--goal <text>`,`Set or replace the thread goal objective before resuming`).option(`--goal-file <path>`,`Read goal objective from a file`).option(`--token-budget <n>`,`Token budget for the goal (positive integer, or 0 for unlimited)`).option(`--force`,`Replace existing goal with a different objective`).option(`--encrypt-sessions`,`Enable encryption for the .aimax data directory`).option(`--disable-topic-segmentation`,`Disable smart topic segmentation for this resume run`).action(async e=>{await Mn(e)})}const Fn=[`start`,`text`,`done`,`error`],In=[`off`,`gate`,`dry_run`,`write`];function Ln(e){if(!e?.trim())return new Set(Fn);let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean),n=new Set([`start`,`text`,`progress`,`done`,`error`,`hitl`,`title_updated`]),r=new Set;for(let e of t){if(!n.has(e))throw Error(`Invalid stream event: ${e}. Must be one of start,text,progress,done,error,hitl,title_updated`);r.add(e)}return r.size>0?r:new Set(Fn)}function Rn(e){if(e.disableTopicSegmentation===!0||process.env.AIMAX_DISABLE_TOPIC_SEGMENTATION===`true`)return{enabled:!1};let t=dn();return t?{embeddingModelDir:t}:void 0}function zn(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir option or AIMAX_DATA_DIR environment variable`);return t}function Bn(e){return e?.trim()||void 0}function Vn(e){let t=(e.systemAgentsDir??process.env.AIMAX_SYSTEM_AGENTS_DIR)?.trim();if(t){if(!C.isAbsolute(t)){let n=e.systemAgentsDir===void 0?`AIMAX_SYSTEM_AGENTS_DIR`:`--system-agents-dir`;throw Error(`Invalid ${n}: ${t}. Path must be absolute.`)}return t}}function G(e){return e?.trim()||void 0}function Hn(e){return e??`WEB`}function Un(e){return e?y(e):void 0}function Wn(e){if(!e?.trim())return[];let t=e.split(`,`).map(e=>e.trim()).filter(Boolean),n=new Set,r=[];for(let e of t){if(!C.isAbsolute(e))throw Error(`Invalid --skillsLoadPaths entry: ${e}. Each path must be absolute.`);n.has(e)||(n.add(e),r.push(e))}return r}function Gn(e){let t=``;for(let n=0;n<e.length;n+=1){let r=e[n];if(r===`\\`&&n+1<e.length){let r=e[n+1];if(r===`,`||r===`\\`||r===`=`){t+=r,n+=1;continue}}t+=r}return t}function Kn(e){let t=[],n=``;for(let r=0;r<e.length;r+=1){let i=e[r];if(i===`\\`&&r+1<e.length){let t=e[r+1];if(t===`,`||t===`\\`){n+=t,r+=1;continue}}if(i===`,`){t.push(n),n=``;continue}n+=i}return t.push(n),t}function qn(e){if(!e?.trim())return{};let t=[],n=new Set;for(let r of Kn(e)){let e=r.trim();if(!e)continue;let i=e.indexOf(`=`);if(i<=0)throw Error(`Invalid --env entry: ${e}. Expected KEY=VALUE (use \\= to embed an equals sign in the value).`);let a=e.slice(0,i).trim(),o=e.slice(i+1).trim();if(!a)throw Error(`Invalid --env entry: ${e}. Key must not be empty.`);if(n.has(a))throw Error(`Invalid --env entry: duplicate key ${a}.`);n.add(a),t.push([a,Gn(o)])}return Object.fromEntries(t)}function Jn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if([`true`,`1`,`yes`,`on`].includes(n))return!0;if([`false`,`0`,`no`,`off`].includes(n))return!1;throw Error(`Invalid ${t}: ${e}. Must be true or false.`)}}function Yn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(In.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function Xn(e){let t=e.autoSkillsLoadEnabled===void 0?Jn(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):Jn(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?Yn(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):Yn(e.autoSkillsReviewMode,`--auto-skills-review-mode`),r={};return t!==void 0&&(r.load={enabled:t}),n!==void 0&&(r.review={mode:n}),r.load||r.review?r:void 0}function Zn(e,t){return e.length<=t?e:t<=3?e.slice(0,t):`${e.slice(0,t-3)}...`}function Qn(e,t){if(t<=0)return[``];let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n.length>0?n:[``]}function $n(e,t,n=78){let r=Math.max(0,n-4),i=e?e.length+2:0,a=Math.max(r,i,...t.map(e=>e.length)),o=a+2,s=e?` ${Zn(e,Math.max(0,a-2))} `:``,c=e?`┌${s}${`─`.repeat(Math.max(0,o-s.length))}┐`:`┌${`─`.repeat(o)}┐`,l=`└${`─`.repeat(o)}┘`;return[c,...t.flatMap(e=>Qn(e,a).map(e=>`│ ${e.padEnd(a,` `)} │`)),l].join(`
9
- `)}function er(e){return e.kind===`text`?`inline message (${e.message.length} chars)`:`message file (${e.messages.length} messages)`}function K(e,t=`-`){return e==null||e===``?t:String(e)}function tr(e){return e?`set`:`unset`}function nr(e){return e?`true`:`false`}function rr(e,t){let n=Un(e.sessionStore)??`sessions`,r=t.timeoutMs===void 0?`default`:`${t.timeoutMs}`,i=e.callbackUrl?`enabled`:`disabled`,a=e.streamUrl?`enabled`:`disabled`,o=er(t.input),s=t.input.kind===`text`?`inline`:e.fromFile??`file`,c=We(),l=Rn(e)?.enabled===!1?`disabled`:`enabled`,u=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,d=[...Ln(e.streamEvents)].join(`,`),f=t.autoSkills?.load?.enabled,p=t.autoSkills?.review?.mode,m=e.tokenBudget===`0`?`unlimited`:K(e.tokenBudget),h=e.env?Object.keys(qn(e.env)):[],g=h.length===0?`-`:`${h.length} key${h.length===1?``:`s`}`;return{banner:$n(void 0,[`AIMax CLI`,`Stateless Agent Runner`]),contextBox:$n(`Run Context`,[`time : ${c}`,`dataDir : ${t.dataDir}`,`projectDir : ${Bn(e.projectDir)??`-`}`,`systemAgents : ${t.systemAgentsDir??`/aimax/agents`}`,`agent : ${G(e.agent)??`-`}`,`channel : ${t.channel}`,`user : ${e.user??`-`}`,`message : ${e.message===void 0?`-`:`inline (${e.message.length} chars)`}`,`fromFile : ${K(e.fromFile)}`,`input : ${o}`,`skillsPaths : ${t.skillsLoadPaths.length>0?t.skillsLoadPaths.join(`,`):`-`}`,`autoSkillLoad: ${f===void 0?`-`:String(f)}`,`autoSkillRev : ${p??`-`}`,`sessionId : ${e.sessionId??`new`}`,`sessionStore : ${n}`,`messageId : ${e.messageId??`-`}`,`workspace : ${C.join(t.dataDir,`workspace`)}`,`baseUrl : ${t.llm.baseUrl}`,`apiKey : ${tr(e.apiKey)}`,`authToken : ${tr(e.authToken)}`,`model : ${t.llm.model}`,`contextWindow: ${K(t.llm.contextWindow)}`,`flashModel : ${K(t.llm.flashModel)}`,`callbackUrl : ${K(e.callbackUrl)}`,`streamUrl : ${K(e.streamUrl)}`,`streamAuth : ${tr(e.streamAuthToken)}`,`streamEvents : ${d}`,`output : ${t.format}`,`callback : ${i}`,`websocket : ${a}`,`timeoutMs : ${r}`,`pluginsConfig: ${K(u)}`,`env : ${g}`,`goal : ${e.goal===void 0?`-`:`inline (${e.goal.length} chars)`}`,`goalFile : ${K(e.goalFile)}`,`tokenBudget : ${m}`,`force : ${nr(e.force)}`,`resumeReqId : ${K(e.resumeRequestId)}`,`resumeInput : ${e.resumeInputJson===void 0?`-`:`inline (${e.resumeInputJson.length} chars)`}`,`resumeFile : ${K(e.resumeFromFile)}`,`encryptSess : ${nr(e.encryptSessions)}`,`topicSegment : ${l}`]),logContext:{time:c,channel:t.channel,user:e.user,dataDir:t.dataDir,projectDir:Bn(e.projectDir),systemAgentsDir:t.systemAgentsDir,agent:G(e.agent),workspaceDir:C.join(t.dataDir,`workspace`),sessionId:e.sessionId??`new`,sessionStore:n,messageId:e.messageId,hasMessage:e.message!==void 0,fromFile:e.fromFile,skillsLoadPaths:t.skillsLoadPaths.join(`,`)||void 0,autoSkillsLoadEnabled:f,autoSkillsReviewMode:p,baseUrl:t.llm.baseUrl,hasApiKey:!!e.apiKey,hasAuthToken:!!e.authToken,model:t.llm.model,contextWindow:t.llm.contextWindow,flashModel:t.llm.flashModel,callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,hasStreamAuthToken:!!e.streamAuthToken,streamEvents:d,output:t.format,hasCallback:!!e.callbackUrl,hasStream:!!e.streamUrl,timeoutMs:t.timeoutMs,pluginsConfig:u,envKeys:h.length>0?h.join(`,`):void 0,hasGoal:e.goal!==void 0,goalFile:e.goalFile,tokenBudget:m===`-`?void 0:m,force:!!e.force,resumeRequestId:e.resumeRequestId,hasResumeInputJson:e.resumeInputJson!==void 0,resumeFromFile:e.resumeFromFile,encryptSessions:!!e.encryptSessions,topicSegmentation:l,inputKind:t.input.kind,inputSource:s,inputSummary:o}}}async function ir(e,t){let n=zn(e),r=Hn(e.channel),i=Rt({apiFormat:e.apiFormat,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel});return{dataDir:n,systemAgentsDir:Vn(e),channel:r,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:i,input:t,skillsLoadPaths:Wn(e.skillsLoadPaths),autoSkills:Xn(e)}}function ar(e){if(e.kind===`text`)return e.message;if(e.messages.length!==1)return null;let[t]=e.messages;if(t.role!==`user`)return null;if(typeof t.content==`string`)return t.content;if(t.content.length===0)return null;let n=[];for(let e of t.content){if(e.type!==`text`)return null;n.push(e.text)}return n.join(`
10
- `)}async function or(e,t){if(!e.sessionId)return null;let n=ar(t);if(!n)return null;let r=await te(zn(e),e.sessionId,{storeName:Un(e.sessionStore),encryptSessions:e.encryptSessions});return!r||r.status!==`pending`||!_e(n,r.request)?null:{requestId:r.request.requestId,inputText:n}}function sr(e){let t=[],n=null;return e.callbackUrl&&t.push(new Qt(e.callbackUrl)),e.streamUrl&&(n=new on(e.streamUrl,Ln(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new Zt(t),websocketSink:n}}async function q(e,t){M.info(`dispatching external event`,Er(t)),await e.sink.send(t)}function cr(e){let t={sessionId:e.sessionId,messageId:e.messageId,parentSessionId:e.parentSessionId,depth:e.depth,scope:e.scope,phase:e.phase,...e.details};if(e.level===`error`){M.error(e.message,t);return}if(e.level===`warn`){M.warn(e.message,t);return}M.info(e.message,t)}function lr(e,t,n,r,i){return{sink:e,websocketSink:t,channel:n,defaultMessageId:r,user:i}}function ur(e){let t=new AbortController,n=n=>{M.warn(`run abort signal received`,{signal:n,uptimeMs:Math.round(process.uptime()*1e3),alreadyAborted:t.signal.aborted,...e?.()}),t.abort()},r=()=>n(`SIGTERM`),i=()=>n(`SIGINT`);return process.once(`SIGTERM`,r),process.once(`SIGINT`,i),{controller:t,cleanup:()=>{process.off(`SIGTERM`,r),process.off(`SIGINT`,i)}}}function dr(e){return{activeSessionId:e??`pending`,finalResult:null}}function fr(e,t){e.activeSessionId=t.sessionId??e.activeSessionId}function pr(e,t){return e.messageId??t}async function mr(e,t,n){if(!await h(e.dataDir)){if(await hr(t,e.format,n.activeSessionId,e.dataDir,`checking`),(await u(e.dataDir)).performedBootstrap){await hr(t,e.format,n.activeSessionId,e.dataDir,`initializing`),await hr(t,e.format,n.activeSessionId,e.dataDir,`initialized`);return}await hr(t,e.format,n.activeSessionId,e.dataDir,`ready`)}}async function hr(e,t,n,r,i){let a={type:`bootstrap`,phase:i,dataDir:r};t===`text`&&O(a),await q(e,{sessionId:n,channel:e.channel,messageId:e.defaultMessageId,user:e.user,type:`progress`,event:a})}function gr(e,t,n){return async r=>{if(fr(n,r),he(r)){cr(r);return}if(r.type===`stream_text_delta`){e.format===`text`&&O(r),await t.websocketSink?.sendTextDelta({sessionId:n.activeSessionId,channel:e.channel,messageId:pr(r,t.defaultMessageId),user:t.user,text:r.text});return}e.format===`text`&&O(r);let i=pr(r,t.defaultMessageId);if(r.type===`hitl_requested`){await q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`hitl`,request:r.request}),await q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r});return}if(r.type===`start`){await q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`start`,message:r.message});return}if(r.type===`session_reset`){await q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`session_reset`,action:r.action,previousSessionId:r.previousSessionId,message:r.message});return}await q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r})}}function _r(e,t,n,r,i,a){let o={dataDir:t.dataDir,projectDir:Bn(e.projectDir),systemAgentsDir:t.systemAgentsDir,agentPolicy:G(e.agent)?{requestedAgentName:G(e.agent)}:void 0,sessionStoreName:Un(e.sessionStore),sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,abortSignal:n.signal,pendingGoal:a,encryptSessions:e.encryptSessions??!1,topicSegmentation:Rn(e),env:qn(e.env),plugins:i?{config:i,dataDir:t.dataDir,workspaceDir:C.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:i.llmAllowlist}:void 0,onProgress:r};return t.input.kind===`messages`?{...o,messages:t.input.messages}:{...o,message:t.input.message}}async function vr(e,t,n,r){if(t.activeSessionId=r.sessionId,t.finalResult=r,r.error){await q(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:r.error});return}await q(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`done`,result:{text:r.text,usage:r.usage,durationMs:r.durationMs,error:r.error,paused:r.paused}})}async function yr(e,t,n,r){await q(e,{sessionId:t.finalResult?.sessionId??t.activeSessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:`Fatal: ${r.message}`})}function br(e,t){let n=rr(e,t);M.info([`run command started`,n.banner,n.contextBox].join(`
11
- `),n.logContext),t.format===`text`&&(E(n.banner),E(``),E(n.contextBox),E(``))}function xr(e,t,n){return Re(t,n),t.error?M.error(`run command failed: ${t.error}`):M.info(`run command succeeded`),e.end(),t.error?1:0}function Sr(e){let t=tt();if(!t)return;let n=`[${We()}] [ERROR] ${e}\n`;try{S.appendFileSync(C.join(t.logDir,`app.log`),n),S.appendFileSync(C.join(t.logDir,`errors.log`),n)}catch{}}async function Cr(e,t){let n=`run command error: ${t.message}`;M.error(n),Sr(n),D(`Fatal: ${t.message}`),e.end(),await nt(),process.exit(1)}async function wr(e){if(e.resumeInputJson&&e.resumeFromFile)throw Error(`--resume-input-json and --resume-from-file are mutually exclusive`);if(!e.resumeFromFile)return e.resumeInputJson;try{return await x.readFile(e.resumeFromFile,`utf-8`)}catch(e){throw Error(`Failed to read resume input file: ${e.message}`)}}async function Tr(e){let t=zn(e);await z(t,e,async i=>{j(t),e.encryptSessions&&M.info(`--encrypt-sessions run mount state after logger initialization`,{dataDir:t,mounted:i?.mounted??!1,plainDir:i?.plainDir,encryptedDir:i?.encryptedDir});let a=new rt(`run command`),o=await wr(e);if(e.resumeRequestId||o||e.resumeFromFile){if(!e.sessionId||!e.resumeRequestId||!o)throw Error(`--session-id, --resume-request-id, and exactly one of --resume-input-json or --resume-from-file must be provided together`);await Mn({dataDir:e.dataDir,projectDir:e.projectDir,systemAgentsDir:e.systemAgentsDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:e.resumeRequestId,inputJson:o,channel:e.channel,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow,flashModel:e.flashModel,callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamAuthToken:e.streamAuthToken,streamEvents:e.streamEvents,timeout:e.timeout,output:e.output,pluginsConfig:e.pluginsConfig,skillsLoadPaths:e.skillsLoadPaths,autoSkillsLoadEnabled:e.autoSkillsLoadEnabled,autoSkillsReviewMode:e.autoSkillsReviewMode,messageId:e.messageId,user:e.user,goal:e.goal,goalFile:e.goalFile,tokenBudget:e.tokenBudget,force:e.force,encryptSessions:e.encryptSessions,disableTopicSegmentation:e.disableTopicSegmentation});return}let s;try{s=await Xt({message:e.message,fromFile:e.fromFile})}catch(e){await Cr(a,e);return}let c=await or(e,s);if(c){await Mn({dataDir:e.dataDir,projectDir:e.projectDir,systemAgentsDir:e.systemAgentsDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:c.requestId,inputText:c.inputText,channel:e.channel,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow,flashModel:e.flashModel,callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamAuthToken:e.streamAuthToken,streamEvents:e.streamEvents,timeout:e.timeout,output:e.output,pluginsConfig:e.pluginsConfig,skillsLoadPaths:e.skillsLoadPaths,autoSkillsLoadEnabled:e.autoSkillsLoadEnabled,autoSkillsReviewMode:e.autoSkillsReviewMode,messageId:e.messageId,user:e.user,goal:e.goal,goalFile:e.goalFile,tokenBudget:e.tokenBudget,force:e.force,encryptSessions:e.encryptSessions,disableTopicSegmentation:e.disableTopicSegmentation});return}let l=e.channel??`WEB`,u=dr(e.sessionId),{controller:d,cleanup:f}=ur(()=>({activeSessionId:u.activeSessionId,finalSessionId:u.finalResult?.sessionId,messageId:e.messageId,channel:l,user:e.user})),p=null;try{let t=await ir(e,s);l=t.channel,br(e,t);let i=sr(e);p=i.sink,M.info(`external sink configured`,{callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamEvents:e.streamEvents});let o=lr(p,i.websocketSink,t.channel,e.messageId,e.user);await mr(t,o,u);let c,f=null;if(e.goal||e.goalFile){let i;i=e.goalFile?await x.readFile(e.goalFile,`utf-8`):e.goal;let a=cn(i),o=Un(e.sessionStore),s=e.tokenBudget===void 0?void 0:e.tokenBudget===`0`||e.tokenBudget===``?null:Number(e.tokenBudget);s!=null&&(Number.isNaN(s)||s<=0)&&(D(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));try{if(e.sessionId){let n=await b(t.dataDir,e.sessionId,{storeName:o}),i=await r({dataDir:t.dataDir,sessionId:e.sessionId,objective:a,tokenBudget:s,force:e.force,storeName:o});f=un({sessionId:e.sessionId,before:n,result:i})}else c={objective:a,tokenBudget:s??null}}catch(e){throw e instanceof n&&(D(e.message),D(`Existing: ${e.existingObjectivePreview}`),process.exit(2)),e}}let m=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,h=await B(t.dataDir,m),g=gr(t,o,u);f&&await g(f);let _=await de(_r(e,t,d,g,h,c));await vr(o,u,e.messageId,_),process.exitCode=xr(a,_,t.format)}catch(t){let n=t;p&&await yr(lr(p,null,l,e.messageId,e.user),u,e.messageId,n),await Cr(a,n)}finally{await p?.close(),f()}})}function Er(e){return{eventType:e.type,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,progressType:e.type===`progress`?e.event.type:void 0,textLength:e.type===`done`?e.result.text.length:void 0,hasError:e.type===`error`?!0:e.type===`done`?!!e.result.error:void 0}}function Dr(e){e.command(`run`).description(`Run an agent task`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--project-dir <path>`,`Current project directory used as the default cwd context`).option(`--system-agents-dir <path>`,`System agent definition directory (overrides AIMAX_SYSTEM_AGENTS_DIR, default: /aimax/agents)`).option(`--agent <name>`,`Custom agent name to run as the root agent`).option(`--user <id>`,`User identifier propagated to external callback and stream payloads`).option(`--message <text>`,`User message to send to the agent`).option(`--from-file <path>`,`Load structured Message JSON from a file`).option(`--skillsLoadPaths <paths>`,`Comma-separated absolute skill load paths`).option(`--auto-skills-load-enabled <boolean>`,`Enable learned auto-skill loading for the main agent (overrides AIMAX_AUTO_SKILLS_LOAD_ENABLED)`).option(`--auto-skills-review-mode <mode>`,`Auto-skill review mode: off, gate, dry_run, or write (overrides AIMAX_AUTO_SKILLS_REVIEW_MODE)`).option(`-s, --session-id <id>`,`Resume an existing session by ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`--message-id <id>`,`Message ID for correlating events`).option(`-c, --channel <channel>`,`Channel name (default: WEB)`,`WEB`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-format <format>`,`LLM API format: openai-completions or anthropic-messages (overrides AIMAX_API_FORMAT)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY)`).option(`--auth-token <token>`,`Auth token used to generate the API key (highest priority)`).option(`--model <name>`,`LLM model name (overrides AIMAX_MODEL)`).option(`--context-window <n>`,`LLM context window size`).option(`--flash-model <name>`,`Flash model for lightweight tasks like title generation (overrides AIMAX_FLASH_MODEL)`).option(`--callback-url <url>`,`HTTP callback URL for progress events`).option(`--stream-url <url>`,`WebSocket URL for streaming text events`).option(`--stream-auth-token <token>`,`Auth token for WebSocket streaming`).option(`--stream-events <list>`,`Comma-separated stream events: start,text,progress,done,error`).option(`--timeout <ms>`,`Execution timeout in milliseconds`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--plugins-config <path>`,`Plugins config file path`).option(`--env <kvlist>`,`Session-scoped env vars injected into the run. Comma-separated KEY=VALUE pairs. Backslash-escape "," and "=" inside values. Available to plugins via api.runtime.session.env and merged into child process environments spawned by the exec/process tools.`).option(`--goal <text>`,`Set or replace the thread goal objective before running`).option(`--goal-file <path>`,`Read goal objective from a file`).option(`--token-budget <n>`,`Token budget for the goal (positive integer, or 0 for unlimited)`).option(`--force`,`Replace existing goal with a different objective`).option(`--resume-request-id <id>`,`Resume a pending HITL request from aimax run`).option(`--resume-input-json <json>`,`Structured HITL resume payload used with --resume-request-id`).option(`--resume-from-file <path>`,`Load structured HITL resume payload from a file (alternative to --resume-input-json)`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).option(`--disable-topic-segmentation`,`Disable smart topic segmentation for this run`).action(async e=>{await Tr(e)})}function Or(e){e.command(`sessions`).description(`List or inspect sessions for a data directory`).argument(`[action]`,`Action: list (default) | inspect | export`).option(`-d, --data-dir <path>`,`Data directory path`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`-c, --channel <channel>`,`Filter by channel type: H5 | WEB | KLPA | TASK | CRON | EIP_ASSISTANT`).option(`-s, --session-id <id>`,`Session ID for inspect/export`).option(`--output <format>`,`Output format: text or json`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async(e,t,n)=>{let r=n.opts(),i=e??`list`,a=i===`export`?r.output===`text`?`text`:`json`:r.output===`json`?`json`:`text`;r.dataDir||(D(`error: required option '-d, --data-dir <path>' not specified`),process.exit(1)),r.channel&&r.channel!==`H5`&&r.channel!==`WEB`&&r.channel!==`KLPA`&&r.channel!==`TASK`&&r.channel!==`CRON`&&r.channel!==`EIP_ASSISTANT`&&(D(`Invalid channel: ${r.channel}. Must be 'H5', 'WEB', 'KLPA', 'TASK', 'CRON', or 'EIP_ASSISTANT'`),process.exit(1));try{await z(r.dataDir,r,async()=>{let e=r.sessionStore?y(r.sessionStore):void 0;if(i===`list`){ze(await ee(r.dataDir,r.channel,{storeName:e}),a);return}if(r.sessionId||(D(`error: required option '-s, --session-id <id>' not specified`),process.exit(1)),i===`inspect`){Be(await _(r.dataDir,r.sessionId,{storeName:e}),a);return}if(i===`export`){Ve(await d(r.dataDir,r.sessionId,{storeName:e}),a);return}D(`Invalid sessions action: ${i}. Must be 'list', 'inspect', or 'export'`),process.exit(1)})}catch(e){D(`${i===`inspect`?`Error inspecting session`:i===`export`?`Error exporting session`:`Error listing sessions`}: ${e.message}`),process.exit(1)}})}function kr(e){return C.join(e,`workspace`)}function Ar(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function jr(e,t){let n=[];n.push(`backend: ${e.backend}`),n.push(`provider: ${e.provider}${e.model?` (${e.model})`:``}`);let r=typeof e.custom?.providerSource==`string`?e.custom.providerSource:void 0,i=typeof e.custom?.providerId==`string`?e.custom.providerId:void 0,a=typeof e.custom?.pluginId==`string`?e.custom.pluginId:void 0;r&&n.push(`provider_source: ${r}`),i&&n.push(`provider_id: ${i}`),a&&n.push(`plugin_id: ${a}`),typeof e.files==`number`&&n.push(`files: ${e.files}`),typeof e.chunks==`number`&&n.push(`chunks: ${e.chunks}`),typeof e.dirty==`boolean`&&n.push(`dirty: ${e.dirty}`),e.dbPath&&n.push(`db: ${e.dbPath}`),e.sources?.length&&n.push(`sources: ${e.sources.join(`, `)}`),t&&(e.fts&&(n.push(`fts: enabled=${e.fts.enabled} available=${e.fts.available}`),e.fts.error&&n.push(`fts_error: ${e.fts.error}`)),e.vector&&(n.push(`vector: enabled=${e.vector.enabled} available=${e.vector.available??`unknown`}`),e.vector.dims&&n.push(`vector_dims: ${e.vector.dims}`),e.vector.loadError&&n.push(`vector_error: ${e.vector.loadError}`)),e.cache&&n.push(`cache: enabled=${e.cache.enabled} entries=${e.cache.entries??0}`));let o=Array.isArray(e.custom?.cliWarnings)?e.custom.cliWarnings.filter(e=>typeof e==`string`&&e.length>0):[];for(let e of o)n.push(`warning: ${e}`);return n.join(`
12
- `)}function Mr(e){let t=e.level===`error`?`plugin error`:`plugin warning`;return e.pluginId?`${t} (${e.pluginId}): ${e.message}`:`${t}: ${e.message}`}function Nr(e){if(!e||e===`cli`)return`cli`;if(e===`cron`)return`cron`;throw Error(`Unsupported dream trigger: ${e}. Expected "cli" or "cron".`)}async function Pr(e){let t=[],n;try{n=await B(e.dataDir,e.pluginsConfig)}catch(e){t.push(`failed to load plugins config: ${e.message}`)}if(!e.shouldInitialize&&!n)return{warnings:t};try{let r=g({config:n,dataDir:e.dataDir,workspaceDir:kr(e.dataDir),bundledDir:Ar()});return t.push(...r.diagnostics.map(Mr)),{pluginSystem:r,warnings:t}}catch(e){return t.push(`failed to initialize plugin system: ${e.message}`),{warnings:t}}}async function J(e){let t=C.join(e.dataDir,`.aimax`),{pluginSystem:n,warnings:r}=await Pr({dataDir:e.dataDir,pluginsConfig:e.pluginsConfig,shouldInitialize:!!(e.requirePluginSystem||e.provider||e.providerPlugin)}),i=n?.normalizedConfig.slots.memory,a=e.providerPlugin?.trim()||(e.provider?void 0:i),o=se({providerId:e.provider,pluginId:a,dataDir:e.dataDir,memoryDir:t});return o?{provider:o.provider,providerId:o.registration.id,pluginId:o.registration.pluginId,providerOrigin:`plugin`,warnings:r,pluginSystem:n}:((a||e.provider)&&r.push(`requested memory provider was not resolved; falling back to builtin provider`),{provider:c({dataDir:e.dataDir,memoryDir:t},{includeSessions:e.includeSessions}),providerId:`builtin`,providerOrigin:`builtin`,warnings:r,pluginSystem:n})}function Fr(e,t,n){let r={...e.custom??{},providerSource:t.providerOrigin,providerId:t.providerId,pluginId:t.pluginId,cliWarnings:t.warnings},i={...e,custom:r};return n&&t.providerOrigin===`plugin`?i.custom={...r,note:`deep probe details are provider-defined for plugin memory providers`}:n&&(i.custom={...r,note:`deep probe is only supported by builtin provider`}),i}function Ir(e){let t=e.command(`memory`).description(`Manage semantic memory indexing and search`),n=e=>e.option(`--plugins-config <path>`,`Plugins config file path`);n(t.command(`status`)).description(`Show memory index status`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--deep`,`Probe embedding/vector availability`).option(`--index`,`Run a refresh before reporting status`).option(`--include-sessions`,`Include session transcripts in indexing`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--verbose`,`Verbose output`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{await z(e.dataDir,e,async()=>{let n=await J({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,pluginsConfig:e.pluginsConfig,includeSessions:e.includeSessions});e.index&&n.provider.sync&&await n.provider.sync(`cli-status`);let r=Fr(n.provider.status(),n,e.deep);E(t===`json`?JSON.stringify(r,null,2):jr(r,e.deep))})}catch(e){D(`Error getting memory status: ${e.message}`),process.exit(1)}}),n(t.command(`index`)).description(`Reindex memory files`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--include-sessions`,`Include session transcripts in indexing`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--rebuild`,`Force full rebuild from Markdown source`).option(`--verbose`,`Verbose output`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{try{await z(e.dataDir,e,async()=>{let t=await J({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,pluginsConfig:e.pluginsConfig,includeSessions:e.includeSessions}),n;if(t.provider.sync&&(await t.provider.sync(e.rebuild?`cli-rebuild`:`cli-index`),n=t.provider.status().custom?.lastRebuildSummary),t.warnings.length>0)for(let e of t.warnings)D(`Warning: ${e}`);e.verbose&&n&&E(JSON.stringify(n,null,2)),E(e.rebuild?`Memory index rebuilt.`:`Memory index refreshed.`)})}catch(e){D(`Error indexing memory: ${e.message}`),process.exit(1)}}),n(t.command(`search [query]`)).description(`Search semantic memory`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--query <text>`,`Search query`).option(`--include-sessions`,`Include session transcripts in search`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async(e,t)=>{let n=t.output===`json`?`json`:`text`,r=t.query?.trim()||e?.trim();r||(D(`Query is required: provide [query] or --query <text>`),process.exit(1));try{await z(t.dataDir,t,async()=>{let e=await(await J({dataDir:t.dataDir,provider:t.provider,providerPlugin:t.providerPlugin,pluginsConfig:t.pluginsConfig,includeSessions:t.includeSessions})).provider.search(r);if(n===`json`){E(JSON.stringify(e,null,2));return}if(e.length===0){E(`No results found for: ${r}`);return}E(e.map(e=>{let t=`${e.path}:${e.startLine}-${e.endLine} (${e.score.toFixed(4)}) ${e.snippet}`;return e.citation?`${t}\n${e.citation}`:t}).join(`
13
- `))})}catch(e){D(`Error searching memory: ${e.message}`),process.exit(1)}}),n(t.command(`dream`)).description(`Trigger Dream Gate host hook for memory plugins`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--trigger <mode>`,`Dream Gate trigger mode: cli (default) or cron`,`cli`).option(`--dry-run`,`Return hook results without plugin-side mutation`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{await z(e.dataDir,e,async()=>{let n=Nr(e.trigger),r=await J({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,pluginsConfig:e.pluginsConfig,requirePluginSystem:!0}),i=r.pluginSystem?await r.pluginSystem.registry.hooks.dispatch(`dream_gate`,{dataDir:e.dataDir,memoryDir:C.join(e.dataDir,`.aimax`),providerId:r.providerId,pluginId:r.pluginId,trigger:n,dryRun:!!e.dryRun},{workspaceDir:kr(e.dataDir)}):[],a={ok:!0,trigger:n,providerSource:r.providerOrigin,providerId:r.providerId,pluginId:r.pluginId,resultCount:i.length,results:i,warnings:r.warnings};if(t===`json`){E(JSON.stringify(a,null,2));return}E(`trigger: ${a.trigger}`),E(`provider_source: ${a.providerSource}`),E(`provider_id: ${a.providerId}`),a.pluginId&&E(`plugin_id: ${a.pluginId}`),E(`result_count: ${a.resultCount}`),a.results.length===0?E(`note: no dream_gate hook registered`):E(`results: ${JSON.stringify(a.results)}`);for(let e of a.warnings)E(`warning: ${e}`)})}catch(e){D(`Error running dream gate: ${e.message}`),process.exit(1)}})}function Lr(e){return`${e.match.accountId?`${e.match.channel}:${e.match.accountId}`:e.match.channel} -> ${e.agentId}`}function Rr(e){return async t=>{let n=await T(t),r=De(n),i=Oe(n);if(Ne(n),e.json){console.log(JSON.stringify({agents:r,bindings:i},null,2));return}console.log(`Agents:`);for(let e of r){let n=e.default?` (default)`:``,r=e.name&&e.name!==e.id?`${e.id}${n} (${e.name})`:`${e.id}${n}`;if(console.log(` - ${r}`),e.identity?.emoji||e.identity?.name){let t=[e.identity.emoji,e.identity.name].filter(Boolean).join(` `);console.log(` Identity: ${t}`)}let a=Me(t,e.id);if(console.log(` Agent dir: ${a}`),e.model){let t=typeof e.model==`string`?e.model:e.model.primary;console.log(` Model: ${t}`)}let o=i.filter(t=>t.agentId===e.id);if(o.length>0){console.log(` Routing rules:`);for(let e of o)console.log(` - ${Lr(e)}`)}}}}function zr(e,t){return async n=>{w(await T(n),ke(e))&&(console.error(`Agent "${e}" already exists.`),process.exit(1)),await Te(n,{id:e,name:t.name,model:t.model,default:t.default})||(console.error(`Agent "${e}" already exists.`),process.exit(1));let r=Me(n,e);console.log(`Agent "${e}" added successfully.`),console.log(` Agent dir: ${r}`)}}function Br(e){return async t=>{let n=w(await T(t),ke(e));n||(console.error(`Agent "${e}" not found.`),process.exit(1)),n.default===!0&&(console.error(`Cannot delete default agent "${e}".`),process.exit(1)),await Ae(t,e)||(console.error(`Failed to delete agent "${e}".`),process.exit(1)),console.log(`Agent "${e}" deleted.`)}}function Vr(e){return async t=>{let n=await T(t),r=e.agent??Ne(n);w(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),(!e.bind||e.bind.length===0)&&(console.error(`Please specify --bind <channel>[:<account>]`),process.exit(1));for(let n of e.bind){let[e,...i]=n.split(`:`),a=i.join(`:`),o=[`H5`,`WEB`,`KLPA`,`TASK`,`CRON`,`EIP_ASSISTANT`];o.includes(e)||(console.error(`Invalid channel: ${e}`),console.error(`Valid channels: ${o.join(`, `)}`),process.exit(1)),await Ee(t,{agentId:r,match:{channel:e,accountId:a||void 0}}),console.log(`Binding added: ${n} -> ${r}`)}}}function Hr(e){return async t=>{let n=await T(t),r=e.agent??Ne(n);if(w(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),e.all){let e=await je(t,r,`*`);console.log(`Removed ${e} binding(s) for agent "${r}".`)}else if(e.bind&&e.bind.length>0){let n=0;for(let i of e.bind){let[e,...a]=i.split(`:`),o=await je(t,r,e,a.join(`:`)||void 0);o>0?(console.log(`Binding removed: ${i} -> ${r}`),n+=o):console.log(`No binding found: ${i} -> ${r}`)}}else console.error(`Please specify --bind <channel>[:<account>] or --all`),process.exit(1)}}function Ur(e){return async t=>{let n=Oe(await T(t));if(e.agent&&(n=n.filter(t=>t.agentId===e.agent)),e.json){console.log(JSON.stringify(n,null,2));return}if(n.length===0){console.log(`No bindings configured.`);return}console.log(`Routing bindings:`);for(let e of n)console.log(` ${Lr(e)}`)}}function Wr(e){return async t=>{let n=await T(t),r=e.agent??Ne(n);w(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),await Pe(t,r,{name:e.name,emoji:e.emoji,avatar:e.avatar})||(console.error(`Failed to update identity for agent "${r}".`),process.exit(1)),console.log(`Identity updated for agent "${r}".`)}}function Gr(e,t){let n=e.command(`agents`).description(`Manage agents`),r=e=>e.option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`);r(n.command(`list`).description(`List all configured agents`).option(`-j, --json`,`Output as JSON`).option(`-b, --bindings`,`Show detailed binding rules`)).action(async e=>{let n=t();await z(n,e,async()=>{await Rr(e)(n)})}),r(n.command(`add <id>`).description(`Add a new agent`).option(`-n, --name <name>`,`Display name`).option(`-m, --model <model>`,`Model identifier`).option(`--default`,`Mark as default agent`)).action(async(e,n)=>{let r=t();await z(r,n,async()=>{await zr(e,n)(r)})}),r(n.command(`delete <id>`).description(`Delete an agent`)).action(async(e,n)=>{let r=t();await z(r,n,async()=>{await Br(e)(r)})}),r(n.command(`bind`).description(`Bind a channel to an agent`).option(`-a, --agent <id>`,`Target agent ID`).option(`-b, --bind <channel...>`,`Channel binding (e.g., WEB, KLPA:ops)`)).action(async e=>{let n=t();await z(n,e,async()=>{await Vr(e)(n)})}),r(n.command(`unbind`).description(`Unbind a channel from an agent`).option(`-a, --agent <id>`,`Target agent ID`).option(`-b, --bind <channel...>`,`Channel binding to remove`).option(`--all`,`Remove all bindings for the agent`)).action(async e=>{let n=t();await z(n,e,async()=>{await Hr(e)(n)})}),r(n.command(`bindings`).description(`List routing bindings`).option(`-a, --agent <id>`,`Filter by agent ID`).option(`-j, --json`,`Output as JSON`)).action(async e=>{let n=t();await z(n,e,async()=>{await Ur(e)(n)})}),r(n.command(`set-identity`).description(`Set agent identity`).option(`-a, --agent <id>`,`Target agent ID`).option(`-n, --name <name>`,`Agent name`).option(`-e, --emoji <emoji>`,`Agent emoji`).option(`--avatar <path>`,`Avatar path`)).action(async e=>{let n=t();await z(n,e,async()=>{await Wr(e)(n)})})}function Y(e){return C.join(e,`workspace`)}function X(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function Kr(e){if(e.length===0){E(`No plugins discovered.`);return}for(let t of e){let e=t.status.padEnd(8,` `);E(`${t.id} ${e} ${t.origin} ${t.source}`)}}function qr(e){E(`id: ${e.id}`),E(`status: ${e.status}`),E(`origin: ${e.origin}`),E(`source: ${e.source}`),E(`enabled: ${e.enabled}`),e.error&&E(`error: ${e.error}`),E(`tools: ${e.toolCount}`),E(`hooks: ${e.hookCount}`),e.skills.length>0&&E(`skills: ${e.skills.join(`, `)}`)}function Jr(e){return Array.from(new Set((e??[]).map(e=>e.trim()).filter(Boolean)))}function Yr(e){if(e.length===0){E(`LLM allowlist is empty.`);return}for(let t of e)E(t)}function Xr(e,t){let n=e.command(`plugins`).description(`Manage AIMax plugins`),r=e=>e.option(`--plugins-config <path>`,`Plugins config file path`),i=e=>e.option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`);i(r(n.command(`list`))).description(`List discovered plugins`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await z(n,e,async()=>{Kr(g({config:await B(n,e.pluginsConfig),dataDir:n,workspaceDir:Y(n),bundledDir:X()}).registry.plugins)})}),i(r(n.command(`info`))).description(`Show plugin details`).argument(`<id>`,`Plugin id`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await z(r,n,async()=>{let t=g({config:await B(r,n.pluginsConfig),dataDir:r,workspaceDir:Y(r),bundledDir:X()}).registry.plugins.find(t=>t.id===e);t||(D(`Plugin not found: ${e}`),process.exit(1)),qr(t)})}),i(r(n.command(`enable`))).description(`Enable a plugin`).argument(`<id>`,`Plugin id`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await z(r,n,async()=>{let t=await B(r,n.pluginsConfig)??{},i=ae(t);g({config:t,dataDir:r,workspaceDir:Y(r),bundledDir:X()}).registry.plugins.some(t=>t.id===e)||(D(`Plugin not found: ${e}`),process.exit(1)),await V(r,{...t,entries:{...t.entries,[e]:{...t.entries?.[e]??{},enabled:!0}}},n.pluginsConfig),E(`Enabled ${e}`),i.allow.length>0&&!i.allow.includes(e)&&E(`Note: plugins.allow is set; add this plugin id to allowlist if needed.`)})}),i(r(n.command(`disable`))).description(`Disable a plugin`).argument(`<id>`,`Plugin id`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await z(r,n,async()=>{let t=await B(r,n.pluginsConfig)??{};g({config:t,dataDir:r,workspaceDir:Y(r),bundledDir:X()}).registry.plugins.some(t=>t.id===e)||(D(`Plugin not found: ${e}`),process.exit(1)),await V(r,{...t,entries:{...t.entries,[e]:{...t.entries?.[e]??{},enabled:!1}}},n.pluginsConfig),E(`Disabled ${e}`)})}),i(r(n.command(`doctor`))).description(`Validate plugin configuration`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await z(n,e,async()=>{let t=g({config:await B(n,e.pluginsConfig),dataDir:n,workspaceDir:Y(n),bundledDir:X()});if(t.diagnostics.length===0){E(`No plugin issues detected.`);return}for(let e of t.diagnostics)E(`${e.level===`error`?`ERROR`:`WARN`}${e.pluginId?` ${e.pluginId}`:``}: ${e.message}`);t.diagnostics.some(e=>e.level===`error`)&&process.exit(1)})});let a=n.command(`llm-allow`).description(`Manage plugin LLM allowlist`);i(r(a.command(`list`))).description(`List LLM allowlist entries`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await z(n,e,async()=>{Yr(Jr((await B(n,e.pluginsConfig))?.llmAllowlist))})}),i(r(a.command(`add`))).description(`Add entries to the LLM allowlist (plugin id or tool name)`).argument(`<entry...>`,`Plugin id or tool name`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await z(r,n,async()=>{let t=await B(r,n.pluginsConfig)??{},i=Jr([...t.llmAllowlist??[],...e]);await V(r,{...t,llmAllowlist:i},n.pluginsConfig),E(`LLM allowlist updated (${i.length} entries).`)})}),i(r(a.command(`remove`))).description(`Remove entries from the LLM allowlist`).argument(`<entry...>`,`Plugin id or tool name`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await z(r,n,async()=>{let t=await B(r,n.pluginsConfig)??{},i=new Set(e.map(e=>e.trim()).filter(Boolean)),a=Jr(t.llmAllowlist).filter(e=>!i.has(e));await V(r,{...t,llmAllowlist:a},n.pluginsConfig),E(`LLM allowlist updated (${a.length} entries).`)})}),i(r(a.command(`clear`))).description(`Clear the LLM allowlist`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await z(n,e,async()=>{await V(n,{...await B(n,e.pluginsConfig)??{},llmAllowlist:[]},e.pluginsConfig),E(`LLM allowlist cleared.`)})})}function Zr(e){e.command(`commands`).description(`List available slash commands for a data directory`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{await z(e.dataDir,e,async()=>{let n=v(await re(e.dataDir,[]));if(t===`json`){E(JSON.stringify(n,null,2));return}E(`Commands`),E(` builtin: ${n.builtin.map(e=>e.name).join(` | `)}`),n.skillCommands.length>0?E(` skills: ${n.skillCommands.map(e=>e.name).join(` | `)}`):E(` skills: (none)`)})}catch(e){D(`Error listing commands: ${e.message}`),process.exit(1)}})}function Z(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir option or AIMAX_DATA_DIR environment variable`);return t}function Q(e){if(!e.sessionId)throw Error(`Session ID is required (--session-id or -s)`);return e.sessionId}function $(e){return e?y(e):void 0}async function Qr(e){let t={storeName:e.sessionStoreName},n=e.objective.trim(),r=await b(e.dataDir,e.sessionId,t);if(!r||(await oe(e.dataDir,e.sessionId,r,t)).trim()!==n)return pe(e.dataDir,e.sessionId,{goalId:Fe(),objective:n,status:`active`,tokenBudget:e.tokenBudget??null,tokensUsed:0,timeUsedSeconds:0},{...t,eventSource:`cli`});if(r.status===`complete`)return r;let i={};return r.status===`paused`&&(i.status=`active`),e.tokenBudget!==void 0&&e.tokenBudget!==r.tokenBudget&&(i.tokenBudget=e.tokenBudget),Object.keys(i).length===0?r:await fe(e.dataDir,e.sessionId,i,{...t,eventSource:`cli`})}async function $r(e,t){let n=Z(t),r=Q(t),i=$(t.sessionStore),a=e.trim();a||(D(`error: objective cannot be empty`),process.exit(1));let o=t.tokenBudget===void 0||t.tokenBudget===`0`||t.tokenBudget===``?null:Number(t.tokenBudget);o!==null&&(Number.isNaN(o)||o<=0)&&(D(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));let s=await Qr({dataDir:n,sessionId:r,sessionStoreName:i,objective:a,tokenBudget:o});E(JSON.stringify({goal:s},null,2))}async function ei(e){let t=Z(e),n=Q(e),r=$(e.sessionStore),i=await b(t,n,{storeName:r});if(!i){E(JSON.stringify({goal:null},null,2));return}let a=await oe(t,n,i,{storeName:r});E(JSON.stringify({goal:{...i,objective:a}},null,2))}async function ti(e){let t=Z(e),n=Q(e),r=$(e.sessionStore),i=await b(t,n,{storeName:r});i||(D(`error: no goal exists for this session`),process.exit(1)),i.status===`complete`&&(D(`error: cannot pause a completed goal`),process.exit(1));let a=await fe(t,n,{status:`paused`},{storeName:r,eventSource:`cli`});E(JSON.stringify({goal:a},null,2))}async function ni(e){let t=Z(e),n=Q(e),r=$(e.sessionStore),i=await b(t,n,{storeName:r});if(i||(D(`error: no goal exists for this session`),process.exit(1)),i.status===`complete`&&(D(`error: cannot resume a completed goal`),process.exit(1)),i.status===`budget_limited`&&(D(`error: cannot resume a budget-limited goal; clear or replace it instead`),process.exit(1)),i.status===`active`){E(JSON.stringify({goal:i},null,2));return}let a=await fe(t,n,{status:`active`},{storeName:r,eventSource:`cli`});E(JSON.stringify({goal:a},null,2))}async function ri(e){let t=await l(Z(e),Q(e),{storeName:$(e.sessionStore),eventSource:`cli`});E(JSON.stringify({cleared:t},null,2))}function ii(e){let t=e.command(`goal`).description(`Manage thread goals for a session`).addHelpText(`after`,a());t.command(`set <objective>`).description(`Set or replace the thread goal (creates new goalId)`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).requiredOption(`-s, --session-id <id>`,`Session ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`--token-budget <n>`,`Optional token budget (positive integer, or 0 for unlimited)`).action(async(e,t)=>{try{await $r(e,t)}catch(e){D(`error: ${e.message}`),process.exit(1)}}),t.command(`get`).description(`Get the current goal as JSON`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).requiredOption(`-s, --session-id <id>`,`Session ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).action(async e=>{try{await ei(e)}catch(e){D(`error: ${e.message}`),process.exit(1)}}),t.command(`pause`).description(`Pause the current goal`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).requiredOption(`-s, --session-id <id>`,`Session ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).action(async e=>{try{await ti(e)}catch(e){D(`error: ${e.message}`),process.exit(1)}}),t.command(`resume`).description(`Resume a paused goal`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).requiredOption(`-s, --session-id <id>`,`Session ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).action(async e=>{try{await ni(e)}catch(e){D(`error: ${e.message}`),process.exit(1)}}),t.command(`clear`).description(`Clear the current goal`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).requiredOption(`-s, --session-id <id>`,`Session ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).action(async e=>{try{await ri(e)}catch(e){D(`error: ${e.message}`),process.exit(1)}})}const ai=[`progress`,`error`,`hitl`];function oi(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir or AIMAX_DATA_DIR`);return t}function si(e){if(!e?.trim())return new Set(ai);let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean),n=new Set([`start`,`text`,`progress`,`done`,`error`,`hitl`,`title_updated`]),r=new Set;for(let e of t){if(!n.has(e))throw Error(`Invalid stream event: ${e}. Must be one of start,text,progress,done,error,hitl`);r.add(e)}return r.size>0?r:new Set(ai)}function ci(e){return e?y(e):void 0}function li(e){let t=[];return e.callbackUrl&&t.push(new Qt(e.callbackUrl)),e.streamUrl&&t.push(new on(e.streamUrl,si(e.streamEvents),e.streamAuthToken)),new Zt(t)}async function ui(e){let t=oi(e);await z(t,e,async()=>{j(t);let n=new rt(`cancel command`),r=e.channel??`WEB`,i=e.output===`json`?`json`:`text`,a=li(e),o=ci(e.sessionStore);try{let s=await te(t,e.sessionId,{storeName:o});if(!s)throw Error(`No pending HITL request found for session "${e.sessionId}"`);let c=e.requestId??s.request.requestId;if(s.request.requestId!==c)throw Error(`Request ID mismatch: pending is "${s.request.requestId}", got "${c}"`);if(!(await ce({dataDir:t,sessionStoreName:o,sessionId:e.sessionId,requestId:c,resolution:{requestId:c,sessionId:e.sessionId,action:`cancel`,submittedAt:new Date().toISOString(),submittedBy:{channel:r}}})).state)throw Error(`Failed to cancel HITL request`);let l={type:`hitl_cancelled`,sessionId:e.sessionId,requestId:c,reason:e.reason??`cancelled by operator`};i===`text`&&O(l),await a.send({type:`progress`,sessionId:e.sessionId,channel:r,messageId:e.messageId,event:l}),n.end(),process.exit(0)}catch(t){let i=t;await a.send({type:`error`,sessionId:e.sessionId,channel:r,messageId:e.messageId,message:i.message}),M.error(`cancel command error: ${i.message}`),D(`Fatal: ${i.message}`),n.end(),process.exit(1)}finally{await a.close()}})}function di(e){e.command(`cancel`).description(`Cancel a pending HITL request`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).requiredOption(`-s, --session-id <id>`,`Session ID containing the pending HITL request`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`--request-id <id>`,`HITL request ID to cancel`).option(`--reason <text>`,`Human-readable cancel reason`).option(`-c, --channel <channel>`,`Channel type (default: WEB)`,`WEB`).option(`--callback-url <url>`,`HTTP callback URL for progress events`).option(`--stream-url <url>`,`WebSocket URL for streaming text events`).option(`--stream-auth-token <token>`,`Auth token for WebSocket streaming`).option(`--stream-events <list>`,`Comma-separated stream events`).option(`--message-id <id>`,`Message ID for correlating events`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{await ui(e)})}function fi(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir option or AIMAX_DATA_DIR environment variable`);return t}function pi(e){return e.query?.trim()||void 0}function mi(e){if(!e)return;let t=Number(e);if(!Number.isFinite(t)||t<=0)throw Error(`--timeout must be a positive number of milliseconds`);return t}function hi(e){if(!e)return;let t=Number(e);if(!Number.isInteger(t)||t<=0)throw Error(`--max-tokens must be a positive integer`);return t}async function gi(e){if(e.filePath){if(!C.isAbsolute(e.filePath))throw Error(`--file-path must be an absolute path`);try{await x.access(e.filePath)}catch(e){throw Error(`Failed to access --file-path: ${e.message}`)}return{source:`file`,filePath:e.filePath}}let t=e.content;if(!t||!t.trim())throw Error(`Either --file-path or --content must be provided`);return{source:`content`,content:t}}async function _i(e){let t=null;try{let n=fi(e);j(n),t=new rt(`summarize command`);let r=pi(e),i=await gi(e),a=Rt({apiFormat:e.apiFormat,baseUrl:e.baseUrl,apiKey:e.apiKey,model:e.model,contextWindow:2e5}),o=mi(e.timeout),s=hi(e.maxTokens);M.info(`summarize command started`,{dataDir:n,source:i.source,filePath:i.source===`file`?i.filePath:void 0,queryLength:r?.length,contentLength:i.source===`content`?i.content.length:void 0,timeoutMs:o,maxTokens:s});let c=await de({dataDir:n,channel:`WEB`,message:vi(i,r),llm:{...a,maxTokens:s},timeoutMs:o});E(c.text.trim()),M.info(`summarize command succeeded`,{source:i.source,summaryLength:c.text.length,durationMs:c.durationMs}),t.end()}catch(e){M.error(`summarize command error: ${e.message}`),D(`Fatal: ${e.message}`),t?.end(),process.exit(1)}}function vi(e,t){return e.source===`file`?[t?`Summarize exactly one file for the query below.`:`Summarize exactly one file.`,`Read only the absolute file path provided here. Do not search, browse, read other files, execute commands, modify files, or perform any other processing.`,`Return only the summary text.`,``,...t?[`Query:\n${t}`,``]:[],`Input source: file`,`File path: ${e.filePath}`].join(`
14
- `):[t?`Summarize the provided content for the query below.`:`Summarize the provided content.`,t?`Use only the provided content and query. Do not search, browse, read files, execute commands, modify files, or perform any other processing.`:`Use only the provided content. Do not search, browse, read files, execute commands, modify files, or perform any other processing.`,`Return only the summary text.`,``,...t?[`Query:\n${t}`,``]:[],`Input source: content`,`Source content:`,`<source>`,e.content,`</source>`].join(`
15
- `)}function yi(e){e.command(`summarize`).description(`Summarize one absolute file path or inline content`).option(`--file-path <path>`,`Absolute file path to summarize`).option(`--content <text>`,`Inline text content to summarize when --file-path is not provided`).option(`--query <text>`,`Optional search target or current description to focus the summary`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-format <format>`,`LLM API format: openai-completions or anthropic-messages (overrides AIMAX_API_FORMAT)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY)`).option(`--model <name>`,`LLM model name (overrides AIMAX_MODEL)`).option(`--timeout <ms>`,`Execution timeout in milliseconds`).option(`--max-tokens <number>`,`Maximum number of tokens for model output`).action(async e=>{await _i(e)})}const bi=e(import.meta.url)(`../package.json`);function xi(){return process.env.AIMAX_DATA_DIR||process.cwd()}function Si(){let e=new t;return e.name(`aimax`).description(`AIMax CLI — runs agent tasks in a containerized environment`).version(bi.version),Dr(e),Pn(e),ii(e),di(e),Or(e),yi(e),Zr(e),Ft(e),Ir(e),Gr(e,xi),Xr(e,xi),e}export{nt as a,M as i,xi as n,j as r,Si as t};