@gencode/cli 0.0.32 → 0.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +1 -1
- package/dist/program-B2JBui5b.js +6 -0
- package/dist/program.js +1 -1
- package/package.json +3 -3
- package/dist/program-jAtKec-j.js +0 -9
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-B2JBui5b.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{};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{createRequire as e}from"node:module";import{Command as t}from"commander";import{bootstrapMountLayout as n,buildResumeNarration as r,createBuiltinMemoryProvider as i,ensureBootstrapMountLayout as a,exportSession as o,formatApprovalResolution as s,hasBootstrapSentinel as c,initializePluginSystem as l,inspectSession as u,listAvailableSlashCommands as d,listSessionSummaries as ee,loadPendingHitl as te,loadSkillsWithPluginDirs as f,normalizePluginsConfig as p,normalizeSessionStoreName as m,resolveMemoryProvider as ne,resolvePendingHitl as re,rewriteTranscript as ie,runAgent as ae}from"@gencode/agents";import{isAgentDiagnosticEvent as h}from"@gencode/shared";import g from"node:path";import oe from"gensign-node";import _ from"node:fs/promises";import se from"node:fs";import v from"log4js";import{addAgent as ce,addBinding as le,getAgentConfig as y,listAgents as ue,listBindings as b,loadAgentsConfig as x,normalizeAgentId as S,removeAgent as de,removeBindings as fe,resolveAgentDir as pe,resolveDefaultAgentId as C,updateAgentIdentity as me}from"@gencode/agents/config";function he(e){process.stdout.write(e)}function w(e){process.stdout.write(e+`
|
|
2
|
+
`)}function T(e){process.stderr.write(e+`
|
|
3
|
+
`)}function E(e){switch(e.type){case`start`:w(`\n[start] ${e.message}`);break;case`text`:he(e.text);break;case`stream_text_delta`:he(e.text);break;case`bootstrap`:w(`\n[bootstrap:${e.phase}] ${e.dataDir}`);break;case`session_reset`:w(`\n[session:${e.action}] ${e.message}`);break;case`tool_start`:w(`\n[tool:${e.name}] ${JSON.stringify(e.input)}`);break;case`tool_end`:w(`[tool:${e.name}] ${e.isError?`ERROR`:`OK`} ${e.output.slice(0,200)}`);break;case`compaction`:w(`\n[compaction${e.layer?`:${e.layer}`:``}] ${e.reason}${e.strategy?` (${e.strategy})`:``}`);break;case`skill_used`:w(`\n[skill] ${e.skillName} agent=${e.agent} task=${e.taskId}`);break;case`custom`:w(`\n[plugin:${e.pluginId}] ${e.name}${e.label?` ${e.label}`:``}${e.data?` ${JSON.stringify(e.data)}`:``}`);break;case`error`:T(`\n[error] ${e.message}`);break;case`diagnostic`:break;case`subagent_spawn`:w(`\n[subagent:spawn]${e.label?` "${e.label}"`:``} ${e.task}`);break;case`subagent_complete`:w(`[subagent:${e.status}] ${e.task}`);break;case`hitl_requested`:if(w(`\n[hitl:${e.request.kind}] ${e.request.title}`),w(` prompt: ${e.request.prompt}`),w(` requestId: ${e.request.requestId}`),e.request.input.mode===`choice`)for(let t of e.request.input.choices)w(` - [${t.id}] ${t.label}`);break;case`hitl_resumed`:w(`\n[hitl:resumed] requestId=${e.requestId} action=${e.resolution.action}`);break;case`hitl_expired`:w(`\n[hitl:expired] requestId=${e.requestId} reason=${e.reason}`);break;case`hitl_cancelled`:w(`\n[hitl:cancelled] requestId=${e.requestId}${e.reason?` reason=${e.reason}`:``}`);break}}function D(e,t){if(t===`json`){w(JSON.stringify(e,null,2));return}w(`
|
|
4
|
+
`),w(`session: ${e.sessionId}`),w(`duration: ${e.durationMs}ms`),w(`tokens: input=${e.usage.input} output=${e.usage.output} total=${e.usage.total}`),e.context&&(w(`context: ${e.context.snapshotPath}`),w(`tool-results: ${e.context.toolResultsDir}`)),e.error&&T(`error: ${e.error}`)}function ge(e,t){if(t===`json`){w(JSON.stringify(e,null,2));return}if(e.length===0){w(`No sessions found.`);return}for(let t of e){let e=t.createdAt?new Date(t.createdAt).toLocaleString():`unknown`;w(`${t.id} ${e} [${t.channel}] ${t.title}`)}}function _e(e,t){if(t===`json`){w(JSON.stringify(e,null,2));return}w(`session: ${e.id}`),e.metadata&&(w(`title: ${e.metadata.title}`),w(`channel: ${e.metadata.channel}`),w(`created: ${e.metadata.createdAt}`),w(`updated: ${e.metadata.updatedAt}`)),w(`transcript: ${e.transcriptPath}`),w(`entries: ${e.transcriptEntryCount}`),w(`context: ${e.contextSnapshotPath}`),w(`session-memory: ${e.sessionMemoryPath}`),w(`collapse-log: ${e.collapseLogPath}`),w(`read-states: ${e.readStateCount}`),w(`tool-results: ${e.toolResultRefCount}`),w(`tool-results-dir: ${e.toolResultsDir}`)}function ve(e,t){if(t===`json`){w(JSON.stringify(e,null,2));return}w(`session: ${e.id}`),w(`transcript: ${e.paths.transcriptPath}`),w(`context: ${e.paths.contextSnapshotPath}`),w(`session-memory: ${e.paths.sessionMemoryPath}`),w(`collapse-log: ${e.paths.collapseLogPath}`),w(`tool-results-dir: ${e.paths.toolResultsDir}`),w(`transcript-entries: ${e.transcript.length}`),w(`read-states: ${e.context.readStates.length}`),w(`tool-results: ${e.context.toolResults.length}`),w(`collapse-spans: ${e.context.compaction.collapseSpans.length}`)}function ye(e,t){if(t===`json`){w(JSON.stringify(e,null,2));return}w(`Bootstrap completed.`),w(`dataDir: ${e.dataDir}`),w(`created dirs: ${e.createdDirs.length}`),w(`created files: ${e.createdFiles.length}`),w(`skipped dirs: ${e.skippedDirs.length}`),w(`skipped files: ${e.skippedFiles.length}`)}function be(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`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{ye(await n(e.dataDir),t)}catch(e){T(`Error bootstrapping data directory: ${e.message}`),process.exit(1)}})}function xe(e){return oe.sm4_encrypt_ecb(e)}function Se(e){return xe(e)}function O(e={}){let t=e.baseUrl??process.env.AIMAX_BASE_URL,n=process.env.AIMAX_AUTH_TOKEN,r=e.authToken?Se(e.authToken):n?Se(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 k(e,t){return t?g.resolve(t):g.join(e,`.aimax`,`plugins.json`)}async function A(e,t){let n=k(e,t);try{let e=await _.readFile(n,`utf-8`);return JSON.parse(e)}catch(e){if(e.code===`ENOENT`)return;throw e}}async function j(e,t,n){let r=k(e,n);await _.mkdir(g.dirname(r),{recursive:!0}),await _.writeFile(r,JSON.stringify(t,null,2),`utf-8`)}function M(e){return typeof e==`object`&&!!e}function N(e){return M(e)&&e.type===`text`&&typeof e.text==`string`&&(e.textSignature===void 0||typeof e.textSignature==`string`)}function P(e){return M(e)&&e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`}function Ce(e){return M(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 we(e){return M(e)&&e.type===`toolCall`&&typeof e.id==`string`&&typeof e.name==`string`&&M(e.arguments)&&(e.thoughtSignature===void 0||typeof e.thoughtSignature==`string`)}function Te(e){return typeof e==`string`||Array.isArray(e)&&e.every(e=>N(e)||P(e))}function Ee(e){return Array.isArray(e)&&e.every(e=>N(e)||Ce(e)||we(e))}function De(e){return M(e)&&typeof e.input==`number`&&typeof e.output==`number`&&typeof e.cacheRead==`number`&&typeof e.cacheWrite==`number`&&typeof e.totalTokens==`number`&&M(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 Oe(e){return!M(e)||typeof e.role!=`string`?!1:e.role===`user`?Te(e.content):e.role===`assistant`?Ee(e.content)&&typeof e.api==`string`&&typeof e.provider==`string`&&typeof e.model==`string`&&De(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=>N(e)||P(e))&&typeof e.isError==`boolean`:!1}async function ke(e){let t;try{t=await _.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=>Oe(e)))throw Error(`Message file must contain one Message object or an array of Message objects`);return r}async function Ae(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 ke(e.fromFile)}:{kind:`text`,message:e.message}}let F=function(e){return e.INFO=`INFO`,e.ERROR=`ERROR`,e.WARN=`WARN`,e}({}),I=null;function je(){let e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)} ${String(e.getHours()).padStart(2,`0`)}:${String(e.getMinutes()).padStart(2,`0`)}:${String(e.getSeconds()).padStart(2,`0`)}.${String(e.getMilliseconds()).padStart(3,`0`)}`}function L(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 Me(e){return g.join(e,`.aimax`)}function Ne(e){return{appLogPath:g.join(e,`app.log`),errorLogPath:g.join(e,`errors.log`)}}function Pe(e){let{appLogPath:t,errorLogPath:n}=Ne(e);v.configure({appenders:{appFile:{type:`file`,filename:t,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`pattern`,pattern:`[%d{yyyy-MM-dd hh:mm:ss.SSS}] [%p] %m`}},errorFile:{type:`file`,filename:n,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`pattern`,pattern:`[%d{yyyy-MM-dd hh:mm:ss.SSS}] [%p] %m`}},errorsOnly:{type:`logLevelFilter`,appender:`errorFile`,level:`error`,maxLevel:`fatal`}},categories:{default:{appenders:[`appFile`,`errorsOnly`],level:`info`}}})}function Fe(e,t,n){process.stderr.write(`[${je()}] [${e}] ${t}${L(n)}\n`)}function R(e,t,n){let r=`${t}${L(n)}`;if(!I){Fe(e,r);return}let i=v.getLogger();if(e===F.ERROR){i.error(r);return}if(e===F.WARN){i.warn(r);return}i.info(r)}function z(e){let t=Me(e);I?.dataDir!==e&&(se.mkdirSync(t,{recursive:!0}),Pe(t),I={dataDir:e,logDir:t})}async function Ie(){await v.shutdown()}const B={info:(e,t)=>R(F.INFO,e,t),warn:(e,t)=>R(F.WARN,e,t),error:(e,t)=>R(F.ERROR,e,t)};var V=class{startTime;name;constructor(e){this.name=e,this.startTime=Date.now()}end(){let e=Date.now()-this.startTime;return B.info(`${this.name} completed in ${e}ms`),e}},H=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()}))}},U=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=Le(e);B.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 B.error(`callback event failed`,{callbackUrl:this.url,httpStatus:r.status,durationMs:i,...n}),Error(`Callback failed with status ${r.status}`);B.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 Le(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 Re(e,t){if(t.kind===`none`)return e;let n=new URL(e);return n.searchParams.set(`authToken`,t.token),n.toString()}function W(){let e=globalThis.WebSocket;if(!e)throw Error(`WebSocket is not available in this runtime`);return e}function ze(e){return e?{kind:`query_token`,token:e}:{kind:`none`}}function G(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 Be(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 K=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=W();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){B.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=W();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){B.warn(`websocket sink disabled after text delta send failure`,{url:this.url,error:e instanceof Error?e.message:String(e)}),this.enabled=!1}}async close(){this.enabled=!1;let e=this.socket;if(this.socket=null,this.connectPromise=null,!e)return;let t=W();e.readyState!==t.CLOSED&&await new Promise(t=>{G(e,`close`,()=>t()),e.close()})}async ensureConnected(){if(!this.enabled)return;let e=W();if(this.socket&&this.socket.readyState===e.OPEN)return;if(this.connectPromise){await this.connectPromise;return}let t=new e(Re(this.url,ze(this.authToken)));this.connectPromise=new Promise((e,n)=>{G(t,`open`,()=>{this.socket=t,Be(t,`close`,()=>{this.socket===t&&(this.socket=null)}),e()}),G(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)}`)}}}};const Ve=[`start`,`text`,`done`,`error`,`hitl`];function He(e){if(!e?.trim())return new Set(Ve);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(Ve)}function Ue(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 We(e){return e?m(e):void 0}function Ge(e){if(!e.inputJson)throw Error(`--input-json is required for 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}`)}}async function Ke(e){let t=Ue(e),n=e.channel??`WEB`,r=O({baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel}),i=Ge(e);return{dataDir:t,channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,resolution:i}}function qe(e){let t=[],n=null;return e.callbackUrl&&t.push(new U(e.callbackUrl)),e.streamUrl&&(n=new K(e.streamUrl,He(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new H(t),websocketSink:n}}async function Je(e){let{dataDir:t,sessionId:n,sessionStoreName:r,toolCallId:i,resolution:a}=e;i&&await ie(t,n,e=>{let t=e.findIndex(e=>e.role===`tool_result`&&e.toolCallId===i&&e.toolName===`request_approval`);if(t===-1)return e;let n=e.slice(0,t+1);return n[t]={...n[t],content:s(a),isError:!1},n},{storeName:r})}async function Ye(e){z(Ue(e));let t=new V(`resume command`),n=null;try{let r=await Ke(e),i=We(e.sessionStore);B.info(`resume command started`,{sessionId:e.sessionId,requestId:e.requestId,channel:r.channel,dataDir:r.dataDir});let a=await te(r.dataDir,e.sessionId,{storeName:i});if(!a)throw Error(`No pending HITL request found for session "${e.sessionId}"`);if(a.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${a.request.requestId}", got "${e.requestId}"`);if(a.status===`expired`)throw Error(`HITL request has expired`);if(a.status===`cancelled`)throw Error(`HITL request has been cancelled`);let o=await re({dataDir:r.dataDir,sessionStoreName:i,sessionId:e.sessionId,requestId:e.requestId,resolution:r.resolution}),s=o.state;if(!s)throw Error(`Resolved HITL state was not persisted`);let c=Xe(r.resolution,s.request.kind);await Je({dataDir:r.dataDir,sessionId:e.sessionId,sessionStoreName:i,toolCallId:s.toolContext?.toolCallId,resolution:r.resolution});let l=qe(e);n=l.sink;let u=e.sessionId,d=async t=>{if(u=t.sessionId??u,!h(t)){if(t.type===`stream_text_delta`){r.format===`text`&&E(t),await l.websocketSink?.sendTextDelta({sessionId:u,channel:r.channel,messageId:e.messageId,user:e.user,text:t.text});return}if(r.format===`text`&&E(t),t.type===`hitl_resumed`){await n?.send({sessionId:u,channel:r.channel,messageId:e.messageId,user:e.user,type:`progress`,event:t});return}if(t.type===`start`){await n?.send({sessionId:u,channel:r.channel,messageId:e.messageId,user:e.user,type:`start`,message:t.message});return}await n?.send({sessionId:u,channel:r.channel,messageId:e.messageId,user:e.user,type:`progress`,event:t})}};await d({type:`hitl_resumed`,requestId:e.requestId,resolution:r.resolution,sessionId:e.sessionId}),`idempotentReplay`in o&&o.idempotentReplay&&(B.info(`resume command treated as idempotent replay`,{sessionId:e.sessionId,requestId:e.requestId,idempotencyKey:r.resolution.idempotencyKey}),D({sessionId:e.sessionId,text:`Resume request already processed.`,usage:{input:0,output:0,total:0},durationMs:0},r.format),t.end(),process.exit(0));let ee=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,f=await A(r.dataDir,ee),p;try{p=await ae({dataDir:r.dataDir,sessionStoreName:i,sessionId:e.sessionId,messageId:e.messageId,channel:r.channel,llm:r.llm,timeoutMs:r.timeoutMs,message:c,hitlResume:{request:s.request,resolution:r.resolution,checkpoint:s.checkpoint,toolContext:s.toolContext},plugins:f?{config:f,dataDir:r.dataDir,workspaceDir:g.join(r.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:f.llmAllowlist}:void 0,onProgress:d})}finally{}p.error?await n?.send({sessionId:p.sessionId,channel:r.channel,messageId:e.messageId,user:e.user,type:`error`,message:p.error}):await n?.send({sessionId:p.sessionId,channel:r.channel,messageId:e.messageId,user:e.user,type:`done`,result:{text:p.text,usage:p.usage,durationMs:p.durationMs,error:p.error,paused:p.paused}}),D(p,r.format),p.error?B.error(`resume command failed: ${p.error}`):B.info(`resume command succeeded`),t.end(),process.exit(p.error?1:0)}catch(r){let i=r;n&&(i.message.includes(`expired`)&&await n.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:i.message}}),i.message.includes(`cancelled`)&&await n.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:i.message}}),await n.send({sessionId:e.sessionId,channel:e.channel??`WEB`,messageId:e.messageId,user:e.user,type:`error`,message:`Resume failed: ${i.message}`})),B.error(`resume command error: ${i.message}`),T(`Fatal: ${i.message}`),t.end(),process.exit(1)}finally{await n?.close()}}function Xe(e,t){return r(e,t)}function Ze(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)`).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`).requiredOption(`--input-json <json>`,`JSON string with the resolution (action, values, etc.)`).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`).action(async e=>{await Ye(e)})}const Qe=[`start`,`text`,`done`,`error`];function $e(e){if(!e?.trim())return new Set(Qe);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(Qe)}function et(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 tt(e){return e??`WEB`}function nt(e){return e?m(e):void 0}async function rt(e){let t=et(e),n=tt(e.channel),r=O({baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel}),i=await Ae({message:e.message,fromFile:e.fromFile});return{dataDir:t,channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,input:i}}function it(e){let t=[],n=null;return e.callbackUrl&&t.push(new U(e.callbackUrl)),e.streamUrl&&(n=new K(e.streamUrl,$e(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new H(t),websocketSink:n}}async function q(e,t){B.info(`dispatching external event`,xt(t)),await e.sink.send(t)}function at(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 ot(e){let t={sessionId:e.sessionId,messageId:e.messageId,parentSessionId:e.parentSessionId,depth:e.depth,scope:e.scope,phase:e.phase,...at(e.details)};if(e.level===`error`){B.error(e.message,t);return}if(e.level===`warn`){B.warn(e.message,t);return}B.info(e.message,t)}function st(e,t,n,r,i){return{sink:e,websocketSink:t,channel:n,defaultMessageId:r,user:i}}function ct(){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 lt(e){return{activeSessionId:e??`pending`,finalResult:null}}function ut(e,t){e.activeSessionId=t.sessionId??e.activeSessionId}function dt(e,t){return e.messageId??t}async function ft(e,t,n){if(!await c(e.dataDir)){if(await J(t,e.format,n.activeSessionId,e.dataDir,`checking`),(await a(e.dataDir)).performedBootstrap){await J(t,e.format,n.activeSessionId,e.dataDir,`initializing`),await J(t,e.format,n.activeSessionId,e.dataDir,`initialized`);return}await J(t,e.format,n.activeSessionId,e.dataDir,`ready`)}}async function J(e,t,n,r,i){let a={type:`bootstrap`,phase:i,dataDir:r};t===`text`&&E(a),await q(e,{sessionId:n,channel:e.channel,messageId:e.defaultMessageId,user:e.user,type:`progress`,event:a})}function pt(e,t,n){return async r=>{if(ut(n,r),h(r)){ot(r);return}if(r.type===`stream_text_delta`){e.format===`text`&&E(r),await t.websocketSink?.sendTextDelta({sessionId:n.activeSessionId,channel:e.channel,messageId:dt(r,t.defaultMessageId),user:t.user,text:r.text});return}e.format===`text`&&E(r);let i=dt(r,t.defaultMessageId);if(r.type===`hitl_requested`){await q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`hitl`,request:r.request}),await q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r});return}if(r.type===`start`){await q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`start`,message:r.message});return}if(r.type===`session_reset`){await q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`session_reset`,action:r.action,previousSessionId:r.previousSessionId,message:r.message});return}await q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r})}}function mt(e,t,n,r,i){let a={dataDir:t.dataDir,sessionStoreName:nt(e.sessionStore),sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,timeoutMs:t.timeoutMs,abortSignal:n.signal,plugins:i?{config:i,dataDir:t.dataDir,workspaceDir:g.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:i.llmAllowlist}:void 0,onProgress:r};return t.input.kind===`messages`?{...a,messages:t.input.messages}:{...a,message:t.input.message}}async function ht(e,t,n,r){if(t.activeSessionId=r.sessionId,t.finalResult=r,r.error){await q(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:r.error});return}await q(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`done`,result:{text:r.text,usage:r.usage,durationMs:r.durationMs,error:r.error,paused:r.paused}})}async function gt(e,t,n,r){await q(e,{sessionId:t.finalResult?.sessionId??t.activeSessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:`Fatal: ${r.message}`})}function _t(e,t){B.info(`run command started`,{channel:t.channel,dataDir:t.dataDir,sessionId:e.sessionId??`new`,messageId:e.messageId,output:t.format,hasCallback:!!e.callbackUrl,hasStream:!!e.streamUrl})}function vt(e,t,n){D(t,n),t.error?B.error(`run command failed: ${t.error}`):B.info(`run command succeeded`),e.end(),process.exit(t.error?1:0)}function yt(e,t){B.error(`run command error: ${t.message}`),T(`Fatal: ${t.message}`),e.end(),process.exit(1)}async function bt(e){if(e.resumeRequestId||e.resumeInputJson){if(!e.sessionId||!e.resumeRequestId||!e.resumeInputJson)throw Error(`--session-id, --resume-request-id and --resume-input-json must be provided together`);await Ye({dataDir:e.dataDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:e.resumeRequestId,inputJson:e.resumeInputJson,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,messageId:e.messageId,user:e.user});return}z(et(e));let t=new V(`run command`),{controller:n,cleanup:r}=ct(),i=null,a=e.channel??`WEB`,o=lt(e.sessionId);try{let r=await rt(e);a=r.channel,_t(e,r);let s=it(e);i=s.sink,B.info(`external sink configured`,{callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamEvents:e.streamEvents});let c=st(i,s.websocketSink,r.channel,e.messageId,e.user);await ft(r,c,o);let l=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,u=await A(r.dataDir,l),d=await ae(mt(e,r,n,pt(r,c,o),u));await ht(c,o,e.messageId,d),vt(t,d,r.format)}catch(n){let r=n;i&&await gt(st(i,null,a,e.messageId,e.user),o,e.messageId,r),yt(t,r)}finally{await i?.close(),r()}}function xt(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 St(e){e.command(`run`).description(`Run an agent task`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).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(`-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(`--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`).action(async e=>{await bt(e)})}function Ct(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`).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||(T(`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`&&(T(`Invalid channel: ${r.channel}. Must be 'H5', 'WEB', 'KLPA', 'TASK', 'CRON', or 'EIP_ASSISTANT'`),process.exit(1));try{let e=r.sessionStore?m(r.sessionStore):void 0;if(i===`list`){ge(await ee(r.dataDir,r.channel,{storeName:e}),a);return}if(r.sessionId||(T(`error: required option '-s, --session-id <id>' not specified`),process.exit(1)),i===`inspect`){_e(await u(r.dataDir,r.sessionId,{storeName:e}),a);return}if(i===`export`){ve(await o(r.dataDir,r.sessionId,{storeName:e}),a);return}T(`Invalid sessions action: ${i}. Must be 'list', 'inspect', or 'export'`),process.exit(1)}catch(e){T(`${i===`inspect`?`Error inspecting session`:i===`export`?`Error exporting session`:`Error listing sessions`}: ${e.message}`),process.exit(1)}})}function wt(e,t){let n=[];return n.push(`backend: ${e.backend}`),n.push(`provider: ${e.provider}${e.model?` (${e.model})`:``}`),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}`)),n.join(`
|
|
5
|
+
`)}function Y(e){let t=g.join(e.dataDir,`.aimax`),n=ne({providerId:e.provider,pluginId:e.providerPlugin,dataDir:e.dataDir,memoryDir:t});return n?n.provider:i({dataDir:e.dataDir,memoryDir:t},{includeSessions:e.includeSessions})}function Tt(e){let t=e.command(`memory`).description(`Manage semantic memory indexing and search`);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`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{let n=Y({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,includeSessions:e.includeSessions});e.index&&n.sync&&await n.sync(`cli-status`);let r=n.status();e.deep&&((r.custom??={}).note=`deep probe is only supported by builtin provider`),w(t===`json`?JSON.stringify(r,null,2):wt(r,e.deep))}catch(e){T(`Error getting memory status: ${e.message}`),process.exit(1)}}),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(`--verbose`,`Verbose output`).action(async e=>{try{let t=Y({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,includeSessions:e.includeSessions});t.sync&&await t.sync(`cli-index`),w(`Memory index refreshed.`)}catch(e){T(`Error indexing memory: ${e.message}`),process.exit(1)}}),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`).action(async(e,t)=>{let n=t.output===`json`?`json`:`text`,r=t.query?.trim()||e?.trim();r||(T(`Query is required: provide [query] or --query <text>`),process.exit(1));try{let e=await Y({dataDir:t.dataDir,provider:t.provider,providerPlugin:t.providerPlugin,includeSessions:t.includeSessions}).search(r);if(n===`json`){w(JSON.stringify(e,null,2));return}if(e.length===0){w(`No results found for: ${r}`);return}w(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(`
|
|
6
|
+
`))}catch(e){T(`Error searching memory: ${e.message}`),process.exit(1)}})}function Et(e){return`${e.match.accountId?`${e.match.channel}:${e.match.accountId}`:e.match.channel} -> ${e.agentId}`}function Dt(e){return async t=>{let n=await x(t),r=ue(n),i=b(n);if(C(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=pe(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(` - ${Et(e)}`)}}}}function Ot(e,t){return async n=>{y(await x(n),S(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=pe(n,e);console.log(`Agent "${e}" added successfully.`),console.log(` Agent dir: ${r}`)}}function kt(e){return async t=>{let n=y(await x(t),S(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 de(t,e)||(console.error(`Failed to delete agent "${e}".`),process.exit(1)),console.log(`Agent "${e}" deleted.`)}}function At(e){return async t=>{let n=await x(t),r=e.agent??C(n);y(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 le(t,{agentId:r,match:{channel:e,accountId:a||void 0}}),console.log(`Binding added: ${n} -> ${r}`)}}}function jt(e){return async t=>{let n=await x(t),r=e.agent??C(n);if(y(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),e.all){let e=await fe(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 fe(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 Mt(e){return async t=>{let n=b(await x(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(` ${Et(e)}`)}}function Nt(e){return async t=>{let n=await x(t),r=e.agent??C(n);y(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),await me(t,r,{name:e.name,emoji:e.emoji,avatar:e.avatar})||(console.error(`Failed to update identity for agent "${r}".`),process.exit(1)),console.log(`Identity updated for agent "${r}".`)}}function Pt(e,t){let n=e.command(`agents`).description(`Manage agents`);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 Dt(e)(n)}),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 Ot(e,n)(r)}),n.command(`delete <id>`).description(`Delete an agent`).action(async e=>{let n=t();await kt(e)(n)}),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 At(e)(n)}),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 jt(e)(n)}),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 Mt(e)(n)}),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 Nt(e)(n)})}function X(e){return g.join(e,`workspace`)}function Z(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function Ft(e){if(e.length===0){w(`No plugins discovered.`);return}for(let t of e){let e=t.status.padEnd(8,` `);w(`${t.id} ${e} ${t.origin} ${t.source}`)}}function It(e){w(`id: ${e.id}`),w(`status: ${e.status}`),w(`origin: ${e.origin}`),w(`source: ${e.source}`),w(`enabled: ${e.enabled}`),e.error&&w(`error: ${e.error}`),w(`tools: ${e.toolCount}`),w(`hooks: ${e.hookCount}`),e.skills.length>0&&w(`skills: ${e.skills.join(`, `)}`)}function Q(e){return Array.from(new Set((e??[]).map(e=>e.trim()).filter(Boolean)))}function Lt(e){if(e.length===0){w(`LLM allowlist is empty.`);return}for(let t of e)w(t)}function Rt(e,t){let n=e.command(`plugins`).description(`Manage AIMax plugins`),r=e=>e.option(`--plugins-config <path>`,`Plugins config file path`);r(n.command(`list`)).description(`List discovered plugins`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();Ft(l({config:await A(n,e.pluginsConfig),dataDir:n,workspaceDir:X(n),bundledDir:Z()}).registry.plugins)}),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(),i=l({config:await A(r,n.pluginsConfig),dataDir:r,workspaceDir:X(r),bundledDir:Z()}).registry.plugins.find(t=>t.id===e);i||(T(`Plugin not found: ${e}`),process.exit(1)),It(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(),i=await A(r,n.pluginsConfig)??{},a=p(i);l({config:i,dataDir:r,workspaceDir:X(r),bundledDir:Z()}).registry.plugins.some(t=>t.id===e)||(T(`Plugin not found: ${e}`),process.exit(1)),await j(r,{...i,entries:{...i.entries,[e]:{...i.entries?.[e]??{},enabled:!0}}},n.pluginsConfig),w(`Enabled ${e}`),a.allow.length>0&&!a.allow.includes(e)&&w(`Note: plugins.allow is set; add this plugin id to allowlist if needed.`)}),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(),i=await A(r,n.pluginsConfig)??{};l({config:i,dataDir:r,workspaceDir:X(r),bundledDir:Z()}).registry.plugins.some(t=>t.id===e)||(T(`Plugin not found: ${e}`),process.exit(1)),await j(r,{...i,entries:{...i.entries,[e]:{...i.entries?.[e]??{},enabled:!1}}},n.pluginsConfig),w(`Disabled ${e}`)}),r(n.command(`doctor`)).description(`Validate plugin configuration`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t(),r=l({config:await A(n,e.pluginsConfig),dataDir:n,workspaceDir:X(n),bundledDir:Z()});if(r.diagnostics.length===0){w(`No plugin issues detected.`);return}for(let e of r.diagnostics)w(`${e.level===`error`?`ERROR`:`WARN`}${e.pluginId?` ${e.pluginId}`:``}: ${e.message}`);r.diagnostics.some(e=>e.level===`error`)&&process.exit(1)});let i=n.command(`llm-allow`).description(`Manage plugin LLM allowlist`);r(i.command(`list`)).description(`List LLM allowlist entries`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{Lt(Q((await A(e.dataDir??t(),e.pluginsConfig))?.llmAllowlist))}),r(i.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(),i=await A(r,n.pluginsConfig)??{},a=Q([...i.llmAllowlist??[],...e]);await j(r,{...i,llmAllowlist:a},n.pluginsConfig),w(`LLM allowlist updated (${a.length} entries).`)}),r(i.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(),i=await A(r,n.pluginsConfig)??{},a=new Set(e.map(e=>e.trim()).filter(Boolean)),o=Q(i.llmAllowlist).filter(e=>!a.has(e));await j(r,{...i,llmAllowlist:o},n.pluginsConfig),w(`LLM allowlist updated (${o.length} entries).`)}),r(i.command(`clear`)).description(`Clear the LLM allowlist`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await j(n,{...await A(n,e.pluginsConfig)??{},llmAllowlist:[]},e.pluginsConfig),w(`LLM allowlist cleared.`)})}function zt(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`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{let n=d(await f(e.dataDir,[]));if(t===`json`){w(JSON.stringify(n,null,2));return}w(`Commands`),w(` builtin: ${n.builtin.map(e=>e.name).join(` | `)}`),n.skillCommands.length>0?w(` skills: ${n.skillCommands.map(e=>e.name).join(` | `)}`):w(` skills: (none)`)}catch(e){T(`Error listing commands: ${e.message}`),process.exit(1)}})}const Bt=[`progress`,`error`,`hitl`];function Vt(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 Ht(e){if(!e?.trim())return new Set(Bt);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(Bt)}function Ut(e){return e?m(e):void 0}function Wt(e){let t=[];return e.callbackUrl&&t.push(new U(e.callbackUrl)),e.streamUrl&&t.push(new K(e.streamUrl,Ht(e.streamEvents),e.streamAuthToken)),new H(t)}async function Gt(e){z(Vt(e));let t=new V(`cancel command`),n=Vt(e),r=e.channel??`WEB`,i=e.output===`json`?`json`:`text`,a=Wt(e),o=Ut(e.sessionStore);try{let s=await te(n,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 re({dataDir:n,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`&&E(l),await a.send({type:`progress`,sessionId:e.sessionId,channel:r,messageId:e.messageId,event:l}),t.end(),process.exit(0)}catch(n){let i=n;await a.send({type:`error`,sessionId:e.sessionId,channel:r,messageId:e.messageId,message:i.message}),B.error(`cancel command error: ${i.message}`),T(`Fatal: ${i.message}`),t.end(),process.exit(1)}finally{await a.close()}}function Kt(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`).action(async e=>{await Gt(e)})}const qt=e(import.meta.url)(`../package.json`);function $(){return process.env.AIMAX_DATA_DIR||process.cwd()}function Jt(){let e=new t;return e.name(`aimax`).description(`AIMax CLI — runs agent tasks in a containerized environment`).version(qt.version),St(e),Ze(e),Kt(e),Ct(e),zt(e),be(e),Tt(e),Pt(e,$),Rt(e,$),e}export{Ie as a,B as i,$ as n,z as r,Jt 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-B2JBui5b.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.0.
|
|
3
|
+
"version": "0.0.34",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"aimax": "./dist/bin.js"
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"commander": "^14.0.3",
|
|
22
22
|
"gensign-node": "latest",
|
|
23
23
|
"log4js": "^6.9.1",
|
|
24
|
-
"@gencode/
|
|
25
|
-
"@gencode/
|
|
24
|
+
"@gencode/shared": "0.0.11",
|
|
25
|
+
"@gencode/agents": "0.0.35"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^22.0.0",
|
package/dist/program-jAtKec-j.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import{createRequire as e}from"node:module";import{Command as t}from"commander";import{bootstrapMountLayout as n,createBuiltinMemoryProvider as r,ensureBootstrapMountLayout as i,exportSession as a,hasBootstrapSentinel as o,initializePluginSystem as s,inspectSession as c,listAvailableSlashCommands as l,listSessionSummaries as u,loadPendingHitl as d,loadSkillsWithPluginDirs as f,normalizePluginsConfig as p,normalizeSessionStoreName as m,resolveMemoryProvider as h,resolvePendingHitl as ee,runAgent as g}from"@gencode/agents";import{isAgentDiagnosticEvent as te}from"@gencode/shared";import _ from"node:path";import ne from"gensign-node";import v from"node:fs/promises";import re from"node:fs";import y from"log4js";import{addAgent as ie,addBinding as ae,getAgentConfig as b,listAgents as oe,listBindings as x,loadAgentsConfig as S,normalizeAgentId as se,removeAgent as ce,removeBindings as le,resolveAgentDir as ue,resolveDefaultAgentId as C,updateAgentIdentity as de}from"@gencode/agents/config";function w(e){process.stdout.write(e)}function T(e){process.stdout.write(e+`
|
|
2
|
-
`)}function E(e){process.stderr.write(e+`
|
|
3
|
-
`)}function D(e){switch(e.type){case`start`:T(`\n[start] ${e.message}`);break;case`text`:w(e.text);break;case`stream_text_delta`:w(e.text);break;case`bootstrap`:T(`\n[bootstrap:${e.phase}] ${e.dataDir}`);break;case`session_reset`:T(`\n[session:${e.action}] ${e.message}`);break;case`tool_start`:T(`\n[tool:${e.name}] ${JSON.stringify(e.input)}`);break;case`tool_end`:T(`[tool:${e.name}] ${e.isError?`ERROR`:`OK`} ${e.output.slice(0,200)}`);break;case`compaction`:T(`\n[compaction${e.layer?`:${e.layer}`:``}] ${e.reason}${e.strategy?` (${e.strategy})`:``}`);break;case`skill_used`:T(`\n[skill] ${e.skillName} agent=${e.agent} task=${e.taskId}`);break;case`custom`:T(`\n[plugin:${e.pluginId}] ${e.name}${e.label?` ${e.label}`:``}${e.data?` ${JSON.stringify(e.data)}`:``}`);break;case`error`:E(`\n[error] ${e.message}`);break;case`diagnostic`:break;case`subagent_spawn`:T(`\n[subagent:spawn]${e.label?` "${e.label}"`:``} ${e.task}`);break;case`subagent_complete`:T(`[subagent:${e.status}] ${e.task}`);break;case`hitl_requested`:if(T(`\n[hitl:${e.request.kind}] ${e.request.title}`),T(` prompt: ${e.request.prompt}`),T(` requestId: ${e.request.requestId}`),e.request.input.mode===`choice`)for(let t of e.request.input.choices)T(` - [${t.id}] ${t.label}`);break;case`hitl_resumed`:T(`\n[hitl:resumed] requestId=${e.requestId} action=${e.resolution.action}`);break;case`hitl_expired`:T(`\n[hitl:expired] requestId=${e.requestId} reason=${e.reason}`);break;case`hitl_cancelled`:T(`\n[hitl:cancelled] requestId=${e.requestId}${e.reason?` reason=${e.reason}`:``}`);break}}function O(e,t){if(t===`json`){T(JSON.stringify(e,null,2));return}T(`
|
|
4
|
-
`),T(`session: ${e.sessionId}`),T(`duration: ${e.durationMs}ms`),T(`tokens: input=${e.usage.input} output=${e.usage.output} total=${e.usage.total}`),e.context&&(T(`context: ${e.context.snapshotPath}`),T(`tool-results: ${e.context.toolResultsDir}`)),e.error&&E(`error: ${e.error}`)}function fe(e,t){if(t===`json`){T(JSON.stringify(e,null,2));return}if(e.length===0){T(`No sessions found.`);return}for(let t of e){let e=t.createdAt?new Date(t.createdAt).toLocaleString():`unknown`;T(`${t.id} ${e} [${t.channel}] ${t.title}`)}}function pe(e,t){if(t===`json`){T(JSON.stringify(e,null,2));return}T(`session: ${e.id}`),e.metadata&&(T(`title: ${e.metadata.title}`),T(`channel: ${e.metadata.channel}`),T(`created: ${e.metadata.createdAt}`),T(`updated: ${e.metadata.updatedAt}`)),T(`transcript: ${e.transcriptPath}`),T(`entries: ${e.transcriptEntryCount}`),T(`context: ${e.contextSnapshotPath}`),T(`session-memory: ${e.sessionMemoryPath}`),T(`collapse-log: ${e.collapseLogPath}`),T(`read-states: ${e.readStateCount}`),T(`tool-results: ${e.toolResultRefCount}`),T(`tool-results-dir: ${e.toolResultsDir}`)}function me(e,t){if(t===`json`){T(JSON.stringify(e,null,2));return}T(`session: ${e.id}`),T(`transcript: ${e.paths.transcriptPath}`),T(`context: ${e.paths.contextSnapshotPath}`),T(`session-memory: ${e.paths.sessionMemoryPath}`),T(`collapse-log: ${e.paths.collapseLogPath}`),T(`tool-results-dir: ${e.paths.toolResultsDir}`),T(`transcript-entries: ${e.transcript.length}`),T(`read-states: ${e.context.readStates.length}`),T(`tool-results: ${e.context.toolResults.length}`),T(`collapse-spans: ${e.context.compaction.collapseSpans.length}`)}function he(e,t){if(t===`json`){T(JSON.stringify(e,null,2));return}T(`Bootstrap completed.`),T(`dataDir: ${e.dataDir}`),T(`created dirs: ${e.createdDirs.length}`),T(`created files: ${e.createdFiles.length}`),T(`skipped dirs: ${e.skippedDirs.length}`),T(`skipped files: ${e.skippedFiles.length}`)}function ge(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`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{he(await n(e.dataDir),t)}catch(e){E(`Error bootstrapping data directory: ${e.message}`),process.exit(1)}})}function _e(e){return ne.sm4_encrypt_ecb(e)}function k(e){return _e(e)}function ve(e={}){let t=e.baseUrl??process.env.AIMAX_BASE_URL,n=process.env.AIMAX_AUTH_TOKEN,r=e.authToken?k(e.authToken):n?k(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 ye(e,t){return t?_.resolve(t):_.join(e,`.aimax`,`plugins.json`)}async function A(e,t){let n=ye(e,t);try{let e=await v.readFile(n,`utf-8`);return JSON.parse(e)}catch(e){if(e.code===`ENOENT`)return;throw e}}async function j(e,t,n){let r=ye(e,n);await v.mkdir(_.dirname(r),{recursive:!0}),await v.writeFile(r,JSON.stringify(t,null,2),`utf-8`)}function M(e){return typeof e==`object`&&!!e}function N(e){return M(e)&&e.type===`text`&&typeof e.text==`string`&&(e.textSignature===void 0||typeof e.textSignature==`string`)}function P(e){return M(e)&&e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`}function be(e){return M(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 xe(e){return M(e)&&e.type===`toolCall`&&typeof e.id==`string`&&typeof e.name==`string`&&M(e.arguments)&&(e.thoughtSignature===void 0||typeof e.thoughtSignature==`string`)}function Se(e){return typeof e==`string`||Array.isArray(e)&&e.every(e=>N(e)||P(e))}function Ce(e){return Array.isArray(e)&&e.every(e=>N(e)||be(e)||xe(e))}function we(e){return M(e)&&typeof e.input==`number`&&typeof e.output==`number`&&typeof e.cacheRead==`number`&&typeof e.cacheWrite==`number`&&typeof e.totalTokens==`number`&&M(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 Te(e){return!M(e)||typeof e.role!=`string`?!1:e.role===`user`?Se(e.content):e.role===`assistant`?Ce(e.content)&&typeof e.api==`string`&&typeof e.provider==`string`&&typeof e.model==`string`&&we(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=>N(e)||P(e))&&typeof e.isError==`boolean`:!1}async function Ee(e){let t;try{t=await v.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=>Te(e)))throw Error(`Message file must contain one Message object or an array of Message objects`);return r}async function De(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 Ee(e.fromFile)}:{kind:`text`,message:e.message}}let F=function(e){return e.INFO=`INFO`,e.ERROR=`ERROR`,e.WARN=`WARN`,e}({}),I=null;function Oe(){let e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)} ${String(e.getHours()).padStart(2,`0`)}:${String(e.getMinutes()).padStart(2,`0`)}:${String(e.getSeconds()).padStart(2,`0`)}.${String(e.getMilliseconds()).padStart(3,`0`)}`}function ke(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 Ae(e){return _.join(e,`.aimax`)}function je(e){return{appLogPath:_.join(e,`app.log`),errorLogPath:_.join(e,`errors.log`)}}function Me(e){let{appLogPath:t,errorLogPath:n}=je(e);y.configure({appenders:{appFile:{type:`file`,filename:t,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`pattern`,pattern:`[%d{yyyy-MM-dd hh:mm:ss.SSS}] [%p] %m`}},errorFile:{type:`file`,filename:n,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`pattern`,pattern:`[%d{yyyy-MM-dd hh:mm:ss.SSS}] [%p] %m`}},errorsOnly:{type:`logLevelFilter`,appender:`errorFile`,level:`error`,maxLevel:`fatal`}},categories:{default:{appenders:[`appFile`,`errorsOnly`],level:`info`}}})}function Ne(e,t,n){process.stderr.write(`[${Oe()}] [${e}] ${t}${ke(n)}\n`)}function L(e,t,n){let r=`${t}${ke(n)}`;if(!I){Ne(e,r);return}let i=y.getLogger();if(e===F.ERROR){i.error(r);return}if(e===F.WARN){i.warn(r);return}i.info(r)}function R(e){let t=Ae(e);I?.dataDir!==e&&(re.mkdirSync(t,{recursive:!0}),Me(t),I={dataDir:e,logDir:t})}async function Pe(){await y.shutdown()}const z={info:(e,t)=>L(F.INFO,e,t),warn:(e,t)=>L(F.WARN,e,t),error:(e,t)=>L(F.ERROR,e,t)};var B=class{startTime;name;constructor(e){this.name=e,this.startTime=Date.now()}end(){let e=Date.now()-this.startTime;return z.info(`${this.name} completed in ${e}ms`),e}},V=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()}))}},H=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=Fe(e);z.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 z.error(`callback event failed`,{callbackUrl:this.url,httpStatus:r.status,durationMs:i,...n}),Error(`Callback failed with status ${r.status}`);z.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 Fe(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 Ie(e,t){if(t.kind===`none`)return e;let n=new URL(e);return n.searchParams.set(`authToken`,t.token),n.toString()}function U(){let e=globalThis.WebSocket;if(!e)throw Error(`WebSocket is not available in this runtime`);return e}function Le(e){return e?{kind:`query_token`,token:e}:{kind:`none`}}function W(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 Re(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 G=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=U();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){z.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=U();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){z.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=U();e.readyState!==t.CLOSED&&await new Promise(t=>{W(e,`close`,()=>t()),e.close()})}async ensureConnected(){if(!this.enabled)return;let e=U();if(this.socket&&this.socket.readyState===e.OPEN)return;if(this.connectPromise){await this.connectPromise;return}let t=new e(Ie(this.url,Le(this.authToken)));this.connectPromise=new Promise((e,n)=>{W(t,`open`,()=>{this.socket=t,Re(t,`close`,()=>{this.socket===t&&(this.socket=null)}),e()}),W(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)}`)}}}};const ze=[`start`,`text`,`done`,`error`,`hitl`];function Be(e){if(!e?.trim())return new Set(ze);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(ze)}function Ve(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 He(e){return e?m(e):void 0}function Ue(e){if(!e.inputJson)throw Error(`--input-json is required for 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}`)}}async function We(e){let t=Ve(e),n=e.channel??`WEB`,r=ve({baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel}),i=Ue(e);return{dataDir:t,channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,resolution:i}}function Ge(e){let t=[],n=null;return e.callbackUrl&&t.push(new H(e.callbackUrl)),e.streamUrl&&(n=new G(e.streamUrl,Be(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new V(t),websocketSink:n}}async function Ke(e){R(Ve(e));let t=new B(`resume command`),n=null;try{let r=await We(e),i=He(e.sessionStore);z.info(`resume command started`,{sessionId:e.sessionId,requestId:e.requestId,channel:r.channel,dataDir:r.dataDir});let a=await d(r.dataDir,e.sessionId,{storeName:i});if(!a)throw Error(`No pending HITL request found for session "${e.sessionId}"`);if(a.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${a.request.requestId}", got "${e.requestId}"`);if(a.status===`expired`)throw Error(`HITL request has expired`);if(a.status===`cancelled`)throw Error(`HITL request has been cancelled`);let o=await ee({dataDir:r.dataDir,sessionStoreName:i,sessionId:e.sessionId,requestId:e.requestId,resolution:r.resolution}),s=o.state;if(!s)throw Error(`Resolved HITL state was not persisted`);let c=qe(r.resolution,s.request.kind),l=Ge(e);n=l.sink;let u=e.sessionId,f=async t=>{if(u=t.sessionId??u,!te(t)){if(t.type===`stream_text_delta`){r.format===`text`&&D(t),await l.websocketSink?.sendTextDelta({sessionId:u,channel:r.channel,messageId:e.messageId,user:e.user,text:t.text});return}if(r.format===`text`&&D(t),t.type===`hitl_resumed`){await n?.send({sessionId:u,channel:r.channel,messageId:e.messageId,user:e.user,type:`progress`,event:t});return}if(t.type===`start`){await n?.send({sessionId:u,channel:r.channel,messageId:e.messageId,user:e.user,type:`start`,message:t.message});return}await n?.send({sessionId:u,channel:r.channel,messageId:e.messageId,user:e.user,type:`progress`,event:t})}};await f({type:`hitl_resumed`,requestId:e.requestId,resolution:r.resolution,sessionId:e.sessionId}),`idempotentReplay`in o&&o.idempotentReplay&&(z.info(`resume command treated as idempotent replay`,{sessionId:e.sessionId,requestId:e.requestId,idempotencyKey:r.resolution.idempotencyKey}),O({sessionId:e.sessionId,text:`Resume request already processed.`,usage:{input:0,output:0,total:0},durationMs:0},r.format),t.end(),process.exit(0));let p=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,m=await A(r.dataDir,p),h;try{h=await g({dataDir:r.dataDir,sessionStoreName:i,sessionId:e.sessionId,messageId:e.messageId,channel:r.channel,llm:r.llm,timeoutMs:r.timeoutMs,message:c,hitlResume:{request:s.request,resolution:r.resolution,checkpoint:s.checkpoint,toolContext:s.toolContext},plugins:m?{config:m,dataDir:r.dataDir,workspaceDir:_.join(r.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:m.llmAllowlist}:void 0,onProgress:f})}finally{}h.error?await n?.send({sessionId:h.sessionId,channel:r.channel,messageId:e.messageId,user:e.user,type:`error`,message:h.error}):await n?.send({sessionId:h.sessionId,channel:r.channel,messageId:e.messageId,user:e.user,type:`done`,result:{text:h.text,usage:h.usage,durationMs:h.durationMs,error:h.error,paused:h.paused}}),O(h,r.format),h.error?z.error(`resume command failed: ${h.error}`):z.info(`resume command succeeded`),t.end(),process.exit(h.error?1:0)}catch(r){let i=r;n&&(i.message.includes(`expired`)&&await n.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:i.message}}),i.message.includes(`cancelled`)&&await n.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:i.message}}),await n.send({sessionId:e.sessionId,channel:e.channel??`WEB`,messageId:e.messageId,user:e.user,type:`error`,message:`Resume failed: ${i.message}`})),z.error(`resume command error: ${i.message}`),E(`Fatal: ${i.message}`),t.end(),process.exit(1)}finally{await n?.close()}}function qe(e,t){let n=[];return n.push(`[HITL Resume] The user has responded to the ${t} request (${e.requestId}).`),e.action===`cancel`?(n.push(`Action: The user cancelled the request. Please acknowledge and proceed without this action.`),n.join(`
|
|
5
|
-
`)):e.action===`timeout`?(n.push(`Action: The request timed out without a response. Apply the default timeout policy.`),n.join(`
|
|
6
|
-
`)):(n.push(`Action: The user submitted a response.`),e.values?.selectedChoiceIds&&e.values.selectedChoiceIds.length>0&&n.push(`Selected choices: ${e.values.selectedChoiceIds.join(`, `)}`),e.values?.text&&n.push(`User text: ${e.values.text}`),e.values?.form&&n.push(`Form data: ${JSON.stringify(e.values.form)}`),n.join(`
|
|
7
|
-
`))}function Je(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)`).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`).requiredOption(`--input-json <json>`,`JSON string with the resolution (action, values, etc.)`).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`).action(async e=>{await Ke(e)})}const Ye=[`start`,`text`,`done`,`error`];function Xe(e){if(!e?.trim())return new Set(Ye);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(Ye)}function Ze(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 Qe(e){return e??`WEB`}function $e(e){return e?m(e):void 0}async function et(e){let t=Ze(e),n=Qe(e.channel),r=ve({baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel}),i=await De({message:e.message,fromFile:e.fromFile});return{dataDir:t,channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,input:i}}function tt(e){let t=[],n=null;return e.callbackUrl&&t.push(new H(e.callbackUrl)),e.streamUrl&&(n=new G(e.streamUrl,Xe(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new V(t),websocketSink:n}}async function K(e,t){z.info(`dispatching external event`,_t(t)),await e.sink.send(t)}function nt(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 rt(e){let t={sessionId:e.sessionId,messageId:e.messageId,parentSessionId:e.parentSessionId,depth:e.depth,scope:e.scope,phase:e.phase,...nt(e.details)};if(e.level===`error`){z.error(e.message,t);return}if(e.level===`warn`){z.warn(e.message,t);return}z.info(e.message,t)}function q(e,t,n,r,i){return{sink:e,websocketSink:t,channel:n,defaultMessageId:r,user:i}}function it(){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 at(e){return{activeSessionId:e??`pending`,finalResult:null}}function ot(e,t){e.activeSessionId=t.sessionId??e.activeSessionId}function st(e,t){return e.messageId??t}async function ct(e,t,n){if(!await o(e.dataDir)){if(await J(t,e.format,n.activeSessionId,e.dataDir,`checking`),(await i(e.dataDir)).performedBootstrap){await J(t,e.format,n.activeSessionId,e.dataDir,`initializing`),await J(t,e.format,n.activeSessionId,e.dataDir,`initialized`);return}await J(t,e.format,n.activeSessionId,e.dataDir,`ready`)}}async function J(e,t,n,r,i){let a={type:`bootstrap`,phase:i,dataDir:r};t===`text`&&D(a),await K(e,{sessionId:n,channel:e.channel,messageId:e.defaultMessageId,user:e.user,type:`progress`,event:a})}function lt(e,t,n){return async r=>{if(ot(n,r),te(r)){rt(r);return}if(r.type===`stream_text_delta`){e.format===`text`&&D(r),await t.websocketSink?.sendTextDelta({sessionId:n.activeSessionId,channel:e.channel,messageId:st(r,t.defaultMessageId),user:t.user,text:r.text});return}e.format===`text`&&D(r);let i=st(r,t.defaultMessageId);if(r.type===`hitl_requested`){await K(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`hitl`,request:r.request}),await K(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r});return}if(r.type===`start`){await K(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`start`,message:r.message});return}if(r.type===`session_reset`){await K(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 K(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r})}}function ut(e,t,n,r,i){let a={dataDir:t.dataDir,sessionStoreName:$e(e.sessionStore),sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,timeoutMs:t.timeoutMs,abortSignal:n.signal,plugins:i?{config:i,dataDir:t.dataDir,workspaceDir:_.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:i.llmAllowlist}:void 0,onProgress:r};return t.input.kind===`messages`?{...a,messages:t.input.messages}:{...a,message:t.input.message}}async function dt(e,t,n,r){if(t.activeSessionId=r.sessionId,t.finalResult=r,r.error){await K(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:r.error});return}await K(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 ft(e,t,n,r){await K(e,{sessionId:t.finalResult?.sessionId??t.activeSessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:`Fatal: ${r.message}`})}function pt(e,t){z.info(`run command started`,{channel:t.channel,dataDir:t.dataDir,sessionId:e.sessionId??`new`,messageId:e.messageId,output:t.format,hasCallback:!!e.callbackUrl,hasStream:!!e.streamUrl})}function mt(e,t,n){O(t,n),t.error?z.error(`run command failed: ${t.error}`):z.info(`run command succeeded`),e.end(),process.exit(t.error?1:0)}function ht(e,t){z.error(`run command error: ${t.message}`),E(`Fatal: ${t.message}`),e.end(),process.exit(1)}async function gt(e){if(e.resumeRequestId||e.resumeInputJson){if(!e.sessionId||!e.resumeRequestId||!e.resumeInputJson)throw Error(`--session-id, --resume-request-id and --resume-input-json must be provided together`);await Ke({dataDir:e.dataDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:e.resumeRequestId,inputJson:e.resumeInputJson,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,messageId:e.messageId,user:e.user});return}R(Ze(e));let t=new B(`run command`),{controller:n,cleanup:r}=it(),i=null,a=e.channel??`WEB`,o=at(e.sessionId);try{let r=await et(e);a=r.channel,pt(e,r);let s=tt(e);i=s.sink,z.info(`external sink configured`,{callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamEvents:e.streamEvents});let c=q(i,s.websocketSink,r.channel,e.messageId,e.user);await ct(r,c,o);let l=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,u=await A(r.dataDir,l),d=await g(ut(e,r,n,lt(r,c,o),u));await dt(c,o,e.messageId,d),mt(t,d,r.format)}catch(n){let r=n;i&&await ft(q(i,null,a,e.messageId,e.user),o,e.messageId,r),ht(t,r)}finally{await i?.close(),r()}}function _t(e){return{eventType:e.type,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,progressType:e.type===`progress`?e.event.type:void 0,textLength:e.type===`done`?e.result.text.length:void 0,hasError:e.type===`error`?!0:e.type===`done`?!!e.result.error:void 0}}function vt(e){e.command(`run`).description(`Run an agent task`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).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(`-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(`--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`).action(async e=>{await gt(e)})}function yt(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`).action(async(e,t,n)=>{let r=n.opts(),i=e??`list`,o=i===`export`?r.output===`text`?`text`:`json`:r.output===`json`?`json`:`text`;r.dataDir||(E(`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`&&(E(`Invalid channel: ${r.channel}. Must be 'H5', 'WEB', 'KLPA', 'TASK', 'CRON', or 'EIP_ASSISTANT'`),process.exit(1));try{let e=r.sessionStore?m(r.sessionStore):void 0;if(i===`list`){fe(await u(r.dataDir,r.channel,{storeName:e}),o);return}if(r.sessionId||(E(`error: required option '-s, --session-id <id>' not specified`),process.exit(1)),i===`inspect`){pe(await c(r.dataDir,r.sessionId,{storeName:e}),o);return}if(i===`export`){me(await a(r.dataDir,r.sessionId,{storeName:e}),o);return}E(`Invalid sessions action: ${i}. Must be 'list', 'inspect', or 'export'`),process.exit(1)}catch(e){E(`${i===`inspect`?`Error inspecting session`:i===`export`?`Error exporting session`:`Error listing sessions`}: ${e.message}`),process.exit(1)}})}function bt(e,t){let n=[];return n.push(`backend: ${e.backend}`),n.push(`provider: ${e.provider}${e.model?` (${e.model})`:``}`),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}`)),n.join(`
|
|
8
|
-
`)}function Y(e){let t=_.join(e.dataDir,`.aimax`),n=h({providerId:e.provider,pluginId:e.providerPlugin,dataDir:e.dataDir,memoryDir:t});return n?n.provider:r({dataDir:e.dataDir,memoryDir:t},{includeSessions:e.includeSessions})}function xt(e){let t=e.command(`memory`).description(`Manage semantic memory indexing and search`);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`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{let n=Y({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,includeSessions:e.includeSessions});e.index&&n.sync&&await n.sync(`cli-status`);let r=n.status();e.deep&&((r.custom??={}).note=`deep probe is only supported by builtin provider`),T(t===`json`?JSON.stringify(r,null,2):bt(r,e.deep))}catch(e){E(`Error getting memory status: ${e.message}`),process.exit(1)}}),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(`--verbose`,`Verbose output`).action(async e=>{try{let t=Y({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,includeSessions:e.includeSessions});t.sync&&await t.sync(`cli-index`),T(`Memory index refreshed.`)}catch(e){E(`Error indexing memory: ${e.message}`),process.exit(1)}}),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`).action(async(e,t)=>{let n=t.output===`json`?`json`:`text`,r=t.query?.trim()||e?.trim();r||(E(`Query is required: provide [query] or --query <text>`),process.exit(1));try{let e=await Y({dataDir:t.dataDir,provider:t.provider,providerPlugin:t.providerPlugin,includeSessions:t.includeSessions}).search(r);if(n===`json`){T(JSON.stringify(e,null,2));return}if(e.length===0){T(`No results found for: ${r}`);return}T(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(`
|
|
9
|
-
`))}catch(e){E(`Error searching memory: ${e.message}`),process.exit(1)}})}function St(e){return`${e.match.accountId?`${e.match.channel}:${e.match.accountId}`:e.match.channel} -> ${e.agentId}`}function Ct(e){return async t=>{let n=await S(t),r=oe(n),i=x(n);if(C(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=ue(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(` - ${St(e)}`)}}}}function wt(e,t){return async n=>{b(await S(n),se(e))&&(console.error(`Agent "${e}" already exists.`),process.exit(1)),await ie(n,{id:e,name:t.name,model:t.model,default:t.default})||(console.error(`Agent "${e}" already exists.`),process.exit(1));let r=ue(n,e);console.log(`Agent "${e}" added successfully.`),console.log(` Agent dir: ${r}`)}}function Tt(e){return async t=>{let n=b(await S(t),se(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 ce(t,e)||(console.error(`Failed to delete agent "${e}".`),process.exit(1)),console.log(`Agent "${e}" deleted.`)}}function Et(e){return async t=>{let n=await S(t),r=e.agent??C(n);b(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 ae(t,{agentId:r,match:{channel:e,accountId:a||void 0}}),console.log(`Binding added: ${n} -> ${r}`)}}}function Dt(e){return async t=>{let n=await S(t),r=e.agent??C(n);if(b(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),e.all){let e=await le(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 le(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 Ot(e){return async t=>{let n=x(await S(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(` ${St(e)}`)}}function kt(e){return async t=>{let n=await S(t),r=e.agent??C(n);b(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),await de(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 At(e,t){let n=e.command(`agents`).description(`Manage agents`);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 Ct(e)(n)}),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 wt(e,n)(r)}),n.command(`delete <id>`).description(`Delete an agent`).action(async e=>{let n=t();await Tt(e)(n)}),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 Et(e)(n)}),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 Dt(e)(n)}),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 Ot(e)(n)}),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 kt(e)(n)})}function X(e){return _.join(e,`workspace`)}function Z(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function jt(e){if(e.length===0){T(`No plugins discovered.`);return}for(let t of e){let e=t.status.padEnd(8,` `);T(`${t.id} ${e} ${t.origin} ${t.source}`)}}function Mt(e){T(`id: ${e.id}`),T(`status: ${e.status}`),T(`origin: ${e.origin}`),T(`source: ${e.source}`),T(`enabled: ${e.enabled}`),e.error&&T(`error: ${e.error}`),T(`tools: ${e.toolCount}`),T(`hooks: ${e.hookCount}`),e.skills.length>0&&T(`skills: ${e.skills.join(`, `)}`)}function Q(e){return Array.from(new Set((e??[]).map(e=>e.trim()).filter(Boolean)))}function Nt(e){if(e.length===0){T(`LLM allowlist is empty.`);return}for(let t of e)T(t)}function Pt(e,t){let n=e.command(`plugins`).description(`Manage AIMax plugins`),r=e=>e.option(`--plugins-config <path>`,`Plugins config file path`);r(n.command(`list`)).description(`List discovered plugins`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();jt(s({config:await A(n,e.pluginsConfig),dataDir:n,workspaceDir:X(n),bundledDir:Z()}).registry.plugins)}),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(),i=s({config:await A(r,n.pluginsConfig),dataDir:r,workspaceDir:X(r),bundledDir:Z()}).registry.plugins.find(t=>t.id===e);i||(E(`Plugin not found: ${e}`),process.exit(1)),Mt(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(),i=await A(r,n.pluginsConfig)??{},a=p(i);s({config:i,dataDir:r,workspaceDir:X(r),bundledDir:Z()}).registry.plugins.some(t=>t.id===e)||(E(`Plugin not found: ${e}`),process.exit(1)),await j(r,{...i,entries:{...i.entries,[e]:{...i.entries?.[e]??{},enabled:!0}}},n.pluginsConfig),T(`Enabled ${e}`),a.allow.length>0&&!a.allow.includes(e)&&T(`Note: plugins.allow is set; add this plugin id to allowlist if needed.`)}),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(),i=await A(r,n.pluginsConfig)??{};s({config:i,dataDir:r,workspaceDir:X(r),bundledDir:Z()}).registry.plugins.some(t=>t.id===e)||(E(`Plugin not found: ${e}`),process.exit(1)),await j(r,{...i,entries:{...i.entries,[e]:{...i.entries?.[e]??{},enabled:!1}}},n.pluginsConfig),T(`Disabled ${e}`)}),r(n.command(`doctor`)).description(`Validate plugin configuration`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t(),r=s({config:await A(n,e.pluginsConfig),dataDir:n,workspaceDir:X(n),bundledDir:Z()});if(r.diagnostics.length===0){T(`No plugin issues detected.`);return}for(let e of r.diagnostics)T(`${e.level===`error`?`ERROR`:`WARN`}${e.pluginId?` ${e.pluginId}`:``}: ${e.message}`);r.diagnostics.some(e=>e.level===`error`)&&process.exit(1)});let i=n.command(`llm-allow`).description(`Manage plugin LLM allowlist`);r(i.command(`list`)).description(`List LLM allowlist entries`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{Nt(Q((await A(e.dataDir??t(),e.pluginsConfig))?.llmAllowlist))}),r(i.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(),i=await A(r,n.pluginsConfig)??{},a=Q([...i.llmAllowlist??[],...e]);await j(r,{...i,llmAllowlist:a},n.pluginsConfig),T(`LLM allowlist updated (${a.length} entries).`)}),r(i.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(),i=await A(r,n.pluginsConfig)??{},a=new Set(e.map(e=>e.trim()).filter(Boolean)),o=Q(i.llmAllowlist).filter(e=>!a.has(e));await j(r,{...i,llmAllowlist:o},n.pluginsConfig),T(`LLM allowlist updated (${o.length} entries).`)}),r(i.command(`clear`)).description(`Clear the LLM allowlist`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await j(n,{...await A(n,e.pluginsConfig)??{},llmAllowlist:[]},e.pluginsConfig),T(`LLM allowlist cleared.`)})}function Ft(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`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{let n=l(await f(e.dataDir,[]));if(t===`json`){T(JSON.stringify(n,null,2));return}T(`Commands`),T(` builtin: ${n.builtin.map(e=>e.name).join(` | `)}`),n.skillCommands.length>0?T(` skills: ${n.skillCommands.map(e=>e.name).join(` | `)}`):T(` skills: (none)`)}catch(e){E(`Error listing commands: ${e.message}`),process.exit(1)}})}const It=[`progress`,`error`,`hitl`];function Lt(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 Rt(e){if(!e?.trim())return new Set(It);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(It)}function zt(e){return e?m(e):void 0}function Bt(e){let t=[];return e.callbackUrl&&t.push(new H(e.callbackUrl)),e.streamUrl&&t.push(new G(e.streamUrl,Rt(e.streamEvents),e.streamAuthToken)),new V(t)}async function Vt(e){R(Lt(e));let t=new B(`cancel command`),n=Lt(e),r=e.channel??`WEB`,i=e.output===`json`?`json`:`text`,a=Bt(e),o=zt(e.sessionStore);try{let s=await d(n,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 ee({dataDir:n,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`&&D(l),await a.send({type:`progress`,sessionId:e.sessionId,channel:r,messageId:e.messageId,event:l}),t.end(),process.exit(0)}catch(n){let i=n;await a.send({type:`error`,sessionId:e.sessionId,channel:r,messageId:e.messageId,message:i.message}),z.error(`cancel command error: ${i.message}`),E(`Fatal: ${i.message}`),t.end(),process.exit(1)}finally{await a.close()}}function Ht(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`).action(async e=>{await Vt(e)})}const Ut=e(import.meta.url)(`../package.json`);function $(){return process.env.AIMAX_DATA_DIR||process.cwd()}function Wt(){let e=new t;return e.name(`aimax`).description(`AIMax CLI — runs agent tasks in a containerized environment`).version(Ut.version),vt(e),Je(e),Ht(e),yt(e),Ft(e),ge(e),xt(e),At(e,$),Pt(e,$),e}export{Pe as a,z as i,$ as n,R as r,Wt as t};
|