@gencode/cli 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # @gencode/cli
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - c0283fc: ### Auto-Skills Runtime and Review Workflow
8
+
9
+ Added the learned auto-skills runtime and CLI controls.
10
+
11
+ - Added `.aimax/auto-skills` storage support with `categories.json`, single-level category slugs, `SKILL.md` entrypoints, generated `metadata.json`, archived/active status handling, and `.reviews/run-log.jsonl` audit records for completed review-agent runs.
12
+ - Added `AutoSkillsLoader` APIs to list categories, list active learned skills by category, search compact skill metadata, view a selected `SKILL.md`, and load bounded resource files inside an auto-skill directory.
13
+ - Added manifest-based in-memory and prompt snapshot caching for auto-skill indexes, with cache invalidation after category, create, update, and archive writes.
14
+ - Added main-agent read tools: `auto_skill_categories`, `auto_skill_list`, `auto_skill_search`, and `auto_skill_view`; these are hidden when `autoSkills.load.enabled` is false.
15
+ - Added a system-prompt auto-skills section that routes the main agent from categories to list/view/search while preferring curated, user, and plugin skills when both apply.
16
+ - Added the restricted `auto_skill_manage` tool for internal review-agent use only, supporting `create_category`, `create`, `update`, and `archive` actions with structured success/error payloads.
17
+ - Added public/internal agent visibility, keeping `visibility: internal` definitions out of public custom-agent delegation and `subagent_spawn` selection while still allowing explicit internal orchestration to resolve them by name.
18
+ - Added post-run auto-skill review lifecycle modes: `off`, `gate`, `dry_run`, and `write`, replacing legacy score thresholds with configurable scope-based gates for the full session, current run, and post-review window.
19
+ - Added per-session auto-skill review state with `maxReviewsPerSession`, attempted/completed/failed timestamps, and a reviewed-transcript cursor so repeat reviews focus on newly accumulated work.
20
+ - Added pre-gate skips for subagents, cron runs, run errors, HITL pauses, pending UI tools, gate misses, and sessions that already reached their review cap.
21
+ - Added compact review packets with session/current-run/review-window ranges, stats, tool stats, loaded/viewed skills, failed tool summaries, active categories, review state, and evidence file locations.
22
+ - Added the review-only `auto_skill_review_context_view` tool so the internal curator can read bounded review-window, current-run, recent-conversation, explicit transcript-range, or referenced tool-result evidence.
23
+ - Added silent internal curator integration for dry-run and write review modes, including diagnostic timing events, sanitized tool-result diagnostics, sanitized write-tool arguments, durable-write summaries parsed from `auto_skill_manage` results, and completed/failed review run logs.
24
+ - Added the named internal `auto-skill-reviewer` agent for review orchestration, applying its prompt, init prompt, model override, and tool restrictions to silent review turns; review runs now skip with diagnostics when that internal agent is not configured.
25
+ - Added `--system-agents-dir` and `AIMAX_SYSTEM_AGENTS_DIR` controls for `run` and `resume`, including absolute-path validation, CLI-over-env precedence, start-log reporting, and propagation through direct runs, HITL resumes, UI tool resumes, and run-dispatched resume flows.
26
+ - Added CLI controls for `run` and `resume`: `--auto-skills-load-enabled`, `--auto-skills-review-mode`, `AIMAX_AUTO_SKILLS_LOAD_ENABLED`, and `AIMAX_AUTO_SKILLS_REVIEW_MODE`, including validation, option-overrides-env precedence, and propagation through direct runs, resumed HITL runs, UI tool resumes, and run-dispatched resume flows; when these controls are unset, the agents layer defaults to `load.enabled=false` and `review.mode=write`.
27
+ - Exported auto-skills loader helpers, review gate/state helpers, public types, and read-tool factories from the package entrypoints.
28
+
29
+ ### Patch Changes
30
+
31
+ - 18e17e4: Relax Microcompact staleness handling so tool results stay inline for the last 48 hours and remain protected within the most recent three user turns.
32
+ - c39239c: Use AES-GCM session encryption with CLI-supplied key rotation support so session files no longer rely on reversible encoding alone.
33
+ - Updated dependencies [18e17e4]
34
+ - Updated dependencies [c0283fc]
35
+ - Updated dependencies [c39239c]
36
+ - @gencode/agents@0.6.0
37
+
3
38
  ## 0.4.0
4
39
 
5
40
  ### Minor Changes
