@gencode/cli 0.5.2 → 0.6.1
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 +29 -0
- package/dist/bin.js +1 -1
- package/dist/program-Cc5_Ama2.js +14 -0
- package/dist/program.js +1 -1
- package/package.json +3 -3
- package/dist/program-D2AmoEGO.js +0 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @gencode/cli
|
|
2
2
|
|
|
3
|
+
## 0.6.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- feb2392: Recover interrupted gocryptfs .aimax migrations and log encrypted mount failures under the user data directory.
|
|
8
|
+
- Updated dependencies [46c7c4f]
|
|
9
|
+
- @gencode/agents@0.7.2
|
|
10
|
+
|
|
11
|
+
## 0.6.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- ace4220: Add thread goal audit events, live goal status updates, and objective-change steering across the goal control flow.
|
|
16
|
+
- 7cd5fcc: Add persisted thread goals with CLI controls, automatic continuation, and goal status reporting across sessions.
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- 5dec8b2: Emit pre-run `goal_updated` progress events for `run --session-id --goal` and `resume --goal` so console/callback consumers receive real-time goal state changes before agent turns start.
|
|
21
|
+
- e1882f4: Retry 200-stream LLM payload errors when upstream 5xx details survive only in the error message text.
|
|
22
|
+
- 1df854a: Start work immediately after `/goal` activates or resumes a thread goal, while keeping non-executing goal commands short-circuited.
|
|
23
|
+
- Updated dependencies [e1882f4]
|
|
24
|
+
- Updated dependencies [ace4220]
|
|
25
|
+
- Updated dependencies [1df854a]
|
|
26
|
+
- Updated dependencies [5422fc5]
|
|
27
|
+
- Updated dependencies [7cd5fcc]
|
|
28
|
+
- Updated dependencies [cb8d8d7]
|
|
29
|
+
- @gencode/agents@0.7.0
|
|
30
|
+
- @gencode/shared@0.2.0
|
|
31
|
+
|
|
3
32
|
## 0.5.2
|
|
4
33
|
|
|
5
34
|
### Patch Changes
|
package/dist/bin.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as e,i as t,r as n,t as r}from"./program-
|
|
2
|
+
import{a as e,i as t,r as n,t as r}from"./program-Cc5_Ama2.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,14 @@
|
|
|
1
|
+
import{createRequire as e}from"node:module";import{Command as t}from"commander";import{GoalConflictError as n,applyCliGoalBeforeRun as r,bootstrapMountLayout as i,buildResumeNarration as a,clearPendingUiTool as o,createBuiltinMemoryProvider as s,deleteGoal as c,ensureBootstrapMountLayout as l,exportSession as u,formatApprovalResolution as d,formatClarifyResolution as f,formatReviewResolution as p,hasBootstrapSentinel as m,initializePluginSystem as h,inspectSession as g,listAvailableSlashCommands as _,listSessionSummaries as v,loadPendingHitl as ee,loadPendingUiTool as te,loadSkillsWithPluginDirs as ne,loadTranscript as re,normalizePluginsConfig as ie,normalizeSessionStoreName as y,readGoal as b,resolveGoalObjective as ae,resolveMemoryProvider as oe,resolvePendingHitl as se,resolvePendingUiTool as ce,rewriteTranscript as le,runAgent as x,updateGoal as ue,writeGoal as de}from"@gencode/agents";import{formatTaskForDisplay as fe,isAgentDiagnosticEvent as pe,isHitlTool as me,parseMatchedTextToResolution as he,parseTextToResolution as ge}from"@gencode/shared";import S from"node:fs/promises";import C from"node:path";import _e from"node:os";import{execFile as ve,execFileSync as ye}from"node:child_process";import be from"node:fs";import xe from"gensign-node";import Se from"log4js";import{addAgent as Ce,addBinding as we,getAgentConfig as w,listAgents as Te,listBindings as Ee,loadAgentsConfig as T,normalizeAgentId as De,removeAgent as Oe,removeBindings as ke,resolveAgentDir as Ae,resolveDefaultAgentId as E,updateAgentIdentity as je}from"@gencode/agents/config";import{randomUUID as Me}from"node:crypto";function Ne(e){process.stdout.write(e)}function D(e){process.stdout.write(e+`
|
|
2
|
+
`)}function O(e){process.stderr.write(e+`
|
|
3
|
+
`)}function k(e){switch(e.type){case`start`:D(`\n[start] ${e.message}`);break;case`text`:Ne(e.text);break;case`stream_text_delta`:Ne(e.text);break;case`bootstrap`:D(`\n[bootstrap:${e.phase}] ${e.dataDir}`);break;case`session_reset`:D(`\n[session:${e.action}] ${e.message}`);break;case`tool_start`:D(`\n[tool:${e.name}] ${JSON.stringify(e.input??{})}`);break;case`tool_end`:D(`[tool:${e.name}] ${e.isError?`ERROR`:`OK`} ${e.output.slice(0,200)}`);break;case`compaction`:D(`\n[compaction${e.layer?`:${e.layer}`:``}] ${e.reason}${e.strategy?` (${e.strategy})`:``}`);break;case`skill_used`:D(`\n[skill] ${e.skillName} agent=${e.agent} task=${e.taskId}`);break;case`custom`:D(`\n[plugin:${e.pluginId}] ${e.name}${e.label?` ${e.label}`:``}${e.data?` ${JSON.stringify(e.data)}`:``}`);break;case`error`:O(`\n[error] ${e.message}`);break;case`diagnostic`:break;case`subagent_spawn`:D(`\n[subagent:spawn]${e.label?` "${e.label}"`:``} ${fe(e.task)}`);break;case`subagent_complete`:D(`[subagent:${e.status}] ${fe(e.task)}`);break;case`hitl_requested`:if(D(`\n[hitl:${e.request.kind}] ${e.request.title}`),D(` prompt: ${e.request.prompt}`),D(` requestId: ${e.request.requestId}`),e.request.input.mode===`choice`)for(let t of e.request.input.choices)D(` - [${t.id}] ${t.label}`);break;case`hitl_resumed`:D(`\n[hitl:resumed] requestId=${e.requestId} action=${e.resolution.action}`);break;case`hitl_expired`:D(`\n[hitl:expired] requestId=${e.requestId} reason=${e.reason}`);break;case`hitl_cancelled`:D(`\n[hitl:cancelled] requestId=${e.requestId}${e.reason?` reason=${e.reason}`:``}`);break;case`ui_tool_request`:D(`\n[ui-tool:${e.request.toolName}] ${e.request.outputSchema.title}`),D(` requestId: ${e.request.requestId}`),D(` toolCallId: ${e.request.toolCallId}`);break;case`ui_tool_result`:D(`\n[ui-tool:resumed] requestId=${e.requestId} tool=${e.toolName}`);break}}function A(e,t){if(t===`json`){e&&D(JSON.stringify(e,null,2));return}D(`
|
|
4
|
+
`),D(`session: ${e.sessionId}`),D(`duration: ${e.durationMs}ms`),D(`tokens: input=${e.usage.input} output=${e.usage.output} total=${e.usage.total}`),e.context&&(D(`context: ${e.context.snapshotPath}`),D(`tool-results: ${e.context.toolResultsDir}`)),e.error&&O(`error: ${e.error}`)}function Pe(e,t){if(t===`json`){D(JSON.stringify(e,null,2));return}if(e.length===0){D(`No sessions found.`);return}for(let t of e){let e=t.createdAt?new Date(t.createdAt).toLocaleString():`unknown`,n=t.goalStatus?` [GOAL:${t.goalStatus}]`:` [GOAL:—]`;D(`${t.id} ${e} [${t.channel}]${n} ${t.title}`)}}function Fe(e,t){if(t===`json`){D(JSON.stringify(e,null,2));return}D(`session: ${e.id}`),e.metadata&&(D(`title: ${e.metadata.title}`),D(`channel: ${e.metadata.channel}`),D(`created: ${e.metadata.createdAt}`),D(`updated: ${e.metadata.updatedAt}`)),D(`transcript: ${e.transcriptPath}`),D(`entries: ${e.transcriptEntryCount}`),D(`context: ${e.contextSnapshotPath}`),D(`session-memory: ${e.sessionMemoryPath}`),D(`collapse-log: ${e.collapseLogPath}`),D(`read-states: ${e.readStateCount}`),D(`tool-results: ${e.toolResultRefCount}`),D(`tool-results-dir: ${e.toolResultsDir}`)}function Ie(e,t){if(t===`json`){D(JSON.stringify(e,null,2));return}D(`session: ${e.id}`),D(`transcript: ${e.paths.transcriptPath}`),D(`context: ${e.paths.contextSnapshotPath}`),D(`session-memory: ${e.paths.sessionMemoryPath}`),D(`collapse-log: ${e.paths.collapseLogPath}`),D(`tool-results-dir: ${e.paths.toolResultsDir}`),D(`transcript-entries: ${e.transcript.length}`),D(`read-states: ${e.context.readStates.length}`),D(`tool-results: ${e.context.toolResults.length}`),D(`collapse-spans: ${e.context.compaction.collapseSpans.length}`)}function Le(e,t){if(t===`json`){D(JSON.stringify(e,null,2));return}D(`Bootstrap completed.`),D(`dataDir: ${e.dataDir}`),D(`created dirs: ${e.createdDirs.length}`),D(`created files: ${e.createdFiles.length}`),D(`skipped dirs: ${e.skippedDirs.length}`),D(`skipped files: ${e.skippedFiles.length}`)}const Re=`.aimax`,ze=`${Re}.pre-gocryptfs.`,j=[`fusermount3`,`fusermount`,`umount`];function Be(e){return C.join(e,`.aimax.enc`)}function Ve(e){return C.join(e,Re)}function He(e){return C.join(e,`${ze}${process.pid}.${Date.now()}`)}function Ue(e){return e.replace(/\\([0-7]{3})/g,(e,t)=>String.fromCharCode(Number.parseInt(t,8)))}async function We(e){try{let t=await Ge(),n=C.resolve(e);for(let e of t.split(`
|
|
5
|
+
`)){if(!e.trim())continue;let t=e.split(` `);if(t.length>=5&&C.resolve(Ue(t[4]??``))===n)return!0}return!1}catch{return!1}}async function Ge(){return await S.readFile(`/proc/self/mountinfo`,`utf-8`)}async function M(e){try{return await S.stat(e),!0}catch(e){if(e.code===`ENOENT`)return!1;throw e}}async function Ke(e){await S.mkdir(e,{recursive:!0})}async function qe(e){if(await Ke(e),(await S.readdir(e)).length>0)throw Error(`Refusing to mount encrypted .aimax over non-empty directory: ${e}. Clear stale plaintext files or disable --encrypt-sessions for this run.`)}async function Je(e){return await M(e)?(await S.readdir(e)).length===0:!0}async function Ye(e){if(!await M(C.join(e,`gocryptfs.conf`)))throw Error(`Encrypted .aimax directory exists but is not initialized: ${e}. Remove the incomplete .aimax.enc directory or restore it from backup before retrying --encrypt-sessions.`)}async function Xe(e){return(await S.readdir(e,{withFileTypes:!0})).filter(e=>e.isDirectory()&&e.name.startsWith(ze)).map(t=>C.join(e,t.name)).sort()}async function N(e,t){if(!await M(t))return null;let n=He(e);return await S.rename(t,n),n}async function P(e,t,n){await S.cp(e,t,{recursive:!0,force:n})}async function Ze(e){let t=C.join(_e.tmpdir(),`aimax-gocryptfs-pass.${process.pid}.${Date.now()}`);await S.writeFile(t,`wizard_aimax@2026
|
|
6
|
+
`,{mode:384});try{return await e(t)}finally{await S.rm(t,{force:!0})}}async function Qe(e){try{await ot(`gocryptfs`,e)}catch(t){let n=t instanceof Error?t.message:String(t);throw Error(`gocryptfs ${e.join(` `)} failed: ${n}`)}}async function $e(){await ct(`gocryptfs`,`required for --encrypt-sessions`);for(let e of j)if(await st(e))return;throw Error(`--encrypt-sessions requires one of ${j.join(`, `)} to be installed for secure unmount cleanup.`)}async function et(e,t){await Ze(async n=>{await Qe([`-q`,`-passfile`,n,e,t])})}async function tt(e){await Ze(async t=>{await Qe([`-q`,`-init`,`-passfile`,t,e])})}async function nt(e){let t=[];for(let n of j)try{await ot(n,[`-u`,e]);return}catch(e){t.push(lt(n,e))}throw Error(`Failed to unmount ${e}: ${t.join(`; `)}`)}function rt(e){for(let t of j)try{ye(t,[`-u`,e],{stdio:`ignore`});return}catch{}}function it(e){let t=!1,n=()=>{t||(t=!0,rt(e))},r=()=>n(),i=()=>{n(),process.exit(130)},a=()=>{n(),process.exit(143)};return process.once(`exit`,r),process.once(`SIGINT`,i),process.once(`SIGTERM`,a),{release(){process.removeListener(`exit`,r),process.removeListener(`SIGINT`,i),process.removeListener(`SIGTERM`,a)}}}async function at(e){await $e();let t=Be(e),n=Ve(e);if(await We(n))return{mounted:!1,plainDir:n,encryptedDir:t,async cleanup(){}};let r=null,i=[],a=null,o=null,s=!1;try{if(i=await Xe(e),!await M(t))if(i.length>0?a=await N(e,n):r=await N(e,n),await Ke(t),await tt(t),await Ke(n),await et(t,n),s=!0,o=it(n),i.length>0){for(let e of i)await P(e,n,!0);a&&=(await P(a,n,!1),await S.rm(a,{recursive:!0,force:!0}),null);for(let e of i)await S.rm(e,{recursive:!0,force:!0});i=[]}else r&&=(await P(r,n,!0),await S.rm(r,{recursive:!0,force:!0}),null);else if(await Ye(t),i.length>0?a=await N(e,n):await Je(n)||(r=await N(e,n)),await qe(n),await et(t,n),s=!0,o=it(n),i.length>0){for(let e of i)await P(e,n,!0);a&&=(await P(a,n,!1),await S.rm(a,{recursive:!0,force:!0}),null);for(let e of i)await S.rm(e,{recursive:!0,force:!0});i=[]}else r&&=(await P(r,n,!0),await S.rm(r,{recursive:!0,force:!0}),null);return{mounted:s,plainDir:n,encryptedDir:t,async cleanup(){o?.release(),s&&(s=!1,await nt(n))}}}catch(e){throw o?.release(),s&&await nt(n).catch(()=>{}),r&&await M(r)&&await Je(n)&&(await S.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await S.rename(r,n).catch(()=>{})),a&&await M(a)&&await Je(n)&&(await S.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await S.rename(a,n).catch(()=>{})),e}}async function F(e,t,n){if(!t.encryptSessions)return n();let r=await at(e);try{return await n()}finally{await r.cleanup()}}async function ot(e,t){await new Promise((n,r)=>{ve(e,t,{encoding:`utf-8`},e=>{if(e){r(e);return}n()})})}async function st(e){try{return await ot(`sh`,[`-c`,`command -v "${e}" >/dev/null 2>&1`]),!0}catch{return!1}}async function ct(e,t){if(!await st(e))throw Error(`--encrypt-sessions requires ${e}: ${t}.`)}function lt(e,t){return`${e} -u failed: ${t instanceof Error?t.message:String(t)}`}function ut(e){e.command(`bootstrap`).description(`Initialize the data directory with required directories and templates`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{Le(await F(e.dataDir,e,async()=>i(e.dataDir)),t)}catch(e){O(`Error bootstrapping data directory: ${e.message}`),process.exit(1)}})}function dt(e){return xe.sm4_encrypt_ecb(e)}function ft(e){return dt(e)}function pt(e={}){let t=e.baseUrl??process.env.AIMAX_BASE_URL,n=process.env.AIMAX_AUTH_TOKEN,r=e.authToken?ft(e.authToken):n?ft(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 mt(e,t){return t?C.resolve(t):C.join(e,`.aimax`,`plugins.json`)}async function I(e,t){let n=mt(e,t);try{let e=await S.readFile(n,`utf-8`);return JSON.parse(e)}catch(e){if(e.code===`ENOENT`)return;throw e}}async function L(e,t,n){let r=mt(e,n);await S.mkdir(C.dirname(r),{recursive:!0}),await S.writeFile(r,JSON.stringify(t,null,2),`utf-8`)}function R(e){return typeof e==`object`&&!!e}function ht(e){return R(e)&&e.type===`text`&&typeof e.text==`string`&&(e.textSignature===void 0||typeof e.textSignature==`string`)}function gt(e){return R(e)&&e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`}function _t(e){return R(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 vt(e){return R(e)&&e.type===`toolCall`&&typeof e.id==`string`&&typeof e.name==`string`&&R(e.arguments)&&(e.thoughtSignature===void 0||typeof e.thoughtSignature==`string`)}function yt(e){return typeof e==`string`||Array.isArray(e)&&e.every(e=>ht(e)||gt(e))}function bt(e){return Array.isArray(e)&&e.every(e=>ht(e)||_t(e)||vt(e))}function xt(e){return R(e)&&typeof e.input==`number`&&typeof e.output==`number`&&typeof e.cacheRead==`number`&&typeof e.cacheWrite==`number`&&typeof e.totalTokens==`number`&&R(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 St(e){return!R(e)||typeof e.role!=`string`?!1:e.role===`user`?yt(e.content):e.role===`assistant`?bt(e.content)&&typeof e.api==`string`&&typeof e.provider==`string`&&typeof e.model==`string`&&xt(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=>ht(e)||gt(e))&&typeof e.isError==`boolean`:!1}async function Ct(e){let t;try{t=await S.readFile(e,`utf-8`)}catch(e){throw Error(`Failed to read message file: ${e.message}`)}let n;try{n=JSON.parse(t)}catch(e){throw Error(`Invalid JSON in message file: ${e.message}`)}let r=Array.isArray(n)?n:[n];if(r.length===0||!r.every(e=>St(e)))throw Error(`Message file must contain one Message object or an array of Message objects`);return r}async function wt(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 Ct(e.fromFile)}:{kind:`text`,message:e.message}}function Tt(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 Et(e=new Date){let t=Tt(e),n=String(e.getMilliseconds()).padStart(3,`0`);return`${t.year}-${t.month}-${t.day} ${t.hour}:${t.minute}:${t.second}.${n}`}let z=function(e){return e.INFO=`INFO`,e.ERROR=`ERROR`,e.WARN=`WARN`,e}({}),B=null;function Dt(){return Et()}function Ot(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 kt(e){return C.join(e,`.aimax`)}function At(e){return{appLogPath:C.join(e,`app.log`),errorLogPath:C.join(e,`errors.log`)}}function jt(e){let{appLogPath:t,errorLogPath:n}=At(e);Se.configure({appenders:{appFile:{type:`file`,filename:t,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`messagePassThrough`}},errorFile:{type:`file`,filename:n,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`messagePassThrough`}},errorsOnly:{type:`logLevelFilter`,appender:`errorFile`,level:`error`,maxLevel:`fatal`}},categories:{default:{appenders:[`appFile`,`errorsOnly`],level:`info`}}})}function Mt(e,t,n){return`[${Dt()}] [${e}] ${t}${Ot(n)}`}function Nt(e,t,n){process.stderr.write(`${Mt(e,t,n)}\n`)}function Pt(e,t,n){if(!B){Nt(e,t,n);return}let r=Mt(e,t,n),i=Se.getLogger();if(e===z.ERROR){i.error(r);return}if(e===z.WARN){i.warn(r);return}i.info(r)}function V(e){let t=kt(e);be.mkdirSync(t,{recursive:!0}),jt(t),B={dataDir:e,logDir:t}}function Ft(){return B?{...B}:null}async function It(){await Se.shutdown()}const H={info:(e,t)=>Pt(z.INFO,e,t),warn:(e,t)=>Pt(z.WARN,e,t),error:(e,t)=>Pt(z.ERROR,e,t)};var U=class{startTime;name;constructor(e){this.name=e,this.startTime=Date.now()}end(){let e=Date.now()-this.startTime;return H.info(`${this.name} completed in ${e}ms`),e}},Lt=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()}))}},Rt=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=zt(e);H.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 H.error(`callback event failed`,{callbackUrl:this.url,httpStatus:r.status,durationMs:i,...n}),Error(`Callback failed with status ${r.status}`);H.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 zt(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 Bt(e,t){if(t.kind===`none`)return e;let n=new URL(e);return n.searchParams.set(`authToken`,t.token),n.toString()}function W(){let e=globalThis.WebSocket;if(!e)throw Error(`WebSocket is not available in this runtime`);return e}function Vt(e){return e?{kind:`query_token`,token:e}:{kind:`none`}}function Ht(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 Ut(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 Wt=class{socket=null;connectPromise=null;enabled=!0;textSequence=0;constructor(e,t,n){this.url=e,this.events=t,this.authToken=n}async send(e){let t=this.toEnvelope(e);if(!(!t||!this.enabled))try{await this.ensureConnected();let e=W();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){H.warn(`websocket sink disabled after send failure`,{url:this.url,error:e instanceof Error?e.message:String(e)}),this.enabled=!1}}async sendTextDelta(e){if(!this.enabled||!this.events.has(`text`))return;this.textSequence+=1;let t={type:`text`,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,timestamp:new Date().toISOString(),sequence:this.textSequence,delta:e.text};try{await this.ensureConnected();let e=W();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){H.warn(`websocket sink disabled after text delta send failure`,{url:this.url,error:e instanceof Error?e.message:String(e)}),this.enabled=!1}}async close(){this.enabled=!1;let e=this.socket;if(this.socket=null,this.connectPromise=null,!e)return;let t=W();e.readyState!==t.CLOSED&&await new Promise(t=>{Ht(e,`close`,()=>t()),e.close()})}async ensureConnected(){if(!this.enabled)return;let e=W();if(this.socket&&this.socket.readyState===e.OPEN)return;if(this.connectPromise){await this.connectPromise;return}let t=new e(Bt(this.url,Vt(this.authToken)));this.connectPromise=new Promise((e,n)=>{Ht(t,`open`,()=>{this.socket=t,Ut(t,`close`,()=>{this.socket===t&&(this.socket=null)}),e()}),Ht(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 Gt(e){let t=e.trim();if(!t)throw Error(`Goal objective cannot be empty`);return t}function Kt(e,t){if(t.action===`unchanged`)return null;if(t.action===`created`||t.action===`replaced`)return t.action;if(e?.status!==t.goal.status)switch(t.goal.status){case`active`:return e?.status===`paused`?`resumed`:`updated`;case`paused`:return`paused`;case`complete`:return`completed`;case`budget_limited`:return`budget_limited`;default:return`updated`}return`updated`}function qt(e){let t=Kt(e.before,e.result);return t?{type:`goal_updated`,sessionId:e.sessionId,action:t,goalId:e.result.goal.goalId,goalStatus:e.result.goal.status}:null}const Jt=[`start`,`text`,`done`,`error`,`hitl`],Yt=[`off`,`gate`,`dry_run`,`write`];function Xt(e){if(!e?.trim())return new Set(Jt);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(Jt)}function Zt(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir or AIMAX_DATA_DIR`);return t}function Qt(e){return e?.trim()||void 0}function $t(e){let t=(e.systemAgentsDir??process.env.AIMAX_SYSTEM_AGENTS_DIR)?.trim();if(t){if(!C.isAbsolute(t)){let n=e.systemAgentsDir===void 0?`AIMAX_SYSTEM_AGENTS_DIR`:`--system-agents-dir`;throw Error(`Invalid ${n}: ${t}. Path must be absolute.`)}return t}}function en(e){return e?y(e):void 0}function tn(e){if(!e?.trim())return[];let t=e.split(`,`).map(e=>e.trim()).filter(Boolean),n=new Set,r=[];for(let e of t){if(!C.isAbsolute(e))throw Error(`Invalid --skillsLoadPaths entry: ${e}. Each path must be absolute.`);n.has(e)||(n.add(e),r.push(e))}return r}function nn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if([`true`,`1`,`yes`,`on`].includes(n))return!0;if([`false`,`0`,`no`,`off`].includes(n))return!1;throw Error(`Invalid ${t}: ${e}. Must be true or false.`)}}function rn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(Yt.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function an(e){let t=e.autoSkillsLoadEnabled===void 0?nn(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):nn(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?rn(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):rn(e.autoSkillsReviewMode,`--auto-skills-review-mode`),r={};return t!==void 0&&(r.load={enabled:t}),n!==void 0&&(r.review={mode:n}),r.load||r.review?r:void 0}function on(e,t){if(e.inputText&&t){let n=ge(e.inputText,t);return n.submittedBy={userId:e.user,channel:e.channel??`IM`},n}if(!e.inputJson&&!e.inputText)throw Error(`Either --input-json or --input-text must be provided for the resume command`);try{let t=JSON.parse(e.inputJson);return{requestId:e.requestId,sessionId:e.sessionId,action:t.action??`submit`,values:t.values,submittedBy:t.submittedBy,idempotencyKey:t.idempotencyKey,submittedAt:t.submittedAt??new Date().toISOString()}}catch(e){throw Error(`Invalid --input-json: ${e.message}`)}}function sn(e,t){if(!e.inputJson)throw Error(`UI tool resume requires --input-json`);try{let n=JSON.parse(e.inputJson),r=n&&typeof n==`object`&&`values`in n&&n.values&&typeof n.values==`object`&&!Array.isArray(n.values)?n.values:n;return{requestId:t.request.requestId,sessionId:t.sessionId,toolCallId:t.request.toolCallId,toolName:t.request.toolName,values:r,submittedAt:new Date().toISOString()}}catch(e){throw Error(`Invalid --input-json: ${e.message}`)}}async function cn(e){let t=await re(e.dataDir,e.sessionId,{storeName:e.sessionStoreName,encryptSessions:e.encryptSessions});for(let n=t.length-1;n>=0;--n){let r=t[n];if(r?.role!==`assistant`||!Array.isArray(r.toolCalls))continue;let i=r.toolCalls.find(t=>t.id===e.toolCallId&&t.name===e.toolName);if(i)return i.arguments}}async function ln(e){let t=Zt(e),n=e.channel??`WEB`,r=pt({baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel});return{dataDir:t,systemAgentsDir:$t(e),channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,skillsLoadPaths:tn(e.skillsLoadPaths),autoSkills:an(e)}}function un(e){let t=[],n=null;return e.callbackUrl&&t.push(new Rt(e.callbackUrl)),e.streamUrl&&(n=new Wt(e.streamUrl,Xt(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new Lt(t),websocketSink:n}}async function dn(e){let{dataDir:t,sessionId:n,sessionStoreName:r,toolCallId:i,toolName:a,resolution:o,encryptSessions:s}=e;if(!i||!a||!me(a))return;let c=(e,t)=>{switch(e){case`request_approval`:return d(t);case`clarify`:return f(t);case`request_review`:return p(t);default:return JSON.stringify({action:t.action,values:t.values})}};await le(t,n,e=>{let t=e.findIndex(e=>e.role===`tool_result`&&e.toolCallId===i&&e.toolName===a);if(t===-1)return e;let n=e.slice(0,t+1);return n[t]={...n[t],content:c(a,o),isError:!1},n},{storeName:r,encryptSessions:s})}async function fn(e){let{dataDir:t,sessionId:n,sessionStoreName:r,result:i,encryptSessions:a}=e;await le(t,n,e=>{let t=e.findIndex(e=>e.role===`assistant`&&Array.isArray(e.toolCalls)&&e.toolCalls.some(e=>e.id===i.toolCallId&&e.name===i.toolName));if(t===-1)return e;let n=e.slice(0,t+1);return n.push({role:`tool_result`,toolCallId:i.toolCallId,toolName:i.toolName,content:JSON.stringify({submitted:!0,values:i.values}),isError:!1,timestamp:i.submittedAt}),n},{storeName:r,encryptSessions:a})}async function pn(e){let t=Zt(e);await F(t,e,async()=>{V(t);let i=new U(`resume command`),a=null;try{let t=await ln(e),s=en(e.sessionStore),c=null;if(e.goal||e.goalFile){let i;i=e.goalFile?await S.readFile(e.goalFile,`utf-8`):e.goal;let a=Gt(i),o=e.tokenBudget===void 0?void 0:e.tokenBudget===`0`||e.tokenBudget===``?null:Number(e.tokenBudget);o!=null&&(Number.isNaN(o)||o<=0)&&(O(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));try{let n=await b(t.dataDir,e.sessionId,{storeName:s}),i=await r({dataDir:t.dataDir,sessionId:e.sessionId,objective:a,tokenBudget:o,force:e.force,storeName:s});c=qt({sessionId:e.sessionId,before:n,result:i})}catch(e){throw e instanceof n&&(O(e.message),O(`Existing: ${e.existingObjectivePreview}`),process.exit(2)),e}}H.info(`resume command started`,{sessionId:e.sessionId,requestId:e.requestId,channel:t.channel,dataDir:t.dataDir});let l=await ee(t.dataDir,e.sessionId,{storeName:s,encryptSessions:e.encryptSessions}),u=l?null:await te(t.dataDir,e.sessionId,{storeName:s,encryptSessions:e.encryptSessions});if(!l&&!u)throw Error(`No pending HITL or UI tool request found for session "${e.sessionId}"`);if(l){if(l.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${l.request.requestId}", got "${e.requestId}"`);if(l.status===`expired`)throw Error(`HITL request has expired`);if(l.status===`cancelled`)throw Error(`HITL request has been cancelled`)}else if(u){if(u.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${u.request.requestId}", got "${e.requestId}"`);if(u.status!==`pending`)throw Error(`UI tool request is already "${u.status}", cannot resume`)}if(l){let n=on(e,l.request),r=await se({dataDir:t.dataDir,sessionStoreName:s,sessionId:e.sessionId,requestId:e.requestId,resolution:n}),o=r.state;if(!o)throw Error(`Resolved HITL state was not persisted`);let u=mn(n,o.request.kind);await dn({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:s,toolCallId:o.toolContext?.toolCallId,toolName:o.toolContext?.toolName,resolution:n,encryptSessions:e.encryptSessions});let d=un(e);a=d.sink;let f=e.sessionId,p=async n=>{if(f=n.sessionId??f,!pe(n)){if(n.type===`stream_text_delta`){t.format===`text`&&k(n),await d.websocketSink?.sendTextDelta({sessionId:f,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}t.format===`text`&&k(n),await a?.send({sessionId:f,channel:t.channel,messageId:e.messageId,user:e.user,type:`progress`,event:n})}};c&&await p(c),await p({type:`hitl_resumed`,requestId:e.requestId,resolution:n,sessionId:e.sessionId}),`idempotentReplay`in r&&r.idempotentReplay&&(H.info(`resume command treated as idempotent replay`,{sessionId:e.sessionId,requestId:e.requestId,idempotencyKey:n.idempotencyKey}),A({sessionId:e.sessionId,text:`Resume request already processed.`,usage:{input:0,output:0,total:0},durationMs:0},t.format),i.end(),process.exit(0));let m=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,h=await I(t.dataDir,m),g;try{g=await x({dataDir:t.dataDir,projectDir:Qt(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:s,sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,message:u,encryptSessions:e.encryptSessions??!1,hitlResume:{request:o.request,resolution:n,checkpoint:o.checkpoint,toolContext:o.toolContext},plugins:h?{config:h,dataDir:t.dataDir,workspaceDir:C.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:h.llmAllowlist}:void 0,onProgress:p})}finally{}g.error?await a?.send({sessionId:g.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`error`,message:g.error}):await a?.send({sessionId:g.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`done`,result:{text:g.text,usage:g.usage,durationMs:g.durationMs,error:g.error,paused:g.paused,uiToolPending:g.uiToolPending}}),A(g,t.format),g.error?H.error(`resume command failed: ${g.error}`):H.info(`resume command succeeded`),i.end(),process.exit(g.error?1:0);return}let d=sn(e,u);if(!await ce(t.dataDir,e.sessionId,e.requestId,d,{storeName:s,encryptSessions:e.encryptSessions}))throw Error(`UI tool resume validation failed`);await fn({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:s,result:d,encryptSessions:e.encryptSessions});let f=un(e);a=f.sink;let p=e.sessionId,m=async n=>{if(p=n.sessionId??p,!pe(n)){if(n.type===`stream_text_delta`){t.format===`text`&&k(n),await f.websocketSink?.sendTextDelta({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}if(t.format===`text`&&k(n),n.type===`start`){await a?.send({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,type:`start`,message:n.message});return}await a?.send({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,type:`progress`,event:n})}},h=await cn({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:s,toolCallId:d.toolCallId,toolName:d.toolName,encryptSessions:e.encryptSessions});c&&await m(c),await m({type:`tool_end`,sessionId:e.sessionId,toolCallId:d.toolCallId,name:d.toolName,input:h,output:JSON.stringify({submitted:!0,values:d.values}),isError:!1});let g=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,_=await I(t.dataDir,g),v=await x({dataDir:t.dataDir,projectDir:Qt(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:s,sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,message:`[UI_TOOL_RESUME]
|
|
7
|
+
The pending UI tool result has been written into the transcript. Continue from the latest tool result without repeating the same form request.`,encryptSessions:e.encryptSessions??!1,uiToolResume:d,plugins:_?{config:_,dataDir:t.dataDir,workspaceDir:C.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:_.llmAllowlist}:void 0,onProgress:m});await o(t.dataDir,e.sessionId,{storeName:s,encryptSessions:e.encryptSessions}),v.error?await a?.send({sessionId:v.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`error`,message:v.error}):await a?.send({sessionId:v.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`done`,result:{text:v.text,usage:v.usage,durationMs:v.durationMs,error:v.error,paused:v.paused,uiToolPending:v.uiToolPending}}),A(v,t.format),v.error?H.error(`resume command failed: ${v.error}`):H.info(`resume command succeeded`),i.end(),process.exit(v.error?1:0)}catch(t){let n=t;a&&(n.message.includes(`expired`)&&await a.send({sessionId:e.sessionId,channel:e.channel??`WEB`,messageId:e.messageId,user:e.user,type:`progress`,event:{type:`hitl_expired`,sessionId:e.sessionId,requestId:e.requestId,reason:n.message}}),n.message.includes(`cancelled`)&&await a.send({sessionId:e.sessionId,channel:e.channel??`WEB`,messageId:e.messageId,user:e.user,type:`progress`,event:{type:`hitl_cancelled`,sessionId:e.sessionId,requestId:e.requestId,reason:n.message}}),await a.send({sessionId:e.sessionId,channel:e.channel??`WEB`,messageId:e.messageId,user:e.user,type:`error`,message:`Resume failed: ${n.message}`})),H.error(`resume command error: ${n.message}`),O(`Fatal: ${n.message}`),i.end(),process.exit(1)}finally{await a?.close()}})}function mn(e,t){return a(e,t)}function hn(e){e.command(`resume`).description(`Resume a paused HITL session with user input`).requiredOption(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--project-dir <path>`,`Current project directory used as the default cwd context`).option(`--system-agents-dir <path>`,`System agent definition directory (overrides AIMAX_SYSTEM_AGENTS_DIR, default: /aimax/agents)`).requiredOption(`-s, --session-id <id>`,`Session ID to resume`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).requiredOption(`--request-id <id>`,`HITL request ID to resolve`).option(`--input-json <json>`,`JSON string with the resolution (action, values, etc.)`).option(`--input-text <text>`,`Plain text response for IM channels without rich UI (e.g. '同意', '拒绝')`).option(`--skillsLoadPaths <paths>`,`Comma-separated absolute skill load paths`).option(`--auto-skills-load-enabled <boolean>`,`Enable learned auto-skill loading for the main agent (overrides AIMAX_AUTO_SKILLS_LOAD_ENABLED)`).option(`--auto-skills-review-mode <mode>`,`Auto-skill review mode: off, gate, dry_run, or write (overrides AIMAX_AUTO_SKILLS_REVIEW_MODE)`).option(`--message-id <id>`,`Message ID for correlating events`).option(`--user <id>`,`User identifier propagated to external callback and stream payloads`).option(`-c, --channel <channel>`,`Channel name (default: WEB)`,`WEB`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY)`).option(`--auth-token <token>`,`Auth token used to generate the API key`).option(`--model <name>`,`LLM model name (overrides AIMAX_MODEL)`).option(`--context-window <n>`,`LLM context window size`).option(`--callback-url <url>`,`HTTP callback URL for progress events`).option(`--stream-url <url>`,`WebSocket URL for streaming text events`).option(`--stream-auth-token <token>`,`Auth token for WebSocket streaming`).option(`--stream-events <list>`,`Comma-separated stream events`).option(`--timeout <ms>`,`Execution timeout in milliseconds`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--plugins-config <path>`,`Plugins config file path`).option(`--goal <text>`,`Set or replace the thread goal objective before resuming`).option(`--goal-file <path>`,`Read goal objective from a file`).option(`--token-budget <n>`,`Token budget for the goal (positive integer, or 0 for unlimited)`).option(`--force`,`Replace existing goal with a different objective`).option(`--encrypt-sessions`,`Enable encryption for the .aimax data directory`).action(async e=>{await pn(e)})}const gn=[`start`,`text`,`done`,`error`],_n=[`off`,`gate`,`dry_run`,`write`];function vn(e){if(!e?.trim())return new Set(gn);let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean),n=new Set([`start`,`text`,`progress`,`done`,`error`,`hitl`,`title_updated`]),r=new Set;for(let e of t){if(!n.has(e))throw Error(`Invalid stream event: ${e}. Must be one of start,text,progress,done,error,hitl,title_updated`);r.add(e)}return r.size>0?r:new Set(gn)}function yn(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir option or AIMAX_DATA_DIR environment variable`);return t}function bn(e){return e?.trim()||void 0}function xn(e){let t=(e.systemAgentsDir??process.env.AIMAX_SYSTEM_AGENTS_DIR)?.trim();if(t){if(!C.isAbsolute(t)){let n=e.systemAgentsDir===void 0?`AIMAX_SYSTEM_AGENTS_DIR`:`--system-agents-dir`;throw Error(`Invalid ${n}: ${t}. Path must be absolute.`)}return t}}function G(e){return e?.trim()||void 0}function Sn(e){return e??`WEB`}function K(e){return e?y(e):void 0}function Cn(e){if(!e?.trim())return[];let t=e.split(`,`).map(e=>e.trim()).filter(Boolean),n=new Set,r=[];for(let e of t){if(!C.isAbsolute(e))throw Error(`Invalid --skillsLoadPaths entry: ${e}. Each path must be absolute.`);n.has(e)||(n.add(e),r.push(e))}return r}function wn(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 Tn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(_n.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function En(e){let t=e.autoSkillsLoadEnabled===void 0?wn(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):wn(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?Tn(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):Tn(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 Dn(e,t){return e.length<=t?e:t<=3?e.slice(0,t):`${e.slice(0,t-3)}...`}function On(e,t,n=78){let r=n-2,i=r-2,a=e?` ${Dn(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=>`│ ${Dn(e,i).padEnd(i,` `)} │`),s].join(`
|
|
8
|
+
`)}function kn(e){return e.kind===`text`?`inline message (${e.message.length} chars)`:`message file (${e.messages.length} messages)`}function An(e,t){let n=K(e.sessionStore)??`sessions`,r=t.timeoutMs===void 0?`default`:`${t.timeoutMs}`,i=e.callbackUrl?`enabled`:`disabled`,a=e.streamUrl?`enabled`:`disabled`,o=kn(t.input),s=t.input.kind===`text`?`inline`:e.fromFile??`file`,c=Et();return{banner:On(void 0,[`AIMax CLI`,`Stateless Agent Runner`]),contextBox:On(`Run Context`,[`time : ${c}`,`channel : ${t.channel}`,`user : ${e.user??`-`}`,`sessionId : ${e.sessionId??`new`}`,`sessionStore : ${n}`,`messageId : ${e.messageId??`-`}`,`dataDir : ${t.dataDir}`,`workspace : ${C.join(t.dataDir,`workspace`)}`,`projectDir : ${bn(e.projectDir)??`-`}`,`systemAgents : ${t.systemAgentsDir??`/aimax/agents`}`,`agent : ${G(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:bn(e.projectDir),systemAgentsDir:t.systemAgentsDir,agent:G(e.agent),workspaceDir:C.join(t.dataDir,`workspace`),sessionId:e.sessionId??`new`,sessionStore:n,messageId:e.messageId,output:t.format,hasCallback:!!e.callbackUrl,hasStream:!!e.streamUrl,timeoutMs:t.timeoutMs,inputKind:t.input.kind,inputSource:s,inputSummary:o}}}async function jn(e,t){let n=yn(e),r=Sn(e.channel),i=pt({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:xn(e),channel:r,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:i,input:t,skillsLoadPaths:Cn(e.skillsLoadPaths),autoSkills:En(e)}}function Mn(e){if(e.kind===`text`)return e.message;if(e.messages.length!==1)return null;let[t]=e.messages;if(t.role!==`user`)return null;if(typeof t.content==`string`)return t.content;if(t.content.length===0)return null;let n=[];for(let e of t.content){if(e.type!==`text`)return null;n.push(e.text)}return n.join(`
|
|
9
|
+
`)}async function Nn(e,t){if(!e.sessionId)return null;let n=Mn(t);if(!n)return null;let r=await ee(yn(e),e.sessionId,{storeName:K(e.sessionStore),encryptSessions:e.encryptSessions});return!r||r.status!==`pending`||!he(n,r.request)?null:{requestId:r.request.requestId,inputText:n}}function Pn(e){let t=[],n=null;return e.callbackUrl&&t.push(new Rt(e.callbackUrl)),e.streamUrl&&(n=new Wt(e.streamUrl,vn(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new Lt(t),websocketSink:n}}async function q(e,t){H.info(`dispatching external event`,$n(t)),await e.sink.send(t)}function Fn(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 In(e){let t={sessionId:e.sessionId,messageId:e.messageId,parentSessionId:e.parentSessionId,depth:e.depth,scope:e.scope,phase:e.phase,...Fn(e.details)};if(e.level===`error`){H.error(e.message,t);return}if(e.level===`warn`){H.warn(e.message,t);return}H.info(e.message,t)}function Ln(e,t,n,r,i){return{sink:e,websocketSink:t,channel:n,defaultMessageId:r,user:i}}function Rn(){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 zn(e){return{activeSessionId:e??`pending`,finalResult:null}}function Bn(e,t){e.activeSessionId=t.sessionId??e.activeSessionId}function Vn(e,t){return e.messageId??t}async function Hn(e,t,n){if(!await m(e.dataDir)){if(await J(t,e.format,n.activeSessionId,e.dataDir,`checking`),(await l(e.dataDir)).performedBootstrap){await J(t,e.format,n.activeSessionId,e.dataDir,`initializing`),await J(t,e.format,n.activeSessionId,e.dataDir,`initialized`);return}await J(t,e.format,n.activeSessionId,e.dataDir,`ready`)}}async function J(e,t,n,r,i){let a={type:`bootstrap`,phase:i,dataDir:r};t===`text`&&k(a),await q(e,{sessionId:n,channel:e.channel,messageId:e.defaultMessageId,user:e.user,type:`progress`,event:a})}function Un(e,t,n){return async r=>{if(Bn(n,r),pe(r)){In(r);return}if(r.type===`stream_text_delta`){e.format===`text`&&k(r),await t.websocketSink?.sendTextDelta({sessionId:n.activeSessionId,channel:e.channel,messageId:Vn(r,t.defaultMessageId),user:t.user,text:r.text});return}e.format===`text`&&k(r);let i=Vn(r,t.defaultMessageId);if(r.type===`hitl_requested`){await q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`hitl`,request:r.request}),await q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r});return}if(r.type===`start`){await q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`start`,message:r.message});return}if(r.type===`session_reset`){await q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`session_reset`,action:r.action,previousSessionId:r.previousSessionId,message:r.message});return}await q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r})}}function Wn(e,t,n,r,i,a){let o={dataDir:t.dataDir,projectDir:bn(e.projectDir),systemAgentsDir:t.systemAgentsDir,agentPolicy:G(e.agent)?{requestedAgentName:G(e.agent)}:void 0,sessionStoreName:K(e.sessionStore),sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,abortSignal:n.signal,pendingGoal:a,encryptSessions:e.encryptSessions??!1,plugins:i?{config:i,dataDir:t.dataDir,workspaceDir:C.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:i.llmAllowlist}:void 0,onProgress:r};return t.input.kind===`messages`?{...o,messages:t.input.messages}:{...o,message:t.input.message}}async function Gn(e,t,n,r){if(t.activeSessionId=r.sessionId,t.finalResult=r,r.error){await q(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:r.error});return}await q(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`done`,result:{text:r.text,usage:r.usage,durationMs:r.durationMs,error:r.error,paused:r.paused}})}async function Kn(e,t,n,r){await q(e,{sessionId:t.finalResult?.sessionId??t.activeSessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:`Fatal: ${r.message}`})}function qn(e,t){let n=An(e,t);H.info([`run command started`,n.banner,n.contextBox].join(`
|
|
10
|
+
`),n.logContext),t.format===`text`&&(D(n.banner),D(``),D(n.contextBox),D(``))}function Jn(e,t,n){A(t,n),t.error?H.error(`run command failed: ${t.error}`):H.info(`run command succeeded`),e.end(),process.exit(t.error?1:0)}function Yn(e){let t=Ft();if(!t)return;let n=`[${Et()}] [ERROR] ${e}\n`;try{be.appendFileSync(C.join(t.logDir,`app.log`),n),be.appendFileSync(C.join(t.logDir,`errors.log`),n)}catch{}}async function Xn(e,t){let n=`run command error: ${t.message}`;H.error(n),Yn(n),O(`Fatal: ${t.message}`),e.end(),await It(),process.exit(1)}async function Zn(e){if(e.resumeInputJson&&e.resumeFromFile)throw Error(`--resume-input-json and --resume-from-file are mutually exclusive`);if(!e.resumeFromFile)return e.resumeInputJson;try{return await S.readFile(e.resumeFromFile,`utf-8`)}catch(e){throw Error(`Failed to read resume input file: ${e.message}`)}}async function Qn(e){let t=yn(e);V(t);let i=new U(`run command`),a=null;try{a=e.encryptSessions?await at(t):null,a&&V(t)}catch(e){await Xn(i,e);return}try{let t=await Zn(e);if(e.resumeRequestId||t||e.resumeFromFile){if(!e.sessionId||!e.resumeRequestId||!t)throw Error(`--session-id, --resume-request-id, and exactly one of --resume-input-json or --resume-from-file must be provided together`);await pn({dataDir:e.dataDir,projectDir:e.projectDir,systemAgentsDir:e.systemAgentsDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:e.resumeRequestId,inputJson:t,channel:e.channel,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow,flashModel:e.flashModel,callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamAuthToken:e.streamAuthToken,streamEvents:e.streamEvents,timeout:e.timeout,output:e.output,pluginsConfig:e.pluginsConfig,skillsLoadPaths:e.skillsLoadPaths,autoSkillsLoadEnabled:e.autoSkillsLoadEnabled,autoSkillsReviewMode:e.autoSkillsReviewMode,messageId:e.messageId,user:e.user,goal:e.goal,goalFile:e.goalFile,tokenBudget:e.tokenBudget,force:e.force,encryptSessions:e.encryptSessions});return}let a;try{a=await wt({message:e.message,fromFile:e.fromFile})}catch(e){await Xn(i,e);return}let o=await Nn(e,a);if(o){await pn({dataDir:e.dataDir,projectDir:e.projectDir,systemAgentsDir:e.systemAgentsDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:o.requestId,inputText:o.inputText,channel:e.channel,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow,flashModel:e.flashModel,callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamAuthToken:e.streamAuthToken,streamEvents:e.streamEvents,timeout:e.timeout,output:e.output,pluginsConfig:e.pluginsConfig,skillsLoadPaths:e.skillsLoadPaths,autoSkillsLoadEnabled:e.autoSkillsLoadEnabled,autoSkillsReviewMode:e.autoSkillsReviewMode,messageId:e.messageId,user:e.user,goal:e.goal,goalFile:e.goalFile,tokenBudget:e.tokenBudget,force:e.force,encryptSessions:e.encryptSessions});return}let{controller:s,cleanup:c}=Rn(),l=null,u=e.channel??`WEB`,d=zn(e.sessionId);try{let t=await jn(e,a);u=t.channel,qn(e,t);let o=Pn(e);l=o.sink,H.info(`external sink configured`,{callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamEvents:e.streamEvents});let c=Ln(l,o.websocketSink,t.channel,e.messageId,e.user);await Hn(t,c,d);let f,p=null;if(e.goal||e.goalFile){let i;i=e.goalFile?await S.readFile(e.goalFile,`utf-8`):e.goal;let a=Gt(i),o=K(e.sessionStore),s=e.tokenBudget===void 0?void 0:e.tokenBudget===`0`||e.tokenBudget===``?null:Number(e.tokenBudget);s!=null&&(Number.isNaN(s)||s<=0)&&(O(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));try{if(e.sessionId){let n=await b(t.dataDir,e.sessionId,{storeName:o}),i=await r({dataDir:t.dataDir,sessionId:e.sessionId,objective:a,tokenBudget:s,force:e.force,storeName:o});p=qt({sessionId:e.sessionId,before:n,result:i})}else f={objective:a,tokenBudget:s??null}}catch(e){throw e instanceof n&&(O(e.message),O(`Existing: ${e.existingObjectivePreview}`),process.exit(2)),e}}let m=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,h=await I(t.dataDir,m),g=Un(t,c,d);p&&await g(p);let _=await x(Wn(e,t,s,g,h,f));await Gn(c,d,e.messageId,_),Jn(i,_,t.format)}catch(t){let n=t;l&&await Kn(Ln(l,null,u,e.messageId,e.user),d,e.messageId,n),await Xn(i,n)}finally{await l?.close(),c()}}finally{await a?.cleanup()}}function $n(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 er(e){e.command(`run`).description(`Run an agent task`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--project-dir <path>`,`Current project directory used as the default cwd context`).option(`--system-agents-dir <path>`,`System agent definition directory (overrides AIMAX_SYSTEM_AGENTS_DIR, default: /aimax/agents)`).option(`--agent <name>`,`Custom agent name to run as the root agent`).option(`--user <id>`,`User identifier propagated to external callback and stream payloads`).option(`--message <text>`,`User message to send to the agent`).option(`--from-file <path>`,`Load structured Message JSON from a file`).option(`--skillsLoadPaths <paths>`,`Comma-separated absolute skill load paths`).option(`--auto-skills-load-enabled <boolean>`,`Enable learned auto-skill loading for the main agent (overrides AIMAX_AUTO_SKILLS_LOAD_ENABLED)`).option(`--auto-skills-review-mode <mode>`,`Auto-skill review mode: off, gate, dry_run, or write (overrides AIMAX_AUTO_SKILLS_REVIEW_MODE)`).option(`-s, --session-id <id>`,`Resume an existing session by ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`--message-id <id>`,`Message ID for correlating events`).option(`-c, --channel <channel>`,`Channel name (default: WEB)`,`WEB`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY)`).option(`--auth-token <token>`,`Auth token used to generate the API key (highest priority)`).option(`--model <name>`,`LLM model name (overrides AIMAX_MODEL)`).option(`--context-window <n>`,`LLM context window size`).option(`--flash-model <name>`,`Flash model for lightweight tasks like title generation (overrides AIMAX_FLASH_MODEL)`).option(`--callback-url <url>`,`HTTP callback URL for progress events`).option(`--stream-url <url>`,`WebSocket URL for streaming text events`).option(`--stream-auth-token <token>`,`Auth token for WebSocket streaming`).option(`--stream-events <list>`,`Comma-separated stream events: start,text,progress,done,error`).option(`--timeout <ms>`,`Execution timeout in milliseconds (default: 600000)`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--plugins-config <path>`,`Plugins config file path`).option(`--goal <text>`,`Set or replace the thread goal objective before running`).option(`--goal-file <path>`,`Read goal objective from a file`).option(`--token-budget <n>`,`Token budget for the goal (positive integer, or 0 for unlimited)`).option(`--force`,`Replace existing goal with a different objective`).option(`--resume-request-id <id>`,`Resume a pending HITL request from aimax run`).option(`--resume-input-json <json>`,`Structured HITL resume payload used with --resume-request-id`).option(`--resume-from-file <path>`,`Load structured HITL resume payload from a file (alternative to --resume-input-json)`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{await Qn(e)})}function tr(e){e.command(`sessions`).description(`List or inspect sessions for a data directory`).argument(`[action]`,`Action: list (default) | inspect | export`).option(`-d, --data-dir <path>`,`Data directory path`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`-c, --channel <channel>`,`Filter by channel type: H5 | WEB | KLPA | TASK | CRON | EIP_ASSISTANT`).option(`-s, --session-id <id>`,`Session ID for inspect/export`).option(`--output <format>`,`Output format: text or json`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async(e,t,n)=>{let r=n.opts(),i=e??`list`,a=i===`export`?r.output===`text`?`text`:`json`:r.output===`json`?`json`:`text`;r.dataDir||(O(`error: required option '-d, --data-dir <path>' not specified`),process.exit(1)),r.channel&&r.channel!==`H5`&&r.channel!==`WEB`&&r.channel!==`KLPA`&&r.channel!==`TASK`&&r.channel!==`CRON`&&r.channel!==`EIP_ASSISTANT`&&(O(`Invalid channel: ${r.channel}. Must be 'H5', 'WEB', 'KLPA', 'TASK', 'CRON', or 'EIP_ASSISTANT'`),process.exit(1));try{await F(r.dataDir,r,async()=>{let e=r.sessionStore?y(r.sessionStore):void 0;if(i===`list`){Pe(await v(r.dataDir,r.channel,{storeName:e}),a);return}if(r.sessionId||(O(`error: required option '-s, --session-id <id>' not specified`),process.exit(1)),i===`inspect`){Fe(await g(r.dataDir,r.sessionId,{storeName:e}),a);return}if(i===`export`){Ie(await u(r.dataDir,r.sessionId,{storeName:e}),a);return}O(`Invalid sessions action: ${i}. Must be 'list', 'inspect', or 'export'`),process.exit(1)})}catch(e){O(`${i===`inspect`?`Error inspecting session`:i===`export`?`Error exporting session`:`Error listing sessions`}: ${e.message}`),process.exit(1)}})}function nr(e){return C.join(e,`workspace`)}function rr(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function ir(e,t){let n=[];n.push(`backend: ${e.backend}`),n.push(`provider: ${e.provider}${e.model?` (${e.model})`:``}`);let r=typeof e.custom?.providerSource==`string`?e.custom.providerSource:void 0,i=typeof e.custom?.providerId==`string`?e.custom.providerId:void 0,a=typeof e.custom?.pluginId==`string`?e.custom.pluginId:void 0;r&&n.push(`provider_source: ${r}`),i&&n.push(`provider_id: ${i}`),a&&n.push(`plugin_id: ${a}`),typeof e.files==`number`&&n.push(`files: ${e.files}`),typeof e.chunks==`number`&&n.push(`chunks: ${e.chunks}`),typeof e.dirty==`boolean`&&n.push(`dirty: ${e.dirty}`),e.dbPath&&n.push(`db: ${e.dbPath}`),e.sources?.length&&n.push(`sources: ${e.sources.join(`, `)}`),t&&(e.fts&&(n.push(`fts: enabled=${e.fts.enabled} available=${e.fts.available}`),e.fts.error&&n.push(`fts_error: ${e.fts.error}`)),e.vector&&(n.push(`vector: enabled=${e.vector.enabled} available=${e.vector.available??`unknown`}`),e.vector.dims&&n.push(`vector_dims: ${e.vector.dims}`),e.vector.loadError&&n.push(`vector_error: ${e.vector.loadError}`)),e.cache&&n.push(`cache: enabled=${e.cache.enabled} entries=${e.cache.entries??0}`));let o=Array.isArray(e.custom?.cliWarnings)?e.custom.cliWarnings.filter(e=>typeof e==`string`&&e.length>0):[];for(let e of o)n.push(`warning: ${e}`);return n.join(`
|
|
11
|
+
`)}function ar(e){let t=e.level===`error`?`plugin error`:`plugin warning`;return e.pluginId?`${t} (${e.pluginId}): ${e.message}`:`${t}: ${e.message}`}function or(e){if(!e||e===`cli`)return`cli`;if(e===`cron`)return`cron`;throw Error(`Unsupported dream trigger: ${e}. Expected "cli" or "cron".`)}async function sr(e){let t=[],n;try{n=await I(e.dataDir,e.pluginsConfig)}catch(e){t.push(`failed to load plugins config: ${e.message}`)}if(!e.shouldInitialize&&!n)return{warnings:t};try{let r=h({config:n,dataDir:e.dataDir,workspaceDir:nr(e.dataDir),bundledDir:rr()});return t.push(...r.diagnostics.map(ar)),{pluginSystem:r,warnings:t}}catch(e){return t.push(`failed to initialize plugin system: ${e.message}`),{warnings:t}}}async function cr(e){let t=C.join(e.dataDir,`.aimax`),{pluginSystem:n,warnings:r}=await sr({dataDir:e.dataDir,pluginsConfig:e.pluginsConfig,shouldInitialize:!!(e.requirePluginSystem||e.provider||e.providerPlugin)}),i=n?.normalizedConfig.slots.memory,a=e.providerPlugin?.trim()||(e.provider?void 0:i),o=oe({providerId:e.provider,pluginId:a,dataDir:e.dataDir,memoryDir:t});return o?{provider:o.provider,providerId:o.registration.id,pluginId:o.registration.pluginId,providerOrigin:`plugin`,warnings:r,pluginSystem:n}:((a||e.provider)&&r.push(`requested memory provider was not resolved; falling back to builtin provider`),{provider:s({dataDir:e.dataDir,memoryDir:t},{includeSessions:e.includeSessions}),providerId:`builtin`,providerOrigin:`builtin`,warnings:r,pluginSystem:n})}function lr(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 ur(e){let t=e.command(`memory`).description(`Manage semantic memory indexing and search`),n=e=>e.option(`--plugins-config <path>`,`Plugins config file path`);n(t.command(`status`)).description(`Show memory index status`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--deep`,`Probe embedding/vector availability`).option(`--index`,`Run a refresh before reporting status`).option(`--include-sessions`,`Include session transcripts in indexing`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--verbose`,`Verbose output`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{await F(e.dataDir,e,async()=>{let n=await cr({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=lr(n.provider.status(),n,e.deep);D(t===`json`?JSON.stringify(r,null,2):ir(r,e.deep))})}catch(e){O(`Error getting memory status: ${e.message}`),process.exit(1)}}),n(t.command(`index`)).description(`Reindex memory files`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--include-sessions`,`Include session transcripts in indexing`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--rebuild`,`Force full rebuild from Markdown source`).option(`--verbose`,`Verbose output`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{try{await F(e.dataDir,e,async()=>{let t=await cr({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,pluginsConfig:e.pluginsConfig,includeSessions:e.includeSessions}),n;if(t.provider.sync&&(await t.provider.sync(e.rebuild?`cli-rebuild`:`cli-index`),n=t.provider.status().custom?.lastRebuildSummary),t.warnings.length>0)for(let e of t.warnings)O(`Warning: ${e}`);e.verbose&&n&&D(JSON.stringify(n,null,2)),D(e.rebuild?`Memory index rebuilt.`:`Memory index refreshed.`)})}catch(e){O(`Error indexing memory: ${e.message}`),process.exit(1)}}),n(t.command(`search [query]`)).description(`Search semantic memory`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--query <text>`,`Search query`).option(`--include-sessions`,`Include session transcripts in search`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async(e,t)=>{let n=t.output===`json`?`json`:`text`,r=t.query?.trim()||e?.trim();r||(O(`Query is required: provide [query] or --query <text>`),process.exit(1));try{await F(t.dataDir,t,async()=>{let e=await(await cr({dataDir:t.dataDir,provider:t.provider,providerPlugin:t.providerPlugin,pluginsConfig:t.pluginsConfig,includeSessions:t.includeSessions})).provider.search(r);if(n===`json`){D(JSON.stringify(e,null,2));return}if(e.length===0){D(`No results found for: ${r}`);return}D(e.map(e=>{let t=`${e.path}:${e.startLine}-${e.endLine} (${e.score.toFixed(4)}) ${e.snippet}`;return e.citation?`${t}\n${e.citation}`:t}).join(`
|
|
12
|
+
`))})}catch(e){O(`Error searching memory: ${e.message}`),process.exit(1)}}),n(t.command(`dream`)).description(`Trigger Dream Gate host hook for memory plugins`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--trigger <mode>`,`Dream Gate trigger mode: cli (default) or cron`,`cli`).option(`--dry-run`,`Return hook results without plugin-side mutation`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{await F(e.dataDir,e,async()=>{let n=or(e.trigger),r=await cr({dataDir:e.dataDir,provider:e.provider,providerPlugin:e.providerPlugin,pluginsConfig:e.pluginsConfig,requirePluginSystem:!0}),i=r.pluginSystem?await r.pluginSystem.registry.hooks.dispatch(`dream_gate`,{dataDir:e.dataDir,memoryDir:C.join(e.dataDir,`.aimax`),providerId:r.providerId,pluginId:r.pluginId,trigger:n,dryRun:!!e.dryRun},{workspaceDir:nr(e.dataDir)}):[],a={ok:!0,trigger:n,providerSource:r.providerOrigin,providerId:r.providerId,pluginId:r.pluginId,resultCount:i.length,results:i,warnings:r.warnings};if(t===`json`){D(JSON.stringify(a,null,2));return}D(`trigger: ${a.trigger}`),D(`provider_source: ${a.providerSource}`),D(`provider_id: ${a.providerId}`),a.pluginId&&D(`plugin_id: ${a.pluginId}`),D(`result_count: ${a.resultCount}`),a.results.length===0?D(`note: no dream_gate hook registered`):D(`results: ${JSON.stringify(a.results)}`);for(let e of a.warnings)D(`warning: ${e}`)})}catch(e){O(`Error running dream gate: ${e.message}`),process.exit(1)}})}function dr(e){return`${e.match.accountId?`${e.match.channel}:${e.match.accountId}`:e.match.channel} -> ${e.agentId}`}function fr(e){return async t=>{let n=await T(t),r=Te(n),i=Ee(n);if(E(n),e.json){console.log(JSON.stringify({agents:r,bindings:i},null,2));return}console.log(`Agents:`);for(let e of r){let n=e.default?` (default)`:``,r=e.name&&e.name!==e.id?`${e.id}${n} (${e.name})`:`${e.id}${n}`;if(console.log(` - ${r}`),e.identity?.emoji||e.identity?.name){let t=[e.identity.emoji,e.identity.name].filter(Boolean).join(` `);console.log(` Identity: ${t}`)}let a=Ae(t,e.id);if(console.log(` Agent dir: ${a}`),e.model){let t=typeof e.model==`string`?e.model:e.model.primary;console.log(` Model: ${t}`)}let o=i.filter(t=>t.agentId===e.id);if(o.length>0){console.log(` Routing rules:`);for(let e of o)console.log(` - ${dr(e)}`)}}}}function pr(e,t){return async n=>{w(await T(n),De(e))&&(console.error(`Agent "${e}" already exists.`),process.exit(1)),await Ce(n,{id:e,name:t.name,model:t.model,default:t.default})||(console.error(`Agent "${e}" already exists.`),process.exit(1));let r=Ae(n,e);console.log(`Agent "${e}" added successfully.`),console.log(` Agent dir: ${r}`)}}function mr(e){return async t=>{let n=w(await T(t),De(e));n||(console.error(`Agent "${e}" not found.`),process.exit(1)),n.default===!0&&(console.error(`Cannot delete default agent "${e}".`),process.exit(1)),await Oe(t,e)||(console.error(`Failed to delete agent "${e}".`),process.exit(1)),console.log(`Agent "${e}" deleted.`)}}function hr(e){return async t=>{let n=await T(t),r=e.agent??E(n);w(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),(!e.bind||e.bind.length===0)&&(console.error(`Please specify --bind <channel>[:<account>]`),process.exit(1));for(let n of e.bind){let[e,...i]=n.split(`:`),a=i.join(`:`),o=[`H5`,`WEB`,`KLPA`,`TASK`,`CRON`,`EIP_ASSISTANT`];o.includes(e)||(console.error(`Invalid channel: ${e}`),console.error(`Valid channels: ${o.join(`, `)}`),process.exit(1)),await we(t,{agentId:r,match:{channel:e,accountId:a||void 0}}),console.log(`Binding added: ${n} -> ${r}`)}}}function gr(e){return async t=>{let n=await T(t),r=e.agent??E(n);if(w(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),e.all){let e=await ke(t,r,`*`);console.log(`Removed ${e} binding(s) for agent "${r}".`)}else if(e.bind&&e.bind.length>0){let n=0;for(let i of e.bind){let[e,...a]=i.split(`:`),o=await ke(t,r,e,a.join(`:`)||void 0);o>0?(console.log(`Binding removed: ${i} -> ${r}`),n+=o):console.log(`No binding found: ${i} -> ${r}`)}}else console.error(`Please specify --bind <channel>[:<account>] or --all`),process.exit(1)}}function _r(e){return async t=>{let n=Ee(await T(t));if(e.agent&&(n=n.filter(t=>t.agentId===e.agent)),e.json){console.log(JSON.stringify(n,null,2));return}if(n.length===0){console.log(`No bindings configured.`);return}console.log(`Routing bindings:`);for(let e of n)console.log(` ${dr(e)}`)}}function vr(e){return async t=>{let n=await T(t),r=e.agent??E(n);w(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),await je(t,r,{name:e.name,emoji:e.emoji,avatar:e.avatar})||(console.error(`Failed to update identity for agent "${r}".`),process.exit(1)),console.log(`Identity updated for agent "${r}".`)}}function yr(e,t){let n=e.command(`agents`).description(`Manage agents`),r=e=>e.option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`);r(n.command(`list`).description(`List all configured agents`).option(`-j, --json`,`Output as JSON`).option(`-b, --bindings`,`Show detailed binding rules`)).action(async e=>{let n=t();await F(n,e,async()=>{await fr(e)(n)})}),r(n.command(`add <id>`).description(`Add a new agent`).option(`-n, --name <name>`,`Display name`).option(`-m, --model <model>`,`Model identifier`).option(`--default`,`Mark as default agent`)).action(async(e,n)=>{let r=t();await F(r,n,async()=>{await pr(e,n)(r)})}),r(n.command(`delete <id>`).description(`Delete an agent`)).action(async(e,n)=>{let r=t();await F(r,n,async()=>{await mr(e)(r)})}),r(n.command(`bind`).description(`Bind a channel to an agent`).option(`-a, --agent <id>`,`Target agent ID`).option(`-b, --bind <channel...>`,`Channel binding (e.g., WEB, KLPA:ops)`)).action(async e=>{let n=t();await F(n,e,async()=>{await hr(e)(n)})}),r(n.command(`unbind`).description(`Unbind a channel from an agent`).option(`-a, --agent <id>`,`Target agent ID`).option(`-b, --bind <channel...>`,`Channel binding to remove`).option(`--all`,`Remove all bindings for the agent`)).action(async e=>{let n=t();await F(n,e,async()=>{await gr(e)(n)})}),r(n.command(`bindings`).description(`List routing bindings`).option(`-a, --agent <id>`,`Filter by agent ID`).option(`-j, --json`,`Output as JSON`)).action(async e=>{let n=t();await F(n,e,async()=>{await _r(e)(n)})}),r(n.command(`set-identity`).description(`Set agent identity`).option(`-a, --agent <id>`,`Target agent ID`).option(`-n, --name <name>`,`Agent name`).option(`-e, --emoji <emoji>`,`Agent emoji`).option(`--avatar <path>`,`Avatar path`)).action(async e=>{let n=t();await F(n,e,async()=>{await vr(e)(n)})})}function Y(e){return C.join(e,`workspace`)}function X(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function br(e){if(e.length===0){D(`No plugins discovered.`);return}for(let t of e){let e=t.status.padEnd(8,` `);D(`${t.id} ${e} ${t.origin} ${t.source}`)}}function xr(e){D(`id: ${e.id}`),D(`status: ${e.status}`),D(`origin: ${e.origin}`),D(`source: ${e.source}`),D(`enabled: ${e.enabled}`),e.error&&D(`error: ${e.error}`),D(`tools: ${e.toolCount}`),D(`hooks: ${e.hookCount}`),e.skills.length>0&&D(`skills: ${e.skills.join(`, `)}`)}function Sr(e){return Array.from(new Set((e??[]).map(e=>e.trim()).filter(Boolean)))}function Cr(e){if(e.length===0){D(`LLM allowlist is empty.`);return}for(let t of e)D(t)}function wr(e,t){let n=e.command(`plugins`).description(`Manage AIMax plugins`),r=e=>e.option(`--plugins-config <path>`,`Plugins config file path`),i=e=>e.option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`);i(r(n.command(`list`))).description(`List discovered plugins`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await F(n,e,async()=>{br(h({config:await I(n,e.pluginsConfig),dataDir:n,workspaceDir:Y(n),bundledDir:X()}).registry.plugins)})}),i(r(n.command(`info`))).description(`Show plugin details`).argument(`<id>`,`Plugin id`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await F(r,n,async()=>{let t=h({config:await I(r,n.pluginsConfig),dataDir:r,workspaceDir:Y(r),bundledDir:X()}).registry.plugins.find(t=>t.id===e);t||(O(`Plugin not found: ${e}`),process.exit(1)),xr(t)})}),i(r(n.command(`enable`))).description(`Enable a plugin`).argument(`<id>`,`Plugin id`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await F(r,n,async()=>{let t=await I(r,n.pluginsConfig)??{},i=ie(t);h({config:t,dataDir:r,workspaceDir:Y(r),bundledDir:X()}).registry.plugins.some(t=>t.id===e)||(O(`Plugin not found: ${e}`),process.exit(1)),await L(r,{...t,entries:{...t.entries,[e]:{...t.entries?.[e]??{},enabled:!0}}},n.pluginsConfig),D(`Enabled ${e}`),i.allow.length>0&&!i.allow.includes(e)&&D(`Note: plugins.allow is set; add this plugin id to allowlist if needed.`)})}),i(r(n.command(`disable`))).description(`Disable a plugin`).argument(`<id>`,`Plugin id`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await F(r,n,async()=>{let t=await I(r,n.pluginsConfig)??{};h({config:t,dataDir:r,workspaceDir:Y(r),bundledDir:X()}).registry.plugins.some(t=>t.id===e)||(O(`Plugin not found: ${e}`),process.exit(1)),await L(r,{...t,entries:{...t.entries,[e]:{...t.entries?.[e]??{},enabled:!1}}},n.pluginsConfig),D(`Disabled ${e}`)})}),i(r(n.command(`doctor`))).description(`Validate plugin configuration`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await F(n,e,async()=>{let t=h({config:await I(n,e.pluginsConfig),dataDir:n,workspaceDir:Y(n),bundledDir:X()});if(t.diagnostics.length===0){D(`No plugin issues detected.`);return}for(let e of t.diagnostics)D(`${e.level===`error`?`ERROR`:`WARN`}${e.pluginId?` ${e.pluginId}`:``}: ${e.message}`);t.diagnostics.some(e=>e.level===`error`)&&process.exit(1)})});let a=n.command(`llm-allow`).description(`Manage plugin LLM allowlist`);i(r(a.command(`list`))).description(`List LLM allowlist entries`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await F(n,e,async()=>{Cr(Sr((await I(n,e.pluginsConfig))?.llmAllowlist))})}),i(r(a.command(`add`))).description(`Add entries to the LLM allowlist (plugin id or tool name)`).argument(`<entry...>`,`Plugin id or tool name`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await F(r,n,async()=>{let t=await I(r,n.pluginsConfig)??{},i=Sr([...t.llmAllowlist??[],...e]);await L(r,{...t,llmAllowlist:i},n.pluginsConfig),D(`LLM allowlist updated (${i.length} entries).`)})}),i(r(a.command(`remove`))).description(`Remove entries from the LLM allowlist`).argument(`<entry...>`,`Plugin id or tool name`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await F(r,n,async()=>{let t=await I(r,n.pluginsConfig)??{},i=new Set(e.map(e=>e.trim()).filter(Boolean)),a=Sr(t.llmAllowlist).filter(e=>!i.has(e));await L(r,{...t,llmAllowlist:a},n.pluginsConfig),D(`LLM allowlist updated (${a.length} entries).`)})}),i(r(a.command(`clear`))).description(`Clear the LLM allowlist`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await F(n,e,async()=>{await L(n,{...await I(n,e.pluginsConfig)??{},llmAllowlist:[]},e.pluginsConfig),D(`LLM allowlist cleared.`)})})}function Tr(e){e.command(`commands`).description(`List available slash commands for a data directory`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{await F(e.dataDir,e,async()=>{let n=_(await ne(e.dataDir,[]));if(t===`json`){D(JSON.stringify(n,null,2));return}D(`Commands`),D(` builtin: ${n.builtin.map(e=>e.name).join(` | `)}`),n.skillCommands.length>0?D(` skills: ${n.skillCommands.map(e=>e.name).join(` | `)}`):D(` skills: (none)`)})}catch(e){O(`Error listing commands: ${e.message}`),process.exit(1)}})}function Z(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir option or AIMAX_DATA_DIR environment variable`);return t}function Q(e){if(!e.sessionId)throw Error(`Session ID is required (--session-id or -s)`);return e.sessionId}function $(e){return e?y(e):void 0}async function Er(e){let t={storeName:e.sessionStoreName},n=e.objective.trim(),r=await b(e.dataDir,e.sessionId,t);if(!r||(await ae(e.dataDir,e.sessionId,r,t)).trim()!==n)return de(e.dataDir,e.sessionId,{goalId:Me(),objective:n,status:`active`,tokenBudget:e.tokenBudget??null,tokensUsed:0,timeUsedSeconds:0},{...t,eventSource:`cli`});if(r.status===`complete`)return r;let i={};return r.status===`paused`&&(i.status=`active`),e.tokenBudget!==void 0&&e.tokenBudget!==r.tokenBudget&&(i.tokenBudget=e.tokenBudget),Object.keys(i).length===0?r:await ue(e.dataDir,e.sessionId,i,{...t,eventSource:`cli`})}async function Dr(e,t){let n=Z(t),r=Q(t),i=$(t.sessionStore),a=e.trim();a||(O(`error: objective cannot be empty`),process.exit(1));let o=t.tokenBudget===void 0||t.tokenBudget===`0`||t.tokenBudget===``?null:Number(t.tokenBudget);o!==null&&(Number.isNaN(o)||o<=0)&&(O(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));let s=await Er({dataDir:n,sessionId:r,sessionStoreName:i,objective:a,tokenBudget:o});D(JSON.stringify({goal:s},null,2))}async function Or(e){let t=Z(e),n=Q(e),r=$(e.sessionStore),i=await b(t,n,{storeName:r});if(!i){D(JSON.stringify({goal:null},null,2));return}let a=await ae(t,n,i,{storeName:r});D(JSON.stringify({goal:{...i,objective:a}},null,2))}async function kr(e){let t=Z(e),n=Q(e),r=$(e.sessionStore),i=await b(t,n,{storeName:r});i||(O(`error: no goal exists for this session`),process.exit(1)),i.status===`complete`&&(O(`error: cannot pause a completed goal`),process.exit(1));let a=await ue(t,n,{status:`paused`},{storeName:r,eventSource:`cli`});D(JSON.stringify({goal:a},null,2))}async function Ar(e){let t=Z(e),n=Q(e),r=$(e.sessionStore),i=await b(t,n,{storeName:r});if(i||(O(`error: no goal exists for this session`),process.exit(1)),i.status===`complete`&&(O(`error: cannot resume a completed goal`),process.exit(1)),i.status===`budget_limited`&&(O(`error: cannot resume a budget-limited goal; clear or replace it instead`),process.exit(1)),i.status===`active`){D(JSON.stringify({goal:i},null,2));return}let a=await ue(t,n,{status:`active`},{storeName:r,eventSource:`cli`});D(JSON.stringify({goal:a},null,2))}async function jr(e){let t=await c(Z(e),Q(e),{storeName:$(e.sessionStore),eventSource:`cli`});D(JSON.stringify({cleared:t},null,2))}function Mr(e){let t=e.command(`goal`).description(`Manage thread goals for a session`);t.command(`set <objective>`).description(`Set or replace the thread goal (creates new goalId)`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).requiredOption(`-s, --session-id <id>`,`Session ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`--token-budget <n>`,`Optional token budget (positive integer, or 0 for unlimited)`).action(async(e,t)=>{try{await Dr(e,t)}catch(e){O(`error: ${e.message}`),process.exit(1)}}),t.command(`get`).description(`Get the current goal as JSON`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).requiredOption(`-s, --session-id <id>`,`Session ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).action(async e=>{try{await Or(e)}catch(e){O(`error: ${e.message}`),process.exit(1)}}),t.command(`pause`).description(`Pause the current goal`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).requiredOption(`-s, --session-id <id>`,`Session ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).action(async e=>{try{await kr(e)}catch(e){O(`error: ${e.message}`),process.exit(1)}}),t.command(`resume`).description(`Resume a paused goal`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).requiredOption(`-s, --session-id <id>`,`Session ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).action(async e=>{try{await Ar(e)}catch(e){O(`error: ${e.message}`),process.exit(1)}}),t.command(`clear`).description(`Clear the current goal`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).requiredOption(`-s, --session-id <id>`,`Session ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).action(async e=>{try{await jr(e)}catch(e){O(`error: ${e.message}`),process.exit(1)}})}const Nr=[`progress`,`error`,`hitl`];function Pr(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 Fr(e){if(!e?.trim())return new Set(Nr);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(Nr)}function Ir(e){return e?y(e):void 0}function Lr(e){let t=[];return e.callbackUrl&&t.push(new Rt(e.callbackUrl)),e.streamUrl&&t.push(new Wt(e.streamUrl,Fr(e.streamEvents),e.streamAuthToken)),new Lt(t)}async function Rr(e){let t=Pr(e);await F(t,e,async()=>{V(t);let n=new U(`cancel command`),r=e.channel??`WEB`,i=e.output===`json`?`json`:`text`,a=Lr(e),o=Ir(e.sessionStore);try{let s=await ee(t,e.sessionId,{storeName:o});if(!s)throw Error(`No pending HITL request found for session "${e.sessionId}"`);let c=e.requestId??s.request.requestId;if(s.request.requestId!==c)throw Error(`Request ID mismatch: pending is "${s.request.requestId}", got "${c}"`);if(!(await se({dataDir:t,sessionStoreName:o,sessionId:e.sessionId,requestId:c,resolution:{requestId:c,sessionId:e.sessionId,action:`cancel`,submittedAt:new Date().toISOString(),submittedBy:{channel:r}}})).state)throw Error(`Failed to cancel HITL request`);let l={type:`hitl_cancelled`,sessionId:e.sessionId,requestId:c,reason:e.reason??`cancelled by operator`};i===`text`&&k(l),await a.send({type:`progress`,sessionId:e.sessionId,channel:r,messageId:e.messageId,event:l}),n.end(),process.exit(0)}catch(t){let i=t;await a.send({type:`error`,sessionId:e.sessionId,channel:r,messageId:e.messageId,message:i.message}),H.error(`cancel command error: ${i.message}`),O(`Fatal: ${i.message}`),n.end(),process.exit(1)}finally{await a.close()}})}function zr(e){e.command(`cancel`).description(`Cancel a pending HITL request`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).requiredOption(`-s, --session-id <id>`,`Session ID containing the pending HITL request`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`--request-id <id>`,`HITL request ID to cancel`).option(`--reason <text>`,`Human-readable cancel reason`).option(`-c, --channel <channel>`,`Channel type (default: WEB)`,`WEB`).option(`--callback-url <url>`,`HTTP callback URL for progress events`).option(`--stream-url <url>`,`WebSocket URL for streaming text events`).option(`--stream-auth-token <token>`,`Auth token for WebSocket streaming`).option(`--stream-events <list>`,`Comma-separated stream events`).option(`--message-id <id>`,`Message ID for correlating events`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{await Rr(e)})}function Br(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 Vr(e){return e.query?.trim()||void 0}function Hr(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 Ur(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 Wr(e){if(e.filePath){if(!C.isAbsolute(e.filePath))throw Error(`--file-path must be an absolute path`);try{await S.access(e.filePath)}catch(e){throw Error(`Failed to access --file-path: ${e.message}`)}return{source:`file`,filePath:e.filePath}}let t=e.content;if(!t||!t.trim())throw Error(`Either --file-path or --content must be provided`);return{source:`content`,content:t}}async function Gr(e){let t=null;try{let n=Br(e);V(n),t=new U(`summarize command`);let r=Vr(e),i=await Wr(e),a=pt({baseUrl:e.baseUrl,apiKey:e.apiKey,model:e.model,contextWindow:2e5}),o=Hr(e.timeout),s=Ur(e.maxTokens);H.info(`summarize command started`,{dataDir:n,source:i.source,filePath:i.source===`file`?i.filePath:void 0,queryLength:r?.length,contentLength:i.source===`content`?i.content.length:void 0,timeoutMs:o,maxTokens:s});let c=await x({dataDir:n,channel:`WEB`,message:Kr(i,r),llm:{...a,maxTokens:s},timeoutMs:o});D(c.text.trim()),H.info(`summarize command succeeded`,{source:i.source,summaryLength:c.text.length,durationMs:c.durationMs}),t.end()}catch(e){H.error(`summarize command error: ${e.message}`),O(`Fatal: ${e.message}`),t?.end(),process.exit(1)}}function Kr(e,t){return e.source===`file`?[t?`Summarize exactly one file for the query below.`:`Summarize exactly one file.`,`Read only the absolute file path provided here. Do not search, browse, read other files, execute commands, modify files, or perform any other processing.`,`Return only the summary text.`,``,...t?[`Query:\n${t}`,``]:[],`Input source: file`,`File path: ${e.filePath}`].join(`
|
|
13
|
+
`):[t?`Summarize the provided content for the query below.`:`Summarize the provided content.`,t?`Use only the provided content and query. Do not search, browse, read files, execute commands, modify files, or perform any other processing.`:`Use only the provided content. Do not search, browse, read files, execute commands, modify files, or perform any other processing.`,`Return only the summary text.`,``,...t?[`Query:\n${t}`,``]:[],`Input source: content`,`Source content:`,`<source>`,e.content,`</source>`].join(`
|
|
14
|
+
`)}function qr(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 Gr(e)})}const Jr=e(import.meta.url)(`../package.json`);function Yr(){return process.env.AIMAX_DATA_DIR||process.cwd()}function Xr(){let e=new t;return e.name(`aimax`).description(`AIMax CLI — runs agent tasks in a containerized environment`).version(Jr.version),er(e),hn(e),Mr(e),zr(e),tr(e),qr(e),Tr(e),ut(e),ur(e),yr(e,Yr),wr(e,Yr),e}export{It as a,H as i,Yr as n,V as r,Xr as t};
|
package/dist/program.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,t}from"./program-
|
|
1
|
+
import{n as e,t}from"./program-Cc5_Ama2.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.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"aimax": "./dist/bin.js"
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"commander": "^14.0.3",
|
|
23
23
|
"gensign-node": "latest",
|
|
24
24
|
"log4js": "^6.9.1",
|
|
25
|
-
"@gencode/agents": "0.
|
|
26
|
-
"@gencode/shared": "0.
|
|
25
|
+
"@gencode/agents": "0.7.2",
|
|
26
|
+
"@gencode/shared": "0.2.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^22.0.0",
|
package/dist/program-D2AmoEGO.js
DELETED
|
@@ -1,14 +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"node:os";import{execFile as pe,execFileSync as me}from"node:child_process";import he from"gensign-node";import ge from"node:fs";import _e from"log4js";import{addAgent as ve,addBinding as ye,getAgentConfig as S,listAgents as be,listBindings as xe,loadAgentsConfig as C,normalizeAgentId as Se,removeAgent as Ce,removeBindings as we,resolveAgentDir as Te,resolveDefaultAgentId as w,updateAgentIdentity as Ee}from"@gencode/agents/config";function De(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`:De(e.text);break;case`stream_text_delta`:De(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 Oe(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 ke(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 Ae(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 je(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}`)}const Me=`.aimax`,k=[`fusermount3`,`fusermount`,`umount`];function Ne(e){return x.join(e,`.aimax.enc`)}function Pe(e){return x.join(e,Me)}function Fe(e){return x.join(e,`${Me}.pre-gocryptfs.${process.pid}.${Date.now()}`)}function Ie(e){return e.replace(/\\([0-7]{3})/g,(e,t)=>String.fromCharCode(Number.parseInt(t,8)))}async function Le(e){try{let t=await Re(),n=x.resolve(e);for(let e of t.split(`
|
|
5
|
-
`)){if(!e.trim())continue;let t=e.split(` `);if(t.length>=5&&x.resolve(Ie(t[4]??``))===n)return!0}return!1}catch{return!1}}async function Re(){return await b.readFile(`/proc/self/mountinfo`,`utf-8`)}async function A(e){try{return await b.stat(e),!0}catch(e){if(e.code===`ENOENT`)return!1;throw e}}async function j(e){await b.mkdir(e,{recursive:!0})}async function ze(e){if(await j(e),(await b.readdir(e)).length>0)throw Error(`Refusing to mount encrypted .aimax over non-empty directory: ${e}. Clear stale plaintext files or disable --encrypt-sessions for this run.`)}async function Be(e){let t=x.join(fe.tmpdir(),`aimax-gocryptfs-pass.${process.pid}.${Date.now()}`);await b.writeFile(t,`wizard_aimax@2026
|
|
6
|
-
`,{mode:384});try{return await e(t)}finally{await b.rm(t,{force:!0})}}async function Ve(e){try{await N(`gocryptfs`,e)}catch(t){let n=t instanceof Error?t.message:String(t);throw Error(`gocryptfs ${e.join(` `)} failed: ${n}`)}}async function He(){await Xe(`gocryptfs`,`required for --encrypt-sessions`);for(let e of k)if(await Ye(e))return;throw Error(`--encrypt-sessions requires one of ${k.join(`, `)} to be installed for secure unmount cleanup.`)}async function Ue(e,t){await Be(async n=>{await Ve([`-q`,`-passfile`,n,e,t])})}async function We(e){await Be(async t=>{await Ve([`-q`,`-init`,`-passfile`,t,e])})}async function Ge(e){let t=[];for(let n of k)try{await N(n,[`-u`,e]);return}catch(e){t.push(Ze(n,e))}throw Error(`Failed to unmount ${e}: ${t.join(`; `)}`)}function Ke(e){for(let t of k)try{me(t,[`-u`,e],{stdio:`ignore`});return}catch{}}function qe(e){let t=!1,n=()=>{t||(t=!0,Ke(e))},r=()=>n(),i=()=>{n(),process.exit(130)},a=()=>{n(),process.exit(143)};return process.once(`exit`,r),process.once(`SIGINT`,i),process.once(`SIGTERM`,a),{release(){process.removeListener(`exit`,r),process.removeListener(`SIGINT`,i),process.removeListener(`SIGTERM`,a)}}}async function Je(e){await He();let t=Ne(e),n=Pe(e);if(await Le(n))return{mounted:!1,plainDir:n,encryptedDir:t,async cleanup(){}};let r=null,i=null,a=!1;try{return await A(t)?(await ze(n),await Ue(t,n),a=!0,i=qe(n)):(r=Fe(e),await A(n)&&await b.rename(n,r),await j(t),await We(t),await j(n),await Ue(t,n),a=!0,i=qe(n),r&&=(await b.cp(r,n,{recursive:!0,force:!0}),await b.rm(r,{recursive:!0,force:!0}),null)),{mounted:a,plainDir:n,encryptedDir:t,async cleanup(){i?.release(),a&&(a=!1,await Ge(n))}}}catch(e){throw i?.release(),a&&await Ge(n).catch(()=>{}),r&&await A(r)&&!await A(n)&&await b.rename(r,n).catch(()=>{}),e}}async function M(e,t,n){if(!t.encryptSessions)return n();let r=await Je(e);try{return await n()}finally{await r.cleanup()}}async function N(e,t){await new Promise((n,r)=>{pe(e,t,{encoding:`utf-8`},e=>{if(e){r(e);return}n()})})}async function Ye(e){try{return await N(`sh`,[`-c`,`command -v "${e}" >/dev/null 2>&1`]),!0}catch{return!1}}async function Xe(e,t){if(!await Ye(e))throw Error(`--encrypt-sessions requires ${e}: ${t}.`)}function Ze(e,t){return`${e} -u failed: ${t instanceof Error?t.message:String(t)}`}function Qe(e){e.command(`bootstrap`).description(`Initialize the data directory with required directories and templates`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{je(await M(e.dataDir,e,async()=>n(e.dataDir)),t)}catch(e){E(`Error bootstrapping data directory: ${e.message}`),process.exit(1)}})}function $e(e){return he.sm4_encrypt_ecb(e)}function et(e){return $e(e)}function P(e={}){let t=e.baseUrl??process.env.AIMAX_BASE_URL,n=process.env.AIMAX_AUTH_TOKEN,r=e.authToken?et(e.authToken):n?et(n):e.apiKey??process.env.AIMAX_API_KEY,i=e.model??process.env.AIMAX_MODEL,a=[];if(t||a.push(`--base-url / AIMAX_BASE_URL`),r||a.push(`--api-key / AIMAX_API_KEY`),i||a.push(`--model / AIMAX_MODEL`),a.length>0)throw Error(`Missing required LLM configuration: ${a.join(`, `)}`);return{baseUrl:t,apiKey:r,model:i,contextWindow:e.contextWindow??(process.env.AIMAX_CONTEXT_WINDOW?Number(process.env.AIMAX_CONTEXT_WINDOW):void 0),flashModel:e.flashModel??process.env.AIMAX_FLASH_MODEL}}function tt(e,t){return t?x.resolve(t):x.join(e,`.aimax`,`plugins.json`)}async function F(e,t){let n=tt(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 I(e,t,n){let r=tt(e,n);await b.mkdir(x.dirname(r),{recursive:!0}),await b.writeFile(r,JSON.stringify(t,null,2),`utf-8`)}function L(e){return typeof e==`object`&&!!e}function R(e){return L(e)&&e.type===`text`&&typeof e.text==`string`&&(e.textSignature===void 0||typeof e.textSignature==`string`)}function nt(e){return L(e)&&e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`}function rt(e){return L(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 it(e){return L(e)&&e.type===`toolCall`&&typeof e.id==`string`&&typeof e.name==`string`&&L(e.arguments)&&(e.thoughtSignature===void 0||typeof e.thoughtSignature==`string`)}function at(e){return typeof e==`string`||Array.isArray(e)&&e.every(e=>R(e)||nt(e))}function ot(e){return Array.isArray(e)&&e.every(e=>R(e)||rt(e)||it(e))}function st(e){return L(e)&&typeof e.input==`number`&&typeof e.output==`number`&&typeof e.cacheRead==`number`&&typeof e.cacheWrite==`number`&&typeof e.totalTokens==`number`&&L(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 ct(e){return!L(e)||typeof e.role!=`string`?!1:e.role===`user`?at(e.content):e.role===`assistant`?ot(e.content)&&typeof e.api==`string`&&typeof e.provider==`string`&&typeof e.model==`string`&&st(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=>R(e)||nt(e))&&typeof e.isError==`boolean`:!1}async function lt(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=>ct(e)))throw Error(`Message file must contain one Message object or an array of Message objects`);return r}async function ut(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 lt(e.fromFile)}:{kind:`text`,message:e.message}}function dt(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 ft(e=new Date){let t=dt(e),n=String(e.getMilliseconds()).padStart(3,`0`);return`${t.year}-${t.month}-${t.day} ${t.hour}:${t.minute}:${t.second}.${n}`}let z=function(e){return e.INFO=`INFO`,e.ERROR=`ERROR`,e.WARN=`WARN`,e}({}),B=null;function pt(){return ft()}function mt(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 ht(e){return x.join(e,`.aimax`)}function gt(e){return{appLogPath:x.join(e,`app.log`),errorLogPath:x.join(e,`errors.log`)}}function _t(e){let{appLogPath:t,errorLogPath:n}=gt(e);_e.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 vt(e,t,n){return`[${pt()}] [${e}] ${t}${mt(n)}`}function yt(e,t,n){process.stderr.write(`${vt(e,t,n)}\n`)}function V(e,t,n){if(!B){yt(e,t,n);return}let r=vt(e,t,n),i=_e.getLogger();if(e===z.ERROR){i.error(r);return}if(e===z.WARN){i.warn(r);return}i.info(r)}function H(e){let t=ht(e);B?.dataDir!==e&&(ge.mkdirSync(t,{recursive:!0}),_t(t),B={dataDir:e,logDir:t})}async function bt(){await _e.shutdown()}const U={info:(e,t)=>V(z.INFO,e,t),warn:(e,t)=>V(z.WARN,e,t),error:(e,t)=>V(z.ERROR,e,t)};var W=class{startTime;name;constructor(e){this.name=e,this.startTime=Date.now()}end(){let e=Date.now()-this.startTime;return U.info(`${this.name} completed in ${e}ms`),e}},xt=class{constructor(e){this.sinks=e}async send(e){await Promise.allSettled(this.sinks.map(async t=>{await t.send(e)}))}async close(){await Promise.allSettled(this.sinks.map(async e=>{await e.close()}))}},St=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=Ct(e);U.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 U.error(`callback event failed`,{callbackUrl:this.url,httpStatus:r.status,durationMs:i,...n}),Error(`Callback failed with status ${r.status}`);U.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 Ct(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 wt(e,t){if(t.kind===`none`)return e;let n=new URL(e);return n.searchParams.set(`authToken`,t.token),n.toString()}function G(){let e=globalThis.WebSocket;if(!e)throw Error(`WebSocket is not available in this runtime`);return e}function Tt(e){return e?{kind:`query_token`,token:e}:{kind:`none`}}function Et(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 Dt(e,t,n){if(typeof e.on==`function`){e.on(t,n);return}if(typeof e.addEventListener==`function`){e.addEventListener(t,n);return}throw Error(`WebSocket does not support listener registration for "${t}"`)}var K=class{socket=null;connectPromise=null;enabled=!0;textSequence=0;constructor(e,t,n){this.url=e,this.events=t,this.authToken=n}async send(e){let t=this.toEnvelope(e);if(!(!t||!this.enabled))try{await this.ensureConnected();let e=G();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){U.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=G();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){U.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=G();e.readyState!==t.CLOSED&&await new Promise(t=>{Et(e,`close`,()=>t()),e.close()})}async ensureConnected(){if(!this.enabled)return;let e=G();if(this.socket&&this.socket.readyState===e.OPEN)return;if(this.connectPromise){await this.connectPromise;return}let t=new e(wt(this.url,Tt(this.authToken)));this.connectPromise=new Promise((e,n)=>{Et(t,`open`,()=>{this.socket=t,Dt(t,`close`,()=>{this.socket===t&&(this.socket=null)}),e()}),Et(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 Ot=[`start`,`text`,`done`,`error`,`hitl`],kt=[`off`,`gate`,`dry_run`,`write`];function At(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 jt(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 Mt(e){return e?.trim()||void 0}function Nt(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 Pt(e){return e?_(e):void 0}function Ft(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 It(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 Lt(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(kt.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function Rt(e){let t=e.autoSkillsLoadEnabled===void 0?It(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):It(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?Lt(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):Lt(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 zt(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 Bt(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 Vt(e){let t=await ne(e.dataDir,e.sessionId,{storeName:e.sessionStoreName,encryptSessions:e.encryptSessions});for(let n=t.length-1;n>=0;--n){let r=t[n];if(r?.role!==`assistant`||!Array.isArray(r.toolCalls))continue;let i=r.toolCalls.find(t=>t.id===e.toolCallId&&t.name===e.toolName);if(i)return i.arguments}}async function Ht(e){let t=jt(e),n=e.channel??`WEB`,r=P({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:Nt(e),channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,skillsLoadPaths:Ft(e.skillsLoadPaths),autoSkills:Rt(e)}}function Ut(e){let t=[],n=null;return e.callbackUrl&&t.push(new St(e.callbackUrl)),e.streamUrl&&(n=new K(e.streamUrl,At(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new xt(t),websocketSink:n}}async function Wt(e){let{dataDir:t,sessionId:n,sessionStoreName:r,toolCallId:i,toolName:a,resolution:o,encryptSessions:s}=e;if(!i||!a||!le(a))return;let d=(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:d(a,o),isError:!1},n},{storeName:r,encryptSessions:s})}async function Gt(e){let{dataDir:t,sessionId:n,sessionStoreName:r,result:i,encryptSessions:a}=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,encryptSessions:a})}async function Kt(e){let t=jt(e);await M(t,e,async()=>{H(t);let n=new W(`resume command`),r=null;try{let t=await Ht(e),a=Pt(e.sessionStore);U.info(`resume command started`,{sessionId:e.sessionId,requestId:e.requestId,channel:t.channel,dataDir:t.dataDir});let o=await g(t.dataDir,e.sessionId,{storeName:a,encryptSessions:e.encryptSessions}),s=o?null:await ee(t.dataDir,e.sessionId,{storeName:a,encryptSessions:e.encryptSessions});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=zt(e,o.request),s=await ae({dataDir:t.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=qt(i,c.request.kind);await Wt({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:a,toolCallId:c.toolContext?.toolCallId,toolName:c.toolContext?.toolName,resolution:i,encryptSessions:e.encryptSessions});let u=Ut(e);r=u.sink;let d=e.sessionId,f=async n=>{if(d=n.sessionId??d,!y(n)){if(n.type===`stream_text_delta`){t.format===`text`&&D(n),await u.websocketSink?.sendTextDelta({sessionId:d,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}t.format===`text`&&D(n),await r?.send({sessionId:d,channel:t.channel,messageId:e.messageId,user:e.user,type:`progress`,event:n})}};await f({type:`hitl_resumed`,requestId:e.requestId,resolution:i,sessionId:e.sessionId}),`idempotentReplay`in s&&s.idempotentReplay&&(U.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},t.format),n.end(),process.exit(0));let p=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,m=await F(t.dataDir,p),h;try{h=await v({dataDir:t.dataDir,projectDir:Mt(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:a,sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,message:l,encryptSessions:e.encryptSessions??!1,hitlResume:{request:c.request,resolution:i,checkpoint:c.checkpoint,toolContext:c.toolContext},plugins:m?{config:m,dataDir:t.dataDir,workspaceDir:x.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:m.llmAllowlist}:void 0,onProgress:f})}finally{}h.error?await r?.send({sessionId:h.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`error`,message:h.error}):await r?.send({sessionId:h.sessionId,channel:t.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,t.format),h.error?U.error(`resume command failed: ${h.error}`):U.info(`resume command succeeded`),n.end(),process.exit(h.error?1:0);return}let c=Bt(e,s);if(!await oe(t.dataDir,e.sessionId,e.requestId,c,{storeName:a,encryptSessions:e.encryptSessions}))throw Error(`UI tool resume validation failed`);await Gt({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:a,result:c,encryptSessions:e.encryptSessions});let l=Ut(e);r=l.sink;let u=e.sessionId,d=async n=>{if(u=n.sessionId??u,!y(n)){if(n.type===`stream_text_delta`){t.format===`text`&&D(n),await l.websocketSink?.sendTextDelta({sessionId:u,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}if(t.format===`text`&&D(n),n.type===`start`){await r?.send({sessionId:u,channel:t.channel,messageId:e.messageId,user:e.user,type:`start`,message:n.message});return}await r?.send({sessionId:u,channel:t.channel,messageId:e.messageId,user:e.user,type:`progress`,event:n})}},f=await Vt({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:a,toolCallId:c.toolCallId,toolName:c.toolName,encryptSessions:e.encryptSessions});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 F(t.dataDir,p),h=await v({dataDir:t.dataDir,projectDir:Mt(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:a,sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,message:`[UI_TOOL_RESUME]
|
|
7
|
-
The pending UI tool result has been written into the transcript. Continue from the latest tool result without repeating the same form request.`,encryptSessions:e.encryptSessions??!1,uiToolResume:c,plugins:m?{config:m,dataDir:t.dataDir,workspaceDir:x.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:m.llmAllowlist}:void 0,onProgress:d});await i(t.dataDir,e.sessionId,{storeName:a,encryptSessions:e.encryptSessions}),h.error?await r?.send({sessionId:h.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`error`,message:h.error}):await r?.send({sessionId:h.sessionId,channel:t.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,t.format),h.error?U.error(`resume command failed: ${h.error}`):U.info(`resume command succeeded`),n.end(),process.exit(h.error?1:0)}catch(t){let i=t;r&&(i.message.includes(`expired`)&&await r.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 r.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 r.send({sessionId:e.sessionId,channel:e.channel??`WEB`,messageId:e.messageId,user:e.user,type:`error`,message:`Resume failed: ${i.message}`})),U.error(`resume command error: ${i.message}`),E(`Fatal: ${i.message}`),n.end(),process.exit(1)}finally{await r?.close()}})}function qt(e,t){return r(e,t)}function Jt(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 gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{await Kt(e)})}const Yt=[`start`,`text`,`done`,`error`],Xt=[`off`,`gate`,`dry_run`,`write`];function Zt(e){if(!e?.trim())return new Set(Yt);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(Yt)}function Qt(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 $t(e){return e?.trim()||void 0}function en(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 q(e){return e?.trim()||void 0}function tn(e){return e??`WEB`}function nn(e){return e?_(e):void 0}function rn(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 an(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 on(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(Xt.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function sn(e){let t=e.autoSkillsLoadEnabled===void 0?an(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):an(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?on(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):on(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 cn(e,t){return e.length<=t?e:t<=3?e.slice(0,t):`${e.slice(0,t-3)}...`}function ln(e,t,n=78){let r=n-2,i=r-2,a=e?` ${cn(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=>`│ ${cn(e,i).padEnd(i,` `)} │`),s].join(`
|
|
8
|
-
`)}function un(e){return e.kind===`text`?`inline message (${e.message.length} chars)`:`message file (${e.messages.length} messages)`}function dn(e,t){let n=nn(e.sessionStore)??`sessions`,r=t.timeoutMs===void 0?`default`:`${t.timeoutMs}`,i=e.callbackUrl?`enabled`:`disabled`,a=e.streamUrl?`enabled`:`disabled`,o=un(t.input),s=t.input.kind===`text`?`inline`:e.fromFile??`file`,c=ft();return{banner:ln(void 0,[`AIMax CLI`,`Stateless Agent Runner`]),contextBox:ln(`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 : ${$t(e.projectDir)??`-`}`,`systemAgents : ${t.systemAgentsDir??`/aimax/agents`}`,`agent : ${q(e.agent)??`-`}`,`output : ${t.format}`,`callback : ${i}`,`websocket : ${a}`,`timeoutMs : ${r}`,`input : ${o}`]),logContext:{time:c,channel:t.channel,user:e.user,dataDir:t.dataDir,projectDir:$t(e.projectDir),systemAgentsDir:t.systemAgentsDir,agent:q(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 fn(e,t){let n=Qt(e),r=tn(e.channel),i=P({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:en(e),channel:r,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:i,input:t,skillsLoadPaths:rn(e.skillsLoadPaths),autoSkills:sn(e)}}function pn(e){if(e.kind===`text`)return e.message;if(e.messages.length!==1)return null;let[t]=e.messages;if(t.role!==`user`)return null;if(typeof t.content==`string`)return t.content;if(t.content.length===0)return null;let n=[];for(let e of t.content){if(e.type!==`text`)return null;n.push(e.text)}return n.join(`
|
|
9
|
-
`)}async function mn(e,t){if(!e.sessionId)return null;let n=pn(t);if(!n)return null;let r=await g(Qt(e),e.sessionId,{storeName:nn(e.sessionStore),encryptSessions:e.encryptSessions});return!r||r.status!==`pending`||!ue(n,r.request)?null:{requestId:r.request.requestId,inputText:n}}function hn(e){let t=[],n=null;return e.callbackUrl&&t.push(new St(e.callbackUrl)),e.streamUrl&&(n=new K(e.streamUrl,Zt(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new xt(t),websocketSink:n}}async function J(e,t){U.info(`dispatching external event`,Nn(t)),await e.sink.send(t)}function gn(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 _n(e){let t={sessionId:e.sessionId,messageId:e.messageId,parentSessionId:e.parentSessionId,depth:e.depth,scope:e.scope,phase:e.phase,...gn(e.details)};if(e.level===`error`){U.error(e.message,t);return}if(e.level===`warn`){U.warn(e.message,t);return}U.info(e.message,t)}function vn(e,t,n,r,i){return{sink:e,websocketSink:t,channel:n,defaultMessageId:r,user:i}}function yn(){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 bn(e){return{activeSessionId:e??`pending`,finalResult:null}}function xn(e,t){e.activeSessionId=t.sessionId??e.activeSessionId}function Sn(e,t){return e.messageId??t}async function Cn(e,t,n){if(!await d(e.dataDir)){if(await Y(t,e.format,n.activeSessionId,e.dataDir,`checking`),(await o(e.dataDir)).performedBootstrap){await Y(t,e.format,n.activeSessionId,e.dataDir,`initializing`),await Y(t,e.format,n.activeSessionId,e.dataDir,`initialized`);return}await Y(t,e.format,n.activeSessionId,e.dataDir,`ready`)}}async function Y(e,t,n,r,i){let a={type:`bootstrap`,phase:i,dataDir:r};t===`text`&&D(a),await J(e,{sessionId:n,channel:e.channel,messageId:e.defaultMessageId,user:e.user,type:`progress`,event:a})}function wn(e,t,n){return async r=>{if(xn(n,r),y(r)){_n(r);return}if(r.type===`stream_text_delta`){e.format===`text`&&D(r),await t.websocketSink?.sendTextDelta({sessionId:n.activeSessionId,channel:e.channel,messageId:Sn(r,t.defaultMessageId),user:t.user,text:r.text});return}e.format===`text`&&D(r);let i=Sn(r,t.defaultMessageId);if(r.type===`hitl_requested`){await J(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`hitl`,request:r.request}),await J(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r});return}if(r.type===`start`){await J(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`start`,message:r.message});return}if(r.type===`session_reset`){await J(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`session_reset`,action:r.action,previousSessionId:r.previousSessionId,message:r.message});return}await J(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:i,user:t.user,type:`progress`,event:r})}}function Tn(e,t,n,r,i){let a={dataDir:t.dataDir,projectDir:$t(e.projectDir),systemAgentsDir:t.systemAgentsDir,agentPolicy:q(e.agent)?{requestedAgentName:q(e.agent)}:void 0,sessionStoreName:nn(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,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 J(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:r.error});return}await J(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`done`,result:{text:r.text,usage:r.usage,durationMs:r.durationMs,error:r.error,paused:r.paused}})}async function Dn(e,t,n,r){await J(e,{sessionId:t.finalResult?.sessionId??t.activeSessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:`Fatal: ${r.message}`})}function On(e,t){let n=dn(e,t);U.info([`run command started`,n.banner,n.contextBox].join(`
|
|
10
|
-
`),n.logContext),t.format===`text`&&(T(n.banner),T(``),T(n.contextBox),T(``))}function kn(e,t,n){O(t,n),t.error?U.error(`run command failed: ${t.error}`):U.info(`run command succeeded`),e.end(),process.exit(t.error?1:0)}function An(e,t){U.error(`run command error: ${t.message}`),E(`Fatal: ${t.message}`),e.end(),process.exit(1)}async function jn(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 Mn(e){let t=Qt(e);await M(t,e,async()=>{let n=await jn(e);if(e.resumeRequestId||n||e.resumeFromFile){if(!e.sessionId||!e.resumeRequestId||!n)throw Error(`--session-id, --resume-request-id, and exactly one of --resume-input-json or --resume-from-file must be provided together`);await Kt({dataDir:e.dataDir,projectDir:e.projectDir,systemAgentsDir:e.systemAgentsDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:e.resumeRequestId,inputJson:n,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});return}let r;try{r=await ut({message:e.message,fromFile:e.fromFile})}catch(e){H(t),An(new W(`run command`),e);return}let i=await mn(e,r);if(i){await Kt({dataDir:e.dataDir,projectDir:e.projectDir,systemAgentsDir:e.systemAgentsDir,sessionId:e.sessionId,sessionStore:e.sessionStore,requestId:i.requestId,inputText:i.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});return}H(t);let a=new W(`run command`),{controller:o,cleanup:s}=yn(),c=null,l=e.channel??`WEB`,u=bn(e.sessionId);try{let t=await fn(e,r);l=t.channel,On(e,t);let n=hn(e);c=n.sink,U.info(`external sink configured`,{callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,streamEvents:e.streamEvents});let i=vn(c,n.websocketSink,t.channel,e.messageId,e.user);await Cn(t,i,u);let s=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,d=await F(t.dataDir,s),f=await v(Tn(e,t,o,wn(t,i,u),d));await En(i,u,e.messageId,f),kn(a,f,t.format)}catch(t){let n=t;c&&await Dn(vn(c,null,l,e.messageId,e.user),u,e.messageId,n),An(a,n)}finally{await c?.close(),s()}})}function Nn(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 Pn(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 gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{await Mn(e)})}function Fn(e){e.command(`sessions`).description(`List or inspect sessions for a data directory`).argument(`[action]`,`Action: list (default) | inspect | export`).option(`-d, --data-dir <path>`,`Data directory path`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`-c, --channel <channel>`,`Filter by channel type: H5 | WEB | KLPA | TASK | CRON | EIP_ASSISTANT`).option(`-s, --session-id <id>`,`Session ID for inspect/export`).option(`--output <format>`,`Output format: text or json`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async(e,t,n)=>{let r=n.opts(),i=e??`list`,a=i===`export`?r.output===`text`?`text`:`json`:r.output===`json`?`json`:`text`;r.dataDir||(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{await M(r.dataDir,r,async()=>{let e=r.sessionStore?_(r.sessionStore):void 0;if(i===`list`){Oe(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`){ke(await p(r.dataDir,r.sessionId,{storeName:e}),a);return}if(i===`export`){Ae(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 In(e){return x.join(e,`workspace`)}function Ln(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function Rn(e,t){let n=[];n.push(`backend: ${e.backend}`),n.push(`provider: ${e.provider}${e.model?` (${e.model})`:``}`);let r=typeof e.custom?.providerSource==`string`?e.custom.providerSource:void 0,i=typeof e.custom?.providerId==`string`?e.custom.providerId:void 0,a=typeof e.custom?.pluginId==`string`?e.custom.pluginId:void 0;r&&n.push(`provider_source: ${r}`),i&&n.push(`provider_id: ${i}`),a&&n.push(`plugin_id: ${a}`),typeof e.files==`number`&&n.push(`files: ${e.files}`),typeof e.chunks==`number`&&n.push(`chunks: ${e.chunks}`),typeof e.dirty==`boolean`&&n.push(`dirty: ${e.dirty}`),e.dbPath&&n.push(`db: ${e.dbPath}`),e.sources?.length&&n.push(`sources: ${e.sources.join(`, `)}`),t&&(e.fts&&(n.push(`fts: enabled=${e.fts.enabled} available=${e.fts.available}`),e.fts.error&&n.push(`fts_error: ${e.fts.error}`)),e.vector&&(n.push(`vector: enabled=${e.vector.enabled} available=${e.vector.available??`unknown`}`),e.vector.dims&&n.push(`vector_dims: ${e.vector.dims}`),e.vector.loadError&&n.push(`vector_error: ${e.vector.loadError}`)),e.cache&&n.push(`cache: enabled=${e.cache.enabled} entries=${e.cache.entries??0}`));let o=Array.isArray(e.custom?.cliWarnings)?e.custom.cliWarnings.filter(e=>typeof e==`string`&&e.length>0):[];for(let e of o)n.push(`warning: ${e}`);return n.join(`
|
|
11
|
-
`)}function zn(e){let t=e.level===`error`?`plugin error`:`plugin warning`;return e.pluginId?`${t} (${e.pluginId}): ${e.message}`:`${t}: ${e.message}`}function Bn(e){if(!e||e===`cli`)return`cli`;if(e===`cron`)return`cron`;throw Error(`Unsupported dream trigger: ${e}. Expected "cli" or "cron".`)}async function Vn(e){let t=[],n;try{n=await F(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:In(e.dataDir),bundledDir:Ln()});return t.push(...r.diagnostics.map(zn)),{pluginSystem:r,warnings:t}}catch(e){return t.push(`failed to initialize plugin system: ${e.message}`),{warnings:t}}}async function X(e){let t=x.join(e.dataDir,`.aimax`),{pluginSystem:n,warnings:r}=await Vn({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 Hn(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 Un(e){let t=e.command(`memory`).description(`Manage semantic memory indexing and search`),n=e=>e.option(`--plugins-config <path>`,`Plugins config file path`);n(t.command(`status`)).description(`Show memory index status`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--deep`,`Probe embedding/vector availability`).option(`--index`,`Run a refresh before reporting status`).option(`--include-sessions`,`Include session transcripts in indexing`).option(`--provider <id>`,`Memory provider id`).option(`--provider-plugin <id>`,`Memory provider plugin id`).option(`--verbose`,`Verbose output`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{await M(e.dataDir,e,async()=>{let n=await X({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=Hn(n.provider.status(),n,e.deep);T(t===`json`?JSON.stringify(r,null,2):Rn(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`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{try{await M(e.dataDir,e,async()=>{let t=await X({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`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async(e,t)=>{let n=t.output===`json`?`json`:`text`,r=t.query?.trim()||e?.trim();r||(E(`Query is required: provide [query] or --query <text>`),process.exit(1));try{await M(t.dataDir,t,async()=>{let e=await(await X({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(`
|
|
12
|
-
`))})}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`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{await M(e.dataDir,e,async()=>{let n=Bn(e.trigger),r=await X({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:In(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 Wn(e){return`${e.match.accountId?`${e.match.channel}:${e.match.accountId}`:e.match.channel} -> ${e.agentId}`}function Gn(e){return async t=>{let n=await C(t),r=be(n),i=xe(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=Te(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(` - ${Wn(e)}`)}}}}function Kn(e,t){return async n=>{S(await C(n),Se(e))&&(console.error(`Agent "${e}" already exists.`),process.exit(1)),await ve(n,{id:e,name:t.name,model:t.model,default:t.default})||(console.error(`Agent "${e}" already exists.`),process.exit(1));let r=Te(n,e);console.log(`Agent "${e}" added successfully.`),console.log(` Agent dir: ${r}`)}}function qn(e){return async t=>{let n=S(await C(t),Se(e));n||(console.error(`Agent "${e}" not found.`),process.exit(1)),n.default===!0&&(console.error(`Cannot delete default agent "${e}".`),process.exit(1)),await Ce(t,e)||(console.error(`Failed to delete agent "${e}".`),process.exit(1)),console.log(`Agent "${e}" deleted.`)}}function Jn(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 ye(t,{agentId:r,match:{channel:e,accountId:a||void 0}}),console.log(`Binding added: ${n} -> ${r}`)}}}function Yn(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 we(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 we(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 Xn(e){return async t=>{let n=xe(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(` ${Wn(e)}`)}}function Zn(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 Ee(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 Qn(e,t){let n=e.command(`agents`).description(`Manage agents`),r=e=>e.option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`);r(n.command(`list`).description(`List all configured agents`).option(`-j, --json`,`Output as JSON`).option(`-b, --bindings`,`Show detailed binding rules`)).action(async e=>{let n=t();await M(n,e,async()=>{await Gn(e)(n)})}),r(n.command(`add <id>`).description(`Add a new agent`).option(`-n, --name <name>`,`Display name`).option(`-m, --model <model>`,`Model identifier`).option(`--default`,`Mark as default agent`)).action(async(e,n)=>{let r=t();await M(r,n,async()=>{await Kn(e,n)(r)})}),r(n.command(`delete <id>`).description(`Delete an agent`)).action(async(e,n)=>{let r=t();await M(r,n,async()=>{await qn(e)(r)})}),r(n.command(`bind`).description(`Bind a channel to an agent`).option(`-a, --agent <id>`,`Target agent ID`).option(`-b, --bind <channel...>`,`Channel binding (e.g., WEB, KLPA:ops)`)).action(async e=>{let n=t();await M(n,e,async()=>{await Jn(e)(n)})}),r(n.command(`unbind`).description(`Unbind a channel from an agent`).option(`-a, --agent <id>`,`Target agent ID`).option(`-b, --bind <channel...>`,`Channel binding to remove`).option(`--all`,`Remove all bindings for the agent`)).action(async e=>{let n=t();await M(n,e,async()=>{await Yn(e)(n)})}),r(n.command(`bindings`).description(`List routing bindings`).option(`-a, --agent <id>`,`Filter by agent ID`).option(`-j, --json`,`Output as JSON`)).action(async e=>{let n=t();await M(n,e,async()=>{await Xn(e)(n)})}),r(n.command(`set-identity`).description(`Set agent identity`).option(`-a, --agent <id>`,`Target agent ID`).option(`-n, --name <name>`,`Agent name`).option(`-e, --emoji <emoji>`,`Agent emoji`).option(`--avatar <path>`,`Avatar path`)).action(async e=>{let n=t();await M(n,e,async()=>{await Zn(e)(n)})})}function Z(e){return x.join(e,`workspace`)}function Q(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function $n(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 er(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 $(e){return Array.from(new Set((e??[]).map(e=>e.trim()).filter(Boolean)))}function tr(e){if(e.length===0){T(`LLM allowlist is empty.`);return}for(let t of e)T(t)}function nr(e,t){let n=e.command(`plugins`).description(`Manage AIMax plugins`),r=e=>e.option(`--plugins-config <path>`,`Plugins config file path`),i=e=>e.option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`);i(r(n.command(`list`))).description(`List discovered plugins`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await M(n,e,async()=>{$n(f({config:await F(n,e.pluginsConfig),dataDir:n,workspaceDir:Z(n),bundledDir:Q()}).registry.plugins)})}),i(r(n.command(`info`))).description(`Show plugin details`).argument(`<id>`,`Plugin id`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await M(r,n,async()=>{let t=f({config:await F(r,n.pluginsConfig),dataDir:r,workspaceDir:Z(r),bundledDir:Q()}).registry.plugins.find(t=>t.id===e);t||(E(`Plugin not found: ${e}`),process.exit(1)),er(t)})}),i(r(n.command(`enable`))).description(`Enable a plugin`).argument(`<id>`,`Plugin id`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await M(r,n,async()=>{let t=await F(r,n.pluginsConfig)??{},i=re(t);f({config:t,dataDir:r,workspaceDir:Z(r),bundledDir:Q()}).registry.plugins.some(t=>t.id===e)||(E(`Plugin not found: ${e}`),process.exit(1)),await I(r,{...t,entries:{...t.entries,[e]:{...t.entries?.[e]??{},enabled:!0}}},n.pluginsConfig),T(`Enabled ${e}`),i.allow.length>0&&!i.allow.includes(e)&&T(`Note: plugins.allow is set; add this plugin id to allowlist if needed.`)})}),i(r(n.command(`disable`))).description(`Disable a plugin`).argument(`<id>`,`Plugin id`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await M(r,n,async()=>{let t=await F(r,n.pluginsConfig)??{};f({config:t,dataDir:r,workspaceDir:Z(r),bundledDir:Q()}).registry.plugins.some(t=>t.id===e)||(E(`Plugin not found: ${e}`),process.exit(1)),await I(r,{...t,entries:{...t.entries,[e]:{...t.entries?.[e]??{},enabled:!1}}},n.pluginsConfig),T(`Disabled ${e}`)})}),i(r(n.command(`doctor`))).description(`Validate plugin configuration`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await M(n,e,async()=>{let t=f({config:await F(n,e.pluginsConfig),dataDir:n,workspaceDir:Z(n),bundledDir:Q()});if(t.diagnostics.length===0){T(`No plugin issues detected.`);return}for(let e of t.diagnostics)T(`${e.level===`error`?`ERROR`:`WARN`}${e.pluginId?` ${e.pluginId}`:``}: ${e.message}`);t.diagnostics.some(e=>e.level===`error`)&&process.exit(1)})});let a=n.command(`llm-allow`).description(`Manage plugin LLM allowlist`);i(r(a.command(`list`))).description(`List LLM allowlist entries`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await M(n,e,async()=>{tr($((await F(n,e.pluginsConfig))?.llmAllowlist))})}),i(r(a.command(`add`))).description(`Add entries to the LLM allowlist (plugin id or tool name)`).argument(`<entry...>`,`Plugin id or tool name`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await M(r,n,async()=>{let t=await F(r,n.pluginsConfig)??{},i=$([...t.llmAllowlist??[],...e]);await I(r,{...t,llmAllowlist:i},n.pluginsConfig),T(`LLM allowlist updated (${i.length} entries).`)})}),i(r(a.command(`remove`))).description(`Remove entries from the LLM allowlist`).argument(`<entry...>`,`Plugin id or tool name`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,n)=>{let r=n.dataDir??t();await M(r,n,async()=>{let t=await F(r,n.pluginsConfig)??{},i=new Set(e.map(e=>e.trim()).filter(Boolean)),a=$(t.llmAllowlist).filter(e=>!i.has(e));await I(r,{...t,llmAllowlist:a},n.pluginsConfig),T(`LLM allowlist updated (${a.length} entries).`)})}),i(r(a.command(`clear`))).description(`Clear the LLM allowlist`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let n=e.dataDir??t();await M(n,e,async()=>{await I(n,{...await F(n,e.pluginsConfig)??{},llmAllowlist:[]},e.pluginsConfig),T(`LLM allowlist cleared.`)})})}function rr(e){e.command(`commands`).description(`List available slash commands for a data directory`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{let t=e.output===`json`?`json`:`text`;try{await M(e.dataDir,e,async()=>{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 ir=[`progress`,`error`,`hitl`];function ar(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 or(e){if(!e?.trim())return new Set(ir);let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean),n=new Set([`start`,`text`,`progress`,`done`,`error`,`hitl`,`title_updated`]),r=new Set;for(let e of t){if(!n.has(e))throw Error(`Invalid stream event: ${e}. Must be one of start,text,progress,done,error,hitl`);r.add(e)}return r.size>0?r:new Set(ir)}function sr(e){return e?_(e):void 0}function cr(e){let t=[];return e.callbackUrl&&t.push(new St(e.callbackUrl)),e.streamUrl&&t.push(new K(e.streamUrl,or(e.streamEvents),e.streamAuthToken)),new xt(t)}async function lr(e){let t=ar(e);await M(t,e,async()=>{H(t);let n=new W(`cancel command`),r=e.channel??`WEB`,i=e.output===`json`?`json`:`text`,a=cr(e),o=sr(e.sessionStore);try{let s=await g(t,e.sessionId,{storeName:o});if(!s)throw Error(`No pending HITL request found for session "${e.sessionId}"`);let c=e.requestId??s.request.requestId;if(s.request.requestId!==c)throw Error(`Request ID mismatch: pending is "${s.request.requestId}", got "${c}"`);if(!(await ae({dataDir:t,sessionStoreName:o,sessionId:e.sessionId,requestId:c,resolution:{requestId:c,sessionId:e.sessionId,action:`cancel`,submittedAt:new Date().toISOString(),submittedBy:{channel:r}}})).state)throw Error(`Failed to cancel HITL request`);let l={type:`hitl_cancelled`,sessionId:e.sessionId,requestId:c,reason:e.reason??`cancelled by operator`};i===`text`&&D(l),await a.send({type:`progress`,sessionId:e.sessionId,channel:r,messageId:e.messageId,event:l}),n.end(),process.exit(0)}catch(t){let i=t;await a.send({type:`error`,sessionId:e.sessionId,channel:r,messageId:e.messageId,message:i.message}),U.error(`cancel command error: ${i.message}`),E(`Fatal: ${i.message}`),n.end(),process.exit(1)}finally{await a.close()}})}function ur(e){e.command(`cancel`).description(`Cancel a pending HITL request`).requiredOption(`-d, --data-dir <path>`,`Data directory path`).requiredOption(`-s, --session-id <id>`,`Session ID containing the pending HITL request`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`--request-id <id>`,`HITL request ID to cancel`).option(`--reason <text>`,`Human-readable cancel reason`).option(`-c, --channel <channel>`,`Channel type (default: WEB)`,`WEB`).option(`--callback-url <url>`,`HTTP callback URL for progress events`).option(`--stream-url <url>`,`WebSocket URL for streaming text events`).option(`--stream-auth-token <token>`,`Auth token for WebSocket streaming`).option(`--stream-events <list>`,`Comma-separated stream events`).option(`--message-id <id>`,`Message ID for correlating events`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).action(async e=>{await lr(e)})}function dr(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 fr(e){return e.query?.trim()||void 0}function pr(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 mr(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 hr(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 gr(e){let t=null;try{let n=dr(e);H(n),t=new W(`summarize command`);let r=fr(e),i=await hr(e),a=P({baseUrl:e.baseUrl,apiKey:e.apiKey,model:e.model,contextWindow:2e5}),o=pr(e.timeout),s=mr(e.maxTokens);U.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:_r(i,r),llm:{...a,maxTokens:s},timeoutMs:o});T(c.text.trim()),U.info(`summarize command succeeded`,{source:i.source,summaryLength:c.text.length,durationMs:c.durationMs}),t.end()}catch(e){U.error(`summarize command error: ${e.message}`),E(`Fatal: ${e.message}`),t?.end(),process.exit(1)}}function _r(e,t){return e.source===`file`?[t?`Summarize exactly one file for the query below.`:`Summarize exactly one file.`,`Read only the absolute file path provided here. Do not search, browse, read other files, execute commands, modify files, or perform any other processing.`,`Return only the summary text.`,``,...t?[`Query:\n${t}`,``]:[],`Input source: file`,`File path: ${e.filePath}`].join(`
|
|
13
|
-
`):[t?`Summarize the provided content for the query below.`:`Summarize the provided content.`,t?`Use only the provided content and query. Do not search, browse, read files, execute commands, modify files, or perform any other processing.`:`Use only the provided content. Do not search, browse, read files, execute commands, modify files, or perform any other processing.`,`Return only the summary text.`,``,...t?[`Query:\n${t}`,``]:[],`Input source: content`,`Source content:`,`<source>`,e.content,`</source>`].join(`
|
|
14
|
-
`)}function vr(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 gr(e)})}const yr=e(import.meta.url)(`../package.json`);function br(){return process.env.AIMAX_DATA_DIR||process.cwd()}function xr(){let e=new t;return e.name(`aimax`).description(`AIMax CLI — runs agent tasks in a containerized environment`).version(yr.version),Pn(e),Jt(e),ur(e),Fn(e),vr(e),rr(e),Qe(e),Un(e),Qn(e,br),nr(e,br),e}export{bt as a,U as i,br as n,H as r,xr as t};
|