@gencode/cli 0.6.8 → 0.6.9
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.6.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d60a8fb: Enable smart topic segmentation by default for eligible chat runs, add disable switches for CLI and console executions, and tune classifier timeout handling for real OpenAI-compatible providers.
|
|
8
|
+
- Updated dependencies [d60a8fb]
|
|
9
|
+
- @gencode/agents@0.8.1
|
|
10
|
+
|
|
3
11
|
## 0.6.8
|
|
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-
|
|
2
|
+
import{a as e,i as t,r as n,t as r}from"./program-CokZ3Hdf.js";function i(){globalThis.getPkgPath||(globalThis.getPkgPath=()=>`@wizard/aimax`)}i();const a=Date.now(),o=process.env.AIMAX_DATA_DIR;o&&n(o),t.info(`AIMax CLI starting (pid=${process.pid})`),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{};
|
|
@@ -3,12 +3,12 @@ import{createRequire as e}from"node:module";import{Command as t}from"commander";
|
|
|
3
3
|
`)}function k(e){switch(e.type){case`start`:D(`\n[start] ${e.message}`);break;case`text`:Ne(e.text);break;case`stream_text_delta`:Ne(e.text);break;case`bootstrap`:D(`\n[bootstrap:${e.phase}] ${e.dataDir}`);break;case`session_reset`:D(`\n[session:${e.action}] ${e.message}`);break;case`tool_start`:D(`\n[tool:${e.name}] ${JSON.stringify(e.input??{})}`);break;case`tool_end`:D(`[tool:${e.name}] ${e.isError?`ERROR`:`OK`} ${e.output.slice(0,200)}`);break;case`compaction`:D(`\n[compaction${e.layer?`:${e.layer}`:``}] ${e.reason}${e.strategy?` (${e.strategy})`:``}`);break;case`skill_used`:D(`\n[skill] ${e.skillName} agent=${e.agent} task=${e.taskId}`);break;case`custom`:D(`\n[plugin:${e.pluginId}] ${e.name}${e.label?` ${e.label}`:``}${e.data?` ${JSON.stringify(e.data)}`:``}`);break;case`error`:O(`\n[error] ${e.message}`);break;case`diagnostic`:break;case`subagent_spawn`:D(`\n[subagent:spawn]${e.label?` "${e.label}"`:``} ${fe(e.task)}`);break;case`subagent_complete`:D(`[subagent:${e.status}] ${fe(e.task)}`);break;case`hitl_requested`:if(D(`\n[hitl:${e.request.kind}] ${e.request.title}`),D(` prompt: ${e.request.prompt}`),D(` requestId: ${e.request.requestId}`),e.request.input.mode===`choice`)for(let t of e.request.input.choices)D(` - [${t.id}] ${t.label}`);break;case`hitl_resumed`:D(`\n[hitl:resumed] requestId=${e.requestId} action=${e.resolution.action}`);break;case`hitl_expired`:D(`\n[hitl:expired] requestId=${e.requestId} reason=${e.reason}`);break;case`hitl_cancelled`:D(`\n[hitl:cancelled] requestId=${e.requestId}${e.reason?` reason=${e.reason}`:``}`);break;case`ui_tool_request`:D(`\n[ui-tool:${e.request.toolName}] ${e.request.outputSchema.title}`),D(` requestId: ${e.request.requestId}`),D(` toolCallId: ${e.request.toolCallId}`);break;case`ui_tool_result`:D(`\n[ui-tool:resumed] requestId=${e.requestId} tool=${e.toolName}`);break}}function A(e,t){if(t===`json`){e&&D(JSON.stringify(e,null,2));return}D(`
|
|
4
4
|
`),D(`session: ${e.sessionId}`),D(`duration: ${e.durationMs}ms`),D(`tokens: input=${e.usage.input} output=${e.usage.output} total=${e.usage.total}`),e.context&&(D(`context: ${e.context.snapshotPath}`),D(`tool-results: ${e.context.toolResultsDir}`)),e.error&&O(`error: ${e.error}`)}function Pe(e,t){if(t===`json`){D(JSON.stringify(e,null,2));return}if(e.length===0){D(`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:—]`;D(`${t.id} ${e} [${t.channel}]${n} ${t.title}`)}}function Fe(e,t){if(t===`json`){D(JSON.stringify(e,null,2));return}D(`session: ${e.id}`),e.metadata&&(D(`title: ${e.metadata.title}`),D(`channel: ${e.metadata.channel}`),D(`created: ${e.metadata.createdAt}`),D(`updated: ${e.metadata.updatedAt}`)),D(`transcript: ${e.transcriptPath}`),D(`entries: ${e.transcriptEntryCount}`),D(`context: ${e.contextSnapshotPath}`),D(`session-memory: ${e.sessionMemoryPath}`),D(`collapse-log: ${e.collapseLogPath}`),D(`read-states: ${e.readStateCount}`),D(`tool-results: ${e.toolResultRefCount}`),D(`tool-results-dir: ${e.toolResultsDir}`)}function Ie(e,t){if(t===`json`){D(JSON.stringify(e,null,2));return}D(`session: ${e.id}`),D(`transcript: ${e.paths.transcriptPath}`),D(`context: ${e.paths.contextSnapshotPath}`),D(`session-memory: ${e.paths.sessionMemoryPath}`),D(`collapse-log: ${e.paths.collapseLogPath}`),D(`tool-results-dir: ${e.paths.toolResultsDir}`),D(`transcript-entries: ${e.transcript.length}`),D(`read-states: ${e.context.readStates.length}`),D(`tool-results: ${e.context.toolResults.length}`),D(`collapse-spans: ${e.context.compaction.collapseSpans.length}`)}function Le(e,t){if(t===`json`){D(JSON.stringify(e,null,2));return}D(`Bootstrap completed.`),D(`dataDir: ${e.dataDir}`),D(`created dirs: ${e.createdDirs.length}`),D(`created files: ${e.createdFiles.length}`),D(`skipped dirs: ${e.skippedDirs.length}`),D(`skipped files: ${e.skippedFiles.length}`)}function Re(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 ze(e=new Date){let t=Re(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 Be(){return ze()}function Ve(e){if(!e)return``;let t=Object.entries(e).filter(([,e])=>e!==void 0).map(([e,t])=>`${e}=${JSON.stringify(t)}`);return t.length>0?` ${t.join(` `)}`:``}function He(e){return C.join(e,`.aimax`)}function Ue(e){return{appLogPath:C.join(e,`app.log`),errorLogPath:C.join(e,`errors.log`)}}function We(e){let{appLogPath:t,errorLogPath:n}=Ue(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 Ge(e,t,n){return`[${Be()}] [${e}] ${t}${Ve(n)}`}function Ke(e,t,n){process.stderr.write(`${Ge(e,t,n)}\n`)}function qe(e,t,n){if(!M){Ke(e,t,n);return}let r=Ge(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=He(e);be.mkdirSync(t,{recursive:!0}),We(t),M={dataDir:e,logDir:t}}function Je(){return M?{...M}:null}async function Ye(){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 Xe=`.aimax`,Ze=`${Xe}.pre-gocryptfs.`,I=[`fusermount3`,`fusermount`,`umount`];function Qe(e){return C.join(e,`.aimax.enc`)}function $e(e){return C.join(e,Xe)}function et(e){return C.join(e,`${Ze}${process.pid}.${Date.now()}`)}function tt(e){return e.replace(/\\([0-7]{3})/g,(e,t)=>String.fromCharCode(Number.parseInt(t,8)))}async function nt(e){try{let t=await rt(),n=C.resolve(e);for(let e of t.split(`
|
|
5
5
|
`)){if(!e.trim())continue;let t=e.split(` `);if(t.length>=5&&C.resolve(tt(t[4]??``))===n)return!0}return!1}catch{return!1}}async function rt(){return await S.readFile(`/proc/self/mountinfo`,`utf-8`)}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 it(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 at(e){return await L(e)?(await S.readdir(e)).length===0:!0}async function ot(e){if(!await L(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 st(e){return(await S.readdir(e,{withFileTypes:!0})).filter(e=>e.isDirectory()&&e.name.startsWith(Ze)).map(t=>C.join(e,t.name)).sort()}async function z(e,t){if(!await L(t))return null;let n=et(e);return await S.rename(t,n),n}async function B(e,t,n){await S.cp(e,t,{recursive:!0,force:n})}async function ct(e){let t=C.join(_e.tmpdir(),`aimax-gocryptfs-pass.${process.pid}.${Date.now()}`);await S.writeFile(t,`wizard_aimax@2026
|
|
6
|
-
`,{mode:384});try{return await e(t)}finally{await S.rm(t,{force:!0})}}async function lt(e){try{await H(`gocryptfs`,e)}catch(t){let n=t instanceof Error?t.message:String(t);throw Error(`gocryptfs ${e.join(` `)} failed: ${n}`)}}async function ut(){await dt(),await yt(`gocryptfs`,`required for --encrypt-sessions`);for(let e of I)if(await vt(e))return;throw Error(`--encrypt-sessions requires one of ${I.join(`, `)} to be installed for secure unmount cleanup.`)}async function dt(){try{await H(`modprobe`,[`fuse`])}catch(e){P.warn(`--encrypt-sessions could not load the fuse kernel module; continuing to try gocryptfs`,{error:e instanceof Error?e.message:String(e)})}}async function ft(e,t){await ct(async n=>{await lt([`-q`,`-passfile`,n,e,t])})}async function pt(e){await ct(async t=>{await lt([`-q`,`-init`,`-passfile`,t,e])})}async function mt(e){let t=[];for(let n of I)try{await H(n,[`-u`,e]);return}catch(e){t.push(bt(n,e))}throw Error(`Failed to unmount ${e}: ${t.join(`; `)}`)}function ht(e){for(let t of I)try{ye(t,[`-u`,e],{stdio:`ignore`});return}catch{}}function gt(e){let t=!1,n=()=>{t||(t=!0,ht(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 _t(e){let t=Qe(e),n=$e(e),r=()=>({mounted:!1,plainDir:n,encryptedDir:t,async cleanup(){}});try{await ut()}catch(e){return P.warn(`--encrypt-sessions is unavailable; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e)}),await R(n),r()}if(await nt(n))return r();let i=null,a=[],o=null,s=null,c=!1;try{if(a=await st(e),!await L(t))if(a.length>0?o=await z(e,n):i=await z(e,n),await R(t),await pt(t),await R(n),await ft(t,n),c=!0,s=gt(n),a.length>0){for(let e of a)await B(e,n,!0);o&&=(await B(o,n,!1),await S.rm(o,{recursive:!0,force:!0}),null);for(let e of a)await S.rm(e,{recursive:!0,force:!0});a=[]}else i&&=(await B(i,n,!0),await S.rm(i,{recursive:!0,force:!0}),null);else if(await ot(t),a.length>0?o=await z(e,n):await at(n)||(i=await z(e,n)),await it(n),await ft(t,n),c=!0,s=gt(n),a.length>0){for(let e of a)await B(e,n,!0);o&&=(await B(o,n,!1),await S.rm(o,{recursive:!0,force:!0}),null);for(let e of a)await S.rm(e,{recursive:!0,force:!0});a=[]}else i&&=(await B(i,n,!0),await S.rm(i,{recursive:!0,force:!0}),null);return{mounted:c,plainDir:n,encryptedDir:t,async cleanup(){if(s?.release(),c){c=!1;try{await mt(n)}catch(e){P.warn(`--encrypt-sessions failed to unmount encrypted .aimax; continuing shutdown`,{error:e instanceof Error?e.message:String(e)})}}}}}catch(e){return s?.release(),c&&await mt(n).catch(()=>{}),i&&await L(i)&&await at(n)&&(await S.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await S.rename(i,n).catch(()=>{})),o&&await L(o)&&await at(n)&&(await S.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await S.rename(o,n).catch(()=>{})),P.warn(`--encrypt-sessions failed; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e)}),await R(n),r()}}async function V(e,t,n){if(!t.encryptSessions)return n();let r=await _t(e);try{return await n()}finally{await r.cleanup()}}async function H(e,t){await new Promise((n,r)=>{ve(e,t,{encoding:`utf-8`},e=>{if(e){r(e);return}n()})})}async function vt(e){try{return await H(`sh`,[`-c`,`command -v "${e}" >/dev/null 2>&1`]),!0}catch{return!1}}async function yt(e,t){if(!await vt(e))throw Error(`--encrypt-sessions requires ${e}: ${t}.`)}function bt(e,t){return`${e} -u failed: ${t instanceof Error?t.message:String(t)}`}function xt(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{Le(await V(e.dataDir,e,async()=>i(e.dataDir)),t)}catch(e){O(`Error bootstrapping data directory: ${e.message}`),process.exit(1)}})}function St(e){return Se.sm4_encrypt_ecb(e)}function Ct(e){return St(e)}function wt(e={}){let t=e.baseUrl??process.env.AIMAX_BASE_URL,n=process.env.AIMAX_AUTH_TOKEN,r=e.authToken?Ct(e.authToken):n?Ct(n):e.apiKey??process.env.AIMAX_API_KEY,i=e.model??process.env.AIMAX_MODEL,a=[];if(t||a.push(`--base-url / AIMAX_BASE_URL`),r||a.push(`--api-key / AIMAX_API_KEY`),i||a.push(`--model / AIMAX_MODEL`),a.length>0)throw Error(`Missing required LLM configuration: ${a.join(`, `)}`);return{baseUrl:t,apiKey:r,model:i,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 Tt(e,t){return t?C.resolve(t):C.join(e,`.aimax`,`plugins.json`)}async function U(e,t){let n=Tt(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 W(e,t,n){let r=Tt(e,n);await S.mkdir(C.dirname(r),{recursive:!0}),await S.writeFile(r,JSON.stringify(t,null,2),`utf-8`)}function G(e){return typeof e==`object`&&!!e}function Et(e){return G(e)&&e.type===`text`&&typeof e.text==`string`&&(e.textSignature===void 0||typeof e.textSignature==`string`)}function Dt(e){return G(e)&&e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`}function Ot(e){return G(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 kt(e){return G(e)&&e.type===`toolCall`&&typeof e.id==`string`&&typeof e.name==`string`&&G(e.arguments)&&(e.thoughtSignature===void 0||typeof e.thoughtSignature==`string`)}function At(e){return typeof e==`string`||Array.isArray(e)&&e.every(e=>Et(e)||Dt(e))}function jt(e){return Array.isArray(e)&&e.every(e=>Et(e)||Ot(e)||kt(e))}function Mt(e){return G(e)&&typeof e.input==`number`&&typeof e.output==`number`&&typeof e.cacheRead==`number`&&typeof e.cacheWrite==`number`&&typeof e.totalTokens==`number`&&G(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 Nt(e){return!G(e)||typeof e.role!=`string`?!1:e.role===`user`?At(e.content):e.role===`assistant`?jt(e.content)&&typeof e.api==`string`&&typeof e.provider==`string`&&typeof e.model==`string`&&Mt(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=>Et(e)||Dt(e))&&typeof e.isError==`boolean`:!1}async function Pt(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=>Nt(e)))throw Error(`Message file must contain one Message object or an array of Message objects`);return r}async function Ft(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 Pt(e.fromFile)}:{kind:`text`,message:e.message}}var It=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()}))}},Lt=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=Rt(e);P.info(`sending callback event`,{callbackUrl:this.url,...n});let r=await fetch(this.url,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e)}),i=Date.now()-t;if(!r.ok)throw P.error(`callback event failed`,{callbackUrl:this.url,httpStatus:r.status,durationMs:i,...n}),Error(`Callback failed with status ${r.status}`);P.info(`callback event delivered`,{callbackUrl:this.url,httpStatus:r.status,durationMs:i,...n})}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 Rt(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 zt(e,t){if(t.kind===`none`)return e;let n=new URL(e);return n.searchParams.set(`authToken`,t.token),n.toString()}function K(){let e=globalThis.WebSocket;if(!e)throw Error(`WebSocket is not available in this runtime`);return e}function Bt(e){return e?{kind:`query_token`,token:e}:{kind:`none`}}function Vt(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 Ht(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 Ut=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 this.ensureConnected();let e=K();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 this.ensureConnected();let e=K();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=K();e.readyState!==t.CLOSED&&await new Promise(t=>{Vt(e,`close`,()=>t()),e.close()})}async ensureConnected(){if(!this.enabled)return;let e=K();if(this.socket&&this.socket.readyState===e.OPEN)return;if(this.connectPromise){await this.connectPromise;return}let t=new e(zt(this.url,Bt(this.authToken)));this.connectPromise=new Promise((e,n)=>{Vt(t,`open`,()=>{this.socket=t,Ht(t,`close`,()=>{this.socket===t&&(this.socket=null)}),e()}),Vt(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 Wt(e){let t=e.trim();if(!t)throw Error(`Goal objective cannot be empty`);return t}function Gt(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 Kt(e){let t=Gt(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}const qt=[`start`,`text`,`done`,`error`,`hitl`],Jt=[`off`,`gate`,`dry_run`,`write`];function Yt(e){if(!e?.trim())return new Set(qt);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(qt)}function Xt(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 Zt(e){return e?.trim()||void 0}function Qt(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 $t(e){return e?y(e):void 0}function en(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 tn(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 nn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(Jt.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function rn(e){let t=e.autoSkillsLoadEnabled===void 0?tn(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):tn(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?nn(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):nn(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 an(e,t){if(e.inputText&&t){let n=ge(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 on(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 sn(e){let t=await re(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 cn(e){let t=Xt(e),n=e.channel??`WEB`,r=wt({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:Qt(e),channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,skillsLoadPaths:en(e.skillsLoadPaths),autoSkills:rn(e)}}function ln(e){let t=[],n=null;return e.callbackUrl&&t.push(new Lt(e.callbackUrl)),e.streamUrl&&(n=new Ut(e.streamUrl,Yt(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new It(t),websocketSink:n}}async function un(e){let{dataDir:t,sessionId:n,sessionStoreName:r,toolCallId:i,toolName:a,resolution:o,encryptSessions:s}=e;if(!i||!a||!me(a))return;let c=(e,t)=>{switch(e){case`request_approval`:return d(t);case`clarify`:return f(t);case`request_review`:return p(t);default:return JSON.stringify({action:t.action,values:t.values})}};await le(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 dn(e){let{dataDir:t,sessionId:n,sessionStoreName:r,result:i,encryptSessions:a}=e;await le(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 fn(e){let t=Xt(e);await V(t,e,async()=>{N(t);let i=new F(`resume command`),a=null;try{let t=await cn(e),s=$t(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=Wt(i),o=e.tokenBudget===void 0?void 0:e.tokenBudget===`0`||e.tokenBudget===``?null:Number(e.tokenBudget);o!=null&&(Number.isNaN(o)||o<=0)&&(O(`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:s}),i=await r({dataDir:t.dataDir,sessionId:e.sessionId,objective:a,tokenBudget:o,force:e.force,storeName:s});c=Kt({sessionId:e.sessionId,before:n,result:i})}catch(e){throw e instanceof n&&(O(e.message),O(`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 ee(t.dataDir,e.sessionId,{storeName:s,encryptSessions:e.encryptSessions}),u=l?null:await te(t.dataDir,e.sessionId,{storeName:s,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=an(e,l.request),r=await se({dataDir:t.dataDir,sessionStoreName:s,sessionId:e.sessionId,requestId:e.requestId,resolution:n}),o=r.state;if(!o)throw Error(`Resolved HITL state was not persisted`);let u=pn(n,o.request.kind);await un({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:s,toolCallId:o.toolContext?.toolCallId,toolName:o.toolContext?.toolName,resolution:n,encryptSessions:e.encryptSessions});let d=ln(e);a=d.sink;let f=e.sessionId,p=async n=>{if(f=n.sessionId??f,!pe(n)){if(n.type===`stream_text_delta`){t.format===`text`&&k(n),await d.websocketSink?.sendTextDelta({sessionId:f,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}t.format===`text`&&k(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}),A({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 U(t.dataDir,m),g;try{g=await x({dataDir:t.dataDir,projectDir:Zt(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:s,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,hitlResume:{request:o.request,resolution:n,checkpoint:o.checkpoint,toolContext:o.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}}),A(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=on(e,u);if(!await ce(t.dataDir,e.sessionId,e.requestId,d,{storeName:s,encryptSessions:e.encryptSessions}))throw Error(`UI tool resume validation failed`);await dn({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:s,result:d,encryptSessions:e.encryptSessions});let f=ln(e);a=f.sink;let p=e.sessionId,m=async n=>{if(p=n.sessionId??p,!pe(n)){if(n.type===`stream_text_delta`){t.format===`text`&&k(n),await f.websocketSink?.sendTextDelta({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}if(t.format===`text`&&k(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 sn({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:s,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 U(t.dataDir,g),v=await x({dataDir:t.dataDir,projectDir:Zt(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:s,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]
|
|
7
|
-
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,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 o(t.dataDir,e.sessionId,{storeName:s,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}}),A(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}`),O(`Fatal: ${n.message}`),i.end(),process.exit(1)}finally{await a?.close()}})}function
|
|
8
|
-
`)}function
|
|
9
|
-
`)}async function
|
|
10
|
-
`),n.logContext),t.format===`text`&&(D(n.banner),D(``),D(n.contextBox),D(``))}function Yn(e,t,n){A(t,n),t.error?P.error(`run command failed: ${t.error}`):P.info(`run command succeeded`),e.end(),process.exit(t.error?1:0)}function Xn(e){let t=Je();if(!t)return;let n=`[${ze()}] [ERROR] ${e}\n`;try{be.appendFileSync(C.join(t.logDir,`app.log`),n),be.appendFileSync(C.join(t.logDir,`errors.log`),n)}catch{}}async function Zn(e,t){let n=`run command error: ${t.message}`;P.error(n),Xn(n),O(`Fatal: ${t.message}`),e.end(),await Ye(),process.exit(1)}async function Qn(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 $n(e){let t=vn(e);N(t);let i=new F(`run command`),a=null;try{a=e.encryptSessions?await _t(t):null,a&&N(t)}catch(e){await Zn(i,e);return}try{let t=await Qn(e);if(e.resumeRequestId||t||e.resumeFromFile){if(!e.sessionId||!e.resumeRequestId||!t)throw Error(`--session-id, --resume-request-id, and exactly one of --resume-input-json or --resume-from-file must be provided together`);await fn({dataDir:e.dataDir,projectDir:e.projectDir,systemAgentsDir:e.systemAgentsDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:e.resumeRequestId,inputJson:t,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});return}let a;try{a=await Ft({message:e.message,fromFile:e.fromFile})}catch(e){await Zn(i,e);return}let o=await Nn(e,a);if(o){await fn({dataDir:e.dataDir,projectDir:e.projectDir,systemAgentsDir:e.systemAgentsDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:o.requestId,inputText:o.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});return}let{controller:s,cleanup:c}=Rn(),l=null,u=e.channel??`WEB`,d=zn(e.sessionId);try{let t=await jn(e,a);u=t.channel,Jn(e,t);let o=Pn(e);l=o.sink,P.info(`external sink configured`,{callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamEvents:e.streamEvents});let c=Ln(l,o.websocketSink,t.channel,e.messageId,e.user);await Hn(t,c,d);let f,p=null;if(e.goal||e.goalFile){let i;i=e.goalFile?await S.readFile(e.goalFile,`utf-8`):e.goal;let a=Wt(i),o=Sn(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)&&(O(`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});p=Kt({sessionId:e.sessionId,before:n,result:i})}else f={objective:a,tokenBudget:s??null}}catch(e){throw e instanceof n&&(O(e.message),O(`Existing: ${e.existingObjectivePreview}`),process.exit(2)),e}}let m=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,h=await U(t.dataDir,m),g=Wn(t,c,d);p&&await g(p);let _=await x(Gn(e,t,s,g,h,f));await Kn(c,d,e.messageId,_),Yn(i,_,t.format)}catch(t){let n=t;l&&await qn(Ln(l,null,u,e.messageId,e.user),d,e.messageId,n),await Zn(i,n)}finally{await l?.close(),c()}}finally{await a?.cleanup()}}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 tr(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-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 (default: 600000)`).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 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`).action(async e=>{await $n(e)})}function nr(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||(O(`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`&&(O(`Invalid channel: ${r.channel}. Must be 'H5', 'WEB', 'KLPA', 'TASK', 'CRON', or 'EIP_ASSISTANT'`),process.exit(1));try{await V(r.dataDir,r,async()=>{let e=r.sessionStore?y(r.sessionStore):void 0;if(i===`list`){Pe(await v(r.dataDir,r.channel,{storeName:e}),a);return}if(r.sessionId||(O(`error: required option '-s, --session-id <id>' not specified`),process.exit(1)),i===`inspect`){Fe(await g(r.dataDir,r.sessionId,{storeName:e}),a);return}if(i===`export`){Ie(await u(r.dataDir,r.sessionId,{storeName:e}),a);return}O(`Invalid sessions action: ${i}. Must be 'list', 'inspect', or 'export'`),process.exit(1)})}catch(e){O(`${i===`inspect`?`Error inspecting session`:i===`export`?`Error exporting session`:`Error listing sessions`}: ${e.message}`),process.exit(1)}})}function rr(e){return C.join(e,`workspace`)}function ir(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function ar(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(`
|
|
11
|
-
`)}function
|
|
12
|
-
`))})}catch(e){O(`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 V(e.dataDir,e,async()=>{let n=sr(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:C.join(e.dataDir,`.aimax`),providerId:r.providerId,pluginId:r.pluginId,trigger:n,dryRun:!!e.dryRun},{workspaceDir:rr(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`){D(JSON.stringify(a,null,2));return}D(`trigger: ${a.trigger}`),D(`provider_source: ${a.providerSource}`),D(`provider_id: ${a.providerId}`),a.pluginId&&D(`plugin_id: ${a.pluginId}`),D(`result_count: ${a.resultCount}`),a.results.length===0?D(`note: no dream_gate hook registered`):D(`results: ${JSON.stringify(a.results)}`);for(let e of a.warnings)D(`warning: ${e}`)})}catch(e){O(`Error running dream gate: ${e.message}`),process.exit(1)}})}function fr(e){return`${e.match.accountId?`${e.match.channel}:${e.match.accountId}`:e.match.channel} -> ${e.agentId}`}function pr(e){return async t=>{let n=await T(t),r=Te(n),i=Ee(n);if(E(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=Ae(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(` - ${fr(e)}`)}}}}function mr(e,t){return async n=>{w(await T(n),De(e))&&(console.error(`Agent "${e}" already exists.`),process.exit(1)),await Ce(n,{id:e,name:t.name,model:t.model,default:t.default})||(console.error(`Agent "${e}" already exists.`),process.exit(1));let r=Ae(n,e);console.log(`Agent "${e}" added successfully.`),console.log(` Agent dir: ${r}`)}}function hr(e){return async t=>{let n=w(await T(t),De(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 Oe(t,e)||(console.error(`Failed to delete agent "${e}".`),process.exit(1)),console.log(`Agent "${e}" deleted.`)}}function gr(e){return async t=>{let n=await T(t),r=e.agent??E(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 we(t,{agentId:r,match:{channel:e,accountId:a||void 0}}),console.log(`Binding added: ${n} -> ${r}`)}}}function _r(e){return async t=>{let n=await T(t),r=e.agent??E(n);if(w(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),e.all){let e=await ke(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 ke(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 vr(e){return async t=>{let n=Ee(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(` ${fr(e)}`)}}function yr(e){return async t=>{let n=await T(t),r=e.agent??E(n);w(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),await je(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 br(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 V(n,e,async()=>{await pr(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 V(r,n,async()=>{await mr(e,n)(r)})}),r(n.command(`delete <id>`).description(`Delete an agent`)).action(async(e,n)=>{let r=t();await V(r,n,async()=>{await hr(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 V(n,e,async()=>{await gr(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 V(n,e,async()=>{await _r(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 V(n,e,async()=>{await vr(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 V(n,e,async()=>{await yr(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 xr(e){if(e.length===0){D(`No plugins discovered.`);return}for(let t of e){let e=t.status.padEnd(8,` `);D(`${t.id} ${e} ${t.origin} ${t.source}`)}}function Sr(e){D(`id: ${e.id}`),D(`status: ${e.status}`),D(`origin: ${e.origin}`),D(`source: ${e.source}`),D(`enabled: ${e.enabled}`),e.error&&D(`error: ${e.error}`),D(`tools: ${e.toolCount}`),D(`hooks: ${e.hookCount}`),e.skills.length>0&&D(`skills: ${e.skills.join(`, `)}`)}function Cr(e){return Array.from(new Set((e??[]).map(e=>e.trim()).filter(Boolean)))}function wr(e){if(e.length===0){D(`LLM allowlist is empty.`);return}for(let t of e)D(t)}function Tr(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 V(n,e,async()=>{xr(h({config:await U(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 V(r,n,async()=>{let t=h({config:await U(r,n.pluginsConfig),dataDir:r,workspaceDir:Y(r),bundledDir:X()}).registry.plugins.find(t=>t.id===e);t||(O(`Plugin not found: ${e}`),process.exit(1)),Sr(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 V(r,n,async()=>{let t=await U(r,n.pluginsConfig)??{},i=ie(t);h({config:t,dataDir:r,workspaceDir:Y(r),bundledDir:X()}).registry.plugins.some(t=>t.id===e)||(O(`Plugin not found: ${e}`),process.exit(1)),await W(r,{...t,entries:{...t.entries,[e]:{...t.entries?.[e]??{},enabled:!0}}},n.pluginsConfig),D(`Enabled ${e}`),i.allow.length>0&&!i.allow.includes(e)&&D(`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 V(r,n,async()=>{let t=await U(r,n.pluginsConfig)??{};h({config:t,dataDir:r,workspaceDir:Y(r),bundledDir:X()}).registry.plugins.some(t=>t.id===e)||(O(`Plugin not found: ${e}`),process.exit(1)),await W(r,{...t,entries:{...t.entries,[e]:{...t.entries?.[e]??{},enabled:!1}}},n.pluginsConfig),D(`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 V(n,e,async()=>{let t=h({config:await U(n,e.pluginsConfig),dataDir:n,workspaceDir:Y(n),bundledDir:X()});if(t.diagnostics.length===0){D(`No plugin issues detected.`);return}for(let e of t.diagnostics)D(`${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 V(n,e,async()=>{wr(Cr((await U(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 V(r,n,async()=>{let t=await U(r,n.pluginsConfig)??{},i=Cr([...t.llmAllowlist??[],...e]);await W(r,{...t,llmAllowlist:i},n.pluginsConfig),D(`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 V(r,n,async()=>{let t=await U(r,n.pluginsConfig)??{},i=new Set(e.map(e=>e.trim()).filter(Boolean)),a=Cr(t.llmAllowlist).filter(e=>!i.has(e));await W(r,{...t,llmAllowlist:a},n.pluginsConfig),D(`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 V(n,e,async()=>{await W(n,{...await U(n,e.pluginsConfig)??{},llmAllowlist:[]},e.pluginsConfig),D(`LLM allowlist cleared.`)})})}function Er(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 V(e.dataDir,e,async()=>{let n=_(await ne(e.dataDir,[]));if(t===`json`){D(JSON.stringify(n,null,2));return}D(`Commands`),D(` builtin: ${n.builtin.map(e=>e.name).join(` | `)}`),n.skillCommands.length>0?D(` skills: ${n.skillCommands.map(e=>e.name).join(` | `)}`):D(` skills: (none)`)})}catch(e){O(`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 Dr(e){let t={storeName:e.sessionStoreName},n=e.objective.trim(),r=await b(e.dataDir,e.sessionId,t);if(!r||(await ae(e.dataDir,e.sessionId,r,t)).trim()!==n)return de(e.dataDir,e.sessionId,{goalId:Me(),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 ue(e.dataDir,e.sessionId,i,{...t,eventSource:`cli`})}async function Or(e,t){let n=Z(t),r=Q(t),i=$(t.sessionStore),a=e.trim();a||(O(`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)&&(O(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));let s=await Dr({dataDir:n,sessionId:r,sessionStoreName:i,objective:a,tokenBudget:o});D(JSON.stringify({goal:s},null,2))}async function kr(e){let t=Z(e),n=Q(e),r=$(e.sessionStore),i=await b(t,n,{storeName:r});if(!i){D(JSON.stringify({goal:null},null,2));return}let a=await ae(t,n,i,{storeName:r});D(JSON.stringify({goal:{...i,objective:a}},null,2))}async function Ar(e){let t=Z(e),n=Q(e),r=$(e.sessionStore),i=await b(t,n,{storeName:r});i||(O(`error: no goal exists for this session`),process.exit(1)),i.status===`complete`&&(O(`error: cannot pause a completed goal`),process.exit(1));let a=await ue(t,n,{status:`paused`},{storeName:r,eventSource:`cli`});D(JSON.stringify({goal:a},null,2))}async function jr(e){let t=Z(e),n=Q(e),r=$(e.sessionStore),i=await b(t,n,{storeName:r});if(i||(O(`error: no goal exists for this session`),process.exit(1)),i.status===`complete`&&(O(`error: cannot resume a completed goal`),process.exit(1)),i.status===`budget_limited`&&(O(`error: cannot resume a budget-limited goal; clear or replace it instead`),process.exit(1)),i.status===`active`){D(JSON.stringify({goal:i},null,2));return}let a=await ue(t,n,{status:`active`},{storeName:r,eventSource:`cli`});D(JSON.stringify({goal:a},null,2))}async function Mr(e){let t=await c(Z(e),Q(e),{storeName:$(e.sessionStore),eventSource:`cli`});D(JSON.stringify({cleared:t},null,2))}function Nr(e){let t=e.command(`goal`).description(`Manage thread goals for a session`);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 Or(e,t)}catch(e){O(`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 kr(e)}catch(e){O(`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 Ar(e)}catch(e){O(`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 jr(e)}catch(e){O(`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 Mr(e)}catch(e){O(`error: ${e.message}`),process.exit(1)}})}const Pr=[`progress`,`error`,`hitl`];function Fr(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 Ir(e){if(!e?.trim())return new Set(Pr);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(Pr)}function Lr(e){return e?y(e):void 0}function Rr(e){let t=[];return e.callbackUrl&&t.push(new Lt(e.callbackUrl)),e.streamUrl&&t.push(new Ut(e.streamUrl,Ir(e.streamEvents),e.streamAuthToken)),new It(t)}async function zr(e){let t=Fr(e);await V(t,e,async()=>{N(t);let n=new F(`cancel command`),r=e.channel??`WEB`,i=e.output===`json`?`json`:`text`,a=Rr(e),o=Lr(e.sessionStore);try{let s=await ee(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 se({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`&&k(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}`),O(`Fatal: ${i.message}`),n.end(),process.exit(1)}finally{await a.close()}})}function Br(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 zr(e)})}function Vr(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 Hr(e){return e.query?.trim()||void 0}function Ur(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 Wr(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 Gr(e){if(e.filePath){if(!C.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 Kr(e){let t=null;try{let n=Vr(e);N(n),t=new F(`summarize command`);let r=Hr(e),i=await Gr(e),a=wt({baseUrl:e.baseUrl,apiKey:e.apiKey,model:e.model,contextWindow:2e5}),o=Ur(e.timeout),s=Wr(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:qr(i,r),llm:{...a,maxTokens:s},timeoutMs:o});D(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}`),O(`Fatal: ${e.message}`),t?.end(),process.exit(1)}}function qr(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(`
|
|
6
|
+
`,{mode:384});try{return await e(t)}finally{await S.rm(t,{force:!0})}}async function lt(e){try{await H(`gocryptfs`,e)}catch(t){let n=t instanceof Error?t.message:String(t);throw Error(`gocryptfs ${e.join(` `)} failed: ${n}`)}}async function ut(){await dt(),await yt(`gocryptfs`,`required for --encrypt-sessions`);for(let e of I)if(await vt(e))return;throw Error(`--encrypt-sessions requires one of ${I.join(`, `)} to be installed for secure unmount cleanup.`)}async function dt(){try{await H(`modprobe`,[`fuse`])}catch(e){P.warn(`--encrypt-sessions could not load the fuse kernel module; continuing to try gocryptfs`,{error:e instanceof Error?e.message:String(e)})}}async function ft(e,t){await ct(async n=>{await lt([`-q`,`-passfile`,n,e,t])})}async function pt(e){await ct(async t=>{await lt([`-q`,`-init`,`-passfile`,t,e])})}async function mt(e){let t=[];for(let n of I)try{await H(n,[`-u`,e]);return}catch(e){t.push(bt(n,e))}throw Error(`Failed to unmount ${e}: ${t.join(`; `)}`)}function ht(e){for(let t of I)try{ye(t,[`-u`,e],{stdio:`ignore`});return}catch{}}function gt(e){let t=!1,n=()=>{t||(t=!0,ht(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 _t(e){let t=Qe(e),n=$e(e),r=()=>({mounted:!1,plainDir:n,encryptedDir:t,async cleanup(){}});try{await ut()}catch(e){return P.warn(`--encrypt-sessions is unavailable; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e)}),await R(n),r()}if(await nt(n))return r();let i=null,a=[],o=null,s=null,c=!1;try{if(a=await st(e),!await L(t))if(a.length>0?o=await z(e,n):i=await z(e,n),await R(t),await pt(t),await R(n),await ft(t,n),c=!0,s=gt(n),a.length>0){for(let e of a)await B(e,n,!0);o&&=(await B(o,n,!1),await S.rm(o,{recursive:!0,force:!0}),null);for(let e of a)await S.rm(e,{recursive:!0,force:!0});a=[]}else i&&=(await B(i,n,!0),await S.rm(i,{recursive:!0,force:!0}),null);else if(await ot(t),a.length>0?o=await z(e,n):await at(n)||(i=await z(e,n)),await it(n),await ft(t,n),c=!0,s=gt(n),a.length>0){for(let e of a)await B(e,n,!0);o&&=(await B(o,n,!1),await S.rm(o,{recursive:!0,force:!0}),null);for(let e of a)await S.rm(e,{recursive:!0,force:!0});a=[]}else i&&=(await B(i,n,!0),await S.rm(i,{recursive:!0,force:!0}),null);return{mounted:c,plainDir:n,encryptedDir:t,async cleanup(){if(s?.release(),c){c=!1;try{await mt(n)}catch(e){P.warn(`--encrypt-sessions failed to unmount encrypted .aimax; continuing shutdown`,{error:e instanceof Error?e.message:String(e)})}}}}}catch(e){return s?.release(),c&&await mt(n).catch(()=>{}),i&&await L(i)&&await at(n)&&(await S.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await S.rename(i,n).catch(()=>{})),o&&await L(o)&&await at(n)&&(await S.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await S.rename(o,n).catch(()=>{})),P.warn(`--encrypt-sessions failed; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e)}),await R(n),r()}}async function V(e,t,n){if(!t.encryptSessions)return n();let r=await _t(e);try{return await n()}finally{await r.cleanup()}}async function H(e,t){await new Promise((n,r)=>{ve(e,t,{encoding:`utf-8`},e=>{if(e){r(e);return}n()})})}async function vt(e){try{return await H(`sh`,[`-c`,`command -v "${e}" >/dev/null 2>&1`]),!0}catch{return!1}}async function yt(e,t){if(!await vt(e))throw Error(`--encrypt-sessions requires ${e}: ${t}.`)}function bt(e,t){return`${e} -u failed: ${t instanceof Error?t.message:String(t)}`}function xt(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{Le(await V(e.dataDir,e,async()=>i(e.dataDir)),t)}catch(e){O(`Error bootstrapping data directory: ${e.message}`),process.exit(1)}})}function St(e){return Se.sm4_encrypt_ecb(e)}function Ct(e){return St(e)}function wt(e={}){let t=e.baseUrl??process.env.AIMAX_BASE_URL,n=process.env.AIMAX_AUTH_TOKEN,r=e.authToken?Ct(e.authToken):n?Ct(n):e.apiKey??process.env.AIMAX_API_KEY,i=e.model??process.env.AIMAX_MODEL,a=[];if(t||a.push(`--base-url / AIMAX_BASE_URL`),r||a.push(`--api-key / AIMAX_API_KEY`),i||a.push(`--model / AIMAX_MODEL`),a.length>0)throw Error(`Missing required LLM configuration: ${a.join(`, `)}`);return{baseUrl:t,apiKey:r,model:i,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 Tt(e,t){return t?C.resolve(t):C.join(e,`.aimax`,`plugins.json`)}async function U(e,t){let n=Tt(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 W(e,t,n){let r=Tt(e,n);await S.mkdir(C.dirname(r),{recursive:!0}),await S.writeFile(r,JSON.stringify(t,null,2),`utf-8`)}function G(e){return typeof e==`object`&&!!e}function Et(e){return G(e)&&e.type===`text`&&typeof e.text==`string`&&(e.textSignature===void 0||typeof e.textSignature==`string`)}function Dt(e){return G(e)&&e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`}function Ot(e){return G(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 kt(e){return G(e)&&e.type===`toolCall`&&typeof e.id==`string`&&typeof e.name==`string`&&G(e.arguments)&&(e.thoughtSignature===void 0||typeof e.thoughtSignature==`string`)}function At(e){return typeof e==`string`||Array.isArray(e)&&e.every(e=>Et(e)||Dt(e))}function jt(e){return Array.isArray(e)&&e.every(e=>Et(e)||Ot(e)||kt(e))}function Mt(e){return G(e)&&typeof e.input==`number`&&typeof e.output==`number`&&typeof e.cacheRead==`number`&&typeof e.cacheWrite==`number`&&typeof e.totalTokens==`number`&&G(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 Nt(e){return!G(e)||typeof e.role!=`string`?!1:e.role===`user`?At(e.content):e.role===`assistant`?jt(e.content)&&typeof e.api==`string`&&typeof e.provider==`string`&&typeof e.model==`string`&&Mt(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=>Et(e)||Dt(e))&&typeof e.isError==`boolean`:!1}async function Pt(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=>Nt(e)))throw Error(`Message file must contain one Message object or an array of Message objects`);return r}async function Ft(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 Pt(e.fromFile)}:{kind:`text`,message:e.message}}var It=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()}))}},Lt=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=Rt(e);P.info(`sending callback event`,{callbackUrl:this.url,...n});let r=await fetch(this.url,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e)}),i=Date.now()-t;if(!r.ok)throw P.error(`callback event failed`,{callbackUrl:this.url,httpStatus:r.status,durationMs:i,...n}),Error(`Callback failed with status ${r.status}`);P.info(`callback event delivered`,{callbackUrl:this.url,httpStatus:r.status,durationMs:i,...n})}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 Rt(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 zt(e,t){if(t.kind===`none`)return e;let n=new URL(e);return n.searchParams.set(`authToken`,t.token),n.toString()}function K(){let e=globalThis.WebSocket;if(!e)throw Error(`WebSocket is not available in this runtime`);return e}function Bt(e){return e?{kind:`query_token`,token:e}:{kind:`none`}}function Vt(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 Ht(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 Ut=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 this.ensureConnected();let e=K();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 this.ensureConnected();let e=K();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=K();e.readyState!==t.CLOSED&&await new Promise(t=>{Vt(e,`close`,()=>t()),e.close()})}async ensureConnected(){if(!this.enabled)return;let e=K();if(this.socket&&this.socket.readyState===e.OPEN)return;if(this.connectPromise){await this.connectPromise;return}let t=new e(zt(this.url,Bt(this.authToken)));this.connectPromise=new Promise((e,n)=>{Vt(t,`open`,()=>{this.socket=t,Ht(t,`close`,()=>{this.socket===t&&(this.socket=null)}),e()}),Vt(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 Wt(e){let t=e.trim();if(!t)throw Error(`Goal objective cannot be empty`);return t}function Gt(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 Kt(e){let t=Gt(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}const qt=[`start`,`text`,`done`,`error`,`hitl`],Jt=[`off`,`gate`,`dry_run`,`write`];function Yt(e){if(!e?.trim())return new Set(qt);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(qt)}function Xt(e){return e.disableTopicSegmentation===!0||process.env.AIMAX_DISABLE_TOPIC_SEGMENTATION===`true`?{enabled:!1}:void 0}function Zt(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 Qt(e){return e?.trim()||void 0}function $t(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 en(e){return e?y(e):void 0}function tn(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 nn(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 rn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(Jt.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function an(e){let t=e.autoSkillsLoadEnabled===void 0?nn(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):nn(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?rn(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):rn(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 on(e,t){if(e.inputText&&t){let n=ge(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 sn(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 cn(e){let t=await re(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 ln(e){let t=Zt(e),n=e.channel??`WEB`,r=wt({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:$t(e),channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,skillsLoadPaths:tn(e.skillsLoadPaths),autoSkills:an(e)}}function un(e){let t=[],n=null;return e.callbackUrl&&t.push(new Lt(e.callbackUrl)),e.streamUrl&&(n=new Ut(e.streamUrl,Yt(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new It(t),websocketSink:n}}async function dn(e){let{dataDir:t,sessionId:n,sessionStoreName:r,toolCallId:i,toolName:a,resolution:o,encryptSessions:s}=e;if(!i||!a||!me(a))return;let c=(e,t)=>{switch(e){case`request_approval`:return d(t);case`clarify`:return f(t);case`request_review`:return p(t);default:return JSON.stringify({action:t.action,values:t.values})}};await le(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 fn(e){let{dataDir:t,sessionId:n,sessionStoreName:r,result:i,encryptSessions:a}=e;await le(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 pn(e){let t=Zt(e);await V(t,e,async()=>{N(t);let i=new F(`resume command`),a=null;try{let t=await ln(e),s=en(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=Wt(i),o=e.tokenBudget===void 0?void 0:e.tokenBudget===`0`||e.tokenBudget===``?null:Number(e.tokenBudget);o!=null&&(Number.isNaN(o)||o<=0)&&(O(`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:s}),i=await r({dataDir:t.dataDir,sessionId:e.sessionId,objective:a,tokenBudget:o,force:e.force,storeName:s});c=Kt({sessionId:e.sessionId,before:n,result:i})}catch(e){throw e instanceof n&&(O(e.message),O(`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 ee(t.dataDir,e.sessionId,{storeName:s,encryptSessions:e.encryptSessions}),u=l?null:await te(t.dataDir,e.sessionId,{storeName:s,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=on(e,l.request),r=await se({dataDir:t.dataDir,sessionStoreName:s,sessionId:e.sessionId,requestId:e.requestId,resolution:n}),o=r.state;if(!o)throw Error(`Resolved HITL state was not persisted`);let u=mn(n,o.request.kind);await dn({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:s,toolCallId:o.toolContext?.toolCallId,toolName:o.toolContext?.toolName,resolution:n,encryptSessions:e.encryptSessions});let d=un(e);a=d.sink;let f=e.sessionId,p=async n=>{if(f=n.sessionId??f,!pe(n)){if(n.type===`stream_text_delta`){t.format===`text`&&k(n),await d.websocketSink?.sendTextDelta({sessionId:f,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}t.format===`text`&&k(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}),A({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 U(t.dataDir,m),g;try{g=await x({dataDir:t.dataDir,projectDir:Qt(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:s,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:Xt(e),hitlResume:{request:o.request,resolution:n,checkpoint:o.checkpoint,toolContext:o.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}}),A(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=sn(e,u);if(!await ce(t.dataDir,e.sessionId,e.requestId,d,{storeName:s,encryptSessions:e.encryptSessions}))throw Error(`UI tool resume validation failed`);await fn({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:s,result:d,encryptSessions:e.encryptSessions});let f=un(e);a=f.sink;let p=e.sessionId,m=async n=>{if(p=n.sessionId??p,!pe(n)){if(n.type===`stream_text_delta`){t.format===`text`&&k(n),await f.websocketSink?.sendTextDelta({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}if(t.format===`text`&&k(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 cn({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:s,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 U(t.dataDir,g),v=await x({dataDir:t.dataDir,projectDir:Qt(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:s,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]
|
|
7
|
+
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:Xt(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 o(t.dataDir,e.sessionId,{storeName:s,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}}),A(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}`),O(`Fatal: ${n.message}`),i.end(),process.exit(1)}finally{await a?.close()}})}function mn(e,t){return a(e,t)}function hn(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-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 pn(e)})}const gn=[`start`,`text`,`done`,`error`],_n=[`off`,`gate`,`dry_run`,`write`];function vn(e){if(!e?.trim())return new Set(gn);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(gn)}function yn(e){return e.disableTopicSegmentation===!0||process.env.AIMAX_DISABLE_TOPIC_SEGMENTATION===`true`?{enabled:!1}: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 xn(e){return e?.trim()||void 0}function Sn(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 q(e){return e?.trim()||void 0}function Cn(e){return e??`WEB`}function wn(e){return e?y(e):void 0}function Tn(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 En(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 Dn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(_n.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function On(e){let t=e.autoSkillsLoadEnabled===void 0?En(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):En(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?Dn(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):Dn(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 kn(e,t){return e.length<=t?e:t<=3?e.slice(0,t):`${e.slice(0,t-3)}...`}function An(e,t,n=78){let r=n-2,i=r-2,a=e?` ${kn(e,Math.max(0,i-2))} `:``,o=e?`┌${a}${`─`.repeat(Math.max(0,r-a.length))}┐`:`┌${`─`.repeat(r)}┐`,s=`└${`─`.repeat(r)}┘`;return[o,...t.map(e=>`│ ${kn(e,i).padEnd(i,` `)} │`),s].join(`
|
|
8
|
+
`)}function jn(e){return e.kind===`text`?`inline message (${e.message.length} chars)`:`message file (${e.messages.length} messages)`}function Mn(e,t){let n=wn(e.sessionStore)??`sessions`,r=t.timeoutMs===void 0?`default`:`${t.timeoutMs}`,i=e.callbackUrl?`enabled`:`disabled`,a=e.streamUrl?`enabled`:`disabled`,o=jn(t.input),s=t.input.kind===`text`?`inline`:e.fromFile??`file`,c=ze();return{banner:An(void 0,[`AIMax CLI`,`Stateless Agent Runner`]),contextBox:An(`Run Context`,[`time : ${c}`,`channel : ${t.channel}`,`user : ${e.user??`-`}`,`sessionId : ${e.sessionId??`new`}`,`sessionStore : ${n}`,`messageId : ${e.messageId??`-`}`,`dataDir : ${t.dataDir}`,`workspace : ${C.join(t.dataDir,`workspace`)}`,`projectDir : ${xn(e.projectDir)??`-`}`,`systemAgents : ${t.systemAgentsDir??`/aimax/agents`}`,`agent : ${q(e.agent)??`-`}`,`output : ${t.format}`,`callback : ${i}`,`websocket : ${a}`,`timeoutMs : ${r}`,`input : ${o}`]),logContext:{time:c,channel:t.channel,user:e.user,dataDir:t.dataDir,projectDir:xn(e.projectDir),systemAgentsDir:t.systemAgentsDir,agent:q(e.agent),workspaceDir:C.join(t.dataDir,`workspace`),sessionId:e.sessionId??`new`,sessionStore:n,messageId:e.messageId,output:t.format,hasCallback:!!e.callbackUrl,hasStream:!!e.streamUrl,timeoutMs:t.timeoutMs,inputKind:t.input.kind,inputSource:s,inputSummary:o}}}async function Nn(e,t){let n=bn(e),r=Cn(e.channel),i=wt({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:Sn(e),channel:r,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:i,input:t,skillsLoadPaths:Tn(e.skillsLoadPaths),autoSkills:On(e)}}function Pn(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(`
|
|
9
|
+
`)}async function Fn(e,t){if(!e.sessionId)return null;let n=Pn(t);if(!n)return null;let r=await ee(bn(e),e.sessionId,{storeName:wn(e.sessionStore),encryptSessions:e.encryptSessions});return!r||r.status!==`pending`||!he(n,r.request)?null:{requestId:r.request.requestId,inputText:n}}function In(e){let t=[],n=null;return e.callbackUrl&&t.push(new Lt(e.callbackUrl)),e.streamUrl&&(n=new Ut(e.streamUrl,vn(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new It(t),websocketSink:n}}async function J(e,t){P.info(`dispatching external event`,nr(t)),await e.sink.send(t)}function Ln(e){if(!e)return{};let t={};for(let[n,r]of Object.entries(e)){if(r===null||typeof r==`string`||typeof r==`number`||typeof r==`boolean`){t[n]=r;continue}if(r instanceof Error){t[n]=`${r.name}: ${r.message}`;continue}t[n]=JSON.stringify(r)}return t}function Rn(e){let t={sessionId:e.sessionId,messageId:e.messageId,parentSessionId:e.parentSessionId,depth:e.depth,scope:e.scope,phase:e.phase,...Ln(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 zn(e,t,n,r,i){return{sink:e,websocketSink:t,channel:n,defaultMessageId:r,user:i}}function Bn(){let e=new AbortController,t=()=>e.abort();return process.once(`SIGTERM`,t),process.once(`SIGINT`,t),{controller:e,cleanup:()=>{process.off(`SIGTERM`,t),process.off(`SIGINT`,t)}}}function Vn(e){return{activeSessionId:e??`pending`,finalResult:null}}function Hn(e,t){e.activeSessionId=t.sessionId??e.activeSessionId}function Un(e,t){return e.messageId??t}async function Wn(e,t,n){if(!await m(e.dataDir)){if(await Gn(t,e.format,n.activeSessionId,e.dataDir,`checking`),(await l(e.dataDir)).performedBootstrap){await Gn(t,e.format,n.activeSessionId,e.dataDir,`initializing`),await Gn(t,e.format,n.activeSessionId,e.dataDir,`initialized`);return}await Gn(t,e.format,n.activeSessionId,e.dataDir,`ready`)}}async function Gn(e,t,n,r,i){let a={type:`bootstrap`,phase:i,dataDir:r};t===`text`&&k(a),await J(e,{sessionId:n,channel:e.channel,messageId:e.defaultMessageId,user:e.user,type:`progress`,event:a})}function Kn(e,t,n){return async r=>{if(Hn(n,r),pe(r)){Rn(r);return}if(r.type===`stream_text_delta`){e.format===`text`&&k(r),await t.websocketSink?.sendTextDelta({sessionId:n.activeSessionId,channel:e.channel,messageId:Un(r,t.defaultMessageId),user:t.user,text:r.text});return}e.format===`text`&&k(r);let i=Un(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 qn(e,t,n,r,i,a){let o={dataDir:t.dataDir,projectDir:xn(e.projectDir),systemAgentsDir:t.systemAgentsDir,agentPolicy:q(e.agent)?{requestedAgentName:q(e.agent)}:void 0,sessionStoreName:wn(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:yn(e),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 Jn(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 Yn(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 Xn(e,t){let n=Mn(e,t);P.info([`run command started`,n.banner,n.contextBox].join(`
|
|
10
|
+
`),n.logContext),t.format===`text`&&(D(n.banner),D(``),D(n.contextBox),D(``))}function Zn(e,t,n){A(t,n),t.error?P.error(`run command failed: ${t.error}`):P.info(`run command succeeded`),e.end(),process.exit(t.error?1:0)}function Qn(e){let t=Je();if(!t)return;let n=`[${ze()}] [ERROR] ${e}\n`;try{be.appendFileSync(C.join(t.logDir,`app.log`),n),be.appendFileSync(C.join(t.logDir,`errors.log`),n)}catch{}}async function $n(e,t){let n=`run command error: ${t.message}`;P.error(n),Qn(n),O(`Fatal: ${t.message}`),e.end(),await Ye(),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 tr(e){let t=bn(e);N(t);let i=new F(`run command`),a=null;try{a=e.encryptSessions?await _t(t):null,a&&N(t)}catch(e){await $n(i,e);return}try{let t=await er(e);if(e.resumeRequestId||t||e.resumeFromFile){if(!e.sessionId||!e.resumeRequestId||!t)throw Error(`--session-id, --resume-request-id, and exactly one of --resume-input-json or --resume-from-file must be provided together`);await pn({dataDir:e.dataDir,projectDir:e.projectDir,systemAgentsDir:e.systemAgentsDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:e.resumeRequestId,inputJson:t,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 a;try{a=await Ft({message:e.message,fromFile:e.fromFile})}catch(e){await $n(i,e);return}let o=await Fn(e,a);if(o){await pn({dataDir:e.dataDir,projectDir:e.projectDir,systemAgentsDir:e.systemAgentsDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:o.requestId,inputText:o.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{controller:s,cleanup:c}=Bn(),l=null,u=e.channel??`WEB`,d=Vn(e.sessionId);try{let t=await Nn(e,a);u=t.channel,Xn(e,t);let o=In(e);l=o.sink,P.info(`external sink configured`,{callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamEvents:e.streamEvents});let c=zn(l,o.websocketSink,t.channel,e.messageId,e.user);await Wn(t,c,d);let f,p=null;if(e.goal||e.goalFile){let i;i=e.goalFile?await S.readFile(e.goalFile,`utf-8`):e.goal;let a=Wt(i),o=wn(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)&&(O(`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});p=Kt({sessionId:e.sessionId,before:n,result:i})}else f={objective:a,tokenBudget:s??null}}catch(e){throw e instanceof n&&(O(e.message),O(`Existing: ${e.existingObjectivePreview}`),process.exit(2)),e}}let m=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,h=await U(t.dataDir,m),g=Kn(t,c,d);p&&await g(p);let _=await x(qn(e,t,s,g,h,f));await Jn(c,d,e.messageId,_),Zn(i,_,t.format)}catch(t){let n=t;l&&await Yn(zn(l,null,u,e.messageId,e.user),d,e.messageId,n),await $n(i,n)}finally{await l?.close(),c()}}finally{await a?.cleanup()}}function nr(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 rr(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-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 (default: 600000)`).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 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 ir(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||(O(`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`&&(O(`Invalid channel: ${r.channel}. Must be 'H5', 'WEB', 'KLPA', 'TASK', 'CRON', or 'EIP_ASSISTANT'`),process.exit(1));try{await V(r.dataDir,r,async()=>{let e=r.sessionStore?y(r.sessionStore):void 0;if(i===`list`){Pe(await v(r.dataDir,r.channel,{storeName:e}),a);return}if(r.sessionId||(O(`error: required option '-s, --session-id <id>' not specified`),process.exit(1)),i===`inspect`){Fe(await g(r.dataDir,r.sessionId,{storeName:e}),a);return}if(i===`export`){Ie(await u(r.dataDir,r.sessionId,{storeName:e}),a);return}O(`Invalid sessions action: ${i}. Must be 'list', 'inspect', or 'export'`),process.exit(1)})}catch(e){O(`${i===`inspect`?`Error inspecting session`:i===`export`?`Error exporting session`:`Error listing sessions`}: ${e.message}`),process.exit(1)}})}function ar(e){return C.join(e,`workspace`)}function or(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function sr(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(`
|
|
11
|
+
`)}function cr(e){let t=e.level===`error`?`plugin error`:`plugin warning`;return e.pluginId?`${t} (${e.pluginId}): ${e.message}`:`${t}: ${e.message}`}function lr(e){if(!e||e===`cli`)return`cli`;if(e===`cron`)return`cron`;throw Error(`Unsupported dream trigger: ${e}. Expected "cli" or "cron".`)}async function ur(e){let t=[],n;try{n=await U(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=h({config:n,dataDir:e.dataDir,workspaceDir:ar(e.dataDir),bundledDir:or()});return t.push(...r.diagnostics.map(cr)),{pluginSystem:r,warnings:t}}catch(e){return t.push(`failed to initialize plugin system: ${e.message}`),{warnings:t}}}async function dr(e){let t=C.join(e.dataDir,`.aimax`),{pluginSystem:n,warnings:r}=await ur({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=oe({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:s({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 pr(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 V(e.dataDir,e,async()=>{let n=await dr({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);D(t===`json`?JSON.stringify(r,null,2):sr(r,e.deep))})}catch(e){O(`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 V(e.dataDir,e,async()=>{let t=await dr({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)O(`Warning: ${e}`);e.verbose&&n&&D(JSON.stringify(n,null,2)),D(e.rebuild?`Memory index rebuilt.`:`Memory index refreshed.`)})}catch(e){O(`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||(O(`Query is required: provide [query] or --query <text>`),process.exit(1));try{await V(t.dataDir,t,async()=>{let e=await(await dr({dataDir:t.dataDir,provider:t.provider,providerPlugin:t.providerPlugin,pluginsConfig:t.pluginsConfig,includeSessions:t.includeSessions})).provider.search(r);if(n===`json`){D(JSON.stringify(e,null,2));return}if(e.length===0){D(`No results found for: ${r}`);return}D(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(`
|
|
12
|
+
`))})}catch(e){O(`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 V(e.dataDir,e,async()=>{let n=lr(e.trigger),r=await dr({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:ar(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`){D(JSON.stringify(a,null,2));return}D(`trigger: ${a.trigger}`),D(`provider_source: ${a.providerSource}`),D(`provider_id: ${a.providerId}`),a.pluginId&&D(`plugin_id: ${a.pluginId}`),D(`result_count: ${a.resultCount}`),a.results.length===0?D(`note: no dream_gate hook registered`):D(`results: ${JSON.stringify(a.results)}`);for(let e of a.warnings)D(`warning: ${e}`)})}catch(e){O(`Error running dream gate: ${e.message}`),process.exit(1)}})}function mr(e){return`${e.match.accountId?`${e.match.channel}:${e.match.accountId}`:e.match.channel} -> ${e.agentId}`}function hr(e){return async t=>{let n=await T(t),r=Te(n),i=Ee(n);if(E(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=Ae(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(` - ${mr(e)}`)}}}}function gr(e,t){return async n=>{w(await T(n),De(e))&&(console.error(`Agent "${e}" already exists.`),process.exit(1)),await Ce(n,{id:e,name:t.name,model:t.model,default:t.default})||(console.error(`Agent "${e}" already exists.`),process.exit(1));let r=Ae(n,e);console.log(`Agent "${e}" added successfully.`),console.log(` Agent dir: ${r}`)}}function _r(e){return async t=>{let n=w(await T(t),De(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 Oe(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??E(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 we(t,{agentId:r,match:{channel:e,accountId:a||void 0}}),console.log(`Binding added: ${n} -> ${r}`)}}}function yr(e){return async t=>{let n=await T(t),r=e.agent??E(n);if(w(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),e.all){let e=await ke(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 ke(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 br(e){return async t=>{let n=Ee(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(` ${mr(e)}`)}}function xr(e){return async t=>{let n=await T(t),r=e.agent??E(n);w(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),await je(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 Sr(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 V(n,e,async()=>{await hr(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 V(r,n,async()=>{await gr(e,n)(r)})}),r(n.command(`delete <id>`).description(`Delete an agent`)).action(async(e,n)=>{let r=t();await V(r,n,async()=>{await _r(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 V(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 V(n,e,async()=>{await yr(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 V(n,e,async()=>{await br(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 V(n,e,async()=>{await xr(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 Cr(e){if(e.length===0){D(`No plugins discovered.`);return}for(let t of e){let e=t.status.padEnd(8,` `);D(`${t.id} ${e} ${t.origin} ${t.source}`)}}function wr(e){D(`id: ${e.id}`),D(`status: ${e.status}`),D(`origin: ${e.origin}`),D(`source: ${e.source}`),D(`enabled: ${e.enabled}`),e.error&&D(`error: ${e.error}`),D(`tools: ${e.toolCount}`),D(`hooks: ${e.hookCount}`),e.skills.length>0&&D(`skills: ${e.skills.join(`, `)}`)}function Tr(e){return Array.from(new Set((e??[]).map(e=>e.trim()).filter(Boolean)))}function Er(e){if(e.length===0){D(`LLM allowlist is empty.`);return}for(let t of e)D(t)}function Dr(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 V(n,e,async()=>{Cr(h({config:await U(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 V(r,n,async()=>{let t=h({config:await U(r,n.pluginsConfig),dataDir:r,workspaceDir:Y(r),bundledDir:X()}).registry.plugins.find(t=>t.id===e);t||(O(`Plugin not found: ${e}`),process.exit(1)),wr(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 V(r,n,async()=>{let t=await U(r,n.pluginsConfig)??{},i=ie(t);h({config:t,dataDir:r,workspaceDir:Y(r),bundledDir:X()}).registry.plugins.some(t=>t.id===e)||(O(`Plugin not found: ${e}`),process.exit(1)),await W(r,{...t,entries:{...t.entries,[e]:{...t.entries?.[e]??{},enabled:!0}}},n.pluginsConfig),D(`Enabled ${e}`),i.allow.length>0&&!i.allow.includes(e)&&D(`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 V(r,n,async()=>{let t=await U(r,n.pluginsConfig)??{};h({config:t,dataDir:r,workspaceDir:Y(r),bundledDir:X()}).registry.plugins.some(t=>t.id===e)||(O(`Plugin not found: ${e}`),process.exit(1)),await W(r,{...t,entries:{...t.entries,[e]:{...t.entries?.[e]??{},enabled:!1}}},n.pluginsConfig),D(`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 V(n,e,async()=>{let t=h({config:await U(n,e.pluginsConfig),dataDir:n,workspaceDir:Y(n),bundledDir:X()});if(t.diagnostics.length===0){D(`No plugin issues detected.`);return}for(let e of t.diagnostics)D(`${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 V(n,e,async()=>{Er(Tr((await U(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 V(r,n,async()=>{let t=await U(r,n.pluginsConfig)??{},i=Tr([...t.llmAllowlist??[],...e]);await W(r,{...t,llmAllowlist:i},n.pluginsConfig),D(`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 V(r,n,async()=>{let t=await U(r,n.pluginsConfig)??{},i=new Set(e.map(e=>e.trim()).filter(Boolean)),a=Tr(t.llmAllowlist).filter(e=>!i.has(e));await W(r,{...t,llmAllowlist:a},n.pluginsConfig),D(`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 V(n,e,async()=>{await W(n,{...await U(n,e.pluginsConfig)??{},llmAllowlist:[]},e.pluginsConfig),D(`LLM allowlist cleared.`)})})}function Or(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 V(e.dataDir,e,async()=>{let n=_(await ne(e.dataDir,[]));if(t===`json`){D(JSON.stringify(n,null,2));return}D(`Commands`),D(` builtin: ${n.builtin.map(e=>e.name).join(` | `)}`),n.skillCommands.length>0?D(` skills: ${n.skillCommands.map(e=>e.name).join(` | `)}`):D(` skills: (none)`)})}catch(e){O(`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 kr(e){let t={storeName:e.sessionStoreName},n=e.objective.trim(),r=await b(e.dataDir,e.sessionId,t);if(!r||(await ae(e.dataDir,e.sessionId,r,t)).trim()!==n)return de(e.dataDir,e.sessionId,{goalId:Me(),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 ue(e.dataDir,e.sessionId,i,{...t,eventSource:`cli`})}async function Ar(e,t){let n=Z(t),r=Q(t),i=$(t.sessionStore),a=e.trim();a||(O(`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)&&(O(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));let s=await kr({dataDir:n,sessionId:r,sessionStoreName:i,objective:a,tokenBudget:o});D(JSON.stringify({goal:s},null,2))}async function jr(e){let t=Z(e),n=Q(e),r=$(e.sessionStore),i=await b(t,n,{storeName:r});if(!i){D(JSON.stringify({goal:null},null,2));return}let a=await ae(t,n,i,{storeName:r});D(JSON.stringify({goal:{...i,objective:a}},null,2))}async function Mr(e){let t=Z(e),n=Q(e),r=$(e.sessionStore),i=await b(t,n,{storeName:r});i||(O(`error: no goal exists for this session`),process.exit(1)),i.status===`complete`&&(O(`error: cannot pause a completed goal`),process.exit(1));let a=await ue(t,n,{status:`paused`},{storeName:r,eventSource:`cli`});D(JSON.stringify({goal:a},null,2))}async function Nr(e){let t=Z(e),n=Q(e),r=$(e.sessionStore),i=await b(t,n,{storeName:r});if(i||(O(`error: no goal exists for this session`),process.exit(1)),i.status===`complete`&&(O(`error: cannot resume a completed goal`),process.exit(1)),i.status===`budget_limited`&&(O(`error: cannot resume a budget-limited goal; clear or replace it instead`),process.exit(1)),i.status===`active`){D(JSON.stringify({goal:i},null,2));return}let a=await ue(t,n,{status:`active`},{storeName:r,eventSource:`cli`});D(JSON.stringify({goal:a},null,2))}async function Pr(e){let t=await c(Z(e),Q(e),{storeName:$(e.sessionStore),eventSource:`cli`});D(JSON.stringify({cleared:t},null,2))}function Fr(e){let t=e.command(`goal`).description(`Manage thread goals for a session`);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 Ar(e,t)}catch(e){O(`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 jr(e)}catch(e){O(`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 Mr(e)}catch(e){O(`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 Nr(e)}catch(e){O(`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 Pr(e)}catch(e){O(`error: ${e.message}`),process.exit(1)}})}const Ir=[`progress`,`error`,`hitl`];function Lr(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 Rr(e){if(!e?.trim())return new Set(Ir);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(Ir)}function zr(e){return e?y(e):void 0}function Br(e){let t=[];return e.callbackUrl&&t.push(new Lt(e.callbackUrl)),e.streamUrl&&t.push(new Ut(e.streamUrl,Rr(e.streamEvents),e.streamAuthToken)),new It(t)}async function Vr(e){let t=Lr(e);await V(t,e,async()=>{N(t);let n=new F(`cancel command`),r=e.channel??`WEB`,i=e.output===`json`?`json`:`text`,a=Br(e),o=zr(e.sessionStore);try{let s=await ee(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 se({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`&&k(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}`),O(`Fatal: ${i.message}`),n.end(),process.exit(1)}finally{await a.close()}})}function Hr(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 Vr(e)})}function Ur(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 Wr(e){return e.query?.trim()||void 0}function Gr(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 Kr(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 qr(e){if(e.filePath){if(!C.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 Jr(e){let t=null;try{let n=Ur(e);N(n),t=new F(`summarize command`);let r=Wr(e),i=await qr(e),a=wt({baseUrl:e.baseUrl,apiKey:e.apiKey,model:e.model,contextWindow:2e5}),o=Gr(e.timeout),s=Kr(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:Yr(i,r),llm:{...a,maxTokens:s},timeoutMs:o});D(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}`),O(`Fatal: ${e.message}`),t?.end(),process.exit(1)}}function Yr(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(`
|
|
13
13
|
`):[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(`
|
|
14
|
-
`)}function
|
|
14
|
+
`)}function Xr(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-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 Jr(e)})}const Zr=e(import.meta.url)(`../package.json`);function Qr(){return process.env.AIMAX_DATA_DIR||process.cwd()}function $r(){let e=new t;return e.name(`aimax`).description(`AIMax CLI — runs agent tasks in a containerized environment`).version(Zr.version),rr(e),hn(e),Fr(e),Hr(e),ir(e),Xr(e),Or(e),xt(e),pr(e),Sr(e,Qr),Dr(e,Qr),e}export{Ye as a,P as i,Qr as n,N as r,$r as t};
|
package/dist/program.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,t}from"./program-
|
|
1
|
+
import{n as e,t}from"./program-CokZ3Hdf.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.6.
|
|
3
|
+
"version": "0.6.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"aimax": "./dist/bin.js"
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"commander": "^14.0.3",
|
|
23
23
|
"gensign-node": "latest",
|
|
24
24
|
"log4js": "^6.9.1",
|
|
25
|
-
"@gencode/agents": "0.8.
|
|
25
|
+
"@gencode/agents": "0.8.1",
|
|
26
26
|
"@gencode/shared": "0.2.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|