package/dist/bin.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{a as e,i as t,r as n,t as r}from"./program-BFeRbTb8.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{};
2
+ import{a as e,i as t,r as n,t as r}from"./program-BaCtsPfO.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,12 @@
1
+ import{createRequire as e}from"node:module";import{Command as t}from"commander";import{bootstrapMountLayout as n,buildResumeNarration as r,clearPendingUiTool as i,createBuiltinMemoryProvider as a,createSessionEncryptionConfig as o,ensureBootstrapMountLayout as s,exportSession as c,formatApprovalResolution as l,formatClarifyResolution as u,formatReviewResolution as d,hasBootstrapSentinel as f,initializePluginSystem as p,inspectSession as m,listAvailableSlashCommands as h,listSessionSummaries as g,loadPendingHitl as ee,loadPendingUiTool as te,loadSkillsWithPluginDirs as ne,loadTranscript as re,normalizePluginsConfig as ie,normalizeSessionStoreName as _,resolveMemoryProvider as ae,resolvePendingHitl as oe,resolvePendingUiTool as se,rewriteTranscript as ce,runAgent as v,setDefaultSessionEncryptionConfig as le}from"@gencode/agents";import{formatTaskForDisplay as ue,isAgentDiagnosticEvent as y,isHitlTool as de,parseMatchedTextToResolution as fe,parseTextToResolution as pe}from"@gencode/shared";import b from"node:fs/promises";import x from"node:path";import me from"gensign-node";import he from"node:fs";import ge from"log4js";import{addAgent as _e,addBinding as ve,getAgentConfig as S,listAgents as ye,listBindings as be,loadAgentsConfig as C,normalizeAgentId as xe,removeAgent as Se,removeBindings as Ce,resolveAgentDir as we,resolveDefaultAgentId as w,updateAgentIdentity as Te}from"@gencode/agents/config";function Ee(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`:Ee(e.text);break;case`stream_text_delta`:Ee(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}"`:``} ${ue(e.task)}`);break;case`subagent_complete`:T(`[subagent:${e.status}] ${ue(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;case`ui_tool_request`:T(`\n[ui-tool:${e.request.toolName}] ${e.request.outputSchema.title}`),T(` requestId: ${e.request.requestId}`),T(` toolCallId: ${e.request.toolCallId}`);break;case`ui_tool_result`:T(`\n[ui-tool:resumed] requestId=${e.requestId} tool=${e.toolName}`);break}}function O(e,t){if(t===`json`){e&&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 De(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 Oe(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 ke(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 Ae(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 je(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{Ae(await n(e.dataDir),t)}catch(e){E(`Error bootstrapping data directory: ${e.message}`),process.exit(1)}})}function Me(e){return me.sm4_encrypt_ecb(e)}function Ne(e){return Me(e)}function Pe(e={}){let t=e.baseUrl??process.env.AIMAX_BASE_URL,n=process.env.AIMAX_AUTH_TOKEN,r=e.authToken?Ne(e.authToken):n?Ne(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 Fe(e,t){return t?x.resolve(t):x.join(e,`.aimax`,`plugins.json`)}async function k(e,t){let n=Fe(e,t);try{let e=await b.readFile(n,`utf-8`);return JSON.parse(e)}catch(e){if(e.code===`ENOENT`)return;throw e}}async function A(e,t,n){let r=Fe(e,n);await b.mkdir(x.dirname(r),{recursive:!0}),await b.writeFile(r,JSON.stringify(t,null,2),`utf-8`)}function j(e){return typeof e==`object`&&!!e}function M(e){return j(e)&&e.type===`text`&&typeof e.text==`string`&&(e.textSignature===void 0||typeof e.textSignature==`string`)}function Ie(e){return j(e)&&e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`}function Le(e){return j(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 Re(e){return j(e)&&e.type===`toolCall`&&typeof e.id==`string`&&typeof e.name==`string`&&j(e.arguments)&&(e.thoughtSignature===void 0||typeof e.thoughtSignature==`string`)}function ze(e){return typeof e==`string`||Array.isArray(e)&&e.every(e=>M(e)||Ie(e))}function Be(e){return Array.isArray(e)&&e.every(e=>M(e)||Le(e)||Re(e))}function Ve(e){return j(e)&&typeof e.input==`number`&&typeof e.output==`number`&&typeof e.cacheRead==`number`&&typeof e.cacheWrite==`number`&&typeof e.totalTokens==`number`&&j(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 He(e){return!j(e)||typeof e.role!=`string`?!1:e.role===`user`?ze(e.content):e.role===`assistant`?Be(e.content)&&typeof e.api==`string`&&typeof e.provider==`string`&&typeof e.model==`string`&&Ve(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=>M(e)||Ie(e))&&typeof e.isError==`boolean`:!1}async function Ue(e){let t;try{t=await b.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=>He(e)))throw Error(`Message file must contain one Message object or an array of Message objects`);return r}async function We(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 Ue(e.fromFile)}:{kind:`text`,message:e.message}}function Ge(e){let t=new Intl.DateTimeFormat(`en-CA`,{timeZone:`Asia/Shanghai`,year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1}).formatToParts(e);return Object.fromEntries(t.map(e=>[e.type,e.value]))}function Ke(e=new Date){let t=Ge(e),n=String(e.getMilliseconds()).padStart(3,`0`);return`${t.year}-${t.month}-${t.day} ${t.hour}:${t.minute}:${t.second}.${n}`}let N=function(e){return e.INFO=`INFO`,e.ERROR=`ERROR`,e.WARN=`WARN`,e}({}),P=null;function qe(){return Ke()}function Je(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 Ye(e){return x.join(e,`.aimax`)}function Xe(e){return{appLogPath:x.join(e,`app.log`),errorLogPath:x.join(e,`errors.log`)}}function Ze(e){let{appLogPath:t,errorLogPath:n}=Xe(e);ge.configure({appenders:{appFile:{type:`file`,filename:t,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`messagePassThrough`}},errorFile:{type:`file`,filename:n,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`messagePassThrough`}},errorsOnly:{type:`logLevelFilter`,appender:`errorFile`,level:`error`,maxLevel:`fatal`}},categories:{default:{appenders:[`appFile`,`errorsOnly`],level:`info`}}})}function Qe(e,t,n){return`[${qe()}] [${e}] ${t}${Je(n)}`}function $e(e,t,n){process.stderr.write(`${Qe(e,t,n)}\n`)}function F(e,t,n){if(!P){$e(e,t,n);return}let r=Qe(e,t,n),i=ge.getLogger();if(e===N.ERROR){i.error(r);return}if(e===N.WARN){i.warn(r);return}i.info(r)}function I(e){let t=Ye(e);P?.dataDir!==e&&(he.mkdirSync(t,{recursive:!0}),Ze(t),P={dataDir:e,logDir:t})}async function et(){await ge.shutdown()}const L={info:(e,t)=>F(N.INFO,e,t),warn:(e,t)=>F(N.WARN,e,t),error:(e,t)=>F(N.ERROR,e,t)};var R=class{startTime;name;constructor(e){this.name=e,this.startTime=Date.now()}end(){let e=Date.now()-this.startTime;return L.info(`${this.name} completed in ${e}ms`),e}},z=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()}))}},B=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=tt(e);L.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 L.error(`callback event failed`,{callbackUrl:this.url,httpStatus:r.status,durationMs:i,...n}),Error(`Callback failed with status ${r.status}`);L.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 tt(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 nt(e,t){if(t.kind===`none`)return e;let n=new URL(e);return n.searchParams.set(`authToken`,t.token),n.toString()}function V(){let e=globalThis.WebSocket;if(!e)throw Error(`WebSocket is not available in this runtime`);return e}function rt(e){return e?{kind:`query_token`,token:e}:{kind:`none`}}function H(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 it(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 U=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=V();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){L.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=V();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){L.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=V();e.readyState!==t.CLOSED&&await new Promise(t=>{H(e,`close`,()=>t()),e.close()})}async ensureConnected(){if(!this.enabled)return;let e=V();if(this.socket&&this.socket.readyState===e.OPEN)return;if(this.connectPromise){await this.connectPromise;return}let t=new e(nt(this.url,rt(this.authToken)));this.connectPromise=new Promise((e,n)=>{H(t,`open`,()=>{this.socket=t,it(t,`close`,()=>{this.socket===t&&(this.socket=null)}),e()}),H(t,`error`,e=>{n(e)})});try{await this.connectPromise}finally{this.connectPromise=null}}toEnvelope(e){let t=new Date().toISOString();switch(e.type){case`start`:return this.events.has(`start`)?{...e,timestamp:t}:null;case`done`:return this.events.has(`done`)?{...e,timestamp:t}:null;case`error`:return this.events.has(`error`)?{...e,timestamp:t}:null;case`hitl`:return this.events.has(`hitl`)?{...e,timestamp:t}:null;case`title_updated`:return this.events.has(`title_updated`)?{type:`title_updated`,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,timestamp:t,title:e.title}:null;case`session_reset`:return null;case`progress`:return e.event.type===`text`?this.events.has(`text`)?(this.textSequence+=1,{type:`text`,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,timestamp:t,sequence:this.textSequence,delta:e.event.text}):null:e.event.type===`stream_text_delta`||!this.events.has(`progress`)?null:{type:`progress`,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,timestamp:t,event:e.event};default:{let t=e;throw Error(`Unsupported stream event: ${JSON.stringify(t)}`)}}}};function at(e){return e?.trim()?e.split(`,`).map(e=>e.trim()).filter(Boolean):[]}function W(e){if(e.encryptSessions)return o(e.sessionEncryptionKey,at(e.sessionLegacyKeys))}const ot=[`start`,`text`,`done`,`error`,`hitl`],st=[`off`,`gate`,`dry_run`,`write`];function ct(e){if(!e?.trim())return new Set(ot);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(ot)}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 ut(e){return e?.trim()||void 0}function dt(e){let t=(e.systemAgentsDir??process.env.AIMAX_SYSTEM_AGENTS_DIR)?.trim();if(t){if(!x.isAbsolute(t)){let n=e.systemAgentsDir===void 0?`AIMAX_SYSTEM_AGENTS_DIR`:`--system-agents-dir`;throw Error(`Invalid ${n}: ${t}. Path must be absolute.`)}return t}}function ft(e){return e?_(e):void 0}function pt(e){if(!e?.trim())return[];let t=e.split(`,`).map(e=>e.trim()).filter(Boolean),n=new Set,r=[];for(let e of t){if(!x.isAbsolute(e))throw Error(`Invalid --skillsLoadPaths entry: ${e}. Each path must be absolute.`);n.has(e)||(n.add(e),r.push(e))}return r}function mt(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if([`true`,`1`,`yes`,`on`].includes(n))return!0;if([`false`,`0`,`no`,`off`].includes(n))return!1;throw Error(`Invalid ${t}: ${e}. Must be true or false.`)}}function ht(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(st.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function gt(e){let t=e.autoSkillsLoadEnabled===void 0?mt(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):mt(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?ht(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):ht(e.autoSkillsReviewMode,`--auto-skills-review-mode`),r={};return t!==void 0&&(r.load={enabled:t}),n!==void 0&&(r.review={mode:n}),r.load||r.review?r:void 0}function _t(e,t){if(e.inputText&&t){let n=pe(e.inputText,t);return n.submittedBy={userId:e.user,channel:e.channel??`IM`},n}if(!e.inputJson&&!e.inputText)throw Error(`Either --input-json or --input-text must be provided for the resume command`);try{let t=JSON.parse(e.inputJson);return{requestId:e.requestId,sessionId:e.sessionId,action:t.action??`submit`,values:t.values,submittedBy:t.submittedBy,idempotencyKey:t.idempotencyKey,submittedAt:t.submittedAt??new Date().toISOString()}}catch(e){throw Error(`Invalid --input-json: ${e.message}`)}}function vt(e,t){if(!e.inputJson)throw Error(`UI tool resume requires --input-json`);try{let n=JSON.parse(e.inputJson),r=n&&typeof n==`object`&&`values`in n&&n.values&&typeof n.values==`object`&&!Array.isArray(n.values)?n.values:n;return{requestId:t.request.requestId,sessionId:t.sessionId,toolCallId:t.request.toolCallId,toolName:t.request.toolName,values:r,submittedAt:new Date().toISOString()}}catch(e){throw Error(`Invalid --input-json: ${e.message}`)}}async function yt(e){let t=await re(e.dataDir,e.sessionId,{storeName:e.sessionStoreName,encryptSessions:e.encryptSessions,sessionEncryption:W({encryptSessions:e.encryptSessions,sessionEncryptionKey:e.sessionEncryptionKey,sessionLegacyKeys:e.sessionLegacyKeys})});for(let n=t.length-1;n>=0;--n){let r=t[n];if(r?.role!==`assistant`||!Array.isArray(r.toolCalls))continue;let i=r.toolCalls.find(t=>t.id===e.toolCallId&&t.name===e.toolName);if(i)return i.arguments}}async function bt(e){let t=lt(e),n=e.channel??`WEB`,r=Pe({baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel});return{dataDir:t,systemAgentsDir:dt(e),channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,skillsLoadPaths:pt(e.skillsLoadPaths),autoSkills:gt(e)}}function xt(e){let t=[],n=null;return e.callbackUrl&&t.push(new B(e.callbackUrl)),e.streamUrl&&(n=new U(e.streamUrl,ct(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new z(t),websocketSink:n}}async function St(e){let{dataDir:t,sessionId:n,sessionStoreName:r,toolCallId:i,toolName:a,resolution:o,encryptSessions:s,sessionEncryptionKey:c,sessionLegacyKeys:f}=e;if(!i||!a||!de(a))return;let p=(e,t)=>{switch(e){case`request_approval`:return l(t);case`clarify`:return u(t);case`request_review`:return d(t);default:return JSON.stringify({action:t.action,values:t.values})}};await ce(t,n,e=>{let t=e.findIndex(e=>e.role===`tool_result`&&e.toolCallId===i&&e.toolName===a);if(t===-1)return e;let n=e.slice(0,t+1);return n[t]={...n[t],content:p(a,o),isError:!1},n},{storeName:r,encryptSessions:s,sessionEncryption:W({encryptSessions:s,sessionEncryptionKey:c,sessionLegacyKeys:f})})}async function Ct(e){let{dataDir:t,sessionId:n,sessionStoreName:r,result:i,encryptSessions:a,sessionEncryptionKey:o,sessionLegacyKeys:s}=e;await ce(t,n,e=>{let t=e.findIndex(e=>e.role===`assistant`&&Array.isArray(e.toolCalls)&&e.toolCalls.some(e=>e.id===i.toolCallId&&e.name===i.toolName));if(t===-1)return e;let n=e.slice(0,t+1);return n.push({role:`tool_result`,toolCallId:i.toolCallId,toolName:i.toolName,content:JSON.stringify({submitted:!0,values:i.values}),isError:!1,timestamp:i.submittedAt}),n},{storeName:r,encryptSessions:a,sessionEncryption:W({encryptSessions:a,sessionEncryptionKey:o,sessionLegacyKeys:s})})}async function G(e){le(W(e)),I(lt(e));let t=new R(`resume command`),n=null;try{let r=await bt(e),a=W(e),o=ft(e.sessionStore);L.info(`resume command started`,{sessionId:e.sessionId,requestId:e.requestId,channel:r.channel,dataDir:r.dataDir});let s=await ee(r.dataDir,e.sessionId,{storeName:o,encryptSessions:e.encryptSessions,sessionEncryption:a}),c=s?null:await te(r.dataDir,e.sessionId,{storeName:o,encryptSessions:e.encryptSessions,sessionEncryption:a});if(!s&&!c)throw Error(`No pending HITL or UI tool request found for session "${e.sessionId}"`);if(s){if(s.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${s.request.requestId}", got "${e.requestId}"`);if(s.status===`expired`)throw Error(`HITL request has expired`);if(s.status===`cancelled`)throw Error(`HITL request has been cancelled`)}else if(c){if(c.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${c.request.requestId}", got "${e.requestId}"`);if(c.status!==`pending`)throw Error(`UI tool request is already "${c.status}", cannot resume`)}if(s){let i=_t(e,s.request),c=await oe({dataDir:r.dataDir,sessionStoreName:o,sessionId:e.sessionId,requestId:e.requestId,resolution:i}),l=c.state;if(!l)throw Error(`Resolved HITL state was not persisted`);let u=wt(i,l.request.kind);await St({dataDir:r.dataDir,sessionId:e.sessionId,sessionStoreName:o,toolCallId:l.toolContext?.toolCallId,toolName:l.toolContext?.toolName,resolution:i,encryptSessions:e.encryptSessions,sessionEncryptionKey:e.sessionEncryptionKey,sessionLegacyKeys:e.sessionLegacyKeys});let d=xt(e);n=d.sink;let f=e.sessionId,p=async t=>{if(f=t.sessionId??f,!y(t)){if(t.type===`stream_text_delta`){r.format===`text`&&D(t),await d.websocketSink?.sendTextDelta({sessionId:f,channel:r.channel,messageId:e.messageId,user:e.user,text:t.text});return}r.format===`text`&&D(t),await n?.send({sessionId:f,channel:r.channel,messageId:e.messageId,user:e.user,type:`progress`,event:t})}};await p({type:`hitl_resumed`,requestId:e.requestId,resolution:i,sessionId:e.sessionId}),`idempotentReplay`in c&&c.idempotentReplay&&(L.info(`resume command treated as idempotent replay`,{sessionId:e.sessionId,requestId:e.requestId,idempotencyKey:i.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 m=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,h=await k(r.dataDir,m),g;try{g=await v({dataDir:r.dataDir,projectDir:ut(e.projectDir),systemAgentsDir:r.systemAgentsDir,sessionStoreName:o,sessionId:e.sessionId,messageId:e.messageId,channel:r.channel,llm:r.llm,skillsLoadPaths:r.skillsLoadPaths,autoSkills:r.autoSkills,timeoutMs:r.timeoutMs,message:u,encryptSessions:e.encryptSessions??!1,sessionEncryption:a,hitlResume:{request:l.request,resolution:i,checkpoint:l.checkpoint,toolContext:l.toolContext},plugins:h?{config:h,dataDir:r.dataDir,workspaceDir:x.join(r.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:h.llmAllowlist}:void 0,onProgress:p})}finally{}g.error?await n?.send({sessionId:g.sessionId,channel:r.channel,messageId:e.messageId,user:e.user,type:`error`,message:g.error}):await n?.send({sessionId:g.sessionId,channel:r.channel,messageId:e.messageId,user:e.user,type:`done`,result:{text:g.text,usage:g.usage,durationMs:g.durationMs,error:g.error,paused:g.paused,uiToolPending:g.uiToolPending}}),O(g,r.format),g.error?L.error(`resume command failed: ${g.error}`):L.info(`resume command succeeded`),t.end(),process.exit(g.error?1:0);return}let l=vt(e,c);if(!await se(r.dataDir,e.sessionId,e.requestId,l,{storeName:o,encryptSessions:e.encryptSessions,sessionEncryption:a}))throw Error(`UI tool resume validation failed`);await Ct({dataDir:r.dataDir,sessionId:e.sessionId,sessionStoreName:o,result:l,encryptSessions:e.encryptSessions,sessionEncryptionKey:e.sessionEncryptionKey,sessionLegacyKeys:e.sessionLegacyKeys});let u=xt(e);n=u.sink;let d=e.sessionId,f=async t=>{if(d=t.sessionId??d,!y(t)){if(t.type===`stream_text_delta`){r.format===`text`&&D(t),await u.websocketSink?.sendTextDelta({sessionId:d,channel:r.channel,messageId:e.messageId,user:e.user,text:t.text});return}if(r.format===`text`&&D(t),t.type===`start`){await n?.send({sessionId:d,channel:r.channel,messageId:e.messageId,user:e.user,type:`start`,message:t.message});return}await n?.send({sessionId:d,channel:r.channel,messageId:e.messageId,user:e.user,type:`progress`,event:t})}},p=await yt({dataDir:r.dataDir,sessionId:e.sessionId,sessionStoreName:o,toolCallId:l.toolCallId,toolName:l.toolName,encryptSessions:e.encryptSessions,sessionEncryptionKey:e.sessionEncryptionKey,sessionLegacyKeys:e.sessionLegacyKeys});await f({type:`tool_end`,sessionId:e.sessionId,toolCallId:l.toolCallId,name:l.toolName,input:p,output:JSON.stringify({submitted:!0,values:l.values}),isError:!1});let m=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,h=await k(r.dataDir,m),g=await v({dataDir:r.dataDir,projectDir:ut(e.projectDir),systemAgentsDir:r.systemAgentsDir,sessionStoreName:o,sessionId:e.sessionId,messageId:e.messageId,channel:r.channel,llm:r.llm,skillsLoadPaths:r.skillsLoadPaths,autoSkills:r.autoSkills,timeoutMs:r.timeoutMs,message:`[UI_TOOL_RESUME]
5
+ The pending UI tool result has been written into the transcript. Continue from the latest tool result without repeating the same form request.`,encryptSessions:e.encryptSessions??!1,sessionEncryption:a,uiToolResume:l,plugins:h?{config:h,dataDir:r.dataDir,workspaceDir:x.join(r.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:h.llmAllowlist}:void 0,onProgress:f});await i(r.dataDir,e.sessionId,{storeName:o,encryptSessions:e.encryptSessions,sessionEncryption:a}),g.error?await n?.send({sessionId:g.sessionId,channel:r.channel,messageId:e.messageId,user:e.user,type:`error`,message:g.error}):await n?.send({sessionId:g.sessionId,channel:r.channel,messageId:e.messageId,user:e.user,type:`done`,result:{text:g.text,usage:g.usage,durationMs:g.durationMs,error:g.error,paused:g.paused,uiToolPending:g.uiToolPending}}),O(g,r.format),g.error?L.error(`resume command failed: ${g.error}`):L.info(`resume command succeeded`),t.end(),process.exit(g.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}`})),L.error(`resume command error: ${i.message}`),E(`Fatal: ${i.message}`),t.end(),process.exit(1)}finally{await n?.close()}}function wt(e,t){return r(e,t)}function Tt(e){e.command(`resume`).description(`Resume a paused HITL session with user input`).requiredOption(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--project-dir <path>`,`Current project directory used as the default cwd context`).option(`--system-agents-dir <path>`,`System agent definition directory (overrides AIMAX_SYSTEM_AGENTS_DIR, default: /aimax/agents)`).requiredOption(`-s, --session-id <id>`,`Session ID to resume`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).requiredOption(`--request-id <id>`,`HITL request ID to resolve`).option(`--input-json <json>`,`JSON string with the resolution (action, values, etc.)`).option(`--input-text <text>`,`Plain text response for IM channels without rich UI (e.g. '同意', '拒绝')`).option(`--skillsLoadPaths <paths>`,`Comma-separated absolute skill load paths`).option(`--auto-skills-load-enabled <boolean>`,`Enable learned auto-skill loading for the main agent (overrides AIMAX_AUTO_SKILLS_LOAD_ENABLED)`).option(`--auto-skills-review-mode <mode>`,`Auto-skill review mode: off, gate, dry_run, or write (overrides AIMAX_AUTO_SKILLS_REVIEW_MODE)`).option(`--message-id <id>`,`Message ID for correlating events`).option(`--user <id>`,`User identifier propagated to external callback and stream payloads`).option(`-c, --channel <channel>`,`Channel name (default: WEB)`,`WEB`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY)`).option(`--auth-token <token>`,`Auth token used to generate the API key`).option(`--model <name>`,`LLM model name (overrides AIMAX_MODEL)`).option(`--context-window <n>`,`LLM context window size`).option(`--callback-url <url>`,`HTTP callback URL for progress events`).option(`--stream-url <url>`,`WebSocket URL for streaming text events`).option(`--stream-auth-token <token>`,`Auth token for WebSocket streaming`).option(`--stream-events <list>`,`Comma-separated stream events`).option(`--timeout <ms>`,`Execution timeout in milliseconds`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--plugins-config <path>`,`Plugins config file path`).option(`--encrypt-sessions`,`Enable AES-GCM session data encryption at rest`).option(`--session-encryption-key <secret>`,`Primary secret used to derive the active AES-GCM session key`).option(`--session-legacy-keys <list>`,`Comma-separated legacy session secrets kept for decrypting older encrypted data`).action(async e=>{await G(e)})}const Et=[`start`,`text`,`done`,`error`],Dt=[`off`,`gate`,`dry_run`,`write`];function Ot(e){if(!e?.trim())return new Set(Et);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(Et)}function K(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir option or AIMAX_DATA_DIR environment variable`);return t}function q(e){return e?.trim()||void 0}function kt(e){let t=(e.systemAgentsDir??process.env.AIMAX_SYSTEM_AGENTS_DIR)?.trim();if(t){if(!x.isAbsolute(t)){let n=e.systemAgentsDir===void 0?`AIMAX_SYSTEM_AGENTS_DIR`:`--system-agents-dir`;throw Error(`Invalid ${n}: ${t}. Path must be absolute.`)}return t}}function J(e){return e?.trim()||void 0}function At(e){return e??`WEB`}function jt(e){return e?_(e):void 0}function Mt(e){if(!e?.trim())return[];let t=e.split(`,`).map(e=>e.trim()).filter(Boolean),n=new Set,r=[];for(let e of t){if(!x.isAbsolute(e))throw Error(`Invalid --skillsLoadPaths entry: ${e}. Each path must be absolute.`);n.has(e)||(n.add(e),r.push(e))}return r}function Nt(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if([`true`,`1`,`yes`,`on`].includes(n))return!0;if([`false`,`0`,`no`,`off`].includes(n))return!1;throw Error(`Invalid ${t}: ${e}. Must be true or false.`)}}function Pt(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(Dt.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function Ft(e){let t=e.autoSkillsLoadEnabled===void 0?Nt(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):Nt(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?Pt(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):Pt(e.autoSkillsReviewMode,`--auto-skills-review-mode`),r={};return t!==void 0&&(r.load={enabled:t}),n!==void 0&&(r.review={mode:n}),r.load||r.review?r:void 0}function It(e,t){return e.length<=t?e:t<=3?e.slice(0,t):`${e.slice(0,t-3)}...`}function Lt(e,t,n=78){let r=n-2,i=r-2,a=e?` ${It(e,Math.max(0,i-2))} `:``,o=e?`┌${a}${`─`.repeat(Math.max(0,r-a.length))}┐`:`┌${`─`.repeat(r)}┐`,s=`└${`─`.repeat(r)}┘`;return[o,...t.map(e=>`│ ${It(e,i).padEnd(i,` `)} │`),s].join(`
6
+ `)}function Rt(e){return e.kind===`text`?`inline message (${e.message.length} chars)`:`message file (${e.messages.length} messages)`}function zt(e,t){let n=jt(e.sessionStore)??`sessions`,r=t.timeoutMs===void 0?`default`:`${t.timeoutMs}`,i=e.callbackUrl?`enabled`:`disabled`,a=e.streamUrl?`enabled`:`disabled`,o=Rt(t.input),s=t.input.kind===`text`?`inline`:e.fromFile??`file`,c=Ke();return{banner:Lt(void 0,[`AIMax CLI`,`Stateless Agent Runner`]),contextBox:Lt(`Run Context`,[`time : ${c}`,`channel : ${t.channel}`,`user : ${e.user??`-`}`,`sessionId : ${e.sessionId??`new`}`,`sessionStore : ${n}`,`messageId : ${e.messageId??`-`}`,`dataDir : ${t.dataDir}`,`workspace : ${x.join(t.dataDir,`workspace`)}`,`projectDir : ${q(e.projectDir)??`-`}`,`systemAgents : ${t.systemAgentsDir??`/aimax/agents`}`,`agent : ${J(e.agent)??`-`}`,`output : ${t.format}`,`callback : ${i}`,`websocket : ${a}`,`timeoutMs : ${r}`,`input : ${o}`]),logContext:{time:c,channel:t.channel,user:e.user,dataDir:t.dataDir,projectDir:q(e.projectDir),systemAgentsDir:t.systemAgentsDir,agent:J(e.agent),workspaceDir:x.join(t.dataDir,`workspace`),sessionId:e.sessionId??`new`,sessionStore:n,messageId:e.messageId,output:t.format,hasCallback:!!e.callbackUrl,hasStream:!!e.streamUrl,timeoutMs:t.timeoutMs,inputKind:t.input.kind,inputSource:s,inputSummary:o}}}async function Bt(e,t){let n=K(e),r=At(e.channel),i=Pe({baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel});return{dataDir:n,systemAgentsDir:kt(e),channel:r,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:i,input:t,skillsLoadPaths:Mt(e.skillsLoadPaths),autoSkills:Ft(e)}}function Vt(e){if(e.kind===`text`)return e.message;if(e.messages.length!==1)return null;let[t]=e.messages;if(t.role!==`user`)return null;if(typeof t.content==`string`)return t.content;if(t.content.length===0)return null;let n=[];for(let e of t.content){if(e.type!==`text`)return null;n.push(e.text)}return n.join(`
7
+ `)}async function Ht(e,t){if(!e.sessionId)return null;let n=Vt(t);if(!n)return null;let r=await ee(K(e),e.sessionId,{storeName:jt(e.sessionStore),encryptSessions:e.encryptSessions,sessionEncryption:W(e)});return!r||r.status!==`pending`||!fe(n,r.request)?null:{requestId:r.request.requestId,inputText:n}}function Ut(e){let t=[],n=null;return e.callbackUrl&&t.push(new B(e.callbackUrl)),e.streamUrl&&(n=new U(e.streamUrl,Ot(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new z(t),websocketSink:n}}async function Y(e,t){L.info(`dispatching external event`,cn(t)),await e.sink.send(t)}function Wt(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 Gt(e){let t={sessionId:e.sessionId,messageId:e.messageId,parentSessionId:e.parentSessionId,depth:e.depth,scope:e.scope,phase:e.phase,...Wt(e.details)};if(e.level===`error`){L.error(e.message,t);return}if(e.level===`warn`){L.warn(e.message,t);return}L.info(e.message,t)}function Kt(e,t,n,r,i){return{sink:e,websocketSink:t,channel:n,defaultMessageId:r,user:i}}function qt(){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 Jt(e){return{activeSessionId:e??`pending`,finalResult:null}}function Yt(e,t){e.activeSessionId=t.sessionId??e.activeSessionId}function Xt(e,t){return e.messageId??t}async function Zt(e,t,n){if(!await f(e.dataDir)){if(await X(t,e.format,n.activeSessionId,e.dataDir,`checking`),(await s(e.dataDir)).performedBootstrap){await X(t,e.format,n.activeSessionId,e.dataDir,`initializing`),await X(t,e.format,n.activeSessionId,e.dataDir,`initialized`);return}await X(t,e.format,n.activeSessionId,e.dataDir,`ready`)}}async function X(e,t,n,r,i){let a={type:`bootstrap`,phase:i,dataDir:r};t===`text`&&D(a),await Y(e,{sessionId:n,channel:e.channel,messageId:e.defaultMessageId,user:e.user,type:`progress`,event:a})}function Qt(e,t,n){return async r=>{if(Yt(n,r),y(r)){Gt(r);return}if(r.type===`stream_text_delta`){e.format===`text`&&D(r),await t.websocketSink?.sendTextDelta({sessionId:n.activeSessionId,channel:e.channel,messageId:Xt(r,t.defaultMessageId),user:t.user,text:r.text});return}e.format===`text`&&D(r);let i=Xt(r,t.defaultMessageId);if(r.type===`hitl_requested`){await Y(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`hitl`,request:r.request}),await Y(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r});return}if(r.type===`start`){await Y(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`start`,message:r.message});return}if(r.type===`session_reset`){await Y(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 Y(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r})}}function $t(e,t,n,r,i){let a={dataDir:t.dataDir,projectDir:q(e.projectDir),systemAgentsDir:t.systemAgentsDir,agentPolicy:J(e.agent)?{requestedAgentName:J(e.agent)}:void 0,sessionStoreName:jt(e.sessionStore),sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,abortSignal:n.signal,encryptSessions:e.encryptSessions??!1,sessionEncryption:W(e),plugins:i?{config:i,dataDir:t.dataDir,workspaceDir:x.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 en(e,t,n,r){if(t.activeSessionId=r.sessionId,t.finalResult=r,r.error){await Y(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:r.error});return}await Y(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 tn(e,t,n,r){await Y(e,{sessionId:t.finalResult?.sessionId??t.activeSessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:`Fatal: ${r.message}`})}function nn(e,t){let n=zt(e,t);L.info([`run command started`,n.banner,n.contextBox].join(`
8
+ `),n.logContext),t.format===`text`&&(T(n.banner),T(``),T(n.contextBox),T(``))}function rn(e,t,n){O(t,n),t.error?L.error(`run command failed: ${t.error}`):L.info(`run command succeeded`),e.end(),process.exit(t.error?1:0)}function an(e,t){L.error(`run command error: ${t.message}`),E(`Fatal: ${t.message}`),e.end(),process.exit(1)}async function on(e){if(e.resumeInputJson&&e.resumeFromFile)throw Error(`--resume-input-json and --resume-from-file are mutually exclusive`);if(!e.resumeFromFile)return e.resumeInputJson;try{return await b.readFile(e.resumeFromFile,`utf-8`)}catch(e){throw Error(`Failed to read resume input file: ${e.message}`)}}async function sn(e){le(W(e));let t=await on(e);if(e.resumeRequestId||t||e.resumeFromFile){if(!e.sessionId||!e.resumeRequestId||!t)throw Error(`--session-id, --resume-request-id, and exactly one of --resume-input-json or --resume-from-file must be provided together`);await G({dataDir:e.dataDir,projectDir:e.projectDir,systemAgentsDir:e.systemAgentsDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:e.resumeRequestId,inputJson:t,channel:e.channel,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow,flashModel:e.flashModel,callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamAuthToken:e.streamAuthToken,streamEvents:e.streamEvents,timeout:e.timeout,output:e.output,pluginsConfig:e.pluginsConfig,skillsLoadPaths:e.skillsLoadPaths,autoSkillsLoadEnabled:e.autoSkillsLoadEnabled,autoSkillsReviewMode:e.autoSkillsReviewMode,messageId:e.messageId,user:e.user,encryptSessions:e.encryptSessions,sessionEncryptionKey:e.sessionEncryptionKey,sessionLegacyKeys:e.sessionLegacyKeys});return}let n;try{n=await We({message:e.message,fromFile:e.fromFile})}catch(t){I(K(e)),an(new R(`run command`),t);return}let r=await Ht(e,n);if(r){await G({dataDir:e.dataDir,projectDir:e.projectDir,systemAgentsDir:e.systemAgentsDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:r.requestId,inputText:r.inputText,channel:e.channel,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow,flashModel:e.flashModel,callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamAuthToken:e.streamAuthToken,streamEvents:e.streamEvents,timeout:e.timeout,output:e.output,pluginsConfig:e.pluginsConfig,skillsLoadPaths:e.skillsLoadPaths,autoSkillsLoadEnabled:e.autoSkillsLoadEnabled,autoSkillsReviewMode:e.autoSkillsReviewMode,messageId:e.messageId,user:e.user,encryptSessions:e.encryptSessions,sessionEncryptionKey:e.sessionEncryptionKey,sessionLegacyKeys:e.sessionLegacyKeys});return}I(K(e));let i=new R(`run command`),{controller:a,cleanup:o}=qt(),s=null,c=e.channel??`WEB`,l=Jt(e.sessionId);try{let t=await Bt(e,n);c=t.channel,nn(e,t);let r=Ut(e);s=r.sink,L.info(`external sink configured`,{callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamEvents:e.streamEvents});let o=Kt(s,r.websocketSink,t.channel,e.messageId,e.user);await Zt(t,o,l);let u=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,d=await k(t.dataDir,u),f=await v($t(e,t,a,Qt(t,o,l),d));await en(o,l,e.messageId,f),rn(i,f,t.format)}catch(t){let n=t;s&&await tn(Kt(s,null,c,e.messageId,e.user),l,e.messageId,n),an(i,n)}finally{await s?.close(),o()}}function cn(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 ln(e){e.command(`run`).description(`Run an agent task`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--project-dir <path>`,`Current project directory used as the default cwd context`).option(`--system-agents-dir <path>`,`System agent definition directory (overrides AIMAX_SYSTEM_AGENTS_DIR, default: /aimax/agents)`).option(`--agent <name>`,`Custom agent name to run as the root agent`).option(`--user <id>`,`User identifier propagated to external callback and stream payloads`).option(`--message <text>`,`User message to send to the agent`).option(`--from-file <path>`,`Load structured Message JSON from a file`).option(`--skillsLoadPaths <paths>`,`Comma-separated absolute skill load paths`).option(`--auto-skills-load-enabled <boolean>`,`Enable learned auto-skill loading for the main agent (overrides AIMAX_AUTO_SKILLS_LOAD_ENABLED)`).option(`--auto-skills-review-mode <mode>`,`Auto-skill review mode: off, gate, dry_run, or write (overrides AIMAX_AUTO_SKILLS_REVIEW_MODE)`).option(`-s, --session-id <id>`,`Resume an existing session by ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`--message-id <id>`,`Message ID for correlating events`).option(`-c, --channel <channel>`,`Channel name (default: WEB)`,`WEB`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY)`).option(`--auth-token <token>`,`Auth token used to generate the API key (highest priority)`).option(`--model <name>`,`LLM model name (overrides AIMAX_MODEL)`).option(`--context-window <n>`,`LLM context window size`).option(`--flash-model <name>`,`Flash model for lightweight tasks like title generation (overrides AIMAX_FLASH_MODEL)`).option(`--callback-url <url>`,`HTTP callback URL for progress events`).option(`--stream-url <url>`,`WebSocket URL for streaming text events`).option(`--stream-auth-token <token>`,`Auth token for WebSocket streaming`).option(`--stream-events <list>`,`Comma-separated stream events: start,text,progress,done,error`).option(`--timeout <ms>`,`Execution timeout in milliseconds (default: 600000)`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--plugins-config <path>`,`Plugins config file path`).option(`--resume-request-id <id>`,`Resume a pending HITL request from aimax run`).option(`--resume-input-json <json>`,`Structured HITL resume payload used with --resume-request-id`).option(`--resume-from-file <path>`,`Load structured HITL resume payload from a file (alternative to --resume-input-json)`).option(`--encrypt-sessions`,`Enable AES-GCM session data encryption at rest`).option(`--session-encryption-key <secret>`,`Primary secret used to derive the active AES-GCM session key`).option(`--session-legacy-keys <list>`,`Comma-separated legacy session secrets kept for decrypting older encrypted data`).action(async e=>{await sn(e)})}function un(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||(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?_(r.sessionStore):void 0;if(i===`list`){De(await g(r.dataDir,r.channel,{storeName:e}),a);return}if(r.sessionId||(E(`error: required option '-s, --session-id <id>' not specified`),process.exit(1)),i===`inspect`){Oe(await m(r.dataDir,r.sessionId,{storeName:e}),a);return}if(i===`export`){ke(await c(r.dataDir,r.sessionId,{storeName:e}),a);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 dn(e){return x.join(e,`workspace`)}function fn(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function pn(e,t){let n=[];n.push(`backend: ${e.backend}`),n.push(`provider: ${e.provider}${e.model?` (${e.model})`:``}`);let r=typeof e.custom?.providerSource==`string`?e.custom.providerSource:void 0,i=typeof e.custom?.providerId==`string`?e.custom.providerId:void 0,a=typeof e.custom?.pluginId==`string`?e.custom.pluginId:void 0;r&&n.push(`provider_source: ${r}`),i&&n.push(`provider_id: ${i}`),a&&n.push(`plugin_id: ${a}`),typeof e.files==`number`&&n.push(`files: ${e.files}`),typeof e.chunks==`number`&&n.push(`chunks: ${e.chunks}`),typeof e.dirty==`boolean`&&n.push(`dirty: ${e.dirty}`),e.dbPath&&n.push(`db: ${e.dbPath}`),e.sources?.length&&n.push(`sources: ${e.sources.join(`, `)}`),t&&(e.fts&&(n.push(`fts: enabled=${e.fts.enabled} available=${e.fts.available}`),e.fts.error&&n.push(`fts_error: ${e.fts.error}`)),e.vector&&(n.push(`vector: enabled=${e.vector.enabled} available=${e.vector.available??`unknown`}`),e.vector.dims&&n.push(`vector_dims: ${e.vector.dims}`),e.vector.loadError&&n.push(`vector_error: ${e.vector.loadError}`)),e.cache&&n.push(`cache: enabled=${e.cache.enabled} entries=${e.cache.entries??0}`));let o=Array.isArray(e.custom?.cliWarnings)?e.custom.cliWarnings.filter(e=>typeof e==`string`&&e.length>0):[];for(let e of o)n.push(`warning: ${e}`);return n.join(`
9
+ `)}function mn(e){let t=e.level===`error`?`plugin error`:`plugin warning`;return e.pluginId?`${t} (${e.pluginId}): ${e.message}`:`${t}: ${e.message}`}function hn(e){if(!e||e===`cli`)return`cli`;if(e===`cron`)return`cron`;throw Error(`Unsupported dream trigger: ${e}. Expected "cli" or "cron".`)}async function gn(e){let t=[],n;try{n=await k(e.dataDir,e.pluginsConfig)}catch(e){t.push(`failed to load plugins config: ${e.message}`)}if(!e.shouldInitialize&&!n)return{warnings:t};try{let r=p({config:n,dataDir:e.dataDir,workspaceDir:dn(e.dataDir),bundledDir:fn()});return t.push(...r.diagnostics.map(mn)),{pluginSystem:r,warnings:t}}catch(e){return t.push(`failed to initialize plugin system: ${e.message}`),{warnings:t}}}async function Z(e){let t=x.join(e.dataDir,`.aimax`),{pluginSystem:n,warnings:r}=await gn({dataDir:e.dataDir,pluginsConfig:e.pluginsConfig,shouldInitialize:!!(e.requirePluginSystem||e.provider||e.providerPlugin)}),i=n?.normalizedConfig.slots.memory,o=e.providerPlugin?.trim()||(e.provider?void 0:i),s=ae({providerId:e.provider,pluginId:o,dataDir:e.dataDir,memoryDir:t});return s?{provider:s.provider,providerId:s.registration.id,pluginId:s.registration.pluginId,providerOrigin:`plugin`,warnings:r,pluginSystem:n}:((o||e.provider)&&r.push(`requested memory provider was not resolved; falling back to builtin provider`),{provider:a({dataDir:e.dataDir,memoryDir:t},{includeSessions:e.includeSessions}),providerId:`builtin`,providerOrigin:`builtin`,warnings:r,pluginSystem:n})}function _n(e,t,n){let r={...e.custom??{},providerSource:t.providerOrigin,providerId:t.providerId,pluginId:t.pluginId,cliWarnings:t.warnings},i={...e,custom:r};return n&&t.providerOrigin===`plugin`?i.custom={...r,note:`deep probe details are provider-defined for plugin memory providers`}:n&&(i.custom={...r,note:`deep probe is only supported by builtin provider`}),i}function vn(e){let t=e.command(`memory`).description(`Manage semantic memory indexing and search`),n=e=>e.option(`--plugins-config <path>`,`Plugins config file path`);n(t.command(`status`)).description(`Show memory index status`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--deep`,`Probe embedding/vector availability`).option(`--index`,`Run a refresh before reporting status`).option(`--include-sessions`,`Include session transcripts in indexing`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--verbose`,`Verbose output`).option(`--output <format>`,`Output format: text (default) or json`,`text`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{let n=await Z({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,pluginsConfig:e.pluginsConfig,includeSessions:e.includeSessions});e.index&&n.provider.sync&&await n.provider.sync(`cli-status`);let r=_n(n.provider.status(),n,e.deep);T(t===`json`?JSON.stringify(r,null,2):pn(r,e.deep))}catch(e){E(`Error getting memory status: ${e.message}`),process.exit(1)}}),n(t.command(`index`)).description(`Reindex memory files`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--include-sessions`,`Include session transcripts in indexing`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--rebuild`,`Force full rebuild from Markdown source`).option(`--verbose`,`Verbose output`).action(async e=>{try{let t=await Z({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,pluginsConfig:e.pluginsConfig,includeSessions:e.includeSessions}),n;if(t.provider.sync&&(await t.provider.sync(e.rebuild?`cli-rebuild`:`cli-index`),n=t.provider.status().custom?.lastRebuildSummary),t.warnings.length>0)for(let e of t.warnings)E(`Warning: ${e}`);e.verbose&&n&&T(JSON.stringify(n,null,2)),T(e.rebuild?`Memory index rebuilt.`:`Memory index refreshed.`)}catch(e){E(`Error indexing memory: ${e.message}`),process.exit(1)}}),n(t.command(`search [query]`)).description(`Search semantic memory`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--query <text>`,`Search query`).option(`--include-sessions`,`Include session transcripts in search`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--output <format>`,`Output format: text (default) or json`,`text`).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(await Z({dataDir:t.dataDir,provider:t.provider,providerPlugin:t.providerPlugin,pluginsConfig:t.pluginsConfig,includeSessions:t.includeSessions})).provider.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(`
10
+ `))}catch(e){E(`Error searching memory: ${e.message}`),process.exit(1)}}),n(t.command(`dream`)).description(`Trigger Dream Gate host hook for memory plugins`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--trigger <mode>`,`Dream Gate trigger mode: cli (default) or cron`,`cli`).option(`--dry-run`,`Return hook results without plugin-side mutation`).option(`--output <format>`,`Output format: text (default) or json`,`text`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{let n=hn(e.trigger),r=await Z({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,pluginsConfig:e.pluginsConfig,requirePluginSystem:!0}),i=r.pluginSystem?await r.pluginSystem.registry.hooks.dispatch(`dream_gate`,{dataDir:e.dataDir,memoryDir:x.join(e.dataDir,`.aimax`),providerId:r.providerId,pluginId:r.pluginId,trigger:n,dryRun:!!e.dryRun},{workspaceDir:dn(e.dataDir)}):[],a={ok:!0,trigger:n,providerSource:r.providerOrigin,providerId:r.providerId,pluginId:r.pluginId,resultCount:i.length,results:i,warnings:r.warnings};if(t===`json`){T(JSON.stringify(a,null,2));return}T(`trigger: ${a.trigger}`),T(`provider_source: ${a.providerSource}`),T(`provider_id: ${a.providerId}`),a.pluginId&&T(`plugin_id: ${a.pluginId}`),T(`result_count: ${a.resultCount}`),a.results.length===0?T(`note: no dream_gate hook registered`):T(`results: ${JSON.stringify(a.results)}`);for(let e of a.warnings)T(`warning: ${e}`)}catch(e){E(`Error running dream gate: ${e.message}`),process.exit(1)}})}function yn(e){return`${e.match.accountId?`${e.match.channel}:${e.match.accountId}`:e.match.channel} -> ${e.agentId}`}function bn(e){return async t=>{let n=await C(t),r=ye(n),i=be(n);if(w(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=we(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(` - ${yn(e)}`)}}}}function xn(e,t){return async n=>{S(await C(n),xe(e))&&(console.error(`Agent "${e}" already exists.`),process.exit(1)),await _e(n,{id:e,name:t.name,model:t.model,default:t.default})||(console.error(`Agent "${e}" already exists.`),process.exit(1));let r=we(n,e);console.log(`Agent "${e}" added successfully.`),console.log(` Agent dir: ${r}`)}}function Sn(e){return async t=>{let n=S(await C(t),xe(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 Se(t,e)||(console.error(`Failed to delete agent "${e}".`),process.exit(1)),console.log(`Agent "${e}" deleted.`)}}function Cn(e){return async t=>{let n=await C(t),r=e.agent??w(n);S(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 ve(t,{agentId:r,match:{channel:e,accountId:a||void 0}}),console.log(`Binding added: ${n} -> ${r}`)}}}function wn(e){return async t=>{let n=await C(t),r=e.agent??w(n);if(S(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),e.all){let e=await Ce(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 Ce(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 Tn(e){return async t=>{let n=be(await C(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(` ${yn(e)}`)}}function En(e){return async t=>{let n=await C(t),r=e.agent??w(n);S(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),await Te(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 Dn(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 bn(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 xn(e,n)(r)}),n.command(`delete <id>`).description(`Delete an agent`).action(async e=>{let n=t();await Sn(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 Cn(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 wn(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 Tn(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 En(e)(n)})}function Q(e){return x.join(e,`workspace`)}function $(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function On(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 kn(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 An(e){return Array.from(new Set((e??[]).map(e=>e.trim()).filter(Boolean)))}function jn(e){if(e.length===0){T(`LLM allowlist is empty.`);return}for(let t of e)T(t)}function Mn(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();On(p({config:await k(n,e.pluginsConfig),dataDir:n,workspaceDir:Q(n),bundledDir:$()}).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=p({config:await k(r,n.pluginsConfig),dataDir:r,workspaceDir:Q(r),bundledDir:$()}).registry.plugins.find(t=>t.id===e);i||(E(`Plugin not found: ${e}`),process.exit(1)),kn(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 k(r,n.pluginsConfig)??{},a=ie(i);p({config:i,dataDir:r,workspaceDir:Q(r),bundledDir:$()}).registry.plugins.some(t=>t.id===e)||(E(`Plugin not found: ${e}`),process.exit(1)),await A(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 k(r,n.pluginsConfig)??{};p({config:i,dataDir:r,workspaceDir:Q(r),bundledDir:$()}).registry.plugins.some(t=>t.id===e)||(E(`Plugin not found: ${e}`),process.exit(1)),await A(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=p({config:await k(n,e.pluginsConfig),dataDir:n,workspaceDir:Q(n),bundledDir:$()});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=>{jn(An((await k(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 k(r,n.pluginsConfig)??{},a=An([...i.llmAllowlist??[],...e]);await A(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 k(r,n.pluginsConfig)??{},a=new Set(e.map(e=>e.trim()).filter(Boolean)),o=An(i.llmAllowlist).filter(e=>!a.has(e));await A(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 A(n,{...await k(n,e.pluginsConfig)??{},llmAllowlist:[]},e.pluginsConfig),T(`LLM allowlist cleared.`)})}function Nn(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=h(await ne(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 Pn=[`progress`,`error`,`hitl`];function Fn(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 In(e){if(!e?.trim())return new Set(Pn);let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean),n=new Set([`start`,`text`,`progress`,`done`,`error`,`hitl`,`title_updated`]),r=new Set;for(let e of t){if(!n.has(e))throw Error(`Invalid stream event: ${e}. Must be one of start,text,progress,done,error,hitl`);r.add(e)}return r.size>0?r:new Set(Pn)}function Ln(e){return e?_(e):void 0}function Rn(e){let t=[];return e.callbackUrl&&t.push(new B(e.callbackUrl)),e.streamUrl&&t.push(new U(e.streamUrl,In(e.streamEvents),e.streamAuthToken)),new z(t)}async function zn(e){I(Fn(e));let t=new R(`cancel command`),n=Fn(e),r=e.channel??`WEB`,i=e.output===`json`?`json`:`text`,a=Rn(e),o=Ln(e.sessionStore);try{let s=await ee(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 oe({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}),L.error(`cancel command error: ${i.message}`),E(`Fatal: ${i.message}`),t.end(),process.exit(1)}finally{await a.close()}}function Bn(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 zn(e)})}function Vn(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 Hn(e){return e.query?.trim()||void 0}function Un(e){if(!e)return;let t=Number(e);if(!Number.isFinite(t)||t<=0)throw Error(`--timeout must be a positive number of milliseconds`);return t}function Wn(e){if(!e)return;let t=Number(e);if(!Number.isInteger(t)||t<=0)throw Error(`--max-tokens must be a positive integer`);return t}async function Gn(e){if(e.filePath){if(!x.isAbsolute(e.filePath))throw Error(`--file-path must be an absolute path`);try{await b.access(e.filePath)}catch(e){throw Error(`Failed to access --file-path: ${e.message}`)}return{source:`file`,filePath:e.filePath}}let t=e.content;if(!t||!t.trim())throw Error(`Either --file-path or --content must be provided`);return{source:`content`,content:t}}async function Kn(e){let t=null;try{let n=Vn(e);I(n),t=new R(`summarize command`);let r=Hn(e),i=await Gn(e),a=Pe({baseUrl:e.baseUrl,apiKey:e.apiKey,model:e.model,contextWindow:2e5}),o=Un(e.timeout),s=Wn(e.maxTokens);L.info(`summarize command started`,{dataDir:n,source:i.source,filePath:i.source===`file`?i.filePath:void 0,queryLength:r?.length,contentLength:i.source===`content`?i.content.length:void 0,timeoutMs:o,maxTokens:s});let c=await v({dataDir:n,channel:`WEB`,message:qn(i,r),llm:{...a,maxTokens:s},timeoutMs:o});T(c.text.trim()),L.info(`summarize command succeeded`,{source:i.source,summaryLength:c.text.length,durationMs:c.durationMs}),t.end()}catch(e){L.error(`summarize command error: ${e.message}`),E(`Fatal: ${e.message}`),t?.end(),process.exit(1)}}function qn(e,t){return e.source===`file`?[t?`Summarize exactly one file for the query below.`:`Summarize exactly one file.`,`Read only the absolute file path provided here. Do not search, browse, read other files, execute commands, modify files, or perform any other processing.`,`Return only the summary text.`,``,...t?[`Query:\n${t}`,``]:[],`Input source: file`,`File path: ${e.filePath}`].join(`
11
+ `):[t?`Summarize the provided content for the query below.`:`Summarize the provided content.`,t?`Use only the provided content and query. Do not search, browse, read files, execute commands, modify files, or perform any other processing.`:`Use only the provided content. Do not search, browse, read files, execute commands, modify files, or perform any other processing.`,`Return only the summary text.`,``,...t?[`Query:\n${t}`,``]:[],`Input source: content`,`Source content:`,`<source>`,e.content,`</source>`].join(`
12
+ `)}function Jn(e){e.command(`summarize`).description(`Summarize one absolute file path or inline content`).option(`--file-path <path>`,`Absolute file path to summarize`).option(`--content <text>`,`Inline text content to summarize when --file-path is not provided`).option(`--query <text>`,`Optional search target or current description to focus the summary`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY)`).option(`--model <name>`,`LLM model name (overrides AIMAX_MODEL)`).option(`--timeout <ms>`,`Execution timeout in milliseconds`).option(`--max-tokens <number>`,`Maximum number of tokens for model output`).action(async e=>{await Kn(e)})}const Yn=e(import.meta.url)(`../package.json`);function Xn(){return process.env.AIMAX_DATA_DIR||process.cwd()}function Zn(){let e=new t;return e.name(`aimax`).description(`AIMax CLI — runs agent tasks in a containerized environment`).version(Yn.version),ln(e),Tt(e),Bn(e),un(e),Jn(e),Nn(e),je(e),vn(e),Dn(e,Xn),Mn(e,Xn),e}export{et as a,L as i,Xn as n,I as r,Zn as t};
package/dist/program.js CHANGED
@@ -1 +1 @@
1
- import{n as e,t}from"./program-BFeRbTb8.js";export{t as createProgram,e as getDataDir};
1
+ import{n as e,t}from"./program-BaCtsPfO.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.4.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "aimax": "./dist/bin.js"
@@ -22,7 +22,7 @@
22
22
  "commander": "^14.0.3",
23
23
  "gensign-node": "latest",
24
24
  "log4js": "^6.9.1",
25
- "@gencode/agents": "0.5.0",
25
+ "@gencode/agents": "0.6.0",
26
26
  "@gencode/shared": "0.1.2"
27
27
  },
28
28
  "devDependencies": {
@@ -1,12 +0,0 @@
1
- import{createRequire as e}from"node:module";import{Command as t}from"commander";import{bootstrapMountLayout as n,buildResumeNarration as r,clearPendingUiTool as i,createBuiltinMemoryProvider as a,ensureBootstrapMountLayout as o,exportSession as s,formatApprovalResolution as c,formatClarifyResolution as l,formatReviewResolution as u,hasBootstrapSentinel as d,initializePluginSystem as f,inspectSession as p,listAvailableSlashCommands as m,listSessionSummaries as h,loadPendingHitl as g,loadPendingUiTool as ee,loadSkillsWithPluginDirs as te,loadTranscript as ne,normalizePluginsConfig as re,normalizeSessionStoreName as _,resolveMemoryProvider as ie,resolvePendingHitl as ae,resolvePendingUiTool as oe,rewriteTranscript as se,runAgent as v}from"@gencode/agents";import{formatTaskForDisplay as ce,isAgentDiagnosticEvent as y,isHitlTool as le,parseMatchedTextToResolution as ue,parseTextToResolution as de}from"@gencode/shared";import b from"node:fs/promises";import x from"node:path";import fe from"gensign-node";import pe from"node:fs";import me from"log4js";import{addAgent as he,addBinding as ge,getAgentConfig as S,listAgents as _e,listBindings as ve,loadAgentsConfig as C,normalizeAgentId as ye,removeAgent as be,removeBindings as xe,resolveAgentDir as Se,resolveDefaultAgentId as w,updateAgentIdentity as Ce}from"@gencode/agents/config";function we(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`:we(e.text);break;case`stream_text_delta`:we(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}"`:``} ${ce(e.task)}`);break;case`subagent_complete`:T(`[subagent:${e.status}] ${ce(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;case`ui_tool_request`:T(`\n[ui-tool:${e.request.toolName}] ${e.request.outputSchema.title}`),T(` requestId: ${e.request.requestId}`),T(` toolCallId: ${e.request.toolCallId}`);break;case`ui_tool_result`:T(`\n[ui-tool:resumed] requestId=${e.requestId} tool=${e.toolName}`);break}}function O(e,t){if(t===`json`){e&&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 Te(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 Ee(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 De(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 Oe(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 ke(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{Oe(await n(e.dataDir),t)}catch(e){E(`Error bootstrapping data directory: ${e.message}`),process.exit(1)}})}function Ae(e){return fe.sm4_encrypt_ecb(e)}function je(e){return Ae(e)}function k(e={}){let t=e.baseUrl??process.env.AIMAX_BASE_URL,n=process.env.AIMAX_AUTH_TOKEN,r=e.authToken?je(e.authToken):n?je(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 Me(e,t){return t?x.resolve(t):x.join(e,`.aimax`,`plugins.json`)}async function A(e,t){let n=Me(e,t);try{let e=await b.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=Me(e,n);await b.mkdir(x.dirname(r),{recursive:!0}),await b.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 Ne(e){return M(e)&&e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`}function Pe(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 Fe(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 Ie(e){return typeof e==`string`||Array.isArray(e)&&e.every(e=>N(e)||Ne(e))}function Le(e){return Array.isArray(e)&&e.every(e=>N(e)||Pe(e)||Fe(e))}function Re(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 ze(e){return!M(e)||typeof e.role!=`string`?!1:e.role===`user`?Ie(e.content):e.role===`assistant`?Le(e.content)&&typeof e.api==`string`&&typeof e.provider==`string`&&typeof e.model==`string`&&Re(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)||Ne(e))&&typeof e.isError==`boolean`:!1}async function Be(e){let t;try{t=await b.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=>ze(e)))throw Error(`Message file must contain one Message object or an array of Message objects`);return r}async function Ve(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 Be(e.fromFile)}:{kind:`text`,message:e.message}}function He(e){let t=new Intl.DateTimeFormat(`en-CA`,{timeZone:`Asia/Shanghai`,year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1}).formatToParts(e);return Object.fromEntries(t.map(e=>[e.type,e.value]))}function Ue(e=new Date){let t=He(e),n=String(e.getMilliseconds()).padStart(3,`0`);return`${t.year}-${t.month}-${t.day} ${t.hour}:${t.minute}:${t.second}.${n}`}let P=function(e){return e.INFO=`INFO`,e.ERROR=`ERROR`,e.WARN=`WARN`,e}({}),F=null;function We(){return Ue()}function Ge(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 Ke(e){return x.join(e,`.aimax`)}function qe(e){return{appLogPath:x.join(e,`app.log`),errorLogPath:x.join(e,`errors.log`)}}function Je(e){let{appLogPath:t,errorLogPath:n}=qe(e);me.configure({appenders:{appFile:{type:`file`,filename:t,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`messagePassThrough`}},errorFile:{type:`file`,filename:n,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`messagePassThrough`}},errorsOnly:{type:`logLevelFilter`,appender:`errorFile`,level:`error`,maxLevel:`fatal`}},categories:{default:{appenders:[`appFile`,`errorsOnly`],level:`info`}}})}function Ye(e,t,n){return`[${We()}] [${e}] ${t}${Ge(n)}`}function Xe(e,t,n){process.stderr.write(`${Ye(e,t,n)}\n`)}function I(e,t,n){if(!F){Xe(e,t,n);return}let r=Ye(e,t,n),i=me.getLogger();if(e===P.ERROR){i.error(r);return}if(e===P.WARN){i.warn(r);return}i.info(r)}function L(e){let t=Ke(e);F?.dataDir!==e&&(pe.mkdirSync(t,{recursive:!0}),Je(t),F={dataDir:e,logDir:t})}async function Ze(){await me.shutdown()}const R={info:(e,t)=>I(P.INFO,e,t),warn:(e,t)=>I(P.WARN,e,t),error:(e,t)=>I(P.ERROR,e,t)};var z=class{startTime;name;constructor(e){this.name=e,this.startTime=Date.now()}end(){let e=Date.now()-this.startTime;return R.info(`${this.name} completed in ${e}ms`),e}},B=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()}))}},V=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=Qe(e);R.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 R.error(`callback event failed`,{callbackUrl:this.url,httpStatus:r.status,durationMs:i,...n}),Error(`Callback failed with status ${r.status}`);R.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 Qe(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 $e(e,t){if(t.kind===`none`)return e;let n=new URL(e);return n.searchParams.set(`authToken`,t.token),n.toString()}function H(){let e=globalThis.WebSocket;if(!e)throw Error(`WebSocket is not available in this runtime`);return e}function et(e){return e?{kind:`query_token`,token:e}:{kind:`none`}}function U(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 tt(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 W=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=H();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){R.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=H();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){R.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=H();e.readyState!==t.CLOSED&&await new Promise(t=>{U(e,`close`,()=>t()),e.close()})}async ensureConnected(){if(!this.enabled)return;let e=H();if(this.socket&&this.socket.readyState===e.OPEN)return;if(this.connectPromise){await this.connectPromise;return}let t=new e($e(this.url,et(this.authToken)));this.connectPromise=new Promise((e,n)=>{U(t,`open`,()=>{this.socket=t,tt(t,`close`,()=>{this.socket===t&&(this.socket=null)}),e()}),U(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 nt=[`start`,`text`,`done`,`error`,`hitl`];function rt(e){if(!e?.trim())return new Set(nt);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(nt)}function it(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 at(e){return e?.trim()||void 0}function ot(e){return e?_(e):void 0}function st(e){if(!e?.trim())return[];let t=e.split(`,`).map(e=>e.trim()).filter(Boolean),n=new Set,r=[];for(let e of t){if(!x.isAbsolute(e))throw Error(`Invalid --skillsLoadPaths entry: ${e}. Each path must be absolute.`);n.has(e)||(n.add(e),r.push(e))}return r}function ct(e,t){if(e.inputText&&t){let n=de(e.inputText,t);return n.submittedBy={userId:e.user,channel:e.channel??`IM`},n}if(!e.inputJson&&!e.inputText)throw Error(`Either --input-json or --input-text must be provided for the resume command`);try{let t=JSON.parse(e.inputJson);return{requestId:e.requestId,sessionId:e.sessionId,action:t.action??`submit`,values:t.values,submittedBy:t.submittedBy,idempotencyKey:t.idempotencyKey,submittedAt:t.submittedAt??new Date().toISOString()}}catch(e){throw Error(`Invalid --input-json: ${e.message}`)}}function lt(e,t){if(!e.inputJson)throw Error(`UI tool resume requires --input-json`);try{let n=JSON.parse(e.inputJson),r=n&&typeof n==`object`&&`values`in n&&n.values&&typeof n.values==`object`&&!Array.isArray(n.values)?n.values:n;return{requestId:t.request.requestId,sessionId:t.sessionId,toolCallId:t.request.toolCallId,toolName:t.request.toolName,values:r,submittedAt:new Date().toISOString()}}catch(e){throw Error(`Invalid --input-json: ${e.message}`)}}async function ut(e){let t=await ne(e.dataDir,e.sessionId,{storeName:e.sessionStoreName});for(let n=t.length-1;n>=0;--n){let r=t[n];if(r?.role!==`assistant`||!Array.isArray(r.toolCalls))continue;let i=r.toolCalls.find(t=>t.id===e.toolCallId&&t.name===e.toolName);if(i)return i.arguments}}async function dt(e){let t=it(e),n=e.channel??`WEB`,r=k({baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel});return{dataDir:t,channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,skillsLoadPaths:st(e.skillsLoadPaths)}}function ft(e){let t=[],n=null;return e.callbackUrl&&t.push(new V(e.callbackUrl)),e.streamUrl&&(n=new W(e.streamUrl,rt(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new B(t),websocketSink:n}}async function pt(e){let{dataDir:t,sessionId:n,sessionStoreName:r,toolCallId:i,toolName:a,resolution:o}=e;if(!i||!a||!le(a))return;let s=(e,t)=>{switch(e){case`request_approval`:return c(t);case`clarify`:return l(t);case`request_review`:return u(t);default:return JSON.stringify({action:t.action,values:t.values})}};await se(t,n,e=>{let t=e.findIndex(e=>e.role===`tool_result`&&e.toolCallId===i&&e.toolName===a);if(t===-1)return e;let n=e.slice(0,t+1);return n[t]={...n[t],content:s(a,o),isError:!1},n},{storeName:r})}async function mt(e){let{dataDir:t,sessionId:n,sessionStoreName:r,result:i}=e;await se(t,n,e=>{let t=e.findIndex(e=>e.role===`assistant`&&Array.isArray(e.toolCalls)&&e.toolCalls.some(e=>e.id===i.toolCallId&&e.name===i.toolName));if(t===-1)return e;let n=e.slice(0,t+1);return n.push({role:`tool_result`,toolCallId:i.toolCallId,toolName:i.toolName,content:JSON.stringify({submitted:!0,values:i.values}),isError:!1,timestamp:i.submittedAt}),n},{storeName:r})}async function G(e){L(it(e));let t=new z(`resume command`),n=null;try{let r=await dt(e),a=ot(e.sessionStore);R.info(`resume command started`,{sessionId:e.sessionId,requestId:e.requestId,channel:r.channel,dataDir:r.dataDir});let o=await g(r.dataDir,e.sessionId,{storeName:a}),s=o?null:await ee(r.dataDir,e.sessionId,{storeName:a});if(!o&&!s)throw Error(`No pending HITL or UI tool request found for session "${e.sessionId}"`);if(o){if(o.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${o.request.requestId}", got "${e.requestId}"`);if(o.status===`expired`)throw Error(`HITL request has expired`);if(o.status===`cancelled`)throw Error(`HITL request has been cancelled`)}else if(s){if(s.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${s.request.requestId}", got "${e.requestId}"`);if(s.status!==`pending`)throw Error(`UI tool request is already "${s.status}", cannot resume`)}if(o){let i=ct(e,o.request),s=await ae({dataDir:r.dataDir,sessionStoreName:a,sessionId:e.sessionId,requestId:e.requestId,resolution:i}),c=s.state;if(!c)throw Error(`Resolved HITL state was not persisted`);let l=ht(i,c.request.kind);await pt({dataDir:r.dataDir,sessionId:e.sessionId,sessionStoreName:a,toolCallId:c.toolContext?.toolCallId,toolName:c.toolContext?.toolName,resolution:i});let u=ft(e);n=u.sink;let d=e.sessionId,f=async t=>{if(d=t.sessionId??d,!y(t)){if(t.type===`stream_text_delta`){r.format===`text`&&D(t),await u.websocketSink?.sendTextDelta({sessionId:d,channel:r.channel,messageId:e.messageId,user:e.user,text:t.text});return}r.format===`text`&&D(t),await n?.send({sessionId:d,channel:r.channel,messageId:e.messageId,user:e.user,type:`progress`,event:t})}};await f({type:`hitl_resumed`,requestId:e.requestId,resolution:i,sessionId:e.sessionId}),`idempotentReplay`in s&&s.idempotentReplay&&(R.info(`resume command treated as idempotent replay`,{sessionId:e.sessionId,requestId:e.requestId,idempotencyKey:i.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 v({dataDir:r.dataDir,projectDir:at(e.projectDir),sessionStoreName:a,sessionId:e.sessionId,messageId:e.messageId,channel:r.channel,llm:r.llm,skillsLoadPaths:r.skillsLoadPaths,timeoutMs:r.timeoutMs,message:l,hitlResume:{request:c.request,resolution:i,checkpoint:c.checkpoint,toolContext:c.toolContext},plugins:m?{config:m,dataDir:r.dataDir,workspaceDir:x.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,uiToolPending:h.uiToolPending}}),O(h,r.format),h.error?R.error(`resume command failed: ${h.error}`):R.info(`resume command succeeded`),t.end(),process.exit(h.error?1:0);return}let c=lt(e,s);if(!await oe(r.dataDir,e.sessionId,e.requestId,c,{storeName:a}))throw Error(`UI tool resume validation failed`);await mt({dataDir:r.dataDir,sessionId:e.sessionId,sessionStoreName:a,result:c});let l=ft(e);n=l.sink;let u=e.sessionId,d=async t=>{if(u=t.sessionId??u,!y(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===`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})}},f=await ut({dataDir:r.dataDir,sessionId:e.sessionId,sessionStoreName:a,toolCallId:c.toolCallId,toolName:c.toolName});await d({type:`tool_end`,sessionId:e.sessionId,toolCallId:c.toolCallId,name:c.toolName,input:f,output:JSON.stringify({submitted:!0,values:c.values}),isError:!1});let p=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,m=await A(r.dataDir,p),h=await v({dataDir:r.dataDir,projectDir:at(e.projectDir),sessionStoreName:a,sessionId:e.sessionId,messageId:e.messageId,channel:r.channel,llm:r.llm,skillsLoadPaths:r.skillsLoadPaths,timeoutMs:r.timeoutMs,message:`[UI_TOOL_RESUME]
5
- The pending UI tool result has been written into the transcript. Continue from the latest tool result without repeating the same form request.`,uiToolResume:c,plugins:m?{config:m,dataDir:r.dataDir,workspaceDir:x.join(r.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:m.llmAllowlist}:void 0,onProgress:d});await i(r.dataDir,e.sessionId,{storeName:a}),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,uiToolPending:h.uiToolPending}}),O(h,r.format),h.error?R.error(`resume command failed: ${h.error}`):R.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}`})),R.error(`resume command error: ${i.message}`),E(`Fatal: ${i.message}`),t.end(),process.exit(1)}finally{await n?.close()}}function ht(e,t){return r(e,t)}function gt(e){e.command(`resume`).description(`Resume a paused HITL session with user input`).requiredOption(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--project-dir <path>`,`Current project directory used as the default cwd context`).requiredOption(`-s, --session-id <id>`,`Session ID to resume`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).requiredOption(`--request-id <id>`,`HITL request ID to resolve`).option(`--input-json <json>`,`JSON string with the resolution (action, values, etc.)`).option(`--input-text <text>`,`Plain text response for IM channels without rich UI (e.g. '同意', '拒绝')`).option(`--skillsLoadPaths <paths>`,`Comma-separated absolute skill load paths`).option(`--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 G(e)})}const _t=[`start`,`text`,`done`,`error`];function vt(e){if(!e?.trim())return new Set(_t);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(_t)}function K(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir option or AIMAX_DATA_DIR environment variable`);return t}function q(e){return e?.trim()||void 0}function J(e){return e?.trim()||void 0}function yt(e){return e??`WEB`}function bt(e){return e?_(e):void 0}function xt(e){if(!e?.trim())return[];let t=e.split(`,`).map(e=>e.trim()).filter(Boolean),n=new Set,r=[];for(let e of t){if(!x.isAbsolute(e))throw Error(`Invalid --skillsLoadPaths entry: ${e}. Each path must be absolute.`);n.has(e)||(n.add(e),r.push(e))}return r}function St(e,t){return e.length<=t?e:t<=3?e.slice(0,t):`${e.slice(0,t-3)}...`}function Ct(e,t,n=78){let r=n-2,i=r-2,a=e?` ${St(e,Math.max(0,i-2))} `:``,o=e?`┌${a}${`─`.repeat(Math.max(0,r-a.length))}┐`:`┌${`─`.repeat(r)}┐`,s=`└${`─`.repeat(r)}┘`;return[o,...t.map(e=>`│ ${St(e,i).padEnd(i,` `)} │`),s].join(`
6
- `)}function wt(e){return e.kind===`text`?`inline message (${e.message.length} chars)`:`message file (${e.messages.length} messages)`}function Tt(e,t){let n=bt(e.sessionStore)??`sessions`,r=t.timeoutMs===void 0?`default`:`${t.timeoutMs}`,i=e.callbackUrl?`enabled`:`disabled`,a=e.streamUrl?`enabled`:`disabled`,o=wt(t.input),s=t.input.kind===`text`?`inline`:e.fromFile??`file`,c=Ue();return{banner:Ct(void 0,[`AIMax CLI`,`Stateless Agent Runner`]),contextBox:Ct(`Run Context`,[`time : ${c}`,`channel : ${t.channel}`,`user : ${e.user??`-`}`,`sessionId : ${e.sessionId??`new`}`,`sessionStore : ${n}`,`messageId : ${e.messageId??`-`}`,`dataDir : ${t.dataDir}`,`workspace : ${x.join(t.dataDir,`workspace`)}`,`projectDir : ${q(e.projectDir)??`-`}`,`agent : ${J(e.agent)??`-`}`,`output : ${t.format}`,`callback : ${i}`,`websocket : ${a}`,`timeoutMs : ${r}`,`input : ${o}`]),logContext:{time:c,channel:t.channel,user:e.user,dataDir:t.dataDir,projectDir:q(e.projectDir),agent:J(e.agent),workspaceDir:x.join(t.dataDir,`workspace`),sessionId:e.sessionId??`new`,sessionStore:n,messageId:e.messageId,output:t.format,hasCallback:!!e.callbackUrl,hasStream:!!e.streamUrl,timeoutMs:t.timeoutMs,inputKind:t.input.kind,inputSource:s,inputSummary:o}}}async function Et(e,t){let n=K(e),r=yt(e.channel),i=k({baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel});return{dataDir:n,channel:r,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:i,input:t,skillsLoadPaths:xt(e.skillsLoadPaths)}}function Dt(e){if(e.kind===`text`)return e.message;if(e.messages.length!==1)return null;let[t]=e.messages;if(t.role!==`user`)return null;if(typeof t.content==`string`)return t.content;if(t.content.length===0)return null;let n=[];for(let e of t.content){if(e.type!==`text`)return null;n.push(e.text)}return n.join(`
7
- `)}async function Ot(e,t){if(!e.sessionId)return null;let n=Dt(t);if(!n)return null;let r=await g(K(e),e.sessionId,{storeName:bt(e.sessionStore)});return!r||r.status!==`pending`||!ue(n,r.request)?null:{requestId:r.request.requestId,inputText:n}}function kt(e){let t=[],n=null;return e.callbackUrl&&t.push(new V(e.callbackUrl)),e.streamUrl&&(n=new W(e.streamUrl,vt(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new B(t),websocketSink:n}}async function Y(e,t){R.info(`dispatching external event`,qt(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 jt(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`){R.error(e.message,t);return}if(e.level===`warn`){R.warn(e.message,t);return}R.info(e.message,t)}function Mt(e,t,n,r,i){return{sink:e,websocketSink:t,channel:n,defaultMessageId:r,user:i}}function Nt(){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 Pt(e){return{activeSessionId:e??`pending`,finalResult:null}}function Ft(e,t){e.activeSessionId=t.sessionId??e.activeSessionId}function It(e,t){return e.messageId??t}async function Lt(e,t,n){if(!await d(e.dataDir)){if(await X(t,e.format,n.activeSessionId,e.dataDir,`checking`),(await o(e.dataDir)).performedBootstrap){await X(t,e.format,n.activeSessionId,e.dataDir,`initializing`),await X(t,e.format,n.activeSessionId,e.dataDir,`initialized`);return}await X(t,e.format,n.activeSessionId,e.dataDir,`ready`)}}async function X(e,t,n,r,i){let a={type:`bootstrap`,phase:i,dataDir:r};t===`text`&&D(a),await Y(e,{sessionId:n,channel:e.channel,messageId:e.defaultMessageId,user:e.user,type:`progress`,event:a})}function Rt(e,t,n){return async r=>{if(Ft(n,r),y(r)){jt(r);return}if(r.type===`stream_text_delta`){e.format===`text`&&D(r),await t.websocketSink?.sendTextDelta({sessionId:n.activeSessionId,channel:e.channel,messageId:It(r,t.defaultMessageId),user:t.user,text:r.text});return}e.format===`text`&&D(r);let i=It(r,t.defaultMessageId);if(r.type===`hitl_requested`){await Y(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`hitl`,request:r.request}),await Y(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r});return}if(r.type===`start`){await Y(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`start`,message:r.message});return}if(r.type===`session_reset`){await Y(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 Y(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r})}}function zt(e,t,n,r,i){let a={dataDir:t.dataDir,projectDir:q(e.projectDir),agentPolicy:J(e.agent)?{requestedAgentName:J(e.agent)}:void 0,sessionStoreName:bt(e.sessionStore),sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,timeoutMs:t.timeoutMs,abortSignal:n.signal,encryptSessions:e.encryptSessions??!1,plugins:i?{config:i,dataDir:t.dataDir,workspaceDir:x.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 Bt(e,t,n,r){if(t.activeSessionId=r.sessionId,t.finalResult=r,r.error){await Y(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:r.error});return}await Y(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 Vt(e,t,n,r){await Y(e,{sessionId:t.finalResult?.sessionId??t.activeSessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:`Fatal: ${r.message}`})}function Ht(e,t){let n=Tt(e,t);R.info([`run command started`,n.banner,n.contextBox].join(`
8
- `),n.logContext),t.format===`text`&&(T(n.banner),T(``),T(n.contextBox),T(``))}function Ut(e,t,n){O(t,n),t.error?R.error(`run command failed: ${t.error}`):R.info(`run command succeeded`),e.end(),process.exit(t.error?1:0)}function Wt(e,t){R.error(`run command error: ${t.message}`),E(`Fatal: ${t.message}`),e.end(),process.exit(1)}async function Gt(e){if(e.resumeInputJson&&e.resumeFromFile)throw Error(`--resume-input-json and --resume-from-file are mutually exclusive`);if(!e.resumeFromFile)return e.resumeInputJson;try{return await b.readFile(e.resumeFromFile,`utf-8`)}catch(e){throw Error(`Failed to read resume input file: ${e.message}`)}}async function Kt(e){let t=await Gt(e);if(e.resumeRequestId||t||e.resumeFromFile){if(!e.sessionId||!e.resumeRequestId||!t)throw Error(`--session-id, --resume-request-id, and exactly one of --resume-input-json or --resume-from-file must be provided together`);await G({dataDir:e.dataDir,projectDir:e.projectDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:e.resumeRequestId,inputJson:t,channel:e.channel,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow,flashModel:e.flashModel,callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamAuthToken:e.streamAuthToken,streamEvents:e.streamEvents,timeout:e.timeout,output:e.output,pluginsConfig:e.pluginsConfig,skillsLoadPaths:e.skillsLoadPaths,messageId:e.messageId,user:e.user});return}let n;try{n=await Ve({message:e.message,fromFile:e.fromFile})}catch(t){L(K(e)),Wt(new z(`run command`),t);return}let r=await Ot(e,n);if(r){await G({dataDir:e.dataDir,projectDir:e.projectDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:r.requestId,inputText:r.inputText,channel:e.channel,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow,flashModel:e.flashModel,callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamAuthToken:e.streamAuthToken,streamEvents:e.streamEvents,timeout:e.timeout,output:e.output,pluginsConfig:e.pluginsConfig,skillsLoadPaths:e.skillsLoadPaths,messageId:e.messageId,user:e.user});return}L(K(e));let i=new z(`run command`),{controller:a,cleanup:o}=Nt(),s=null,c=e.channel??`WEB`,l=Pt(e.sessionId);try{let t=await Et(e,n);c=t.channel,Ht(e,t);let r=kt(e);s=r.sink,R.info(`external sink configured`,{callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamEvents:e.streamEvents});let o=Mt(s,r.websocketSink,t.channel,e.messageId,e.user);await Lt(t,o,l);let u=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,d=await A(t.dataDir,u),f=await v(zt(e,t,a,Rt(t,o,l),d));await Bt(o,l,e.messageId,f),Ut(i,f,t.format)}catch(t){let n=t;s&&await Vt(Mt(s,null,c,e.messageId,e.user),l,e.messageId,n),Wt(i,n)}finally{await s?.close(),o()}}function qt(e){return{eventType:e.type,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,progressType:e.type===`progress`?e.event.type:void 0,textLength:e.type===`done`?e.result.text.length:void 0,hasError:e.type===`error`?!0:e.type===`done`?!!e.result.error:void 0}}function Jt(e){e.command(`run`).description(`Run an agent task`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--project-dir <path>`,`Current project directory used as the default cwd context`).option(`--agent <name>`,`Custom agent name to run as the root agent`).option(`--user <id>`,`User identifier propagated to external callback and stream payloads`).option(`--message <text>`,`User message to send to the agent`).option(`--from-file <path>`,`Load structured Message JSON from a file`).option(`--skillsLoadPaths <paths>`,`Comma-separated absolute skill load paths`).option(`-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`).option(`--resume-from-file <path>`,`Load structured HITL resume payload from a file (alternative to --resume-input-json)`).option(`--encrypt-sessions`,`Enable session data encryption using lz-string compression`).action(async e=>{await Kt(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`,a=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?_(r.sessionStore):void 0;if(i===`list`){Te(await h(r.dataDir,r.channel,{storeName:e}),a);return}if(r.sessionId||(E(`error: required option '-s, --session-id <id>' not specified`),process.exit(1)),i===`inspect`){Ee(await p(r.dataDir,r.sessionId,{storeName:e}),a);return}if(i===`export`){De(await s(r.dataDir,r.sessionId,{storeName:e}),a);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 Xt(e){return x.join(e,`workspace`)}function Zt(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function Qt(e,t){let n=[];n.push(`backend: ${e.backend}`),n.push(`provider: ${e.provider}${e.model?` (${e.model})`:``}`);let r=typeof e.custom?.providerSource==`string`?e.custom.providerSource:void 0,i=typeof e.custom?.providerId==`string`?e.custom.providerId:void 0,a=typeof e.custom?.pluginId==`string`?e.custom.pluginId:void 0;r&&n.push(`provider_source: ${r}`),i&&n.push(`provider_id: ${i}`),a&&n.push(`plugin_id: ${a}`),typeof e.files==`number`&&n.push(`files: ${e.files}`),typeof e.chunks==`number`&&n.push(`chunks: ${e.chunks}`),typeof e.dirty==`boolean`&&n.push(`dirty: ${e.dirty}`),e.dbPath&&n.push(`db: ${e.dbPath}`),e.sources?.length&&n.push(`sources: ${e.sources.join(`, `)}`),t&&(e.fts&&(n.push(`fts: enabled=${e.fts.enabled} available=${e.fts.available}`),e.fts.error&&n.push(`fts_error: ${e.fts.error}`)),e.vector&&(n.push(`vector: enabled=${e.vector.enabled} available=${e.vector.available??`unknown`}`),e.vector.dims&&n.push(`vector_dims: ${e.vector.dims}`),e.vector.loadError&&n.push(`vector_error: ${e.vector.loadError}`)),e.cache&&n.push(`cache: enabled=${e.cache.enabled} entries=${e.cache.entries??0}`));let o=Array.isArray(e.custom?.cliWarnings)?e.custom.cliWarnings.filter(e=>typeof e==`string`&&e.length>0):[];for(let e of o)n.push(`warning: ${e}`);return n.join(`
9
- `)}function $t(e){let t=e.level===`error`?`plugin error`:`plugin warning`;return e.pluginId?`${t} (${e.pluginId}): ${e.message}`:`${t}: ${e.message}`}function en(e){if(!e||e===`cli`)return`cli`;if(e===`cron`)return`cron`;throw Error(`Unsupported dream trigger: ${e}. Expected "cli" or "cron".`)}async function tn(e){let t=[],n;try{n=await A(e.dataDir,e.pluginsConfig)}catch(e){t.push(`failed to load plugins config: ${e.message}`)}if(!e.shouldInitialize&&!n)return{warnings:t};try{let r=f({config:n,dataDir:e.dataDir,workspaceDir:Xt(e.dataDir),bundledDir:Zt()});return t.push(...r.diagnostics.map($t)),{pluginSystem:r,warnings:t}}catch(e){return t.push(`failed to initialize plugin system: ${e.message}`),{warnings:t}}}async function Z(e){let t=x.join(e.dataDir,`.aimax`),{pluginSystem:n,warnings:r}=await tn({dataDir:e.dataDir,pluginsConfig:e.pluginsConfig,shouldInitialize:!!(e.requirePluginSystem||e.provider||e.providerPlugin)}),i=n?.normalizedConfig.slots.memory,o=e.providerPlugin?.trim()||(e.provider?void 0:i),s=ie({providerId:e.provider,pluginId:o,dataDir:e.dataDir,memoryDir:t});return s?{provider:s.provider,providerId:s.registration.id,pluginId:s.registration.pluginId,providerOrigin:`plugin`,warnings:r,pluginSystem:n}:((o||e.provider)&&r.push(`requested memory provider was not resolved; falling back to builtin provider`),{provider:a({dataDir:e.dataDir,memoryDir:t},{includeSessions:e.includeSessions}),providerId:`builtin`,providerOrigin:`builtin`,warnings:r,pluginSystem:n})}function nn(e,t,n){let r={...e.custom??{},providerSource:t.providerOrigin,providerId:t.providerId,pluginId:t.pluginId,cliWarnings:t.warnings},i={...e,custom:r};return n&&t.providerOrigin===`plugin`?i.custom={...r,note:`deep probe details are provider-defined for plugin memory providers`}:n&&(i.custom={...r,note:`deep probe is only supported by builtin provider`}),i}function rn(e){let t=e.command(`memory`).description(`Manage semantic memory indexing and search`),n=e=>e.option(`--plugins-config <path>`,`Plugins config file path`);n(t.command(`status`)).description(`Show memory index status`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--deep`,`Probe embedding/vector availability`).option(`--index`,`Run a refresh before reporting status`).option(`--include-sessions`,`Include session transcripts in indexing`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--verbose`,`Verbose output`).option(`--output <format>`,`Output format: text (default) or json`,`text`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{let n=await Z({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,pluginsConfig:e.pluginsConfig,includeSessions:e.includeSessions});e.index&&n.provider.sync&&await n.provider.sync(`cli-status`);let r=nn(n.provider.status(),n,e.deep);T(t===`json`?JSON.stringify(r,null,2):Qt(r,e.deep))}catch(e){E(`Error getting memory status: ${e.message}`),process.exit(1)}}),n(t.command(`index`)).description(`Reindex memory files`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--include-sessions`,`Include session transcripts in indexing`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--rebuild`,`Force full rebuild from Markdown source`).option(`--verbose`,`Verbose output`).action(async e=>{try{let t=await Z({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,pluginsConfig:e.pluginsConfig,includeSessions:e.includeSessions}),n;if(t.provider.sync&&(await t.provider.sync(e.rebuild?`cli-rebuild`:`cli-index`),n=t.provider.status().custom?.lastRebuildSummary),t.warnings.length>0)for(let e of t.warnings)E(`Warning: ${e}`);e.verbose&&n&&T(JSON.stringify(n,null,2)),T(e.rebuild?`Memory index rebuilt.`:`Memory index refreshed.`)}catch(e){E(`Error indexing memory: ${e.message}`),process.exit(1)}}),n(t.command(`search [query]`)).description(`Search semantic memory`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--query <text>`,`Search query`).option(`--include-sessions`,`Include session transcripts in search`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--output <format>`,`Output format: text (default) or json`,`text`).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(await Z({dataDir:t.dataDir,provider:t.provider,providerPlugin:t.providerPlugin,pluginsConfig:t.pluginsConfig,includeSessions:t.includeSessions})).provider.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(`
10
- `))}catch(e){E(`Error searching memory: ${e.message}`),process.exit(1)}}),n(t.command(`dream`)).description(`Trigger Dream Gate host hook for memory plugins`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--trigger <mode>`,`Dream Gate trigger mode: cli (default) or cron`,`cli`).option(`--dry-run`,`Return hook results without plugin-side mutation`).option(`--output <format>`,`Output format: text (default) or json`,`text`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{let n=en(e.trigger),r=await Z({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,pluginsConfig:e.pluginsConfig,requirePluginSystem:!0}),i=r.pluginSystem?await r.pluginSystem.registry.hooks.dispatch(`dream_gate`,{dataDir:e.dataDir,memoryDir:x.join(e.dataDir,`.aimax`),providerId:r.providerId,pluginId:r.pluginId,trigger:n,dryRun:!!e.dryRun},{workspaceDir:Xt(e.dataDir)}):[],a={ok:!0,trigger:n,providerSource:r.providerOrigin,providerId:r.providerId,pluginId:r.pluginId,resultCount:i.length,results:i,warnings:r.warnings};if(t===`json`){T(JSON.stringify(a,null,2));return}T(`trigger: ${a.trigger}`),T(`provider_source: ${a.providerSource}`),T(`provider_id: ${a.providerId}`),a.pluginId&&T(`plugin_id: ${a.pluginId}`),T(`result_count: ${a.resultCount}`),a.results.length===0?T(`note: no dream_gate hook registered`):T(`results: ${JSON.stringify(a.results)}`);for(let e of a.warnings)T(`warning: ${e}`)}catch(e){E(`Error running dream gate: ${e.message}`),process.exit(1)}})}function an(e){return`${e.match.accountId?`${e.match.channel}:${e.match.accountId}`:e.match.channel} -> ${e.agentId}`}function on(e){return async t=>{let n=await C(t),r=_e(n),i=ve(n);if(w(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=Se(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(` - ${an(e)}`)}}}}function sn(e,t){return async n=>{S(await C(n),ye(e))&&(console.error(`Agent "${e}" already exists.`),process.exit(1)),await he(n,{id:e,name:t.name,model:t.model,default:t.default})||(console.error(`Agent "${e}" already exists.`),process.exit(1));let r=Se(n,e);console.log(`Agent "${e}" added successfully.`),console.log(` Agent dir: ${r}`)}}function cn(e){return async t=>{let n=S(await C(t),ye(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 be(t,e)||(console.error(`Failed to delete agent "${e}".`),process.exit(1)),console.log(`Agent "${e}" deleted.`)}}function ln(e){return async t=>{let n=await C(t),r=e.agent??w(n);S(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 ge(t,{agentId:r,match:{channel:e,accountId:a||void 0}}),console.log(`Binding added: ${n} -> ${r}`)}}}function un(e){return async t=>{let n=await C(t),r=e.agent??w(n);if(S(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),e.all){let e=await xe(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 xe(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 dn(e){return async t=>{let n=ve(await C(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(` ${an(e)}`)}}function fn(e){return async t=>{let n=await C(t),r=e.agent??w(n);S(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),await Ce(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 pn(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 on(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 sn(e,n)(r)}),n.command(`delete <id>`).description(`Delete an agent`).action(async e=>{let n=t();await cn(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 ln(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 un(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 dn(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 fn(e)(n)})}function Q(e){return x.join(e,`workspace`)}function $(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function mn(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 hn(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 gn(e){return Array.from(new Set((e??[]).map(e=>e.trim()).filter(Boolean)))}function _n(e){if(e.length===0){T(`LLM allowlist is empty.`);return}for(let t of e)T(t)}function vn(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();mn(f({config:await A(n,e.pluginsConfig),dataDir:n,workspaceDir:Q(n),bundledDir:$()}).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=f({config:await A(r,n.pluginsConfig),dataDir:r,workspaceDir:Q(r),bundledDir:$()}).registry.plugins.find(t=>t.id===e);i||(E(`Plugin not found: ${e}`),process.exit(1)),hn(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=re(i);f({config:i,dataDir:r,workspaceDir:Q(r),bundledDir:$()}).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)??{};f({config:i,dataDir:r,workspaceDir:Q(r),bundledDir:$()}).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=f({config:await A(n,e.pluginsConfig),dataDir:n,workspaceDir:Q(n),bundledDir:$()});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=>{_n(gn((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=gn([...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=gn(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 yn(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=m(await te(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 bn=[`progress`,`error`,`hitl`];function xn(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 Sn(e){if(!e?.trim())return new Set(bn);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(bn)}function Cn(e){return e?_(e):void 0}function wn(e){let t=[];return e.callbackUrl&&t.push(new V(e.callbackUrl)),e.streamUrl&&t.push(new W(e.streamUrl,Sn(e.streamEvents),e.streamAuthToken)),new B(t)}async function Tn(e){L(xn(e));let t=new z(`cancel command`),n=xn(e),r=e.channel??`WEB`,i=e.output===`json`?`json`:`text`,a=wn(e),o=Cn(e.sessionStore);try{let s=await g(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 ae({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}),R.error(`cancel command error: ${i.message}`),E(`Fatal: ${i.message}`),t.end(),process.exit(1)}finally{await a.close()}}function En(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 Tn(e)})}function Dn(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 On(e){return e.query?.trim()||void 0}function kn(e){if(!e)return;let t=Number(e);if(!Number.isFinite(t)||t<=0)throw Error(`--timeout must be a positive number of milliseconds`);return t}function An(e){if(!e)return;let t=Number(e);if(!Number.isInteger(t)||t<=0)throw Error(`--max-tokens must be a positive integer`);return t}async function jn(e){if(e.filePath){if(!x.isAbsolute(e.filePath))throw Error(`--file-path must be an absolute path`);try{await b.access(e.filePath)}catch(e){throw Error(`Failed to access --file-path: ${e.message}`)}return{source:`file`,filePath:e.filePath}}let t=e.content;if(!t||!t.trim())throw Error(`Either --file-path or --content must be provided`);return{source:`content`,content:t}}async function Mn(e){let t=null;try{let n=Dn(e);L(n),t=new z(`summarize command`);let r=On(e),i=await jn(e),a=k({baseUrl:e.baseUrl,apiKey:e.apiKey,model:e.model,contextWindow:2e5}),o=kn(e.timeout),s=An(e.maxTokens);R.info(`summarize command started`,{dataDir:n,source:i.source,filePath:i.source===`file`?i.filePath:void 0,queryLength:r?.length,contentLength:i.source===`content`?i.content.length:void 0,timeoutMs:o,maxTokens:s});let c=await v({dataDir:n,channel:`WEB`,message:Nn(i,r),llm:{...a,maxTokens:s},timeoutMs:o});T(c.text.trim()),R.info(`summarize command succeeded`,{source:i.source,summaryLength:c.text.length,durationMs:c.durationMs}),t.end()}catch(e){R.error(`summarize command error: ${e.message}`),E(`Fatal: ${e.message}`),t?.end(),process.exit(1)}}function Nn(e,t){return e.source===`file`?[t?`Summarize exactly one file for the query below.`:`Summarize exactly one file.`,`Read only the absolute file path provided here. Do not search, browse, read other files, execute commands, modify files, or perform any other processing.`,`Return only the summary text.`,``,...t?[`Query:\n${t}`,``]:[],`Input source: file`,`File path: ${e.filePath}`].join(`
11
- `):[t?`Summarize the provided content for the query below.`:`Summarize the provided content.`,t?`Use only the provided content and query. Do not search, browse, read files, execute commands, modify files, or perform any other processing.`:`Use only the provided content. Do not search, browse, read files, execute commands, modify files, or perform any other processing.`,`Return only the summary text.`,``,...t?[`Query:\n${t}`,``]:[],`Input source: content`,`Source content:`,`<source>`,e.content,`</source>`].join(`
12
- `)}function Pn(e){e.command(`summarize`).description(`Summarize one absolute file path or inline content`).option(`--file-path <path>`,`Absolute file path to summarize`).option(`--content <text>`,`Inline text content to summarize when --file-path is not provided`).option(`--query <text>`,`Optional search target or current description to focus the summary`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY)`).option(`--model <name>`,`LLM model name (overrides AIMAX_MODEL)`).option(`--timeout <ms>`,`Execution timeout in milliseconds`).option(`--max-tokens <number>`,`Maximum number of tokens for model output`).action(async e=>{await Mn(e)})}const Fn=e(import.meta.url)(`../package.json`);function In(){return process.env.AIMAX_DATA_DIR||process.cwd()}function Ln(){let e=new t;return e.name(`aimax`).description(`AIMax CLI — runs agent tasks in a containerized environment`).version(Fn.version),Jt(e),gt(e),En(e),Yt(e),Pn(e),yn(e),ke(e),rn(e),pn(e,In),vn(e,In),e}export{Ze as a,R as i,In as n,L as r,Ln as t};