@gencode/cli 0.17.1 → 0.17.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,15 +1,41 @@
1
1
  # @gencode/cli
2
2
 
3
+ ## 0.17.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 2ab7f63: Make Thread Goal completion reliable across agents and all applications that consume agent runs.
8
+
9
+ - Goal completion and blocking now use separate model tools with required completion evidence or blocking reasons.
10
+ - Repeated invalid terminal submissions stop after a bounded number of equivalent failures instead of looping indefinitely.
11
+ - Final responses report a persistence failure when delivery work exists but the Goal workflow has not reached `complete`.
12
+ - Administrators can recover an individual historical session through the exported Goal recovery API or the `run-goal-recovery` command without editing Goal files directly.
13
+
14
+ - 2ab7f63: Improve `/goal` task planning consistency across agents, CLI, console, and web consumers.
15
+
16
+ - Complex natural-language objectives can initialize 2–5 persistent execution tasks with acceptance criteria.
17
+ - Vague objectives still start in clarify; models commit plans through the new public `goal_plan` tool instead of overloading `update_task`.
18
+ - Clarify gate now covers the full run lifecycle (first turn, announce, continuations) until a later turn observes committed execution state.
19
+ - Terminal `goal complete` rejects clarify-only or unfinished-clarify workflows.
20
+
21
+ - eb5c06b: CLI websocket streaming now keeps idle connections alive by sending a plain text `ping` frame when no websocket content has been sent for 1 minute. Regular stream messages reset the idle timer, and the heartbeat does not change the existing JSON event envelopes or `--stream-events` filtering.
22
+ - Updated dependencies [2ab7f63]
23
+ - Updated dependencies [2ab7f63]
24
+ - @gencode/agents@0.20.0
25
+
3
26
  ## 0.17.1
4
27
 
5
28
  ### Patch Changes
6
29
 
7
30
  - cc36dad: Improve URL artifact reporting for online documents and shared resources. When an agent creates or publishes a user-openable online resource and shows a link such as a document link, view link, share link, or download link in the final response, the runtime prompt now more explicitly instructs the model to include the same URL in the `<aimax_artifacts>` declaration so backend `done` payloads and transcript artifact metadata can surface it reliably.
8
31
  - 18fd7a1: Make `aimax generate` independent from `--data-dir` / `AIMAX_DATA_DIR`. The command now works with only LLM configuration and `--input`; `--data-dir` remains optional for callers that want CLI logs written under a data directory.
9
- - 0744f2d: When `aimax run` or `aimax resume` receives `--project-dir <path>`, AIMax now automatically loads `<path>/AGENTS.md` when that file exists and injects it into the runtime system prompt as a separate project instructions section. The project file applies only to work in the current repository and does not replace the user-level `.aimax/AGENTS.md` identity and collaboration rules.
32
+ - 8170e03: Support custom HITL approving choice IDs for before-tool safety gates. `HitlChoiceInput` now accepts an optional `approvingChoiceIds` field that declares which choice IDs mean "approve / continue". When resuming a paused run, both guarded operations (`skill_action_run`) and generic non-HITL `before_tool` resumes honor this list. Existing requests that omit the field continue to treat `"approve"` as the only approving choice, preserving backward compatibility.
33
+ - 0d0e504: Improve artifact reporting for Wizard Wiki pages. When the `wizard-wiki` skill creates a page through `scripts/create_page.py` or updates one through `scripts/edit_page.py` and the script response includes a page URL, AIMax now returns that URL in the run artifacts payload as a user-openable Wiki page artifact, distinguishing newly created pages from modified pages.
10
34
  - Updated dependencies [cc36dad]
11
- - Updated dependencies [0744f2d]
35
+ - Updated dependencies [8170e03]
36
+ - Updated dependencies [0d0e504]
12
37
  - @gencode/agents@0.19.1
38
+ - @gencode/shared@0.6.1
13
39
 
14
40
  ## 0.17.0
15
41
 
package/dist/bin.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import"./pkg-path-D6anqptM.js";import{b as e,x as t,y as n}from"./run-9V7V9r8T.js";import{t as r}from"./program-hmgqVomi.js";function i(e){return e instanceof Error?e.stack??`${e.name}: ${e.message}`:String(e)}function a(e){let t=e.shutdownTimeoutMs??2e3,n=!1,r=(r,a)=>{if(e.logError(`Fatal ${r}: ${i(a)}`),n)return;n=!0;let o=setTimeout(()=>e.exit(1),t);typeof o.unref==`function`&&o.unref(),Promise.resolve().then(()=>e.shutdown()).catch(()=>{}).finally(()=>{clearTimeout(o),e.exit(1)})};e.proc.on(`uncaughtException`,e=>r(`uncaughtException`,e)),e.proc.on(`unhandledRejection`,e=>r(`unhandledRejection`,e))}const o=Date.now(),s=process.env.AIMAX_DATA_DIR,c=process.argv.includes(`run`)&&process.argv.includes(`--encrypt-sessions`),l=process.argv.includes(`run`)||process.argv.includes(`resume`);function u(e){for(let t=0;t<e.length;t++){let n=e[t];if(n===`--message-id`||n===`--messageId`)return e[t+1];if(n?.startsWith(`--message-id=`))return n.slice(13);if(n?.startsWith(`--messageId=`))return n.slice(12)}}s&&!c&&!l&&n(s,{messageId:u(process.argv)}),a({proc:process,logError:t=>e.error(t),shutdown:t,exit:e=>process.exit(e)}),e.info(`AIMax CLI starting (pid=${process.pid})`,{dataDir:s,encryptedRun:c,loggerDeferred:!!(s&&(c||l))}),r().parseAsync(process.argv).catch(t=>{e.error(`Unexpected error: ${t.message}`),process.exit(1)}).finally(()=>{let n=Date.now()-o;return e.info(`AIMax CLI exited (total uptime: ${n}ms)`),t()});export{};
2
+ import"./pkg-path-D6anqptM.js";import{b as e,x as t,y as n}from"./run-BfGeE9D_.js";import{t as r}from"./program-DEjggrmn.js";function i(e){return e instanceof Error?e.stack??`${e.name}: ${e.message}`:String(e)}function a(e){let t=e.shutdownTimeoutMs??2e3,n=!1,r=(r,a)=>{if(e.logError(`Fatal ${r}: ${i(a)}`),n)return;n=!0;let o=setTimeout(()=>e.exit(1),t);typeof o.unref==`function`&&o.unref(),Promise.resolve().then(()=>e.shutdown()).catch(()=>{}).finally(()=>{clearTimeout(o),e.exit(1)})};e.proc.on(`uncaughtException`,e=>r(`uncaughtException`,e)),e.proc.on(`unhandledRejection`,e=>r(`unhandledRejection`,e))}const o=Date.now(),s=process.env.AIMAX_DATA_DIR,c=process.argv.includes(`run`)&&process.argv.includes(`--encrypt-sessions`),l=process.argv.includes(`run`)||process.argv.includes(`resume`);function u(e){for(let t=0;t<e.length;t++){let n=e[t];if(n===`--message-id`||n===`--messageId`)return e[t+1];if(n?.startsWith(`--message-id=`))return n.slice(13);if(n?.startsWith(`--messageId=`))return n.slice(12)}}s&&!c&&!l&&n(s,{messageId:u(process.argv)}),a({proc:process,logError:t=>e.error(t),shutdown:t,exit:e=>process.exit(e)}),e.info(`AIMax CLI starting (pid=${process.pid})`,{dataDir:s,encryptedRun:c,loggerDeferred:!!(s&&(c||l))}),r().parseAsync(process.argv).catch(t=>{e.error(`Unexpected error: ${t.message}`),process.exit(1)}).finally(()=>{let n=Date.now()-o;return e.info(`AIMax CLI exited (total uptime: ${n}ms)`),t()});export{};
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import"./pkg-path-D6anqptM.js";import{t as e}from"./run-9V7V9r8T.js";import{n as t,t as n}from"./program-hmgqVomi.js";export{n as createProgram,e as executeRun,t as getDataDir};
1
+ import"./pkg-path-D6anqptM.js";import{t as e}from"./run-BfGeE9D_.js";import{n as t,t as n}from"./program-DEjggrmn.js";export{n as createProgram,e as executeRun,t as getDataDir};
@@ -1,4 +1,4 @@
1
- import{_ as e,a as t,b as n,c as r,d as i,f as a,g as o,h as s,i as c,l,m as u,n as d,o as ee,p as te,r as ne,s as f,u as p,v as m,y as h}from"./run-9V7V9r8T.js";import{createRequire as re}from"node:module";import{Command as ie}from"commander";import{bootstrapMountLayout as ae,buildAimaxGoalCliHelpExtra as oe,deleteGoal as se,exportSession as ce,generateModelResponse as le,initializePluginSystem as g,inspectSession as ue,listAvailableSlashCommands as de,listSessionSummaries as fe,loadPendingHitl as pe,loadSessionExportSnapshots as me,loadSkillsWithPluginDirs as he,loadTranscript as ge,normalizePluginsConfig as _e,normalizeSessionStoreName as _,readGoal as v,resolveGoalObjective as ve,resolveMemoryProviderOrDefault as ye,resolvePendingHitl as be,runAgent as xe,sessionsDir as Se,transcriptPath as Ce,updateGoal as y,writeGoal as we}from"@gencode/agents";import{existsSync as b,mkdirSync as x,readFileSync as S,statSync as Te,writeFileSync as C}from"node:fs";import w,{basename as T,dirname as E,isAbsolute as D,join as O,relative as k,resolve as A}from"node:path";import j from"node:fs/promises";import{fileURLToPath as Ee}from"node:url";import{addAgent as De,addBinding as Oe,getAgentConfig as M,listAgents as ke,listBindings as N,loadAgentsConfig as P,normalizeAgentId as F,removeAgent as Ae,removeBindings as I,resolveAgentDir as je,resolveDefaultAgentId as L,updateAgentIdentity as Me}from"@gencode/agents/config";import{createHash as Ne,randomUUID as R}from"node:crypto";function Pe(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{i(await p(e.dataDir,e,async()=>ae(e.dataDir)),t)}catch(e){o(`Error bootstrapping data directory: ${e.message}`),process.exit(1)}})}function Fe(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 p(r.dataDir,r,async()=>{let e=r.sessionStore?_(r.sessionStore):void 0;if(i===`list`){s(await fe(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`){u(await ue(r.dataDir,r.sessionId,{storeName:e}),a);return}if(i===`export`){te(await ce(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 Ie(e){return w.join(e,`workspace`)}function Le(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function Re(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(`
1
+ import{_ as e,a as t,b as n,c as r,d as i,f as a,g as o,h as s,i as c,l,m as u,n as d,o as ee,p as te,r as ne,s as f,u as p,v as m,y as h}from"./run-BfGeE9D_.js";import{createRequire as re}from"node:module";import{Command as ie}from"commander";import{bootstrapMountLayout as ae,buildAimaxGoalCliHelpExtra as oe,deleteGoal as se,exportSession as ce,generateModelResponse as le,initializePluginSystem as g,inspectSession as ue,listAvailableSlashCommands as de,listSessionSummaries as fe,loadPendingHitl as pe,loadSessionExportSnapshots as me,loadSkillsWithPluginDirs as he,loadTranscript as ge,normalizePluginsConfig as _e,normalizeSessionStoreName as _,readGoal as v,resolveGoalObjective as ve,resolveMemoryProviderOrDefault as ye,resolvePendingHitl as be,runAgent as xe,sessionsDir as Se,transcriptPath as Ce,updateGoal as y,writeGoal as we}from"@gencode/agents";import{existsSync as b,mkdirSync as x,readFileSync as S,statSync as Te,writeFileSync as C}from"node:fs";import w,{basename as T,dirname as E,isAbsolute as D,join as O,relative as k,resolve as A}from"node:path";import j from"node:fs/promises";import{fileURLToPath as Ee}from"node:url";import{addAgent as De,addBinding as Oe,getAgentConfig as M,listAgents as ke,listBindings as N,loadAgentsConfig as P,normalizeAgentId as F,removeAgent as Ae,removeBindings as I,resolveAgentDir as je,resolveDefaultAgentId as L,updateAgentIdentity as Me}from"@gencode/agents/config";import{createHash as Ne,randomUUID as R}from"node:crypto";function Pe(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{i(await p(e.dataDir,e,async()=>ae(e.dataDir)),t)}catch(e){o(`Error bootstrapping data directory: ${e.message}`),process.exit(1)}})}function Fe(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 p(r.dataDir,r,async()=>{let e=r.sessionStore?_(r.sessionStore):void 0;if(i===`list`){s(await fe(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`){u(await ue(r.dataDir,r.sessionId,{storeName:e}),a);return}if(i===`export`){te(await ce(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 Ie(e){return w.join(e,`workspace`)}function Le(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function Re(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(`
2
2
  `)}function ze(e){let t=e.level===`error`?`plugin error`:`plugin warning`;return e.pluginId?`${t} (${e.pluginId}): ${e.message}`:`${t}: ${e.message}`}function Be(e){if(!e||e===`cli`)return`cli`;if(e===`cron`)return`cron`;throw Error(`Unsupported dream trigger: ${e}. Expected "cli" or "cron".`)}async function Ve(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=g({config:n,dataDir:e.dataDir,workspaceDir:Ie(e.dataDir),bundledDir:Le()});return t.push(...r.diagnostics.map(ze)),{pluginSystem:r,warnings:t}}catch(e){return t.push(`failed to initialize plugin system: ${e.message}`),{warnings:t}}}async function z(e){let t=w.join(e.dataDir,`.aimax`),{pluginSystem:n,warnings:r}=await Ve({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=ye({providerId:e.provider,pluginId:a,dataDir:e.dataDir,memoryDir:t,includeSessions:e.includeSessions});return o.providerSource===`plugin`?{provider:o.provider,providerId:o.providerId,pluginId:o.pluginId,providerOrigin:`plugin`,warnings:r,pluginSystem:n}:((a||e.provider)&&r.push(`requested memory provider was not resolved; falling back to builtin provider`),{provider:o.provider,providerId:`builtin`,providerOrigin:`builtin`,warnings:r,pluginSystem:n})}function He(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 Ue(t){let n=t.command(`memory`).description(`Manage semantic memory indexing and search`),r=e=>e.option(`--plugins-config <path>`,`Plugins config file path`);r(n.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 t=>{let n=t.output===`json`?`json`:`text`;try{await p(t.dataDir,t,async()=>{let r=await z({dataDir:t.dataDir,provider:t.provider,providerPlugin:t.providerPlugin,pluginsConfig:t.pluginsConfig,includeSessions:t.includeSessions});t.index&&r.provider.sync&&await r.provider.sync(`cli-status`);let i=He(r.provider.status(),r,t.deep);e(n===`json`?JSON.stringify(i,null,2):Re(i,t.deep))})}catch(e){o(`Error getting memory status: ${e.message}`),process.exit(1)}}),r(n.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 t=>{try{await p(t.dataDir,t,async()=>{let n=await z({dataDir:t.dataDir,provider:t.provider,providerPlugin:t.providerPlugin,pluginsConfig:t.pluginsConfig,includeSessions:t.includeSessions}),r;if(n.provider.sync&&(await n.provider.sync(t.rebuild?`cli-rebuild`:`cli-index`),r=n.provider.status().custom?.lastRebuildSummary),n.warnings.length>0)for(let e of n.warnings)o(`Warning: ${e}`);t.verbose&&r&&e(JSON.stringify(r,null,2)),e(t.rebuild?`Memory index rebuilt.`:`Memory index refreshed.`)})}catch(e){o(`Error indexing memory: ${e.message}`),process.exit(1)}}),r(n.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(t,n)=>{let r=n.output===`json`?`json`:`text`,i=n.query?.trim()||t?.trim();i||(o(`Query is required: provide [query] or --query <text>`),process.exit(1));try{await p(n.dataDir,n,async()=>{let t=await(await z({dataDir:n.dataDir,provider:n.provider,providerPlugin:n.providerPlugin,pluginsConfig:n.pluginsConfig,includeSessions:n.includeSessions})).provider.search(i);if(r===`json`){e(JSON.stringify(t,null,2));return}if(t.length===0){e(`No results found for: ${i}`);return}e(t.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(`
3
3
  `))})}catch(e){o(`Error searching memory: ${e.message}`),process.exit(1)}}),r(n.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 t=>{let n=t.output===`json`?`json`:`text`;try{await p(t.dataDir,t,async()=>{let r=Be(t.trigger),i=await z({dataDir:t.dataDir,provider:t.provider,providerPlugin:t.providerPlugin,pluginsConfig:t.pluginsConfig,requirePluginSystem:!0}),a=i.pluginSystem?await i.pluginSystem.registry.hooks.dispatch(`dream_gate`,{dataDir:t.dataDir,memoryDir:w.join(t.dataDir,`.aimax`),providerId:i.providerId,pluginId:i.pluginId,trigger:r,dryRun:!!t.dryRun},{workspaceDir:Ie(t.dataDir)}):[],o={ok:!0,trigger:r,providerSource:i.providerOrigin,providerId:i.providerId,pluginId:i.pluginId,resultCount:a.length,results:a,warnings:i.warnings};if(n===`json`){e(JSON.stringify(o,null,2));return}e(`trigger: ${o.trigger}`),e(`provider_source: ${o.providerSource}`),e(`provider_id: ${o.providerId}`),o.pluginId&&e(`plugin_id: ${o.pluginId}`),e(`result_count: ${o.resultCount}`),o.results.length===0?e(`note: no dream_gate hook registered`):e(`results: ${JSON.stringify(o.results)}`);for(let t of o.warnings)e(`warning: ${t}`)})}catch(e){o(`Error running dream gate: ${e.message}`),process.exit(1)}})}function We(e){return`${e.match.accountId?`${e.match.channel}:${e.match.accountId}`:e.match.channel} -> ${e.agentId}`}function Ge(e){return async t=>{let n=await P(t),r=ke(n),i=N(n);if(L(n),e.json){console.log(JSON.stringify({agents:r,bindings:i},null,2));return}console.log(`Agents:`);for(let e of r){let n=e.default?` (default)`:``,r=e.name&&e.name!==e.id?`${e.id}${n} (${e.name})`:`${e.id}${n}`;if(console.log(` - ${r}`),e.identity?.emoji||e.identity?.name){let t=[e.identity.emoji,e.identity.name].filter(Boolean).join(` `);console.log(` Identity: ${t}`)}let a=je(t,e.id);if(console.log(` Agent dir: ${a}`),e.model){let t=typeof e.model==`string`?e.model:e.model.primary;console.log(` Model: ${t}`)}let o=i.filter(t=>t.agentId===e.id);if(o.length>0){console.log(` Routing rules:`);for(let e of o)console.log(` - ${We(e)}`)}}}}function Ke(e,t){return async n=>{M(await P(n),F(e))&&(console.error(`Agent "${e}" already exists.`),process.exit(1)),await De(n,{id:e,name:t.name,model:t.model,default:t.default})||(console.error(`Agent "${e}" already exists.`),process.exit(1));let r=je(n,e);console.log(`Agent "${e}" added successfully.`),console.log(` Agent dir: ${r}`)}}function qe(e){return async t=>{let n=M(await P(t),F(e));n||(console.error(`Agent "${e}" not found.`),process.exit(1)),n.default===!0&&(console.error(`Cannot delete default agent "${e}".`),process.exit(1)),await Ae(t,e)||(console.error(`Failed to delete agent "${e}".`),process.exit(1)),console.log(`Agent "${e}" deleted.`)}}function Je(e){return async t=>{let n=await P(t),r=e.agent??L(n);M(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 Oe(t,{agentId:r,match:{channel:e,accountId:a||void 0}}),console.log(`Binding added: ${n} -> ${r}`)}}}function Ye(e){return async t=>{let n=await P(t),r=e.agent??L(n);if(M(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),e.all){let e=await I(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 I(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 Xe(e){return async t=>{let n=N(await P(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(` ${We(e)}`)}}function Ze(e){return async t=>{let n=await P(t),r=e.agent??L(n);M(n,r)||(console.error(`Agent "${r}" not found.`),process.exit(1)),await Me(t,r,{name:e.name,emoji:e.emoji,avatar:e.avatar})||(console.error(`Failed to update identity for agent "${r}".`),process.exit(1)),console.log(`Identity updated for agent "${r}".`)}}function Qe(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 p(n,e,async()=>{await Ge(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 p(r,n,async()=>{await Ke(e,n)(r)})}),r(n.command(`delete <id>`).description(`Delete an agent`)).action(async(e,n)=>{let r=t();await p(r,n,async()=>{await qe(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 p(n,e,async()=>{await Je(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 p(n,e,async()=>{await Ye(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 p(n,e,async()=>{await Xe(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 p(n,e,async()=>{await Ze(e)(n)})})}function B(e){return w.join(e,`workspace`)}function V(){let e=process.env.AIMAX_PLUGINS_BUNDLED_DIR;return e&&e.trim()||void 0}function $e(t){if(t.length===0){e(`No plugins discovered.`);return}for(let n of t){let t=n.status.padEnd(8,` `);e(`${n.id} ${t} ${n.origin} ${n.source}`)}}function et(t){e(`id: ${t.id}`),e(`status: ${t.status}`),e(`origin: ${t.origin}`),e(`source: ${t.source}`),e(`enabled: ${t.enabled}`),t.error&&e(`error: ${t.error}`),e(`tools: ${t.toolCount}`),e(`hooks: ${t.hookCount}`),t.skills.length>0&&e(`skills: ${t.skills.join(`, `)}`)}function H(e){return Array.from(new Set((e??[]).map(e=>e.trim()).filter(Boolean)))}function tt(t){if(t.length===0){e(`LLM allowlist is empty.`);return}for(let n of t)e(n)}function nt(t,n){let i=t.command(`plugins`).description(`Manage AIMax plugins`),a=e=>e.option(`--plugins-config <path>`,`Plugins config file path`),s=e=>e.option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`);s(a(i.command(`list`))).description(`List discovered plugins`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let t=e.dataDir??n();await p(t,e,async()=>{$e(g({config:await f(t,e.pluginsConfig),dataDir:t,workspaceDir:B(t),bundledDir:V()}).registry.plugins)})}),s(a(i.command(`info`))).description(`Show plugin details`).argument(`<id>`,`Plugin id`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(e,t)=>{let r=t.dataDir??n();await p(r,t,async()=>{let n=g({config:await f(r,t.pluginsConfig),dataDir:r,workspaceDir:B(r),bundledDir:V()}).registry.plugins.find(t=>t.id===e);n||(o(`Plugin not found: ${e}`),process.exit(1)),et(n)})}),s(a(i.command(`enable`))).description(`Enable a plugin`).argument(`<id>`,`Plugin id`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(t,i)=>{let a=i.dataDir??n();await p(a,i,async()=>{let n=await f(a,i.pluginsConfig)??{},s=_e(n);g({config:n,dataDir:a,workspaceDir:B(a),bundledDir:V()}).registry.plugins.some(e=>e.id===t)||(o(`Plugin not found: ${t}`),process.exit(1)),await r(a,{...n,entries:{...n.entries,[t]:{...n.entries?.[t]??{},enabled:!0}}},i.pluginsConfig),e(`Enabled ${t}`),s.allow.length>0&&!s.allow.includes(t)&&e(`Note: plugins.allow is set; add this plugin id to allowlist if needed.`)})}),s(a(i.command(`disable`))).description(`Disable a plugin`).argument(`<id>`,`Plugin id`).option(`-d, --data-dir <path>`,`Data directory path`).action(async(t,i)=>{let a=i.dataDir??n();await p(a,i,async()=>{let n=await f(a,i.pluginsConfig)??{};g({config:n,dataDir:a,workspaceDir:B(a),bundledDir:V()}).registry.plugins.some(e=>e.id===t)||(o(`Plugin not found: ${t}`),process.exit(1)),await r(a,{...n,entries:{...n.entries,[t]:{...n.entries?.[t]??{},enabled:!1}}},i.pluginsConfig),e(`Disabled ${t}`)})}),s(a(i.command(`doctor`))).description(`Validate plugin configuration`).option(`-d, --data-dir <path>`,`Data directory path`).action(async t=>{let r=t.dataDir??n();await p(r,t,async()=>{let n=g({config:await f(r,t.pluginsConfig),dataDir:r,workspaceDir:B(r),bundledDir:V()});if(n.diagnostics.length===0){e(`No plugin issues detected.`);return}for(let t of n.diagnostics)e(`${t.level===`error`?`ERROR`:`WARN`}${t.pluginId?` ${t.pluginId}`:``}: ${t.message}`);n.diagnostics.some(e=>e.level===`error`)&&process.exit(1)})});let c=i.command(`llm-allow`).description(`Manage plugin LLM allowlist`);s(a(c.command(`list`))).description(`List LLM allowlist entries`).option(`-d, --data-dir <path>`,`Data directory path`).action(async e=>{let t=e.dataDir??n();await p(t,e,async()=>{tt(H((await f(t,e.pluginsConfig))?.llmAllowlist))})}),s(a(c.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(t,i)=>{let a=i.dataDir??n();await p(a,i,async()=>{let n=await f(a,i.pluginsConfig)??{},o=H([...n.llmAllowlist??[],...t]);await r(a,{...n,llmAllowlist:o},i.pluginsConfig),e(`LLM allowlist updated (${o.length} entries).`)})}),s(a(c.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(t,i)=>{let a=i.dataDir??n();await p(a,i,async()=>{let n=await f(a,i.pluginsConfig)??{},o=new Set(t.map(e=>e.trim()).filter(Boolean)),s=H(n.llmAllowlist).filter(e=>!o.has(e));await r(a,{...n,llmAllowlist:s},i.pluginsConfig),e(`LLM allowlist updated (${s.length} entries).`)})}),s(a(c.command(`clear`))).description(`Clear the LLM allowlist`).option(`-d, --data-dir <path>`,`Data directory path`).action(async t=>{let i=t.dataDir??n();await p(i,t,async()=>{await r(i,{...await f(i,t.pluginsConfig)??{},llmAllowlist:[]},t.pluginsConfig),e(`LLM allowlist cleared.`)})})}function rt(t){t.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 t=>{let n=t.output===`json`?`json`:`text`;try{await p(t.dataDir,t,async()=>{let r=de(await he(t.dataDir,[]));if(n===`json`){e(JSON.stringify(r,null,2));return}e(`Commands`),e(` builtin: ${r.builtin.map(e=>e.name).join(` | `)}`),r.skillCommands.length>0?e(` skills: ${r.skillCommands.map(e=>e.name).join(` | `)}`):e(` skills: (none)`)})}catch(e){o(`Error listing commands: ${e.message}`),process.exit(1)}})}function U(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 W(e){if(!e.sessionId)throw Error(`Session ID is required (--session-id or -s)`);return e.sessionId}function G(e){return e?_(e):void 0}async function it(e){let t={storeName:e.sessionStoreName},n=e.objective.trim(),r=await v(e.dataDir,e.sessionId,t);if(!r||(await ve(e.dataDir,e.sessionId,r,t)).trim()!==n)return we(e.dataDir,e.sessionId,{goalId:R(),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 y(e.dataDir,e.sessionId,i,{...t,eventSource:`cli`})}async function at(t,n){let r=U(n),i=W(n),a=G(n.sessionStore),s=t.trim();s||(o(`error: objective cannot be empty`),process.exit(1));let c=n.tokenBudget===void 0||n.tokenBudget===`0`||n.tokenBudget===``?null:Number(n.tokenBudget);c!==null&&(Number.isNaN(c)||c<=0)&&(o(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));let l=await it({dataDir:r,sessionId:i,sessionStoreName:a,objective:s,tokenBudget:c});e(JSON.stringify({goal:l},null,2))}async function ot(t){let n=U(t),r=W(t),i=G(t.sessionStore),a=await v(n,r,{storeName:i});if(!a){e(JSON.stringify({goal:null},null,2));return}let o=await ve(n,r,a,{storeName:i});e(JSON.stringify({goal:{...a,objective:o}},null,2))}async function st(t){let n=U(t),r=W(t),i=G(t.sessionStore),a=await v(n,r,{storeName:i});a||(o(`error: no goal exists for this session`),process.exit(1)),a.status===`complete`&&(o(`error: cannot pause a completed goal`),process.exit(1));let s=await y(n,r,{status:`paused`},{storeName:i,eventSource:`cli`});e(JSON.stringify({goal:s},null,2))}async function ct(t){let n=U(t),r=W(t),i=G(t.sessionStore),a=await v(n,r,{storeName:i});if(a||(o(`error: no goal exists for this session`),process.exit(1)),a.status===`complete`&&(o(`error: cannot resume a completed goal`),process.exit(1)),a.status===`budget_limited`&&(o(`error: cannot resume a budget-limited goal; clear or replace it instead`),process.exit(1)),a.status===`active`){e(JSON.stringify({goal:a},null,2));return}let s=await y(n,r,{status:`active`},{storeName:i,eventSource:`cli`});e(JSON.stringify({goal:s},null,2))}async function lt(t){let n=await se(U(t),W(t),{storeName:G(t.sessionStore),eventSource:`cli`});e(JSON.stringify({cleared:n},null,2))}function ut(e){let t=e.command(`goal`).description(`Manage thread goals for a session`).addHelpText(`after`,oe());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 at(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 ot(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 st(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 ct(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 lt(e)}catch(e){o(`error: ${e.message}`),process.exit(1)}})}const dt=[`progress`,`error`,`hitl`];function ft(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 pt(e){if(!e?.trim())return new Set(dt);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(dt)}function mt(e){return e?_(e):void 0}function ht(e){let n=[];return e.callbackUrl&&n.push(new t(e.callbackUrl)),e.streamUrl&&n.push(new c(e.streamUrl,pt(e.streamEvents),e.streamAuthToken)),new ee(n)}async function gt(e){let t=ft(e);await p(t,e,async()=>{h(t,{messageId:e.messageId});let r=new m(`cancel command`),i=e.channel??`WEB`,s=e.output===`json`?`json`:`text`,c=ht(e),l=mt(e.sessionStore);try{let n=await pe(t,e.sessionId,{storeName:l});if(!n)throw Error(`No pending HITL request found for session "${e.sessionId}"`);let o=e.requestId??n.request.requestId;if(n.request.requestId!==o)throw Error(`Request ID mismatch: pending is "${n.request.requestId}", got "${o}"`);if(!(await be({dataDir:t,sessionStoreName:l,sessionId:e.sessionId,requestId:o,resolution:{requestId:o,sessionId:e.sessionId,action:`cancel`,submittedAt:new Date().toISOString(),submittedBy:{channel:i}}})).state)throw Error(`Failed to cancel HITL request`);let u={type:`hitl_cancelled`,sessionId:e.sessionId,requestId:o,reason:e.reason??`cancelled by operator`};s===`text`&&a(u),await c.send({type:`progress`,sessionId:e.sessionId,channel:i,messageId:e.messageId,event:u}),r.end(),process.exit(0)}catch(t){let a=t;await c.send({type:`error`,sessionId:e.sessionId,channel:i,messageId:e.messageId,message:a.message}),n.error(`cancel command error: ${a.message}`),o(`Fatal: ${a.message}`),r.end(),process.exit(1)}finally{await c.close()}})}function _t(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 gt(e)})}function vt(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 yt(e){return e.query?.trim()||void 0}function bt(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 xt(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 St(e){if(e.filePath){if(!w.isAbsolute(e.filePath))throw Error(`--file-path must be an absolute path`);try{await j.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 Ct(t){let r=null;try{let i=vt(t);h(i,{messageId:t.messageId}),r=new m(`summarize command`);let a=yt(t),o=await St(t),s=l({apiFormat:t.apiFormat,baseUrl:t.baseUrl,apiKey:t.apiKey,model:t.model,contextWindow:2e5}),c=bt(t.timeout),u=xt(t.maxTokens);n.info(`summarize command started`,{dataDir:i,source:o.source,filePath:o.source===`file`?o.filePath:void 0,queryLength:a?.length,contentLength:o.source===`content`?o.content.length:void 0,timeoutMs:c,maxTokens:u});let d=await xe({dataDir:i,channel:`WEB`,messageId:t.messageId,message:wt(o,a),llm:{...s,maxTokens:u},timeoutMs:c});e(d.text.trim()),n.info(`summarize command succeeded`,{source:o.source,summaryLength:d.text.length,durationMs:d.durationMs}),r.end()}catch(e){n.error(`summarize command error: ${e.message}`),o(`Fatal: ${e.message}`),r?.end(),process.exit(1)}}function wt(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(`
4
4
  `):[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(`
package/dist/program.js CHANGED
@@ -1 +1 @@
1
- import"./run-9V7V9r8T.js";import{n as e,t}from"./program-hmgqVomi.js";export{t as createProgram,e as getDataDir};
1
+ import"./run-BfGeE9D_.js";import{n as e,t}from"./program-DEjggrmn.js";export{t as createProgram,e as getDataDir};
@@ -0,0 +1,11 @@
1
+ import{GoalConflictError as e,applyCliGoalBeforeRun as t,buildResumeNarration as n,clearPendingUiTool as r,ensureBootstrapMountLayout as i,formatApprovalResolution as a,formatClarifyResolution as o,formatReviewResolution as s,hasBootstrapSentinel as c,loadPendingHitl as l,loadPendingUiTool as u,loadTranscript as d,normalizeSessionStoreName as f,readGoal as p,resolvePendingHitl as m,resolvePendingUiTool as h,rewriteTranscript as g,runAgent as _}from"@gencode/agents";import{formatTaskForDisplay as v,isAgentDiagnosticEvent as y,isHitlTool as b,parseMatchedTextToResolution as x,parseTextToResolution as ee}from"@gencode/shared";import S from"node:fs";import C from"node:path";import w from"log4js";import T from"node:fs/promises";import E from"node:os";import{execFile as te,execFileSync as ne}from"node:child_process";import re from"gensign-node";import{fileURLToPath as ie}from"node:url";function ae(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 oe(e=new Date){let t=ae(e),n=String(e.getMilliseconds()).padStart(3,`0`);return`${t.year}-${t.month}-${t.day} ${t.hour}:${t.minute}:${t.second}.${n}`}let D=function(e){return e.INFO=`INFO`,e.ERROR=`ERROR`,e.WARN=`WARN`,e}({}),O=null,k=!1,A=[],se=Promise.resolve();function ce(){return oe()}function le(e){if(!e)return``;let t=Object.entries(e).filter(([,e])=>e!==void 0).map(([e,t])=>`${e}=${ue(t)}`);return t.length>0?` ${t.join(` `)}`:``}function ue(e){return JSON.stringify(de(e,new WeakSet))??`undefined`}function de(e,t){return typeof e==`bigint`?e.toString():e==null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`?e:e instanceof Error?{name:e.name,message:e.message,stack:e.stack}:typeof e!=`object`&&typeof e!=`function`?String(e):t.has(e)?`[Circular]`:(t.add(e),Array.isArray(e)?e.map(e=>de(e,t)):Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0).map(([e,n])=>[e,de(n,t)])))}function fe(e){return C.join(e,`.aimax`)}function pe(e){let t=e?.trim();return t&&t.replace(/[^A-Za-z0-9_.-]/g,`_`)||`no-message-${process.pid}`}function me(e,t){let n=pe(t?.messageId),r=t?.sessionStoreName?.trim()||`sessions`;return t?.sessionId?{runLogId:n,logDir:C.join(fe(e),r,t.sessionId,`logs`,n)}:{runLogId:n,logDir:C.join(fe(e),`logs`,n)}}function he(e){return{appLogPath:C.join(e,`app.log`),errorLogPath:C.join(e,`errors.log`)}}function ge(e){let{appLogPath:t,errorLogPath:n}=he(e);w.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 _e(e,t,n){return`[${ce()}] [${e}] ${t}${le(n)}`}function ve(e,t,n){try{process.stderr.write(`${_e(e,t,n)}\n`)}catch{}}function j(e,t,n){if(!O){A.push({level:e,message:t,context:n}),A.length>200&&(A=A.slice(-200)),ve(e,t,n);return}k||=(ge(O.logDir),!0);let r=_e(e,t,n),i=w.getLogger();if(e===D.ERROR){i.error(r);return}if(e===D.WARN){i.warn(r);return}i.info(r)}function ye(e,t){let{logDir:n,runLogId:r}=me(e,t);if(k&&O?.dataDir===e&&O.runLogId===r&&O.logDir===n)return;S.mkdirSync(n,{recursive:!0}),ge(n),k=!0,O={dataDir:e,logDir:n,runLogId:r};let i=A;A=[];for(let e of i)j(e.level,e.message,e.context)}function be(){return O?{...O}:null}function xe(e){if(!e.logDir){e.level===`ERROR`?j(D.ERROR,e.message,e.context):e.level===`WARN`?j(D.WARN,e.message,e.context):j(D.INFO,e.message,e.context);return}let{appLogPath:t,errorLogPath:n}=he(e.logDir),r=`${e.formatted}\n`;se=se.then(async()=>{await S.promises.mkdir(e.logDir,{recursive:!0}),await S.promises.appendFile(t,r,`utf-8`),e.level===`ERROR`&&await S.promises.appendFile(n,r,`utf-8`)}).catch(t=>{ve(D.ERROR,`delegated agent log write failed`,{logDir:e.logDir,error:t instanceof Error?t.message:String(t)})})}async function M(){await se;try{await Se()}finally{k=!1}}function Se(){return new Promise((e,t)=>{w.shutdown(n=>{if(n){t(n);return}e()})})}const N={info:(e,t)=>j(D.INFO,e,t),warn:(e,t)=>j(D.WARN,e,t),error:(e,t)=>j(D.ERROR,e,t)};var Ce=class{startTime;name;constructor(e){this.name=e,this.startTime=Date.now()}end(){let e=Date.now()-this.startTime;return N.info(`${this.name} completed in ${e}ms`),e}};function we(e){if(typeof e==`string`)return e;let t=JSON.stringify(e);return t===void 0?String(e):t}const Te=new Set;function Ee(e){return e instanceof Error?{name:e.name,message:e.message,code:e.code}:{message:String(e)}}function De(e,t){try{N.warn(`CLI ${e} write failed; suppressing further ${e} writes`,{stream:e,...Ee(t)})}catch{}}function Oe(e,t){if(Te.has(e))return;let n=e===`stdout`?process.stdout:process.stderr;try{n.write(t)}catch(t){Te.add(e),De(e,t)}}function ke(e){Oe(`stdout`,e)}function P(e){Oe(`stdout`,e+`
2
+ `)}function F(e){Oe(`stderr`,e+`
3
+ `)}function I(e){switch(e.type){case`start`:P(`\n[start] ${e.message}`);break;case`text`:ke(e.text);break;case`stream_text_delta`:ke(e.text);break;case`bootstrap`:P(`\n[bootstrap:${e.phase}] ${e.dataDir}`);break;case`session_reset`:P(`\n[session:${e.action}] ${e.message}`);break;case`tool_start`:P(`\n[tool:${e.name}] ${JSON.stringify(e.input??{})}`);break;case`tool_end`:{let t=we(e.output);P(`[tool:${e.name}] ${e.isError?`ERROR`:`OK`} ${t.slice(0,200)}`);break}case`compaction`:P(`\n[compaction${e.layer?`:${e.layer}`:``}] ${e.reason}${e.strategy?` (${e.strategy})`:``}`);break;case`skill_used`:P(`\n[skill] ${e.skillName} agent=${e.agent} task=${e.taskId}`);break;case`custom`:P(`\n[plugin:${e.pluginId}] ${e.name}${e.label?` ${e.label}`:``}${e.data?` ${JSON.stringify(e.data)}`:``}`);break;case`error`:F(`\n[error] ${e.message}`);break;case`diagnostic`:break;case`subagent_spawn`:P(`\n[subagent:spawn]${e.label?` "${e.label}"`:``} ${v(e.task)}`);break;case`subagent_complete`:P(`[subagent:${e.status}] ${v(e.task)}`);break;case`hitl_requested`:if(P(`\n[hitl:${e.request.kind}] ${e.request.title}`),P(` prompt: ${e.request.prompt}`),P(` requestId: ${e.request.requestId}`),e.request.input.mode===`choice`)for(let t of e.request.input.choices)P(` - [${t.id}] ${t.label}`);break;case`hitl_resumed`:P(`\n[hitl:resumed] requestId=${e.requestId} action=${e.resolution.action}`);break;case`hitl_expired`:P(`\n[hitl:expired] requestId=${e.requestId} reason=${e.reason}`);break;case`hitl_cancelled`:P(`\n[hitl:cancelled] requestId=${e.requestId}${e.reason?` reason=${e.reason}`:``}`);break;case`ui_tool_request`:P(`\n[ui-tool:${e.request.toolName}] ${e.request.outputSchema.title}`),P(` requestId: ${e.request.requestId}`),P(` toolCallId: ${e.request.toolCallId}`);break;case`ui_tool_result`:P(`\n[ui-tool:resumed] requestId=${e.requestId} tool=${e.toolName}`);break}}function L(e,t){if(t===`json`){e&&P(JSON.stringify(e,null,2));return}P(`
4
+ `),P(`session: ${e.sessionId}`),P(`duration: ${e.durationMs}ms`),P(`tokens: input=${e.usage.input} output=${e.usage.output} total=${e.usage.total}`),e.context&&(P(`context: ${e.context.snapshotPath}`),P(`tool-results: ${e.context.toolResultsDir}`)),e.error&&F(`error: ${e.error}`)}function Ae(e,t){if(t===`json`){P(JSON.stringify(e,null,2));return}if(e.length===0){P(`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:—]`;P(`${t.id} ${e} [${t.channel}]${n} ${t.title}`)}}function je(e,t){if(t===`json`){P(JSON.stringify(e,null,2));return}P(`session: ${e.id}`),e.metadata&&(P(`title: ${e.metadata.title}`),P(`channel: ${e.metadata.channel}`),P(`created: ${e.metadata.createdAt}`),P(`updated: ${e.metadata.updatedAt}`)),P(`transcript: ${e.transcriptPath}`),P(`entries: ${e.transcriptEntryCount}`),P(`context: ${e.contextSnapshotPath}`),P(`session-memory: ${e.sessionMemoryPath}`),P(`collapse-log: ${e.collapseLogPath}`),P(`read-states: ${e.readStateCount}`),P(`tool-results: ${e.toolResultRefCount}`),P(`tool-results-dir: ${e.toolResultsDir}`)}function Me(e,t){if(t===`json`){P(JSON.stringify(e,null,2));return}P(`session: ${e.id}`),P(`transcript: ${e.paths.transcriptPath}`),P(`context: ${e.paths.contextSnapshotPath}`),P(`session-memory: ${e.paths.sessionMemoryPath}`),P(`collapse-log: ${e.paths.collapseLogPath}`),P(`tool-results-dir: ${e.paths.toolResultsDir}`),P(`transcript-entries: ${e.transcript.length}`),P(`read-states: ${e.context.readStates.length}`),P(`tool-results: ${e.context.toolResults.length}`),P(`collapse-spans: ${e.context.compaction.collapseSpans.length}`)}function Ne(e,t){if(t===`json`){P(JSON.stringify(e,null,2));return}P(`Bootstrap completed.`),P(`dataDir: ${e.dataDir}`),P(`created dirs: ${e.createdDirs.length}`),P(`created files: ${e.createdFiles.length}`),P(`skipped dirs: ${e.skippedDirs.length}`),P(`skipped files: ${e.skippedFiles.length}`)}const R=`.aimax`,Pe=`${R}.pre-gocryptfs.`,Fe=[`app.log`,`errors.log`],Ie=[`logs`],Le=[`fusermount3`,`fusermount`,`umount`],Re=[{command:`fusermount3`,args:[`-u`],label:`fusermount3 -u`},{command:`fusermount3`,args:[`-uz`],label:`fusermount3 -uz`},{command:`fusermount`,args:[`-u`],label:`fusermount -u`},{command:`fusermount`,args:[`-uz`],label:`fusermount -uz`},{command:`umount`,args:[],label:`umount`},{command:`umount`,args:[`-l`],label:`umount -l`}];function ze(e){return C.join(e,`.aimax.enc`)}function Be(e){return C.join(e,R)}function Ve(e){return C.join(e,`${Pe}${process.pid}.${Date.now()}`)}function He(e){return C.join(e,`${R}.plaintext-restore.${process.pid}.${Date.now()}`)}function Ue(e){return e.replace(/\\([0-7]{3})/g,(e,t)=>String.fromCharCode(Number.parseInt(t,8)))}async function z(e){try{let t=await Ke.read(),n=C.resolve(e);for(let e of t.split(`
5
+ `)){if(!e.trim())continue;let t=e.split(` `);if(t.length>=5&&C.resolve(Ue(t[4]??``))===n)return!0}return!1}catch{return!1}}function We(e){try{let t=S.readFileSync(`/proc/self/mountinfo`,`utf-8`),n=C.resolve(e);for(let e of t.split(`
6
+ `)){if(!e.trim())continue;let t=e.split(` `);if(t.length>=5&&C.resolve(Ue(t[4]??``))===n)return!0}return!1}catch{return!1}}async function Ge(){return await T.readFile(`/proc/self/mountinfo`,`utf-8`)}const Ke={read:Ge};async function B(e){try{return await T.stat(e),!0}catch(e){if(e.code===`ENOENT`)return!1;throw e}}async function V(e){await T.mkdir(e,{recursive:!0})}async function qe(e){if(await V(e),(await T.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 B(e)?(await T.readdir(e)).length===0:!0}async function H(e){if(await B(e))return(await T.readdir(e)).length}async function Ye(e){let t;try{t=await T.readdir(e,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return{exists:!1,entryCount:void 0,isEmpty:!0,containsUserData:!1};throw e}let n=!1;for(let e of t)if(!(e.isDirectory()&&Ie.includes(e.name))&&!(e.isFile()&&Fe.some(t=>e.name.startsWith(t)))){n=!0;break}return{exists:!0,entryCount:t.length,isEmpty:t.length===0,containsUserData:n}}async function Xe(e){let t=await T.readdir(e,{withFileTypes:!0});for(let n of t){if(n.isDirectory()&&Ie.includes(n.name)){await T.rm(C.join(e,n.name),{recursive:!0,force:!0}).catch(()=>{});continue}n.isFile()&&Fe.some(e=>n.name.startsWith(e))&&await T.rm(C.join(e,n.name),{force:!0}).catch(()=>{})}}async function Ze(e){if(!await B(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 Qe(e){return(await T.readdir(e,{withFileTypes:!0})).filter(e=>e.isDirectory()&&e.name.startsWith(Pe)).map(t=>C.join(e,t.name)).sort()}async function U(e,t){if(!await B(t))return null;let n=Ve(e);return N.info(`--encrypt-sessions moving plaintext .aimax aside before migration`,{plainDir:t,backupDir:n}),await T.rename(t,n),n}async function W(e,t,n){N.info(`--encrypt-sessions copying plaintext backup into encrypted mount`,{backupDir:e,plainDir:t,force:n}),await T.cp(e,t,{recursive:!0,force:n})}async function $e(e,t){if(e.length===0)return[];await V(t);let n=[];for(let r of e)await B(r)&&(await W(r,t,!0),await T.rm(r,{recursive:!0,force:!0}),N.info(`--encrypt-sessions restored interrupted plaintext backup after failed migration`,{backupDir:r,plainDir:t}),n.push(r));return n}async function et(e){let t=Date.now(),n=ze(e),r=Be(e),i=await B(n);if(!i)return;let a=i&&await B(C.join(n,`gocryptfs.conf`)),o=await Ye(r),s=o.exists?await z(r):!1;if(N.info(`plaintext .aimax restore check for disabled --encrypt-sessions`,{dataDir:e,encryptedDir:n,plainDir:r,encryptedDirExists:i,encryptedDirInitialized:a,plainDirExists:o.exists,plainDirMountPoint:s,plainDirEntryCount:o.entryCount,probeDurationMs:Date.now()-t}),!a){N.warn(`plaintext .aimax restore skipped because .aimax.enc is not initialized`,{encryptedDir:n,plainDir:r}),await V(r);return}if(s){N.warn(`plaintext .aimax restore skipped because .aimax is already a mount point`,{plainDir:r,encryptedDir:n});return}if(o.containsUserData){N.info(`plaintext .aimax restore skipped because plaintext .aimax already contains data`,{plainDir:r,encryptedDir:n,plainDirEntryCount:o.entryCount,probeDurationMs:Date.now()-t});return}o.isEmpty||(N.info(`plaintext .aimax clearing ephemeral files before restore`,{plainDir:r,encryptedDir:n,plainDirEntryCount:o.entryCount}),await Xe(r));try{await rt()}catch(e){N.warn(`plaintext .aimax restore unavailable; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e),plainDir:r,encryptedDir:n}),await V(r);return}let c=He(e),l=!1;try{await qe(r),await G(n,r),l=!0,await T.rm(c,{recursive:!0,force:!0}),await V(c),await T.cp(r,c,{recursive:!0,force:!0}),N.info(`plaintext .aimax restore copied encrypted history to staging directory`,{plainDir:r,encryptedDir:n,restoreDir:c,restoredEntryCount:await H(c)}),await K(r),l=!1,await T.rm(r,{recursive:!0,force:!0}),await T.rename(c,r),N.info(`plaintext .aimax restore completed for disabled --encrypt-sessions`,{plainDir:r,encryptedDir:n})}catch(e){l&&await K(r).catch(e=>{N.warn(`plaintext .aimax restore failed to unmount during rollback`,{error:e instanceof Error?e.message:String(e),plainDir:r,encryptedDir:n})}),await T.rm(c,{recursive:!0,force:!0}).catch(()=>{}),await V(r).catch(()=>{}),N.warn(`plaintext .aimax restore failed; continuing with existing plaintext .aimax`,{error:e instanceof Error?e.message:String(e),plainDir:r,encryptedDir:n})}}async function tt(e){let t=C.join(E.tmpdir(),`aimax-gocryptfs-pass.${process.pid}.${Date.now()}`);await T.writeFile(t,`wizard_aimax@2026
7
+ `,{mode:384});try{return await e(t)}finally{await T.rm(t,{force:!0})}}async function nt(e){let t=e.includes(`-init`)?`init`:`mount`;N.info(`--encrypt-sessions starting gocryptfs ${t}`);try{await lt(`gocryptfs`,e),N.info(`--encrypt-sessions completed gocryptfs ${t}`)}catch(n){let r=n instanceof Error?n.message:String(n);throw N.warn(`--encrypt-sessions failed gocryptfs ${t}`,{error:r}),Error(`gocryptfs ${e.join(` `)} failed: ${r}`)}}async function rt(){N.info(`--encrypt-sessions checking encryption dependencies`),await dt(`gocryptfs`,`required for --encrypt-sessions`),N.info(`--encrypt-sessions dependency available`,{command:`gocryptfs`});for(let e of Le)if(await ut(e)){N.info(`--encrypt-sessions unmount dependency available`,{command:e});return}throw Error(`--encrypt-sessions requires one of ${Le.join(`, `)} to be installed for secure unmount cleanup.`)}async function G(e,t){N.info(`--encrypt-sessions mounting encrypted .aimax`,{encryptedDir:e,plainDir:t}),await tt(async n=>{await nt([`-q`,`-passfile`,n,e,t])})}async function it(e){N.info(`--encrypt-sessions initializing encrypted .aimax directory`,{encryptedDir:e}),await tt(async t=>{await nt([`-q`,`-init`,`-passfile`,t,e])})}async function K(e){let t=[];N.info(`--encrypt-sessions unmounting encrypted .aimax`,{plainDir:e});for(let n of Re)try{if(N.info(`--encrypt-sessions attempting encrypted .aimax unmount`,{command:n.label,plainDir:e}),await lt(n.command,[...n.args,e]),!await z(e)){N.info(`--encrypt-sessions unmounted encrypted .aimax`,{command:n.label,plainDir:e});return}let r=`${n.label} returned success but ${e} is still mounted`;t.push(r),N.warn(`--encrypt-sessions unmount command returned success but mountpoint remains`,{command:n.label,plainDir:e})}catch(r){let i=ft(n.label,r);t.push(i),N.warn(`--encrypt-sessions unmount attempt failed`,{command:n.label,plainDir:e,error:r instanceof Error?r.message:String(r)})}throw Error(`Failed to unmount ${e}: ${t.join(`; `)}`)}function at(e){for(let t of Re)try{if(ne(t.command,[...t.args,e],{stdio:`ignore`}),!We(e))return}catch{}}function ot(e){let t=!1,n=()=>{t||(t=!0,at(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 st(e){let t=ze(e),n=Be(e),r=await B(n),i=await B(t),a=i&&await B(C.join(t,`gocryptfs.conf`)),o=r?await z(n):!1;N.info(`--encrypt-sessions preparing encrypted .aimax mount`,{dataDir:e,encryptedDir:t,plainDir:n,plainDirExists:r,encryptedDirExists:i,encryptedDirInitialized:a,plainDirMountPoint:o,plainDirEntryCount:await H(n),encryptedDirEntryCount:await H(t)});let s=()=>({mounted:!1,plainDir:n,encryptedDir:t,async cleanup(){}});try{await rt()}catch(e){return N.warn(`--encrypt-sessions is unavailable; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e)}),await V(n),s()}if(await z(n))return N.warn(`--encrypt-sessions found existing .aimax mount; continuing without taking ownership`,{plainDir:n}),s();let c=null,l=[],u=null,d=null,f=!1;try{if(l=await Qe(e),l.length>0&&N.warn(`--encrypt-sessions found interrupted pre-gocryptfs migration backups`,{count:l.length}),!await B(t))if(N.info(`--encrypt-sessions encrypted .aimax directory does not exist; starting first-time migration`,{encryptedDir:t,plainDir:n,resumedBackupCount:l.length}),l.length>0?u=await U(e,n):c=await U(e,n),await V(t),await it(t),await V(n),await G(t,n),f=!0,d=ot(n),N.info(`--encrypt-sessions mounted encrypted .aimax`,{plainDir:n,encryptedDir:t}),l.length>0){for(let e of l)await W(e,n,!0);u&&=(await W(u,n,!1),await T.rm(u,{recursive:!0,force:!0}),N.info(`--encrypt-sessions removed residual plaintext backup after migration`,{backupDir:u}),null);for(let e of l)await T.rm(e,{recursive:!0,force:!0}),N.info(`--encrypt-sessions removed resumed plaintext migration backup`,{backupDir:e});l=[]}else c&&=(await W(c,n,!0),await T.rm(c,{recursive:!0,force:!0}),N.info(`--encrypt-sessions removed plaintext migration backup`,{backupDir:c}),null);else if(N.info(`--encrypt-sessions encrypted .aimax directory exists; mounting existing encrypted data`,{encryptedDir:t,plainDir:n,resumedBackupCount:l.length,plainDirEntryCount:await H(n)}),await Ze(t),l.length>0?u=await U(e,n):await Je(n)||(c=await U(e,n)),await qe(n),await G(t,n),f=!0,d=ot(n),N.info(`--encrypt-sessions mounted encrypted .aimax`,{plainDir:n,encryptedDir:t}),l.length>0){for(let e of l)await W(e,n,!0);u&&=(await W(u,n,!1),await T.rm(u,{recursive:!0,force:!0}),N.info(`--encrypt-sessions removed residual plaintext backup after migration`,{backupDir:u}),null);for(let e of l)await T.rm(e,{recursive:!0,force:!0}),N.info(`--encrypt-sessions removed resumed plaintext migration backup`,{backupDir:e});l=[]}else c&&=(await W(c,n,!0),await T.rm(c,{recursive:!0,force:!0}),N.info(`--encrypt-sessions removed plaintext migration backup`,{backupDir:c}),null);return N.info(`--encrypt-sessions prepared encrypted .aimax mount result`,{mounted:f,plainDir:n,encryptedDir:t,plainDirMountPoint:await z(n),plainDirEntryCount:await H(n),encryptedDirEntryCount:await H(t)}),{mounted:f,plainDir:n,encryptedDir:t,async cleanup(){if(d?.release(),!f){N.info(`--encrypt-sessions cleanup skipped because encrypted .aimax is not mounted`,{plainDir:n,encryptedDir:t});return}f=!1,N.info(`--encrypt-sessions cleanup started`,{plainDir:n,encryptedDir:t});try{await K(n),N.info(`--encrypt-sessions cleanup completed`,{plainDir:n,encryptedDir:t})}catch(e){N.warn(`--encrypt-sessions failed to unmount encrypted .aimax; continuing shutdown`,{error:e instanceof Error?e.message:String(e)})}}}}catch(e){d?.release(),f&&await K(n).catch(e=>{N.warn(`--encrypt-sessions failed to unmount during mount rollback`,{error:e instanceof Error?e.message:String(e),plainDir:n,encryptedDir:t})}),c&&await B(c)&&await Je(n)&&(await T.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await T.rename(c,n).catch(()=>{}),N.info(`--encrypt-sessions restored plaintext backup after failed migration`,{backupDir:c,plainDir:n})),u&&await B(u)&&await Je(n)&&(await T.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await T.rename(u,n).catch(()=>{}),N.info(`--encrypt-sessions restored residual plaintext backup after failed migration`,{backupDir:u,plainDir:n}));let r=await $e(l,n).catch(e=>(N.warn(`--encrypt-sessions failed to restore interrupted plaintext backups after failed migration`,{error:e instanceof Error?e.message:String(e),plainDir:n,backupCount:l.length}),[]));return l=l.filter(e=>!r.includes(e)),N.warn(`--encrypt-sessions failed; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e),mountedBeforeFailure:f,plainDir:n,encryptedDir:t,backupDir:c,residualPlainBackupDir:u,resumedBackupCount:l.length}),await V(n),s()}}async function ct(e,t,n){if(!t.encryptSessions)return await et(e),n();N.info(`--encrypt-sessions wrapper starting encrypted .aimax preparation`,{dataDir:e});let r=await st(e);N.info(`--encrypt-sessions wrapper prepared encrypted .aimax state`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir});try{return N.info(`--encrypt-sessions wrapper entering protected operation`,{dataDir:e,mounted:r.mounted}),await n(r)}finally{N.info(`--encrypt-sessions wrapper starting cleanup`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir}),await r.cleanup(),N.info(`--encrypt-sessions wrapper finished cleanup`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir})}}async function lt(e,t){await new Promise((n,r)=>{te(e,t,{encoding:`utf-8`},e=>{if(e){r(e);return}n()})})}async function ut(e){try{return await lt(`sh`,[`-c`,`command -v "${e}" >/dev/null 2>&1`]),!0}catch{return!1}}async function dt(e,t){if(!await ut(e))throw Error(`--encrypt-sessions requires ${e}: ${t}.`)}function ft(e,t){return`${e} failed: ${t instanceof Error?t.message:String(t)}`}function pt(e){return re.sm4_encrypt_ecb(e)}function mt(e){return pt(e)}const ht=[`minimal`,`low`,`medium`,`high`,`xhigh`];function gt(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(ht.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of ${ht.join(`, `)}.`)}}function _t(e={}){let t=vt(e.apiFormat??process.env.AIMAX_API_FORMAT),n=e.baseUrl??process.env.AIMAX_BASE_URL,r=process.env.AIMAX_AUTH_TOKEN,i=process.env.AIMAX_API_KEY??process.env.AIMAX_LLM_API_KEY,a=e.authToken?mt(e.authToken):r?mt(r):e.apiKey??i,o=e.model??process.env.AIMAX_MODEL,s=[];if(n||s.push(`--base-url / AIMAX_BASE_URL`),a||s.push(`--api-key / AIMAX_API_KEY / AIMAX_LLM_API_KEY`),o||s.push(`--model / AIMAX_MODEL`),s.length>0)throw Error(`Missing required LLM configuration: ${s.join(`, `)}`);return{apiFormat:t,baseUrl:n,apiKey:a,model:o,contextWindow:e.contextWindow??(process.env.AIMAX_CONTEXT_WINDOW?Number(process.env.AIMAX_CONTEXT_WINDOW):void 0),flashModel:e.flashModel??process.env.AIMAX_FLASH_MODEL,thinking:e.thinking===void 0?gt(process.env.AIMAX_THINKING,`AIMAX_THINKING`):gt(e.thinking,`--thinking`)}}function vt(e){if(!e||e===`openai-completions`||e===`anthropic-messages`)return e;throw Error(`Unsupported LLM API format: ${e}`)}const yt=[`off`,`fallback`];function bt(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 xt(e,t){if(e===void 0)return;let n=e.trim();if(!n)return;let r=Number(n);if(!Number.isFinite(r))throw Error(`Invalid ${t}: ${e}. Must be a number.`);return r}function St(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 ${yt.join(`, `)}.`)}}function Ct(){return[`AIMAX_MEMORY_KC_ENABLED`,`AIMAX_MEMORY_KC_BASE_URL`,`AIMAX_MEMORY_KC_BASE_PATH`,`AIMAX_MEMORY_KC_AUTH_TOKEN`,`AIMAX_MEMORY_KC_SEARCH_MODE`,`AIMAX_MEMORY_KC_TOP_K`,`AIMAX_MEMORY_KC_SCORE_THRESHOLD`,`AIMAX_MEMORY_KC_TIMEOUT_MS`,`AIMAX_MEMORY_KC_SYNC_ENABLED`].some(e=>process.env[e]!==void 0)}function wt(e){return Object.values(e).some(e=>e!==void 0)}function Tt(e={}){if(!(!wt(e)&&!Ct()))return{knowledgeController:{enabled:e.kcEnabled??bt(process.env.AIMAX_MEMORY_KC_ENABLED,`AIMAX_MEMORY_KC_ENABLED`),baseUrl:e.kcBaseUrl??process.env.AIMAX_MEMORY_KC_BASE_URL,basePath:e.kcBasePath??process.env.AIMAX_MEMORY_KC_BASE_PATH,authToken:e.kcAuthToken??process.env.AIMAX_MEMORY_KC_AUTH_TOKEN,searchMode:e.kcSearchMode===void 0?St(process.env.AIMAX_MEMORY_KC_SEARCH_MODE,`AIMAX_MEMORY_KC_SEARCH_MODE`)??`off`:St(e.kcSearchMode,`kcSearchMode`),topK:e.kcTopK??xt(process.env.AIMAX_MEMORY_KC_TOP_K,`AIMAX_MEMORY_KC_TOP_K`),scoreThreshold:e.kcScoreThreshold??xt(process.env.AIMAX_MEMORY_KC_SCORE_THRESHOLD,`AIMAX_MEMORY_KC_SCORE_THRESHOLD`),timeoutMs:e.kcTimeoutMs??xt(process.env.AIMAX_MEMORY_KC_TIMEOUT_MS,`AIMAX_MEMORY_KC_TIMEOUT_MS`),syncEnabled:e.kcSyncEnabled??bt(process.env.AIMAX_MEMORY_KC_SYNC_ENABLED,`AIMAX_MEMORY_KC_SYNC_ENABLED`)}}}function Et(e,t){return t?C.resolve(t):C.join(e,`.aimax`,`plugins.json`)}async function q(e,t){let n=Et(e,t);try{let e=await T.readFile(n,`utf-8`);return JSON.parse(e)}catch(e){if(e.code===`ENOENT`)return;throw e}}async function Dt(e,t,n){let r=Et(e,n);await T.mkdir(C.dirname(r),{recursive:!0}),await T.writeFile(r,JSON.stringify(t,null,2),`utf-8`)}function J(e){return typeof e==`object`&&!!e}function Ot(e){return J(e)&&e.type===`text`&&typeof e.text==`string`&&(e.textSignature===void 0||typeof e.textSignature==`string`)}function kt(e){return J(e)&&e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`}function At(e){return J(e)&&e.type===`thinking`&&typeof e.thinking==`string`&&(e.thinkingSignature===void 0||typeof e.thinkingSignature==`string`)&&(e.redacted===void 0||typeof e.redacted==`boolean`)}function jt(e){return J(e)&&e.type===`toolCall`&&typeof e.id==`string`&&typeof e.name==`string`&&J(e.arguments)&&(e.thoughtSignature===void 0||typeof e.thoughtSignature==`string`)}function Mt(e){return typeof e==`string`||Array.isArray(e)&&e.every(e=>Ot(e)||kt(e))}function Nt(e){return Array.isArray(e)&&e.every(e=>Ot(e)||At(e)||jt(e))}function Pt(e){return J(e)&&typeof e.input==`number`&&typeof e.output==`number`&&typeof e.cacheRead==`number`&&typeof e.cacheWrite==`number`&&typeof e.totalTokens==`number`&&J(e.cost)&&typeof e.cost.input==`number`&&typeof e.cost.output==`number`&&typeof e.cost.cacheRead==`number`&&typeof e.cost.cacheWrite==`number`&&typeof e.cost.total==`number`}function Ft(e){return!J(e)||typeof e.role!=`string`?!1:e.role===`user`?Mt(e.content):e.role===`assistant`?Nt(e.content)&&typeof e.api==`string`&&typeof e.provider==`string`&&typeof e.model==`string`&&Pt(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=>Ot(e)||kt(e))&&typeof e.isError==`boolean`:!1}async function It(e){let t;try{t=await T.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}`)}return Lt(n,`Message file`)}function Lt(e,t=`Messages input`){let n=Array.isArray(e)?e:[e];if(n.length===0||!n.every(e=>Ft(e)))throw Error(`${t} must contain one Message object or an array of Message objects`);return n}async function Rt(e){if([!!e.message,!!e.fromFile,e.messages!==void 0].filter(Boolean).length!==1)throw Error(`Exactly one of --message, --from-file, or messages must be provided`);return e.fromFile?{kind:`messages`,messages:await It(e.fromFile),source:`file`}:e.messages===void 0?{kind:`text`,message:e.message}:{kind:`messages`,messages:Lt(e.messages),source:`inline`}}var zt=class{constructor(e){this.sinks=e}async send(e){await Promise.allSettled(this.sinks.map(async t=>{await t.send(e)}))}async close(){await Promise.allSettled(this.sinks.map(async e=>{await e.close()}))}},Bt=class{deliveryQueue=Promise.resolve();constructor(e){this.url=e}async send(e){this.enqueue(this.toPayload(e))}async close(){await this.deliveryQueue}enqueue(e){let t=this.deliveryQueue.then(async()=>{await this.post(e)},async()=>{await this.post(e)});return this.deliveryQueue=t.catch(()=>{}),t}async post(e){let t=Date.now(),n=Vt(e);N.info(`sending callback event`,{callbackUrl:this.url,...n});let r=new AbortController,i=!1,a=setTimeout(()=>{i=!0,r.abort()},5e3);try{let a=await fetch(this.url,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e),signal:r.signal}),o=Date.now()-t;if(!a.ok){N.error(`callback event failed`,{callbackUrl:this.url,httpStatus:a.status,durationMs:o,timedOut:i,...n});return}N.info(`callback event delivered`,{callbackUrl:this.url,httpStatus:a.status,durationMs:o,...n})}catch(e){let r=Date.now()-t;N.error(`callback event failed`,{callbackUrl:this.url,error:e instanceof Error?e.message:String(e),durationMs:r,timedOut:i,...n})}finally{clearTimeout(a)}}toPayload(e){switch(e.type){case`start`:return e;case`progress`:return e;case`done`:return e;case`error`:return e;case`session_reset`:return e;case`hitl`:return e;case`title_updated`:return e;default:{let t=e;throw Error(`Unsupported callback event: ${JSON.stringify(t)}`)}}}};function Vt(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 Ht(e,t){if(t.kind===`none`)return e;let n=new URL(e);return n.searchParams.set(`authToken`,t.token),n.toString()}const Ut=5e3,Wt=5e3,Gt=6e4;function Y(){let e=globalThis.WebSocket;if(!e)throw Error(`WebSocket is not available in this runtime`);return e}function Kt(e){return e?{kind:`query_token`,token:e}:{kind:`none`}}function qt(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 Jt(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 Yt=class{socket=null;connectPromise=null;heartbeatTimer=null;lastSentAt=0;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.sendPayload(JSON.stringify(t))}catch(e){N.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.sendPayload(JSON.stringify(t))}catch(e){N.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,this.stopHeartbeat();let e=this.socket;if(this.socket=null,this.connectPromise=null,!e)return;let t=Y();if(e.readyState!==t.CLOSED)try{await Xt(new Promise(t=>{qt(e,`close`,()=>t()),e.close()}),Wt,`WebSocket close timed out after ${Wt}ms`)}catch(e){N.warn(`websocket sink close timed out`,{url:this.url,error:e instanceof Error?e.message:String(e)})}}async ensureConnected(){if(!this.enabled)return;let e=Y();if(this.socket&&this.socket.readyState===e.OPEN)return;if(this.connectPromise){await this.connectPromise;return}let t=new e(Ht(this.url,Kt(this.authToken)));this.connectPromise=new Promise((e,n)=>{qt(t,`open`,()=>{this.socket=t,this.markSent(),Jt(t,`close`,()=>{this.socket===t&&(this.socket=null),this.stopHeartbeat()}),e()}),qt(t,`error`,e=>{n(e)})});try{await this.connectPromise}finally{this.connectPromise=null}}async sendPayload(e){await Xt(this.ensureConnected(),Ut,`WebSocket connection timed out after ${Ut}ms`);let t=Y();!this.socket||this.socket.readyState!==t.OPEN||(this.socket.send(e),this.markSent())}markSent(){this.lastSentAt=Date.now(),this.scheduleHeartbeat()}scheduleHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setTimeout(()=>{this.sendHeartbeatIfIdle()},Gt)}stopHeartbeat(){this.heartbeatTimer&&=(clearTimeout(this.heartbeatTimer),null)}async sendHeartbeatIfIdle(){if(!this.enabled)return;let e=Y();if(!(!this.socket||this.socket.readyState!==e.OPEN)&&!(Date.now()-this.lastSentAt<Gt))try{this.socket.send(`ping`),this.markSent()}catch(e){N.warn(`websocket sink disabled after heartbeat send failure`,{url:this.url,error:e instanceof Error?e.message:String(e)}),this.enabled=!1,this.stopHeartbeat()}}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 Xt(e,t,n){return new Promise((r,i)=>{let a=setTimeout(()=>i(Error(n)),t);e.then(e=>{clearTimeout(a),r(e)},e=>{clearTimeout(a),i(e)})})}function Zt(e){let t=e.trim();if(!t)throw Error(`Goal objective cannot be empty`);return t}function Qt(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 $t(e){let t=Qt(e.before,e.result);return t?{type:`goal_updated`,sessionId:e.sessionId,action:t,goalId:e.result.goal.goalId,goalStatus:e.result.goal.status}:null}function en(e){let t=e?.packageRoot??tn(),n=C.join(t,`models`),r=C.join(n,...`Xenova/bge-small-zh-v1.5`.split(`/`));if(S.existsSync(C.join(r,`config.json`)))return n}function tn(){let e=C.dirname(ie(import.meta.url));return C.basename(e)===`src`||C.basename(e)===`dist`?C.resolve(e,`..`):e}function nn(e){return{text:e.text,usage:e.usage,durationMs:e.durationMs,...e.error?{error:e.error}:{},...e.paused?{paused:e.paused}:{},...e.uiToolPending?{uiToolPending:e.uiToolPending}:{},...e.artifacts&&e.artifacts.length>0?{artifacts:e.artifacts}:{}}}function rn(e){if(!e?.trim())return;let t=new Set,n=[];for(let r of e.split(`,`)){let e=r.trim();if(!e)continue;let i=an(e);if(!i)throw Error(`Invalid --artifacts-url-whitelist entry: ${e}. Expected a domain or URL with a valid hostname.`);t.has(i)||(t.add(i),n.push(i))}return n.length>0?n:void 0}function an(e){try{let t=/^[a-z][a-z\d+.-]*:\/\//i.test(e)?e:`http://${e}`,n=new URL(t);return n.username||n.password?null:n.hostname.trim().toLowerCase()||null}catch{return null}}const on=[`start`,`text`,`done`,`error`,`hitl`],sn=[`off`,`gate`,`dry_run`,`write`];function cn(e){if(!e?.trim())return new Set(on);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(on)}function ln(e){if(e.disableTopicSegmentation===!0||process.env.AIMAX_DISABLE_TOPIC_SEGMENTATION===`true`)return{enabled:!1};let t=en();return t?{embeddingModelDir:t}:void 0}function un(e){return e.disableTitle===!0||process.env.AIMAX_DISABLE_TITLE===`true`?{enabled:!1}:void 0}function dn(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 fn(e){return e?.trim()||void 0}function pn(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 mn(e){return e?f(e):void 0}function hn(e){if(!e?.trim())return[];let t=e.split(`,`).map(e=>e.trim()).filter(Boolean),n=new Set,r=[];for(let e of t){if(!C.isAbsolute(e))throw Error(`Invalid --skillsLoadPaths entry: ${e}. Each path must be absolute.`);n.has(e)||(n.add(e),r.push(e))}return r}function gn(e){if(!e?.trim())return[];let t=e.split(`,`).map(e=>e.trim()).filter(Boolean),n=new Set,r=[];for(let e of t)n.has(e)||(n.add(e),r.push(e));return r}function _n(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 vn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(sn.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function yn(e){let t=e.autoSkillsLoadEnabled===void 0?_n(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):_n(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?vn(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):vn(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 bn(e,t){if(e.inputText&&t){let n=ee(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 xn(e,t){if(!e.inputJson)throw Error(`UI tool resume requires --input-json`);try{let n=JSON.parse(e.inputJson),r=n&&typeof n==`object`&&`values`in n&&n.values&&typeof n.values==`object`&&!Array.isArray(n.values)?n.values:n;return{requestId:t.request.requestId,sessionId:t.sessionId,toolCallId:t.request.toolCallId,toolName:t.request.toolName,values:r,submittedAt:new Date().toISOString()}}catch(e){throw Error(`Invalid --input-json: ${e.message}`)}}async function Sn(e){let t=await d(e.dataDir,e.sessionId,{storeName:e.sessionStoreName,encryptSessions:e.encryptSessions});for(let n=t.length-1;n>=0;--n){let r=t[n];if(r?.role!==`assistant`||!Array.isArray(r.toolCalls))continue;let i=r.toolCalls.find(t=>t.id===e.toolCallId&&t.name===e.toolName);if(i)return i.arguments}}async function Cn(e){let t=dn(e),n=e.channel??`WEB`,r=_t({apiFormat:e.apiFormat,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel,thinking:e.thinking});return{dataDir:t,systemAgentsDir:pn(e),channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,skillsLoadPaths:hn(e.skillsLoadPaths),workdirAllowlist:gn(e.workdirAllowlist),artifactsUrlWhitelist:rn(e.artifactsUrlWhitelist),autoSkills:yn(e)}}function wn(e){let t=[],n=null;return e.callbackUrl&&t.push(new Bt(e.callbackUrl)),e.streamUrl&&(n=new Yt(e.streamUrl,cn(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new zt(t),websocketSink:n}}async function Tn(e){let{dataDir:t,sessionId:n,sessionStoreName:r,toolCallId:i,toolName:c,resolution:l,encryptSessions:u}=e;if(!i||!c||!b(c))return;let d=(e,t)=>{switch(e){case`request_approval`:return a(t);case`clarify`:return o(t);case`request_review`:return s(t);default:return JSON.stringify({action:t.action,values:t.values})}};await g(t,n,e=>{let t=e.findIndex(e=>e.role===`tool_result`&&e.toolCallId===i&&e.toolName===c);if(t===-1)return e;let n=e.slice(0,t+1);return n[t]={...n[t],content:d(c,l),isError:!1},n},{storeName:r,encryptSessions:u})}async function En(e){let{dataDir:t,sessionId:n,sessionStoreName:r,result:i,encryptSessions:a}=e;await g(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})}function Dn(){let e=Tt();return e?{core:e}:void 0}async function On(n){let i=dn(n);await ct(i,n,async()=>{ye(i,{messageId:n.messageId,sessionId:n.sessionId,sessionStoreName:mn(n.sessionStore)});let a=new Ce(`resume command`),o=null;try{let i=await Cn(n),s=mn(n.sessionStore),c=null;if(n.goal||n.goalFile){let r;r=n.goalFile?await T.readFile(n.goalFile,`utf-8`):n.goal;let a=Zt(r),o=n.tokenBudget===void 0?void 0:n.tokenBudget===`0`||n.tokenBudget===``?null:Number(n.tokenBudget);o!=null&&(Number.isNaN(o)||o<=0)&&(F(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));try{let e=await p(i.dataDir,n.sessionId,{storeName:s}),r=await t({dataDir:i.dataDir,sessionId:n.sessionId,objective:a,tokenBudget:o,force:n.force,storeName:s});c=$t({sessionId:n.sessionId,before:e,result:r})}catch(t){throw t instanceof e&&(F(t.message),F(`Existing: ${t.existingObjectivePreview}`),process.exit(2)),t}}N.info(`resume command started`,{sessionId:n.sessionId,requestId:n.requestId,channel:i.channel,dataDir:i.dataDir});let d=await l(i.dataDir,n.sessionId,{storeName:s,encryptSessions:n.encryptSessions}),f=d?null:await u(i.dataDir,n.sessionId,{storeName:s,encryptSessions:n.encryptSessions});if(!d&&!f)throw Error(`No pending HITL or UI tool request found for session "${n.sessionId}"`);if(d){if(d.request.requestId!==n.requestId)throw Error(`Request ID mismatch: pending is "${d.request.requestId}", got "${n.requestId}"`);if(d.status===`expired`)throw Error(`HITL request has expired`);if(d.status===`cancelled`)throw Error(`HITL request has been cancelled`)}else if(f){if(f.request.requestId!==n.requestId)throw Error(`Request ID mismatch: pending is "${f.request.requestId}", got "${n.requestId}"`);if(f.status!==`pending`)throw Error(`UI tool request is already "${f.status}", cannot resume`)}if(d){let e=bn(n,d.request),t=await m({dataDir:i.dataDir,sessionStoreName:s,sessionId:n.sessionId,requestId:n.requestId,resolution:e}),r=t.state;if(!r)throw Error(`Resolved HITL state was not persisted`);let l=kn(e,r.request.kind);await Tn({dataDir:i.dataDir,sessionId:n.sessionId,sessionStoreName:s,toolCallId:r.toolContext?.toolCallId,toolName:r.toolContext?.toolName,resolution:e,encryptSessions:n.encryptSessions});let u=wn(n);o=u.sink;let f=n.sessionId,p=async e=>{if(f=e.sessionId??f,!y(e)){if(e.type===`stream_text_delta`){i.format===`text`&&I(e),await u.websocketSink?.sendTextDelta({sessionId:f,channel:i.channel,messageId:n.messageId,user:n.user,text:e.text});return}i.format===`text`&&I(e),await o?.send({sessionId:f,channel:i.channel,messageId:n.messageId,user:n.user,type:`progress`,event:e})}};c&&await p(c),await p({type:`hitl_resumed`,requestId:n.requestId,resolution:e,sessionId:n.sessionId}),`idempotentReplay`in t&&t.idempotentReplay&&(N.info(`resume command treated as idempotent replay`,{sessionId:n.sessionId,requestId:n.requestId,idempotencyKey:e.idempotencyKey}),L({sessionId:n.sessionId,text:`Resume request already processed.`,usage:{input:0,output:0,total:0},durationMs:0},i.format),a.end(),process.exit(0));let h=n.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,g=await q(i.dataDir,h),v;try{v=await _({dataDir:i.dataDir,projectDir:fn(n.projectDir),systemAgentsDir:i.systemAgentsDir,sessionStoreName:s,sessionId:n.sessionId,messageId:n.messageId,channel:i.channel,llm:i.llm,skillsLoadPaths:i.skillsLoadPaths,workdirAllowlist:i.workdirAllowlist,artifactsUrlWhitelist:i.artifactsUrlWhitelist,autoSkills:i.autoSkills,timeoutMs:i.timeoutMs,message:l,encryptSessions:n.encryptSessions??!1,topicSegmentation:ln(n),titleGeneration:un(n),memory:Dn(),hitlResume:{request:r.request,resolution:e,checkpoint:r.checkpoint,toolContext:r.toolContext},plugins:g?{config:g,dataDir:i.dataDir,workspaceDir:C.join(i.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:g.llmAllowlist}:void 0,onProgress:p,onLog:xe})}finally{}v.error?await o?.send({sessionId:v.sessionId,channel:i.channel,messageId:n.messageId,user:n.user,type:`error`,message:v.error}):await o?.send({sessionId:v.sessionId,channel:i.channel,messageId:n.messageId,user:n.user,type:`done`,result:nn(v)}),L(v,i.format),v.error?N.error(`resume command failed: ${v.error}`):N.info(`resume command succeeded`),a.end(),process.exit(v.error?1:0)}let g=xn(n,f);if(!await h(i.dataDir,n.sessionId,n.requestId,g,{storeName:s,encryptSessions:n.encryptSessions}))throw Error(`UI tool resume validation failed`);await En({dataDir:i.dataDir,sessionId:n.sessionId,sessionStoreName:s,result:g,encryptSessions:n.encryptSessions}),await r(i.dataDir,n.sessionId,{storeName:s,encryptSessions:n.encryptSessions});let v=wn(n);o=v.sink;let b=n.sessionId,x=async e=>{if(b=e.sessionId??b,!y(e)){if(e.type===`stream_text_delta`){i.format===`text`&&I(e),await v.websocketSink?.sendTextDelta({sessionId:b,channel:i.channel,messageId:n.messageId,user:n.user,text:e.text});return}if(i.format===`text`&&I(e),e.type===`start`){await o?.send({sessionId:b,channel:i.channel,messageId:n.messageId,user:n.user,type:`start`,message:e.message});return}await o?.send({sessionId:b,channel:i.channel,messageId:n.messageId,user:n.user,type:`progress`,event:e})}},ee=await Sn({dataDir:i.dataDir,sessionId:n.sessionId,sessionStoreName:s,toolCallId:g.toolCallId,toolName:g.toolName,encryptSessions:n.encryptSessions});c&&await x(c),await x({type:`tool_end`,sessionId:n.sessionId,toolCallId:g.toolCallId,name:g.toolName,input:ee,output:JSON.stringify({submitted:!0,values:g.values}),isError:!1});let S=n.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,w=await q(i.dataDir,S),E=await _({dataDir:i.dataDir,projectDir:fn(n.projectDir),systemAgentsDir:i.systemAgentsDir,sessionStoreName:s,sessionId:n.sessionId,messageId:n.messageId,channel:i.channel,llm:i.llm,skillsLoadPaths:i.skillsLoadPaths,workdirAllowlist:i.workdirAllowlist,artifactsUrlWhitelist:i.artifactsUrlWhitelist,autoSkills:i.autoSkills,timeoutMs:i.timeoutMs,message:`[UI_TOOL_RESUME]
8
+ The pending UI tool result has been written into the transcript. Continue from the latest tool result without repeating the same form request.`,encryptSessions:n.encryptSessions??!1,topicSegmentation:ln(n),titleGeneration:un(n),memory:Dn(),uiToolResume:g,plugins:w?{config:w,dataDir:i.dataDir,workspaceDir:C.join(i.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:w.llmAllowlist}:void 0,onProgress:x,onLog:xe});E.error?await o?.send({sessionId:E.sessionId,channel:i.channel,messageId:n.messageId,user:n.user,type:`error`,message:E.error}):await o?.send({sessionId:E.sessionId,channel:i.channel,messageId:n.messageId,user:n.user,type:`done`,result:nn(E)}),L(E,i.format),E.error?N.error(`resume command failed: ${E.error}`):N.info(`resume command succeeded`),a.end(),process.exit(E.error?1:0)}catch(e){let t=e;o&&(t.message.includes(`expired`)&&await o.send({sessionId:n.sessionId,channel:n.channel??`WEB`,messageId:n.messageId,user:n.user,type:`progress`,event:{type:`hitl_expired`,sessionId:n.sessionId,requestId:n.requestId,reason:t.message}}),t.message.includes(`cancelled`)&&await o.send({sessionId:n.sessionId,channel:n.channel??`WEB`,messageId:n.messageId,user:n.user,type:`progress`,event:{type:`hitl_cancelled`,sessionId:n.sessionId,requestId:n.requestId,reason:t.message}}),await o.send({sessionId:n.sessionId,channel:n.channel??`WEB`,messageId:n.messageId,user:n.user,type:`error`,message:`Resume failed: ${t.message}`})),N.error(`resume command error: ${t.message}`),F(`Fatal: ${t.message}`),a.end(),process.exit(1)}})}function kn(e,t){return n(e,t)}function An(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(`--workdir-allowlist <paths>`,`Comma-separated additional roots allowed as cwd for exec-style tools`).option(`--auto-skills-load-enabled <boolean>`,`Enable learned auto-skill loading for the main agent (overrides AIMAX_AUTO_SKILLS_LOAD_ENABLED)`).option(`--auto-skills-review-mode <mode>`,`Auto-skill review mode: off, gate, dry_run, or write (overrides AIMAX_AUTO_SKILLS_REVIEW_MODE)`).option(`--message-id <id>`,`Message ID for correlating events`).option(`--user <id>`,`User identifier propagated to external callback and stream payloads`).option(`-c, --channel <channel>`,`Channel name (default: WEB)`,`WEB`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-format <format>`,`LLM API format: openai-completions or anthropic-messages (overrides AIMAX_API_FORMAT)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY / AIMAX_LLM_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(`--thinking <level>`,`Explicit thinking level: minimal, low, medium, high, or xhigh (overrides AIMAX_THINKING)`).option(`--callback-url <url>`,`HTTP callback URL for progress events`).option(`--stream-url <url>`,`WebSocket URL for streaming text events`).option(`--stream-auth-token <token>`,`Auth token for WebSocket streaming`).option(`--stream-events <list>`,`Comma-separated stream events`).option(`--timeout <ms>`,`Execution timeout in milliseconds`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--plugins-config <path>`,`Plugins config file path`).option(`--goal <text>`,`Set or replace the thread goal objective before resuming`).option(`--goal-file <path>`,`Read goal objective from a file`).option(`--token-budget <n>`,`Token budget for the goal (positive integer, or 0 for unlimited)`).option(`--force`,`Replace existing goal with a different objective`).option(`--encrypt-sessions`,`Enable encryption for the .aimax data directory`).option(`--disable-topic-segmentation`,`Disable smart topic segmentation for this resume run`).option(`--disable-title`,`Skip LLM session title generation for new sessions (overrides AIMAX_DISABLE_TITLE)`).action(async e=>{await On(e)})}function jn(e,t){return{notify:(n,r=`info`)=>{t?.readyState===1?t.send(JSON.stringify({type:`diagnostic`,sessionId:e,level:r,message:n})):console.log(`[${r}] ${n}`)},confirm:async n=>!t||t.readyState!==1?!1:new Promise(r=>{let i=`confirm-${Date.now()}`;t.send(JSON.stringify({type:`hitl_confirm`,sessionId:e,id:i,message:n}));let a=e=>{try{let t=JSON.parse(String(e));r(t.id===i&&t.confirmed===!0)}catch{r(!1)}};typeof t.once==`function`?t.once(`message`,a):t.addEventListener(`message`,e=>a(e.data),{once:!0})}),select:async(n,r)=>{if(!(!t||t.readyState!==1))return new Promise(i=>{let a=`select-${Date.now()}`;t.send(JSON.stringify({type:`hitl_select`,sessionId:e,id:a,title:n,options:r}));let o=e=>{try{let t=JSON.parse(String(e));i(t.id===a?t.selected:void 0)}catch{i(void 0)}};typeof t.once==`function`?t.once(`message`,o):t.addEventListener(`message`,e=>o(e.data),{once:!0})})},setStatus:n=>{t?.readyState===1?t.send(JSON.stringify({type:`diagnostic`,sessionId:e,level:`info`,message:n})):console.log(`[status] ${n}`)}}}const Mn=[`start`,`text`,`done`,`error`],Nn=[`off`,`gate`,`dry_run`,`write`];function Pn(e){if(!e?.trim())return new Set(Mn);let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean),n=new Set([`start`,`text`,`progress`,`done`,`error`,`hitl`,`title_updated`]),r=new Set;for(let e of t){if(!n.has(e))throw Error(`Invalid stream event: ${e}. Must be one of start,text,progress,done,error,hitl,title_updated`);r.add(e)}return r.size>0?r:new Set(Mn)}function Fn(e){if(e.disableTopicSegmentation===!0||process.env.AIMAX_DISABLE_TOPIC_SEGMENTATION===`true`)return{enabled:!1};let t=en();return t?{embeddingModelDir:t}:void 0}function In(e){return e.disableTitle===!0||process.env.AIMAX_DISABLE_TITLE===`true`?{enabled:!1}:void 0}function Ln(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 Rn(e){return e?.trim()||void 0}function zn(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 X(e){return e?.trim()||void 0}function Bn(e){return e??`WEB`}function Vn(e){return e?f(e):void 0}function Hn(e,t){return e===`CRON`?`crons`:Vn(t)}function Un(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){if(!e?.trim())return[];let t=e.split(`,`).map(e=>e.trim()).filter(Boolean),n=new Set,r=[];for(let e of t)n.has(e)||(n.add(e),r.push(e));return r}function Gn(e){let t=``;for(let n=0;n<e.length;n+=1){let r=e[n];if(r===`\\`&&n+1<e.length){let r=e[n+1];if(r===`,`||r===`\\`||r===`=`){t+=r,n+=1;continue}}t+=r}return t}function Kn(e){let t=[],n=``;for(let r=0;r<e.length;r+=1){let i=e[r];if(i===`\\`&&r+1<e.length){let t=e[r+1];if(t===`,`||t===`\\`){n+=t,r+=1;continue}}if(i===`,`){t.push(n),n=``;continue}n+=i}return t.push(n),t}function qn(e){if(!e?.trim())return{};let t=[],n=new Set;for(let r of Kn(e)){let e=r.trim();if(!e)continue;let i=e.indexOf(`=`);if(i<=0)throw Error(`Invalid --env entry: ${e}. Expected KEY=VALUE (use \\= to embed an equals sign in the value).`);let a=e.slice(0,i).trim(),o=e.slice(i+1).trim();if(!a)throw Error(`Invalid --env entry: ${e}. Key must not be empty.`);if(n.has(a))throw Error(`Invalid --env entry: duplicate key ${a}.`);n.add(a),t.push([a,Gn(o)])}return Object.fromEntries(t)}function Jn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if([`true`,`1`,`yes`,`on`].includes(n))return!0;if([`false`,`0`,`no`,`off`].includes(n))return!1;throw Error(`Invalid ${t}: ${e}. Must be true or false.`)}}function Yn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(Nn.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function Xn(e){let t=e.autoSkillsLoadEnabled===void 0?Jn(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):Jn(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?Yn(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):Yn(e.autoSkillsReviewMode,`--auto-skills-review-mode`),r={};return t!==void 0&&(r.load={enabled:t}),n!==void 0&&(r.review={mode:n}),r.load||r.review?r:void 0}function Zn(e,t){return e.length<=t?e:t<=3?e.slice(0,t):`${e.slice(0,t-3)}...`}function Qn(e,t){if(t<=0)return[``];let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n.length>0?n:[``]}function $n(e,t,n=78){let r=Math.max(0,n-4),i=e?e.length+2:0,a=Math.max(r,i,...t.map(e=>e.length)),o=a+2,s=e?` ${Zn(e,Math.max(0,a-2))} `:``,c=e?`┌${s}${`─`.repeat(Math.max(0,o-s.length))}┐`:`┌${`─`.repeat(o)}┐`,l=`└${`─`.repeat(o)}┘`;return[c,...t.flatMap(e=>Qn(e,a).map(e=>`│ ${e.padEnd(a,` `)} │`)),l].join(`
9
+ `)}function er(e){return e.kind===`text`?`inline message (${e.message.length} chars)`:e.source===`file`?`message file (${e.messages.length} messages)`:`inline messages (${e.messages.length} messages)`}function Z(e,t=`-`){return e==null||e===``?t:String(e)}function tr(e){return e?`set`:`unset`}function nr(e){return e?`true`:`false`}function rr(e,t){let n=Hn(t.channel,e.sessionStore)??`sessions`,r=t.timeoutMs===void 0?`default`:`${t.timeoutMs}`,i=e.callbackUrl?`enabled`:`disabled`,a=e.streamUrl?`enabled`:`disabled`,o=er(t.input),s=t.input.kind===`text`?`inline`:e.fromFile??t.input.source,c=oe(),l=Fn(e)?.enabled===!1?`disabled`:`enabled`,u=In(e)?.enabled===!1?`disabled`:`enabled`,d=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,f=[...Pn(e.streamEvents)].join(`,`),p=t.autoSkills?.load?.enabled,m=t.autoSkills?.review?.mode,h=e.tokenBudget===`0`?`unlimited`:Z(e.tokenBudget),g=t.artifactsUrlWhitelist?.join(`,`)??`-`,_=e.env?Object.keys(qn(e.env)):[],v=_.length===0?`-`:`${_.length} key${_.length===1?``:`s`}`;return{banner:$n(void 0,[`AIMax CLI`,`Stateless Agent Runner`]),contextBox:$n(`Run Context`,[`time : ${c}`,`dataDir : ${t.dataDir}`,`projectDir : ${Rn(e.projectDir)??`-`}`,`systemAgents : ${t.systemAgentsDir??`/aimax/agents`}`,`agent : ${X(e.agent)??`-`}`,`channel : ${t.channel}`,`user : ${e.user??`-`}`,`message : ${e.message===void 0?`-`:`inline (${e.message.length} chars)`}`,`fromFile : ${Z(e.fromFile)}`,`input : ${o}`,`skillsPaths : ${t.skillsLoadPaths.length>0?t.skillsLoadPaths.join(`,`):`-`}`,`autoSkillLoad: ${p===void 0?`-`:String(p)}`,`autoSkillRev : ${m??`-`}`,`sessionId : ${e.sessionId??`new`}`,`sessionStore : ${n}`,`messageId : ${e.messageId??`-`}`,`workspace : ${C.join(t.dataDir,`workspace`)}`,`baseUrl : ${t.llm.baseUrl}`,`apiKey : ${tr(t.llm.apiKey)}`,`authToken : ${tr(e.authToken)}`,`model : ${t.llm.model}`,`contextWindow: ${Z(t.llm.contextWindow)}`,`flashModel : ${Z(t.llm.flashModel)}`,`thinking : ${Z(t.llm.thinking)}`,`callbackUrl : ${Z(e.callbackUrl)}`,`streamUrl : ${Z(e.streamUrl)}`,`streamAuth : ${tr(e.streamAuthToken)}`,`streamEvents : ${f}`,`artifactUrls : ${g}`,`output : ${t.format}`,`callback : ${i}`,`websocket : ${a}`,`timeoutMs : ${r}`,`pluginsConfig: ${Z(d)}`,`env : ${v}`,`goal : ${e.goal===void 0?`-`:`inline (${e.goal.length} chars)`}`,`goalFile : ${Z(e.goalFile)}`,`tokenBudget : ${h}`,`force : ${nr(e.force)}`,`resumeReqId : ${Z(e.resumeRequestId)}`,`resumeInput : ${e.resumeInputJson===void 0?`-`:`inline (${e.resumeInputJson.length} chars)`}`,`resumeFile : ${Z(e.resumeFromFile)}`,`encryptSess : ${nr(e.encryptSessions)}`,`topicSegment : ${l}`,`titleGen : ${u}`]),logContext:{time:c,channel:t.channel,user:e.user,dataDir:t.dataDir,projectDir:Rn(e.projectDir),systemAgentsDir:t.systemAgentsDir,agent:X(e.agent),workspaceDir:C.join(t.dataDir,`workspace`),sessionId:e.sessionId??`new`,sessionStore:n,messageId:e.messageId,hasMessage:e.message!==void 0,fromFile:e.fromFile,skillsLoadPaths:t.skillsLoadPaths.join(`,`)||void 0,autoSkillsLoadEnabled:p,autoSkillsReviewMode:m,baseUrl:t.llm.baseUrl,hasApiKey:!!t.llm.apiKey,hasAuthToken:!!e.authToken,model:t.llm.model,contextWindow:t.llm.contextWindow,flashModel:t.llm.flashModel,thinking:t.llm.thinking,callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,hasStreamAuthToken:!!e.streamAuthToken,streamEvents:f,artifactsUrlWhitelist:t.artifactsUrlWhitelist?.join(`,`)||void 0,output:t.format,hasCallback:!!e.callbackUrl,hasStream:!!e.streamUrl,timeoutMs:t.timeoutMs,pluginsConfig:d,envKeys:_.length>0?_.join(`,`):void 0,hasGoal:e.goal!==void 0,goalFile:e.goalFile,tokenBudget:h===`-`?void 0:h,force:!!e.force,resumeRequestId:e.resumeRequestId,hasResumeInputJson:e.resumeInputJson!==void 0,resumeFromFile:e.resumeFromFile,encryptSessions:!!e.encryptSessions,topicSegmentation:l,titleGeneration:u,inputKind:t.input.kind,inputSource:s,inputSummary:o}}}async function ir(e,t){let n=Ln(e),r=Bn(e.channel),i=_t({apiFormat:e.apiFormat,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel,thinking:e.thinking});return{dataDir:n,systemAgentsDir:zn(e),channel:r,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:i,input:t,skillsLoadPaths:Un(e.skillsLoadPaths),workdirAllowlist:Wn(e.workdirAllowlist),artifactsUrlWhitelist:rn(e.artifactsUrlWhitelist),autoSkills:Xn(e)}}function ar(e){if(e.kind===`text`)return e.message;if(e.messages.length!==1)return null;let[t]=e.messages;if(t.role!==`user`)return null;if(typeof t.content==`string`)return t.content;if(t.content.length===0)return null;let n=[];for(let e of t.content){if(e.type!==`text`)return null;n.push(e.text)}return n.join(`
10
+ `)}async function or(e,t){if(!e.sessionId)return null;let n=ar(t);if(!n)return null;let r=await l(Ln(e),e.sessionId,{storeName:Vn(e.sessionStore),encryptSessions:e.encryptSessions});return!r||r.status!==`pending`||!x(n,r.request)?null:{requestId:r.request.requestId,inputText:n}}function sr(e){let t=[],n=null;return e.callbackUrl&&t.push(new Bt(e.callbackUrl)),e.streamUrl&&(n=new Yt(e.streamUrl,Pn(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new zt(t),websocketSink:n}}async function Q(e,t){N.info(`dispatching external event`,Dr(t)),await e.sink.send(t)}function cr(e){let t={sessionId:e.sessionId,messageId:e.messageId,parentSessionId:e.parentSessionId,depth:e.depth,scope:e.scope,phase:e.phase,...e.details};if(e.level===`error`){N.error(e.message,t);return}if(e.level===`warn`){N.warn(e.message,t);return}N.info(e.message,t)}function lr(e,t,n,r,i){return{sink:e,websocketSink:t,channel:n,defaultMessageId:r,user:i}}function ur(e){let t=new AbortController,n=n=>{N.warn(`run abort signal received`,{signal:n,uptimeMs:Math.round(process.uptime()*1e3),alreadyAborted:t.signal.aborted,...e?.()}),t.abort()},r=()=>n(`SIGTERM`),i=()=>n(`SIGINT`);return process.once(`SIGTERM`,r),process.once(`SIGINT`,i),{controller:t,cleanup:()=>{process.off(`SIGTERM`,r),process.off(`SIGINT`,i)}}}function dr(e){return{activeSessionId:e??`pending`,finalResult:null,loggerSessionId:void 0}}function fr(e,t,n,r){!r||n.loggerSessionId===r||(ye(e,{messageId:t.messageId,sessionId:r,sessionStoreName:Hn(t.channel,t.sessionStore)}),n.loggerSessionId=r)}function pr(e,t){e.activeSessionId=t.sessionId??e.activeSessionId}function mr(e,t){return e.messageId??t}async function hr(e,t,n){if(!await c(e.dataDir)){if(await $(t,e.format,n.activeSessionId,e.dataDir,`checking`),(await i(e.dataDir)).performedBootstrap){await $(t,e.format,n.activeSessionId,e.dataDir,`initializing`),await $(t,e.format,n.activeSessionId,e.dataDir,`initialized`);return}await $(t,e.format,n.activeSessionId,e.dataDir,`ready`)}}async function $(e,t,n,r,i){let a={type:`bootstrap`,phase:i,dataDir:r};t===`text`&&I(a),await Q(e,{sessionId:n,channel:e.channel,messageId:e.defaultMessageId,user:e.user,type:`progress`,event:a})}function gr(e,t,n,r){return async i=>{if(pr(n,i),fr(e.dataDir,{...r,channel:e.channel},n,i.sessionId),y(i)){cr(i);return}if(i.type===`stream_text_delta`){e.format===`text`&&I(i),await t.websocketSink?.sendTextDelta({sessionId:n.activeSessionId,channel:e.channel,messageId:mr(i,t.defaultMessageId),user:t.user,text:i.text});return}e.format===`text`&&I(i);let a=mr(i,t.defaultMessageId);if(i.type===`hitl_requested`){await Q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:a,user:t.user,type:`hitl`,request:i.request}),await Q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:a,user:t.user,type:`progress`,event:i});return}if(i.type===`start`){await Q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:a,user:t.user,type:`start`,message:i.message});return}if(i.type===`session_reset`){await Q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:a,user:t.user,type:`session_reset`,action:i.action,previousSessionId:i.previousSessionId,message:i.message});return}await Q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:a,user:t.user,type:`progress`,event:i})}}function _r(e){let t=jn(e);return{confirm:(e,n)=>t.confirm(e),select:(e,n,r)=>t.select?t.select(e,n):Promise.resolve(void 0)}}function vr(e,t,n,r,i,a){let o=Tt(),s={dataDir:t.dataDir,projectDir:Rn(e.projectDir),systemAgentsDir:t.systemAgentsDir,agentPolicy:X(e.agent)?{requestedAgentName:X(e.agent)}:void 0,sessionStoreName:Hn(t.channel,e.sessionStore),sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,workdirAllowlist:t.workdirAllowlist,artifactsUrlWhitelist:t.artifactsUrlWhitelist,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,abortSignal:n.signal,pendingGoal:a,encryptSessions:e.encryptSessions??!1,topicSegmentation:Fn(e),titleGeneration:In(e),env:qn(e.env),...o?{memory:{core:o}}:{},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,onLog:xe,createPiExtensionDialogBridge:_r};return t.input.kind===`messages`?{...s,messages:t.input.messages}:{...s,message:t.input.message}}async function yr(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:nn(r)})}async function br(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 xr(e,t){let n=rr(e,t);N.info([`run command started`,n.banner,n.contextBox].join(`
11
+ `),n.logContext),t.format===`text`&&(P(n.banner),P(``),P(n.contextBox),P(``))}function Sr(e,t,n){return L(t,n),t.error?N.error(`run command failed: ${t.error}`):N.info(`run command succeeded`),e.end(),t.error?1:0}function Cr(e){let t=be();if(!t)return;let n=`[${oe()}] [ERROR] ${e}\n`;try{S.appendFileSync(C.join(t.logDir,`app.log`),n),S.appendFileSync(C.join(t.logDir,`errors.log`),n)}catch{}}async function wr(e,t){let n=`run command error: ${t.message}`;N.error(n),Cr(n),F(`Fatal: ${t.message}`),e.end(),await M(),process.exit(1)}async function Tr(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 T.readFile(e.resumeFromFile,`utf-8`)}catch(e){throw Error(`Failed to read resume input file: ${e.message}`)}}async function Er(n){let r=Ln(n);try{await ct(r,n,async i=>{let a=dr(n.sessionId);fr(r,{...n,channel:Bn(n.channel)},a,n.sessionId),n.encryptSessions&&N.info(`--encrypt-sessions run mount state after logger initialization`,{dataDir:r,mounted:i?.mounted??!1,plainDir:i?.plainDir,encryptedDir:i?.encryptedDir});let o=new Ce(`run command`),s=await Tr(n);if(n.resumeRequestId||s||n.resumeFromFile){if(!n.sessionId||!n.resumeRequestId||!s)throw Error(`--session-id, --resume-request-id, and exactly one of --resume-input-json or --resume-from-file must be provided together`);await On({dataDir:n.dataDir,projectDir:n.projectDir,systemAgentsDir:n.systemAgentsDir,sessionId:n.sessionId,sessionStore:n.sessionStore,requestId:n.resumeRequestId,inputJson:s,channel:n.channel,baseUrl:n.baseUrl,apiKey:n.apiKey,authToken:n.authToken,model:n.model,contextWindow:n.contextWindow,flashModel:n.flashModel,thinking:n.thinking,callbackUrl:n.callbackUrl,streamUrl:n.streamUrl,streamAuthToken:n.streamAuthToken,streamEvents:n.streamEvents,timeout:n.timeout,output:n.output,pluginsConfig:n.pluginsConfig,artifactsUrlWhitelist:n.artifactsUrlWhitelist,skillsLoadPaths:n.skillsLoadPaths,workdirAllowlist:n.workdirAllowlist,autoSkillsLoadEnabled:n.autoSkillsLoadEnabled,autoSkillsReviewMode:n.autoSkillsReviewMode,messageId:n.messageId,user:n.user,goal:n.goal,goalFile:n.goalFile,tokenBudget:n.tokenBudget,force:n.force,encryptSessions:n.encryptSessions,disableTopicSegmentation:n.disableTopicSegmentation,disableTitle:n.disableTitle});return}let c;try{c=await Rt({message:n.message,fromFile:n.fromFile,messages:n.messages})}catch(e){await wr(o,e);return}let l=await or(n,c);if(l){await On({dataDir:n.dataDir,projectDir:n.projectDir,systemAgentsDir:n.systemAgentsDir,sessionId:n.sessionId,sessionStore:n.sessionStore,requestId:l.requestId,inputText:l.inputText,channel:n.channel,baseUrl:n.baseUrl,apiKey:n.apiKey,authToken:n.authToken,model:n.model,contextWindow:n.contextWindow,flashModel:n.flashModel,thinking:n.thinking,callbackUrl:n.callbackUrl,streamUrl:n.streamUrl,streamAuthToken:n.streamAuthToken,streamEvents:n.streamEvents,timeout:n.timeout,output:n.output,pluginsConfig:n.pluginsConfig,artifactsUrlWhitelist:n.artifactsUrlWhitelist,skillsLoadPaths:n.skillsLoadPaths,workdirAllowlist:n.workdirAllowlist,autoSkillsLoadEnabled:n.autoSkillsLoadEnabled,autoSkillsReviewMode:n.autoSkillsReviewMode,messageId:n.messageId,user:n.user,goal:n.goal,goalFile:n.goalFile,tokenBudget:n.tokenBudget,force:n.force,encryptSessions:n.encryptSessions,disableTopicSegmentation:n.disableTopicSegmentation,disableTitle:n.disableTitle});return}let u=n.channel??`WEB`,{controller:d,cleanup:f}=ur(()=>({activeSessionId:a.activeSessionId,finalSessionId:a.finalResult?.sessionId,messageId:n.messageId,channel:u,user:n.user})),m=null;try{let r=await ir(n,c);u=r.channel,xr(n,r);let i=sr(n);m=i.sink,N.info(`external sink configured`,{callbackUrl:n.callbackUrl,streamUrl:n.streamUrl,streamEvents:n.streamEvents});let s=lr(m,i.websocketSink,r.channel,n.messageId,n.user);await hr(r,s,a);let l,f=null;if(n.goal||n.goalFile){let i;i=n.goalFile?await T.readFile(n.goalFile,`utf-8`):n.goal;let a=Zt(i),o=Vn(n.sessionStore),s=n.tokenBudget===void 0?void 0:n.tokenBudget===`0`||n.tokenBudget===``?null:Number(n.tokenBudget);s!=null&&(Number.isNaN(s)||s<=0)&&(F(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));try{if(n.sessionId){let e=await p(r.dataDir,n.sessionId,{storeName:o}),i=await t({dataDir:r.dataDir,sessionId:n.sessionId,objective:a,tokenBudget:s,force:n.force,storeName:o});f=$t({sessionId:n.sessionId,before:e,result:i})}else l={objective:a,tokenBudget:s??null}}catch(t){throw t instanceof e&&(F(t.message),F(`Existing: ${t.existingObjectivePreview}`),process.exit(2)),t}}let h=n.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,g=await q(r.dataDir,h),v=gr(r,s,a,n);f&&await v(f);let y=await _(vr(n,r,d,v,g,l));fr(r.dataDir,{...n,channel:r.channel},a,y.sessionId),await yr(s,a,n.messageId,y),process.exitCode=Sr(o,y,r.format)}catch(e){let t=e;m&&await br(lr(m,null,u,n.messageId,n.user),a,n.messageId,t),await wr(o,t)}finally{await m?.close(),f()}})}finally{await M()}}function Dr(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 Or(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(`--workdir-allowlist <paths>`,`Comma-separated additional roots allowed as cwd for exec-style tools`).option(`--auto-skills-load-enabled <boolean>`,`Enable learned auto-skill loading for the main agent (overrides AIMAX_AUTO_SKILLS_LOAD_ENABLED)`).option(`--auto-skills-review-mode <mode>`,`Auto-skill review mode: off, gate, dry_run, or write (overrides AIMAX_AUTO_SKILLS_REVIEW_MODE)`).option(`-s, --session-id <id>`,`Resume an existing session by ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`--message-id <id>`,`Message ID for correlating events`).option(`-c, --channel <channel>`,`Channel name (default: WEB)`,`WEB`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-format <format>`,`LLM API format: openai-completions or anthropic-messages (overrides AIMAX_API_FORMAT)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY / AIMAX_LLM_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(`--thinking <level>`,`Explicit thinking level: minimal, low, medium, high, or xhigh (overrides AIMAX_THINKING)`).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(`--artifacts-url-whitelist <urls>`,`Comma-separated URL artifact hostnames or URLs to collect; unset collects all URL artifacts`).option(`--timeout <ms>`,`Execution timeout in milliseconds`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--plugins-config <path>`,`Plugins config file path`).option(`--env <kvlist>`,`Session-scoped env vars injected into the run. Comma-separated KEY=VALUE pairs. Backslash-escape "," and "=" inside values. Available to plugins via api.runtime.session.env and merged into child process environments spawned by the exec/process tools.`).option(`--goal <text>`,`Set or replace the thread goal objective before running`).option(`--goal-file <path>`,`Read goal objective from a file`).option(`--token-budget <n>`,`Token budget for the goal (positive integer, or 0 for unlimited)`).option(`--force`,`Replace existing goal with a different objective`).option(`--resume-request-id <id>`,`Resume a pending HITL request from aimax run`).option(`--resume-input-json <json>`,`Structured HITL resume payload used with --resume-request-id`).option(`--resume-from-file <path>`,`Load structured HITL resume payload from a file (alternative to --resume-input-json)`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).option(`--disable-topic-segmentation`,`Disable smart topic segmentation for this run`).option(`--disable-title`,`Skip LLM session title generation for new sessions (title falls back to a truncated first message; overrides AIMAX_DISABLE_TITLE)`).action(async e=>{await Er(e)})}export{P as _,Bt as a,N as b,Dt as c,Ne as d,I as f,F as g,Ae as h,Yt as i,_t as l,je as m,Or as n,zt as o,Me as p,An as r,q as s,Er as t,ct as u,Ce as v,M as x,ye as y};
package/dist/run.js CHANGED
@@ -1 +1 @@
1
- import"./pkg-path-D6anqptM.js";import{t as e}from"./run-9V7V9r8T.js";export{e as executeRun};
1
+ import"./pkg-path-D6anqptM.js";import{t as e}from"./run-BfGeE9D_.js";export{e as executeRun};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gencode/cli",
3
- "version": "0.17.1",
3
+ "version": "0.17.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "aimax": "./dist/bin.js"
@@ -32,8 +32,8 @@
32
32
  "commander": "^14.0.3",
33
33
  "gensign-node": "latest",
34
34
  "log4js": "^6.9.1",
35
- "@gencode/agents": "0.19.1",
36
- "@gencode/shared": "0.6.0"
35
+ "@gencode/agents": "0.20.0",
36
+ "@gencode/shared": "0.6.1"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^22.0.0",
@@ -1,11 +0,0 @@
1
- import{GoalConflictError as e,applyCliGoalBeforeRun as t,buildResumeNarration as n,clearPendingUiTool as r,ensureBootstrapMountLayout as i,formatApprovalResolution as a,formatClarifyResolution as o,formatReviewResolution as s,hasBootstrapSentinel as c,loadPendingHitl as l,loadPendingUiTool as u,loadTranscript as d,normalizeSessionStoreName as f,readGoal as p,resolvePendingHitl as m,resolvePendingUiTool as h,rewriteTranscript as g,runAgent as _}from"@gencode/agents";import{formatTaskForDisplay as v,isAgentDiagnosticEvent as y,isHitlTool as b,parseMatchedTextToResolution as x,parseTextToResolution as ee}from"@gencode/shared";import S from"node:fs";import C from"node:path";import w from"log4js";import T from"node:fs/promises";import E from"node:os";import{execFile as te,execFileSync as ne}from"node:child_process";import re from"gensign-node";import{fileURLToPath as ie}from"node:url";function ae(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 oe(e=new Date){let t=ae(e),n=String(e.getMilliseconds()).padStart(3,`0`);return`${t.year}-${t.month}-${t.day} ${t.hour}:${t.minute}:${t.second}.${n}`}let D=function(e){return e.INFO=`INFO`,e.ERROR=`ERROR`,e.WARN=`WARN`,e}({}),O=null,k=!1,A=[],j=Promise.resolve();function se(){return oe()}function ce(e){if(!e)return``;let t=Object.entries(e).filter(([,e])=>e!==void 0).map(([e,t])=>`${e}=${le(t)}`);return t.length>0?` ${t.join(` `)}`:``}function le(e){return JSON.stringify(ue(e,new WeakSet))??`undefined`}function ue(e,t){return typeof e==`bigint`?e.toString():e==null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`?e:e instanceof Error?{name:e.name,message:e.message,stack:e.stack}:typeof e!=`object`&&typeof e!=`function`?String(e):t.has(e)?`[Circular]`:(t.add(e),Array.isArray(e)?e.map(e=>ue(e,t)):Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0).map(([e,n])=>[e,ue(n,t)])))}function de(e){return C.join(e,`.aimax`)}function fe(e){let t=e?.trim();return t&&t.replace(/[^A-Za-z0-9_.-]/g,`_`)||`no-message-${process.pid}`}function pe(e,t){let n=fe(t?.messageId),r=t?.sessionStoreName?.trim()||`sessions`;return t?.sessionId?{runLogId:n,logDir:C.join(de(e),r,t.sessionId,`logs`,n)}:{runLogId:n,logDir:C.join(de(e),`logs`,n)}}function me(e){return{appLogPath:C.join(e,`app.log`),errorLogPath:C.join(e,`errors.log`)}}function he(e){let{appLogPath:t,errorLogPath:n}=me(e);w.configure({appenders:{appFile:{type:`file`,filename:t,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`messagePassThrough`}},errorFile:{type:`file`,filename:n,maxLogSize:5*1024*1024,backups:3,compress:!0,keepFileExt:!0,layout:{type:`messagePassThrough`}},errorsOnly:{type:`logLevelFilter`,appender:`errorFile`,level:`error`,maxLevel:`fatal`}},categories:{default:{appenders:[`appFile`,`errorsOnly`],level:`info`}}})}function ge(e,t,n){return`[${se()}] [${e}] ${t}${ce(n)}`}function _e(e,t,n){try{process.stderr.write(`${ge(e,t,n)}\n`)}catch{}}function M(e,t,n){if(!O){A.push({level:e,message:t,context:n}),A.length>200&&(A=A.slice(-200)),_e(e,t,n);return}k||=(he(O.logDir),!0);let r=ge(e,t,n),i=w.getLogger();if(e===D.ERROR){i.error(r);return}if(e===D.WARN){i.warn(r);return}i.info(r)}function ve(e,t){let{logDir:n,runLogId:r}=pe(e,t);if(k&&O?.dataDir===e&&O.runLogId===r&&O.logDir===n)return;S.mkdirSync(n,{recursive:!0}),he(n),k=!0,O={dataDir:e,logDir:n,runLogId:r};let i=A;A=[];for(let e of i)M(e.level,e.message,e.context)}function ye(){return O?{...O}:null}function be(e){if(!e.logDir){e.level===`ERROR`?M(D.ERROR,e.message,e.context):e.level===`WARN`?M(D.WARN,e.message,e.context):M(D.INFO,e.message,e.context);return}let{appLogPath:t,errorLogPath:n}=me(e.logDir),r=`${e.formatted}\n`;j=j.then(async()=>{await S.promises.mkdir(e.logDir,{recursive:!0}),await S.promises.appendFile(t,r,`utf-8`),e.level===`ERROR`&&await S.promises.appendFile(n,r,`utf-8`)}).catch(t=>{_e(D.ERROR,`delegated agent log write failed`,{logDir:e.logDir,error:t instanceof Error?t.message:String(t)})})}async function xe(){await j;try{await Se()}finally{k=!1}}function Se(){return new Promise((e,t)=>{w.shutdown(n=>{if(n){t(n);return}e()})})}const N={info:(e,t)=>M(D.INFO,e,t),warn:(e,t)=>M(D.WARN,e,t),error:(e,t)=>M(D.ERROR,e,t)};var Ce=class{startTime;name;constructor(e){this.name=e,this.startTime=Date.now()}end(){let e=Date.now()-this.startTime;return N.info(`${this.name} completed in ${e}ms`),e}};function we(e){if(typeof e==`string`)return e;let t=JSON.stringify(e);return t===void 0?String(e):t}const Te=new Set;function Ee(e){return e instanceof Error?{name:e.name,message:e.message,code:e.code}:{message:String(e)}}function De(e,t){try{N.warn(`CLI ${e} write failed; suppressing further ${e} writes`,{stream:e,...Ee(t)})}catch{}}function Oe(e,t){if(Te.has(e))return;let n=e===`stdout`?process.stdout:process.stderr;try{n.write(t)}catch(t){Te.add(e),De(e,t)}}function ke(e){Oe(`stdout`,e)}function P(e){Oe(`stdout`,e+`
2
- `)}function F(e){Oe(`stderr`,e+`
3
- `)}function I(e){switch(e.type){case`start`:P(`\n[start] ${e.message}`);break;case`text`:ke(e.text);break;case`stream_text_delta`:ke(e.text);break;case`bootstrap`:P(`\n[bootstrap:${e.phase}] ${e.dataDir}`);break;case`session_reset`:P(`\n[session:${e.action}] ${e.message}`);break;case`tool_start`:P(`\n[tool:${e.name}] ${JSON.stringify(e.input??{})}`);break;case`tool_end`:{let t=we(e.output);P(`[tool:${e.name}] ${e.isError?`ERROR`:`OK`} ${t.slice(0,200)}`);break}case`compaction`:P(`\n[compaction${e.layer?`:${e.layer}`:``}] ${e.reason}${e.strategy?` (${e.strategy})`:``}`);break;case`skill_used`:P(`\n[skill] ${e.skillName} agent=${e.agent} task=${e.taskId}`);break;case`custom`:P(`\n[plugin:${e.pluginId}] ${e.name}${e.label?` ${e.label}`:``}${e.data?` ${JSON.stringify(e.data)}`:``}`);break;case`error`:F(`\n[error] ${e.message}`);break;case`diagnostic`:break;case`subagent_spawn`:P(`\n[subagent:spawn]${e.label?` "${e.label}"`:``} ${v(e.task)}`);break;case`subagent_complete`:P(`[subagent:${e.status}] ${v(e.task)}`);break;case`hitl_requested`:if(P(`\n[hitl:${e.request.kind}] ${e.request.title}`),P(` prompt: ${e.request.prompt}`),P(` requestId: ${e.request.requestId}`),e.request.input.mode===`choice`)for(let t of e.request.input.choices)P(` - [${t.id}] ${t.label}`);break;case`hitl_resumed`:P(`\n[hitl:resumed] requestId=${e.requestId} action=${e.resolution.action}`);break;case`hitl_expired`:P(`\n[hitl:expired] requestId=${e.requestId} reason=${e.reason}`);break;case`hitl_cancelled`:P(`\n[hitl:cancelled] requestId=${e.requestId}${e.reason?` reason=${e.reason}`:``}`);break;case`ui_tool_request`:P(`\n[ui-tool:${e.request.toolName}] ${e.request.outputSchema.title}`),P(` requestId: ${e.request.requestId}`),P(` toolCallId: ${e.request.toolCallId}`);break;case`ui_tool_result`:P(`\n[ui-tool:resumed] requestId=${e.requestId} tool=${e.toolName}`);break}}function L(e,t){if(t===`json`){e&&P(JSON.stringify(e,null,2));return}P(`
4
- `),P(`session: ${e.sessionId}`),P(`duration: ${e.durationMs}ms`),P(`tokens: input=${e.usage.input} output=${e.usage.output} total=${e.usage.total}`),e.context&&(P(`context: ${e.context.snapshotPath}`),P(`tool-results: ${e.context.toolResultsDir}`)),e.error&&F(`error: ${e.error}`)}function Ae(e,t){if(t===`json`){P(JSON.stringify(e,null,2));return}if(e.length===0){P(`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:—]`;P(`${t.id} ${e} [${t.channel}]${n} ${t.title}`)}}function je(e,t){if(t===`json`){P(JSON.stringify(e,null,2));return}P(`session: ${e.id}`),e.metadata&&(P(`title: ${e.metadata.title}`),P(`channel: ${e.metadata.channel}`),P(`created: ${e.metadata.createdAt}`),P(`updated: ${e.metadata.updatedAt}`)),P(`transcript: ${e.transcriptPath}`),P(`entries: ${e.transcriptEntryCount}`),P(`context: ${e.contextSnapshotPath}`),P(`session-memory: ${e.sessionMemoryPath}`),P(`collapse-log: ${e.collapseLogPath}`),P(`read-states: ${e.readStateCount}`),P(`tool-results: ${e.toolResultRefCount}`),P(`tool-results-dir: ${e.toolResultsDir}`)}function Me(e,t){if(t===`json`){P(JSON.stringify(e,null,2));return}P(`session: ${e.id}`),P(`transcript: ${e.paths.transcriptPath}`),P(`context: ${e.paths.contextSnapshotPath}`),P(`session-memory: ${e.paths.sessionMemoryPath}`),P(`collapse-log: ${e.paths.collapseLogPath}`),P(`tool-results-dir: ${e.paths.toolResultsDir}`),P(`transcript-entries: ${e.transcript.length}`),P(`read-states: ${e.context.readStates.length}`),P(`tool-results: ${e.context.toolResults.length}`),P(`collapse-spans: ${e.context.compaction.collapseSpans.length}`)}function Ne(e,t){if(t===`json`){P(JSON.stringify(e,null,2));return}P(`Bootstrap completed.`),P(`dataDir: ${e.dataDir}`),P(`created dirs: ${e.createdDirs.length}`),P(`created files: ${e.createdFiles.length}`),P(`skipped dirs: ${e.skippedDirs.length}`),P(`skipped files: ${e.skippedFiles.length}`)}const Pe=`.aimax`,Fe=`${Pe}.pre-gocryptfs.`,Ie=[`app.log`,`errors.log`],Le=[`logs`],Re=[`fusermount3`,`fusermount`,`umount`],ze=[{command:`fusermount3`,args:[`-u`],label:`fusermount3 -u`},{command:`fusermount3`,args:[`-uz`],label:`fusermount3 -uz`},{command:`fusermount`,args:[`-u`],label:`fusermount -u`},{command:`fusermount`,args:[`-uz`],label:`fusermount -uz`},{command:`umount`,args:[],label:`umount`},{command:`umount`,args:[`-l`],label:`umount -l`}];function Be(e){return C.join(e,`.aimax.enc`)}function Ve(e){return C.join(e,Pe)}function He(e){return C.join(e,`${Fe}${process.pid}.${Date.now()}`)}function Ue(e){return C.join(e,`${Pe}.plaintext-restore.${process.pid}.${Date.now()}`)}function We(e){return e.replace(/\\([0-7]{3})/g,(e,t)=>String.fromCharCode(Number.parseInt(t,8)))}async function R(e){try{let t=await qe.read(),n=C.resolve(e);for(let e of t.split(`
5
- `)){if(!e.trim())continue;let t=e.split(` `);if(t.length>=5&&C.resolve(We(t[4]??``))===n)return!0}return!1}catch{return!1}}function Ge(e){try{let t=S.readFileSync(`/proc/self/mountinfo`,`utf-8`),n=C.resolve(e);for(let e of t.split(`
6
- `)){if(!e.trim())continue;let t=e.split(` `);if(t.length>=5&&C.resolve(We(t[4]??``))===n)return!0}return!1}catch{return!1}}async function Ke(){return await T.readFile(`/proc/self/mountinfo`,`utf-8`)}const qe={read:Ke};async function z(e){try{return await T.stat(e),!0}catch(e){if(e.code===`ENOENT`)return!1;throw e}}async function B(e){await T.mkdir(e,{recursive:!0})}async function Je(e){if(await B(e),(await T.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 Ye(e){return await z(e)?(await T.readdir(e)).length===0:!0}async function V(e){if(await z(e))return(await T.readdir(e)).length}async function Xe(e){let t;try{t=await T.readdir(e,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return{exists:!1,entryCount:void 0,isEmpty:!0,containsUserData:!1};throw e}let n=!1;for(let e of t)if(!(e.isDirectory()&&Le.includes(e.name))&&!(e.isFile()&&Ie.some(t=>e.name.startsWith(t)))){n=!0;break}return{exists:!0,entryCount:t.length,isEmpty:t.length===0,containsUserData:n}}async function Ze(e){let t=await T.readdir(e,{withFileTypes:!0});for(let n of t){if(n.isDirectory()&&Le.includes(n.name)){await T.rm(C.join(e,n.name),{recursive:!0,force:!0}).catch(()=>{});continue}n.isFile()&&Ie.some(e=>n.name.startsWith(e))&&await T.rm(C.join(e,n.name),{force:!0}).catch(()=>{})}}async function Qe(e){if(!await z(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 $e(e){return(await T.readdir(e,{withFileTypes:!0})).filter(e=>e.isDirectory()&&e.name.startsWith(Fe)).map(t=>C.join(e,t.name)).sort()}async function H(e,t){if(!await z(t))return null;let n=He(e);return N.info(`--encrypt-sessions moving plaintext .aimax aside before migration`,{plainDir:t,backupDir:n}),await T.rename(t,n),n}async function U(e,t,n){N.info(`--encrypt-sessions copying plaintext backup into encrypted mount`,{backupDir:e,plainDir:t,force:n}),await T.cp(e,t,{recursive:!0,force:n})}async function et(e,t){if(e.length===0)return[];await B(t);let n=[];for(let r of e)await z(r)&&(await U(r,t,!0),await T.rm(r,{recursive:!0,force:!0}),N.info(`--encrypt-sessions restored interrupted plaintext backup after failed migration`,{backupDir:r,plainDir:t}),n.push(r));return n}async function tt(e){let t=Date.now(),n=Be(e),r=Ve(e),i=await z(n);if(!i)return;let a=i&&await z(C.join(n,`gocryptfs.conf`)),o=await Xe(r),s=o.exists?await R(r):!1;if(N.info(`plaintext .aimax restore check for disabled --encrypt-sessions`,{dataDir:e,encryptedDir:n,plainDir:r,encryptedDirExists:i,encryptedDirInitialized:a,plainDirExists:o.exists,plainDirMountPoint:s,plainDirEntryCount:o.entryCount,probeDurationMs:Date.now()-t}),!a){N.warn(`plaintext .aimax restore skipped because .aimax.enc is not initialized`,{encryptedDir:n,plainDir:r}),await B(r);return}if(s){N.warn(`plaintext .aimax restore skipped because .aimax is already a mount point`,{plainDir:r,encryptedDir:n});return}if(o.containsUserData){N.info(`plaintext .aimax restore skipped because plaintext .aimax already contains data`,{plainDir:r,encryptedDir:n,plainDirEntryCount:o.entryCount,probeDurationMs:Date.now()-t});return}o.isEmpty||(N.info(`plaintext .aimax clearing ephemeral files before restore`,{plainDir:r,encryptedDir:n,plainDirEntryCount:o.entryCount}),await Ze(r));try{await it()}catch(e){N.warn(`plaintext .aimax restore unavailable; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e),plainDir:r,encryptedDir:n}),await B(r);return}let c=Ue(e),l=!1;try{await Je(r),await at(n,r),l=!0,await T.rm(c,{recursive:!0,force:!0}),await B(c),await T.cp(r,c,{recursive:!0,force:!0}),N.info(`plaintext .aimax restore copied encrypted history to staging directory`,{plainDir:r,encryptedDir:n,restoreDir:c,restoredEntryCount:await V(c)}),await W(r),l=!1,await T.rm(r,{recursive:!0,force:!0}),await T.rename(c,r),N.info(`plaintext .aimax restore completed for disabled --encrypt-sessions`,{plainDir:r,encryptedDir:n})}catch(e){l&&await W(r).catch(e=>{N.warn(`plaintext .aimax restore failed to unmount during rollback`,{error:e instanceof Error?e.message:String(e),plainDir:r,encryptedDir:n})}),await T.rm(c,{recursive:!0,force:!0}).catch(()=>{}),await B(r).catch(()=>{}),N.warn(`plaintext .aimax restore failed; continuing with existing plaintext .aimax`,{error:e instanceof Error?e.message:String(e),plainDir:r,encryptedDir:n})}}async function nt(e){let t=C.join(E.tmpdir(),`aimax-gocryptfs-pass.${process.pid}.${Date.now()}`);await T.writeFile(t,`wizard_aimax@2026
7
- `,{mode:384});try{return await e(t)}finally{await T.rm(t,{force:!0})}}async function rt(e){let t=e.includes(`-init`)?`init`:`mount`;N.info(`--encrypt-sessions starting gocryptfs ${t}`);try{await dt(`gocryptfs`,e),N.info(`--encrypt-sessions completed gocryptfs ${t}`)}catch(n){let r=n instanceof Error?n.message:String(n);throw N.warn(`--encrypt-sessions failed gocryptfs ${t}`,{error:r}),Error(`gocryptfs ${e.join(` `)} failed: ${r}`)}}async function it(){N.info(`--encrypt-sessions checking encryption dependencies`),await pt(`gocryptfs`,`required for --encrypt-sessions`),N.info(`--encrypt-sessions dependency available`,{command:`gocryptfs`});for(let e of Re)if(await ft(e)){N.info(`--encrypt-sessions unmount dependency available`,{command:e});return}throw Error(`--encrypt-sessions requires one of ${Re.join(`, `)} to be installed for secure unmount cleanup.`)}async function at(e,t){N.info(`--encrypt-sessions mounting encrypted .aimax`,{encryptedDir:e,plainDir:t}),await nt(async n=>{await rt([`-q`,`-passfile`,n,e,t])})}async function ot(e){N.info(`--encrypt-sessions initializing encrypted .aimax directory`,{encryptedDir:e}),await nt(async t=>{await rt([`-q`,`-init`,`-passfile`,t,e])})}async function W(e){let t=[];N.info(`--encrypt-sessions unmounting encrypted .aimax`,{plainDir:e});for(let n of ze)try{if(N.info(`--encrypt-sessions attempting encrypted .aimax unmount`,{command:n.label,plainDir:e}),await dt(n.command,[...n.args,e]),!await R(e)){N.info(`--encrypt-sessions unmounted encrypted .aimax`,{command:n.label,plainDir:e});return}let r=`${n.label} returned success but ${e} is still mounted`;t.push(r),N.warn(`--encrypt-sessions unmount command returned success but mountpoint remains`,{command:n.label,plainDir:e})}catch(r){let i=mt(n.label,r);t.push(i),N.warn(`--encrypt-sessions unmount attempt failed`,{command:n.label,plainDir:e,error:r instanceof Error?r.message:String(r)})}throw Error(`Failed to unmount ${e}: ${t.join(`; `)}`)}function st(e){for(let t of ze)try{if(ne(t.command,[...t.args,e],{stdio:`ignore`}),!Ge(e))return}catch{}}function ct(e){let t=!1,n=()=>{t||(t=!0,st(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 lt(e){let t=Be(e),n=Ve(e),r=await z(n),i=await z(t),a=i&&await z(C.join(t,`gocryptfs.conf`)),o=r?await R(n):!1;N.info(`--encrypt-sessions preparing encrypted .aimax mount`,{dataDir:e,encryptedDir:t,plainDir:n,plainDirExists:r,encryptedDirExists:i,encryptedDirInitialized:a,plainDirMountPoint:o,plainDirEntryCount:await V(n),encryptedDirEntryCount:await V(t)});let s=()=>({mounted:!1,plainDir:n,encryptedDir:t,async cleanup(){}});try{await it()}catch(e){return N.warn(`--encrypt-sessions is unavailable; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e)}),await B(n),s()}if(await R(n))return N.warn(`--encrypt-sessions found existing .aimax mount; continuing without taking ownership`,{plainDir:n}),s();let c=null,l=[],u=null,d=null,f=!1;try{if(l=await $e(e),l.length>0&&N.warn(`--encrypt-sessions found interrupted pre-gocryptfs migration backups`,{count:l.length}),!await z(t))if(N.info(`--encrypt-sessions encrypted .aimax directory does not exist; starting first-time migration`,{encryptedDir:t,plainDir:n,resumedBackupCount:l.length}),l.length>0?u=await H(e,n):c=await H(e,n),await B(t),await ot(t),await B(n),await at(t,n),f=!0,d=ct(n),N.info(`--encrypt-sessions mounted encrypted .aimax`,{plainDir:n,encryptedDir:t}),l.length>0){for(let e of l)await U(e,n,!0);u&&=(await U(u,n,!1),await T.rm(u,{recursive:!0,force:!0}),N.info(`--encrypt-sessions removed residual plaintext backup after migration`,{backupDir:u}),null);for(let e of l)await T.rm(e,{recursive:!0,force:!0}),N.info(`--encrypt-sessions removed resumed plaintext migration backup`,{backupDir:e});l=[]}else c&&=(await U(c,n,!0),await T.rm(c,{recursive:!0,force:!0}),N.info(`--encrypt-sessions removed plaintext migration backup`,{backupDir:c}),null);else if(N.info(`--encrypt-sessions encrypted .aimax directory exists; mounting existing encrypted data`,{encryptedDir:t,plainDir:n,resumedBackupCount:l.length,plainDirEntryCount:await V(n)}),await Qe(t),l.length>0?u=await H(e,n):await Ye(n)||(c=await H(e,n)),await Je(n),await at(t,n),f=!0,d=ct(n),N.info(`--encrypt-sessions mounted encrypted .aimax`,{plainDir:n,encryptedDir:t}),l.length>0){for(let e of l)await U(e,n,!0);u&&=(await U(u,n,!1),await T.rm(u,{recursive:!0,force:!0}),N.info(`--encrypt-sessions removed residual plaintext backup after migration`,{backupDir:u}),null);for(let e of l)await T.rm(e,{recursive:!0,force:!0}),N.info(`--encrypt-sessions removed resumed plaintext migration backup`,{backupDir:e});l=[]}else c&&=(await U(c,n,!0),await T.rm(c,{recursive:!0,force:!0}),N.info(`--encrypt-sessions removed plaintext migration backup`,{backupDir:c}),null);return N.info(`--encrypt-sessions prepared encrypted .aimax mount result`,{mounted:f,plainDir:n,encryptedDir:t,plainDirMountPoint:await R(n),plainDirEntryCount:await V(n),encryptedDirEntryCount:await V(t)}),{mounted:f,plainDir:n,encryptedDir:t,async cleanup(){if(d?.release(),!f){N.info(`--encrypt-sessions cleanup skipped because encrypted .aimax is not mounted`,{plainDir:n,encryptedDir:t});return}f=!1,N.info(`--encrypt-sessions cleanup started`,{plainDir:n,encryptedDir:t});try{await W(n),N.info(`--encrypt-sessions cleanup completed`,{plainDir:n,encryptedDir:t})}catch(e){N.warn(`--encrypt-sessions failed to unmount encrypted .aimax; continuing shutdown`,{error:e instanceof Error?e.message:String(e)})}}}}catch(e){d?.release(),f&&await W(n).catch(e=>{N.warn(`--encrypt-sessions failed to unmount during mount rollback`,{error:e instanceof Error?e.message:String(e),plainDir:n,encryptedDir:t})}),c&&await z(c)&&await Ye(n)&&(await T.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await T.rename(c,n).catch(()=>{}),N.info(`--encrypt-sessions restored plaintext backup after failed migration`,{backupDir:c,plainDir:n})),u&&await z(u)&&await Ye(n)&&(await T.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await T.rename(u,n).catch(()=>{}),N.info(`--encrypt-sessions restored residual plaintext backup after failed migration`,{backupDir:u,plainDir:n}));let r=await et(l,n).catch(e=>(N.warn(`--encrypt-sessions failed to restore interrupted plaintext backups after failed migration`,{error:e instanceof Error?e.message:String(e),plainDir:n,backupCount:l.length}),[]));return l=l.filter(e=>!r.includes(e)),N.warn(`--encrypt-sessions failed; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e),mountedBeforeFailure:f,plainDir:n,encryptedDir:t,backupDir:c,residualPlainBackupDir:u,resumedBackupCount:l.length}),await B(n),s()}}async function ut(e,t,n){if(!t.encryptSessions)return await tt(e),n();N.info(`--encrypt-sessions wrapper starting encrypted .aimax preparation`,{dataDir:e});let r=await lt(e);N.info(`--encrypt-sessions wrapper prepared encrypted .aimax state`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir});try{return N.info(`--encrypt-sessions wrapper entering protected operation`,{dataDir:e,mounted:r.mounted}),await n(r)}finally{N.info(`--encrypt-sessions wrapper starting cleanup`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir}),await r.cleanup(),N.info(`--encrypt-sessions wrapper finished cleanup`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir})}}async function dt(e,t){await new Promise((n,r)=>{te(e,t,{encoding:`utf-8`},e=>{if(e){r(e);return}n()})})}async function ft(e){try{return await dt(`sh`,[`-c`,`command -v "${e}" >/dev/null 2>&1`]),!0}catch{return!1}}async function pt(e,t){if(!await ft(e))throw Error(`--encrypt-sessions requires ${e}: ${t}.`)}function mt(e,t){return`${e} failed: ${t instanceof Error?t.message:String(t)}`}function ht(e){return re.sm4_encrypt_ecb(e)}function gt(e){return ht(e)}const _t=[`minimal`,`low`,`medium`,`high`,`xhigh`];function vt(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(_t.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of ${_t.join(`, `)}.`)}}function G(e={}){let t=yt(e.apiFormat??process.env.AIMAX_API_FORMAT),n=e.baseUrl??process.env.AIMAX_BASE_URL,r=process.env.AIMAX_AUTH_TOKEN,i=process.env.AIMAX_API_KEY??process.env.AIMAX_LLM_API_KEY,a=e.authToken?gt(e.authToken):r?gt(r):e.apiKey??i,o=e.model??process.env.AIMAX_MODEL,s=[];if(n||s.push(`--base-url / AIMAX_BASE_URL`),a||s.push(`--api-key / AIMAX_API_KEY / AIMAX_LLM_API_KEY`),o||s.push(`--model / AIMAX_MODEL`),s.length>0)throw Error(`Missing required LLM configuration: ${s.join(`, `)}`);return{apiFormat:t,baseUrl:n,apiKey:a,model:o,contextWindow:e.contextWindow??(process.env.AIMAX_CONTEXT_WINDOW?Number(process.env.AIMAX_CONTEXT_WINDOW):void 0),flashModel:e.flashModel??process.env.AIMAX_FLASH_MODEL,thinking:e.thinking===void 0?vt(process.env.AIMAX_THINKING,`AIMAX_THINKING`):vt(e.thinking,`--thinking`)}}function yt(e){if(!e||e===`openai-completions`||e===`anthropic-messages`)return e;throw Error(`Unsupported LLM API format: ${e}`)}const bt=[`off`,`fallback`];function xt(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 St(e,t){if(e===void 0)return;let n=e.trim();if(!n)return;let r=Number(n);if(!Number.isFinite(r))throw Error(`Invalid ${t}: ${e}. Must be a number.`);return r}function Ct(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(bt.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of ${bt.join(`, `)}.`)}}function wt(){return[`AIMAX_MEMORY_KC_ENABLED`,`AIMAX_MEMORY_KC_BASE_URL`,`AIMAX_MEMORY_KC_BASE_PATH`,`AIMAX_MEMORY_KC_AUTH_TOKEN`,`AIMAX_MEMORY_KC_SEARCH_MODE`,`AIMAX_MEMORY_KC_TOP_K`,`AIMAX_MEMORY_KC_SCORE_THRESHOLD`,`AIMAX_MEMORY_KC_TIMEOUT_MS`,`AIMAX_MEMORY_KC_SYNC_ENABLED`].some(e=>process.env[e]!==void 0)}function Tt(e){return Object.values(e).some(e=>e!==void 0)}function Et(e={}){if(!(!Tt(e)&&!wt()))return{knowledgeController:{enabled:e.kcEnabled??xt(process.env.AIMAX_MEMORY_KC_ENABLED,`AIMAX_MEMORY_KC_ENABLED`),baseUrl:e.kcBaseUrl??process.env.AIMAX_MEMORY_KC_BASE_URL,basePath:e.kcBasePath??process.env.AIMAX_MEMORY_KC_BASE_PATH,authToken:e.kcAuthToken??process.env.AIMAX_MEMORY_KC_AUTH_TOKEN,searchMode:e.kcSearchMode===void 0?Ct(process.env.AIMAX_MEMORY_KC_SEARCH_MODE,`AIMAX_MEMORY_KC_SEARCH_MODE`)??`off`:Ct(e.kcSearchMode,`kcSearchMode`),topK:e.kcTopK??St(process.env.AIMAX_MEMORY_KC_TOP_K,`AIMAX_MEMORY_KC_TOP_K`),scoreThreshold:e.kcScoreThreshold??St(process.env.AIMAX_MEMORY_KC_SCORE_THRESHOLD,`AIMAX_MEMORY_KC_SCORE_THRESHOLD`),timeoutMs:e.kcTimeoutMs??St(process.env.AIMAX_MEMORY_KC_TIMEOUT_MS,`AIMAX_MEMORY_KC_TIMEOUT_MS`),syncEnabled:e.kcSyncEnabled??xt(process.env.AIMAX_MEMORY_KC_SYNC_ENABLED,`AIMAX_MEMORY_KC_SYNC_ENABLED`)}}}function Dt(e,t){return t?C.resolve(t):C.join(e,`.aimax`,`plugins.json`)}async function K(e,t){let n=Dt(e,t);try{let e=await T.readFile(n,`utf-8`);return JSON.parse(e)}catch(e){if(e.code===`ENOENT`)return;throw e}}async function Ot(e,t,n){let r=Dt(e,n);await T.mkdir(C.dirname(r),{recursive:!0}),await T.writeFile(r,JSON.stringify(t,null,2),`utf-8`)}function q(e){return typeof e==`object`&&!!e}function kt(e){return q(e)&&e.type===`text`&&typeof e.text==`string`&&(e.textSignature===void 0||typeof e.textSignature==`string`)}function At(e){return q(e)&&e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`}function jt(e){return q(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 Mt(e){return q(e)&&e.type===`toolCall`&&typeof e.id==`string`&&typeof e.name==`string`&&q(e.arguments)&&(e.thoughtSignature===void 0||typeof e.thoughtSignature==`string`)}function Nt(e){return typeof e==`string`||Array.isArray(e)&&e.every(e=>kt(e)||At(e))}function Pt(e){return Array.isArray(e)&&e.every(e=>kt(e)||jt(e)||Mt(e))}function Ft(e){return q(e)&&typeof e.input==`number`&&typeof e.output==`number`&&typeof e.cacheRead==`number`&&typeof e.cacheWrite==`number`&&typeof e.totalTokens==`number`&&q(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 It(e){return!q(e)||typeof e.role!=`string`?!1:e.role===`user`?Nt(e.content):e.role===`assistant`?Pt(e.content)&&typeof e.api==`string`&&typeof e.provider==`string`&&typeof e.model==`string`&&Ft(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=>kt(e)||At(e))&&typeof e.isError==`boolean`:!1}async function Lt(e){let t;try{t=await T.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}`)}return Rt(n,`Message file`)}function Rt(e,t=`Messages input`){let n=Array.isArray(e)?e:[e];if(n.length===0||!n.every(e=>It(e)))throw Error(`${t} must contain one Message object or an array of Message objects`);return n}async function zt(e){if([!!e.message,!!e.fromFile,e.messages!==void 0].filter(Boolean).length!==1)throw Error(`Exactly one of --message, --from-file, or messages must be provided`);return e.fromFile?{kind:`messages`,messages:await Lt(e.fromFile),source:`file`}:e.messages===void 0?{kind:`text`,message:e.message}:{kind:`messages`,messages:Rt(e.messages),source:`inline`}}var Bt=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()}))}},Vt=class{deliveryQueue=Promise.resolve();constructor(e){this.url=e}async send(e){this.enqueue(this.toPayload(e))}async close(){await this.deliveryQueue}enqueue(e){let t=this.deliveryQueue.then(async()=>{await this.post(e)},async()=>{await this.post(e)});return this.deliveryQueue=t.catch(()=>{}),t}async post(e){let t=Date.now(),n=Ht(e);N.info(`sending callback event`,{callbackUrl:this.url,...n});let r=new AbortController,i=!1,a=setTimeout(()=>{i=!0,r.abort()},5e3);try{let a=await fetch(this.url,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e),signal:r.signal}),o=Date.now()-t;if(!a.ok){N.error(`callback event failed`,{callbackUrl:this.url,httpStatus:a.status,durationMs:o,timedOut:i,...n});return}N.info(`callback event delivered`,{callbackUrl:this.url,httpStatus:a.status,durationMs:o,...n})}catch(e){let r=Date.now()-t;N.error(`callback event failed`,{callbackUrl:this.url,error:e instanceof Error?e.message:String(e),durationMs:r,timedOut:i,...n})}finally{clearTimeout(a)}}toPayload(e){switch(e.type){case`start`:return e;case`progress`:return e;case`done`:return e;case`error`:return e;case`session_reset`:return e;case`hitl`:return e;case`title_updated`:return e;default:{let t=e;throw Error(`Unsupported callback event: ${JSON.stringify(t)}`)}}}};function Ht(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 Ut(e,t){if(t.kind===`none`)return e;let n=new URL(e);return n.searchParams.set(`authToken`,t.token),n.toString()}const J=5e3,Wt=5e3;function Y(){let e=globalThis.WebSocket;if(!e)throw Error(`WebSocket is not available in this runtime`);return e}function Gt(e){return e?{kind:`query_token`,token:e}:{kind:`none`}}function Kt(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 qt(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 Jt=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 Yt(this.ensureConnected(),J,`WebSocket connection timed out after ${J}ms`);let e=Y();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){N.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 Yt(this.ensureConnected(),J,`WebSocket connection timed out after ${J}ms`);let e=Y();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){N.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=Y();if(e.readyState!==t.CLOSED)try{await Yt(new Promise(t=>{Kt(e,`close`,()=>t()),e.close()}),Wt,`WebSocket close timed out after ${Wt}ms`)}catch(e){N.warn(`websocket sink close timed out`,{url:this.url,error:e instanceof Error?e.message:String(e)})}}async ensureConnected(){if(!this.enabled)return;let e=Y();if(this.socket&&this.socket.readyState===e.OPEN)return;if(this.connectPromise){await this.connectPromise;return}let t=new e(Ut(this.url,Gt(this.authToken)));this.connectPromise=new Promise((e,n)=>{Kt(t,`open`,()=>{this.socket=t,qt(t,`close`,()=>{this.socket===t&&(this.socket=null)}),e()}),Kt(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 Yt(e,t,n){return new Promise((r,i)=>{let a=setTimeout(()=>i(Error(n)),t);e.then(e=>{clearTimeout(a),r(e)},e=>{clearTimeout(a),i(e)})})}function Xt(e){let t=e.trim();if(!t)throw Error(`Goal objective cannot be empty`);return t}function Zt(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=Zt(e.before,e.result);return t?{type:`goal_updated`,sessionId:e.sessionId,action:t,goalId:e.result.goal.goalId,goalStatus:e.result.goal.status}:null}function $t(e){let t=e?.packageRoot??en(),n=C.join(t,`models`),r=C.join(n,...`Xenova/bge-small-zh-v1.5`.split(`/`));if(S.existsSync(C.join(r,`config.json`)))return n}function en(){let e=C.dirname(ie(import.meta.url));return C.basename(e)===`src`||C.basename(e)===`dist`?C.resolve(e,`..`):e}function tn(e){return{text:e.text,usage:e.usage,durationMs:e.durationMs,...e.error?{error:e.error}:{},...e.paused?{paused:e.paused}:{},...e.uiToolPending?{uiToolPending:e.uiToolPending}:{},...e.artifacts&&e.artifacts.length>0?{artifacts:e.artifacts}:{}}}function nn(e){if(!e?.trim())return;let t=new Set,n=[];for(let r of e.split(`,`)){let e=r.trim();if(!e)continue;let i=rn(e);if(!i)throw Error(`Invalid --artifacts-url-whitelist entry: ${e}. Expected a domain or URL with a valid hostname.`);t.has(i)||(t.add(i),n.push(i))}return n.length>0?n:void 0}function rn(e){try{let t=/^[a-z][a-z\d+.-]*:\/\//i.test(e)?e:`http://${e}`,n=new URL(t);return n.username||n.password?null:n.hostname.trim().toLowerCase()||null}catch{return null}}const an=[`start`,`text`,`done`,`error`,`hitl`],on=[`off`,`gate`,`dry_run`,`write`];function sn(e){if(!e?.trim())return new Set(an);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(an)}function cn(e){if(e.disableTopicSegmentation===!0||process.env.AIMAX_DISABLE_TOPIC_SEGMENTATION===`true`)return{enabled:!1};let t=$t();return t?{embeddingModelDir:t}:void 0}function ln(e){return e.disableTitle===!0||process.env.AIMAX_DISABLE_TITLE===`true`?{enabled:!1}:void 0}function un(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 dn(e){return e?.trim()||void 0}function fn(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 pn(e){return e?f(e):void 0}function mn(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 hn(e){if(!e?.trim())return[];let t=e.split(`,`).map(e=>e.trim()).filter(Boolean),n=new Set,r=[];for(let e of t)n.has(e)||(n.add(e),r.push(e));return r}function gn(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 _n(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(on.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function vn(e){let t=e.autoSkillsLoadEnabled===void 0?gn(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):gn(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?_n(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):_n(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 yn(e,t){if(e.inputText&&t){let n=ee(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 bn(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 xn(e){let t=await d(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 Sn(e){let t=un(e),n=e.channel??`WEB`,r=G({apiFormat:e.apiFormat,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel,thinking:e.thinking});return{dataDir:t,systemAgentsDir:fn(e),channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,skillsLoadPaths:mn(e.skillsLoadPaths),workdirAllowlist:hn(e.workdirAllowlist),artifactsUrlWhitelist:nn(e.artifactsUrlWhitelist),autoSkills:vn(e)}}function Cn(e){let t=[],n=null;return e.callbackUrl&&t.push(new Vt(e.callbackUrl)),e.streamUrl&&(n=new Jt(e.streamUrl,sn(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new Bt(t),websocketSink:n}}async function wn(e){let{dataDir:t,sessionId:n,sessionStoreName:r,toolCallId:i,toolName:c,resolution:l,encryptSessions:u}=e;if(!i||!c||!b(c))return;let d=(e,t)=>{switch(e){case`request_approval`:return a(t);case`clarify`:return o(t);case`request_review`:return s(t);default:return JSON.stringify({action:t.action,values:t.values})}};await g(t,n,e=>{let t=e.findIndex(e=>e.role===`tool_result`&&e.toolCallId===i&&e.toolName===c);if(t===-1)return e;let n=e.slice(0,t+1);return n[t]={...n[t],content:d(c,l),isError:!1},n},{storeName:r,encryptSessions:u})}async function Tn(e){let{dataDir:t,sessionId:n,sessionStoreName:r,result:i,encryptSessions:a}=e;await g(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})}function En(){let e=Et();return e?{core:e}:void 0}async function Dn(n){let i=un(n);await ut(i,n,async()=>{ve(i,{messageId:n.messageId,sessionId:n.sessionId,sessionStoreName:pn(n.sessionStore)});let a=new Ce(`resume command`),o=null;try{let i=await Sn(n),s=pn(n.sessionStore),c=null;if(n.goal||n.goalFile){let r;r=n.goalFile?await T.readFile(n.goalFile,`utf-8`):n.goal;let a=Xt(r),o=n.tokenBudget===void 0?void 0:n.tokenBudget===`0`||n.tokenBudget===``?null:Number(n.tokenBudget);o!=null&&(Number.isNaN(o)||o<=0)&&(F(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));try{let e=await p(i.dataDir,n.sessionId,{storeName:s}),r=await t({dataDir:i.dataDir,sessionId:n.sessionId,objective:a,tokenBudget:o,force:n.force,storeName:s});c=Qt({sessionId:n.sessionId,before:e,result:r})}catch(t){throw t instanceof e&&(F(t.message),F(`Existing: ${t.existingObjectivePreview}`),process.exit(2)),t}}N.info(`resume command started`,{sessionId:n.sessionId,requestId:n.requestId,channel:i.channel,dataDir:i.dataDir});let d=await l(i.dataDir,n.sessionId,{storeName:s,encryptSessions:n.encryptSessions}),f=d?null:await u(i.dataDir,n.sessionId,{storeName:s,encryptSessions:n.encryptSessions});if(!d&&!f)throw Error(`No pending HITL or UI tool request found for session "${n.sessionId}"`);if(d){if(d.request.requestId!==n.requestId)throw Error(`Request ID mismatch: pending is "${d.request.requestId}", got "${n.requestId}"`);if(d.status===`expired`)throw Error(`HITL request has expired`);if(d.status===`cancelled`)throw Error(`HITL request has been cancelled`)}else if(f){if(f.request.requestId!==n.requestId)throw Error(`Request ID mismatch: pending is "${f.request.requestId}", got "${n.requestId}"`);if(f.status!==`pending`)throw Error(`UI tool request is already "${f.status}", cannot resume`)}if(d){let e=yn(n,d.request),t=await m({dataDir:i.dataDir,sessionStoreName:s,sessionId:n.sessionId,requestId:n.requestId,resolution:e}),r=t.state;if(!r)throw Error(`Resolved HITL state was not persisted`);let l=On(e,r.request.kind);await wn({dataDir:i.dataDir,sessionId:n.sessionId,sessionStoreName:s,toolCallId:r.toolContext?.toolCallId,toolName:r.toolContext?.toolName,resolution:e,encryptSessions:n.encryptSessions});let u=Cn(n);o=u.sink;let f=n.sessionId,p=async e=>{if(f=e.sessionId??f,!y(e)){if(e.type===`stream_text_delta`){i.format===`text`&&I(e),await u.websocketSink?.sendTextDelta({sessionId:f,channel:i.channel,messageId:n.messageId,user:n.user,text:e.text});return}i.format===`text`&&I(e),await o?.send({sessionId:f,channel:i.channel,messageId:n.messageId,user:n.user,type:`progress`,event:e})}};c&&await p(c),await p({type:`hitl_resumed`,requestId:n.requestId,resolution:e,sessionId:n.sessionId}),`idempotentReplay`in t&&t.idempotentReplay&&(N.info(`resume command treated as idempotent replay`,{sessionId:n.sessionId,requestId:n.requestId,idempotencyKey:e.idempotencyKey}),L({sessionId:n.sessionId,text:`Resume request already processed.`,usage:{input:0,output:0,total:0},durationMs:0},i.format),a.end(),process.exit(0));let h=n.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,g=await K(i.dataDir,h),v;try{v=await _({dataDir:i.dataDir,projectDir:dn(n.projectDir),systemAgentsDir:i.systemAgentsDir,sessionStoreName:s,sessionId:n.sessionId,messageId:n.messageId,channel:i.channel,llm:i.llm,skillsLoadPaths:i.skillsLoadPaths,workdirAllowlist:i.workdirAllowlist,artifactsUrlWhitelist:i.artifactsUrlWhitelist,autoSkills:i.autoSkills,timeoutMs:i.timeoutMs,message:l,encryptSessions:n.encryptSessions??!1,topicSegmentation:cn(n),titleGeneration:ln(n),memory:En(),hitlResume:{request:r.request,resolution:e,checkpoint:r.checkpoint,toolContext:r.toolContext},plugins:g?{config:g,dataDir:i.dataDir,workspaceDir:C.join(i.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:g.llmAllowlist}:void 0,onProgress:p,onLog:be})}finally{}v.error?await o?.send({sessionId:v.sessionId,channel:i.channel,messageId:n.messageId,user:n.user,type:`error`,message:v.error}):await o?.send({sessionId:v.sessionId,channel:i.channel,messageId:n.messageId,user:n.user,type:`done`,result:tn(v)}),L(v,i.format),v.error?N.error(`resume command failed: ${v.error}`):N.info(`resume command succeeded`),a.end(),process.exit(v.error?1:0)}let g=bn(n,f);if(!await h(i.dataDir,n.sessionId,n.requestId,g,{storeName:s,encryptSessions:n.encryptSessions}))throw Error(`UI tool resume validation failed`);await Tn({dataDir:i.dataDir,sessionId:n.sessionId,sessionStoreName:s,result:g,encryptSessions:n.encryptSessions}),await r(i.dataDir,n.sessionId,{storeName:s,encryptSessions:n.encryptSessions});let v=Cn(n);o=v.sink;let b=n.sessionId,x=async e=>{if(b=e.sessionId??b,!y(e)){if(e.type===`stream_text_delta`){i.format===`text`&&I(e),await v.websocketSink?.sendTextDelta({sessionId:b,channel:i.channel,messageId:n.messageId,user:n.user,text:e.text});return}if(i.format===`text`&&I(e),e.type===`start`){await o?.send({sessionId:b,channel:i.channel,messageId:n.messageId,user:n.user,type:`start`,message:e.message});return}await o?.send({sessionId:b,channel:i.channel,messageId:n.messageId,user:n.user,type:`progress`,event:e})}},ee=await xn({dataDir:i.dataDir,sessionId:n.sessionId,sessionStoreName:s,toolCallId:g.toolCallId,toolName:g.toolName,encryptSessions:n.encryptSessions});c&&await x(c),await x({type:`tool_end`,sessionId:n.sessionId,toolCallId:g.toolCallId,name:g.toolName,input:ee,output:JSON.stringify({submitted:!0,values:g.values}),isError:!1});let S=n.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,w=await K(i.dataDir,S),E=await _({dataDir:i.dataDir,projectDir:dn(n.projectDir),systemAgentsDir:i.systemAgentsDir,sessionStoreName:s,sessionId:n.sessionId,messageId:n.messageId,channel:i.channel,llm:i.llm,skillsLoadPaths:i.skillsLoadPaths,workdirAllowlist:i.workdirAllowlist,artifactsUrlWhitelist:i.artifactsUrlWhitelist,autoSkills:i.autoSkills,timeoutMs:i.timeoutMs,message:`[UI_TOOL_RESUME]
8
- The pending UI tool result has been written into the transcript. Continue from the latest tool result without repeating the same form request.`,encryptSessions:n.encryptSessions??!1,topicSegmentation:cn(n),titleGeneration:ln(n),memory:En(),uiToolResume:g,plugins:w?{config:w,dataDir:i.dataDir,workspaceDir:C.join(i.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:w.llmAllowlist}:void 0,onProgress:x,onLog:be});E.error?await o?.send({sessionId:E.sessionId,channel:i.channel,messageId:n.messageId,user:n.user,type:`error`,message:E.error}):await o?.send({sessionId:E.sessionId,channel:i.channel,messageId:n.messageId,user:n.user,type:`done`,result:tn(E)}),L(E,i.format),E.error?N.error(`resume command failed: ${E.error}`):N.info(`resume command succeeded`),a.end(),process.exit(E.error?1:0)}catch(e){let t=e;o&&(t.message.includes(`expired`)&&await o.send({sessionId:n.sessionId,channel:n.channel??`WEB`,messageId:n.messageId,user:n.user,type:`progress`,event:{type:`hitl_expired`,sessionId:n.sessionId,requestId:n.requestId,reason:t.message}}),t.message.includes(`cancelled`)&&await o.send({sessionId:n.sessionId,channel:n.channel??`WEB`,messageId:n.messageId,user:n.user,type:`progress`,event:{type:`hitl_cancelled`,sessionId:n.sessionId,requestId:n.requestId,reason:t.message}}),await o.send({sessionId:n.sessionId,channel:n.channel??`WEB`,messageId:n.messageId,user:n.user,type:`error`,message:`Resume failed: ${t.message}`})),N.error(`resume command error: ${t.message}`),F(`Fatal: ${t.message}`),a.end(),process.exit(1)}})}function On(e,t){return n(e,t)}function kn(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(`--workdir-allowlist <paths>`,`Comma-separated additional roots allowed as cwd for exec-style tools`).option(`--auto-skills-load-enabled <boolean>`,`Enable learned auto-skill loading for the main agent (overrides AIMAX_AUTO_SKILLS_LOAD_ENABLED)`).option(`--auto-skills-review-mode <mode>`,`Auto-skill review mode: off, gate, dry_run, or write (overrides AIMAX_AUTO_SKILLS_REVIEW_MODE)`).option(`--message-id <id>`,`Message ID for correlating events`).option(`--user <id>`,`User identifier propagated to external callback and stream payloads`).option(`-c, --channel <channel>`,`Channel name (default: WEB)`,`WEB`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-format <format>`,`LLM API format: openai-completions or anthropic-messages (overrides AIMAX_API_FORMAT)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY / AIMAX_LLM_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(`--thinking <level>`,`Explicit thinking level: minimal, low, medium, high, or xhigh (overrides AIMAX_THINKING)`).option(`--callback-url <url>`,`HTTP callback URL for progress events`).option(`--stream-url <url>`,`WebSocket URL for streaming text events`).option(`--stream-auth-token <token>`,`Auth token for WebSocket streaming`).option(`--stream-events <list>`,`Comma-separated stream events`).option(`--timeout <ms>`,`Execution timeout in milliseconds`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--plugins-config <path>`,`Plugins config file path`).option(`--goal <text>`,`Set or replace the thread goal objective before resuming`).option(`--goal-file <path>`,`Read goal objective from a file`).option(`--token-budget <n>`,`Token budget for the goal (positive integer, or 0 for unlimited)`).option(`--force`,`Replace existing goal with a different objective`).option(`--encrypt-sessions`,`Enable encryption for the .aimax data directory`).option(`--disable-topic-segmentation`,`Disable smart topic segmentation for this resume run`).option(`--disable-title`,`Skip LLM session title generation for new sessions (overrides AIMAX_DISABLE_TITLE)`).action(async e=>{await Dn(e)})}function An(e,t){return{notify:(n,r=`info`)=>{t?.readyState===1?t.send(JSON.stringify({type:`diagnostic`,sessionId:e,level:r,message:n})):console.log(`[${r}] ${n}`)},confirm:async n=>!t||t.readyState!==1?!1:new Promise(r=>{let i=`confirm-${Date.now()}`;t.send(JSON.stringify({type:`hitl_confirm`,sessionId:e,id:i,message:n}));let a=e=>{try{let t=JSON.parse(String(e));r(t.id===i&&t.confirmed===!0)}catch{r(!1)}};typeof t.once==`function`?t.once(`message`,a):t.addEventListener(`message`,e=>a(e.data),{once:!0})}),select:async(n,r)=>{if(!(!t||t.readyState!==1))return new Promise(i=>{let a=`select-${Date.now()}`;t.send(JSON.stringify({type:`hitl_select`,sessionId:e,id:a,title:n,options:r}));let o=e=>{try{let t=JSON.parse(String(e));i(t.id===a?t.selected:void 0)}catch{i(void 0)}};typeof t.once==`function`?t.once(`message`,o):t.addEventListener(`message`,e=>o(e.data),{once:!0})})},setStatus:n=>{t?.readyState===1?t.send(JSON.stringify({type:`diagnostic`,sessionId:e,level:`info`,message:n})):console.log(`[status] ${n}`)}}}const jn=[`start`,`text`,`done`,`error`],Mn=[`off`,`gate`,`dry_run`,`write`];function Nn(e){if(!e?.trim())return new Set(jn);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(jn)}function Pn(e){if(e.disableTopicSegmentation===!0||process.env.AIMAX_DISABLE_TOPIC_SEGMENTATION===`true`)return{enabled:!1};let t=$t();return t?{embeddingModelDir:t}:void 0}function Fn(e){return e.disableTitle===!0||process.env.AIMAX_DISABLE_TITLE===`true`?{enabled:!1}:void 0}function In(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 Ln(e){return e?.trim()||void 0}function Rn(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 X(e){return e?.trim()||void 0}function zn(e){return e??`WEB`}function Bn(e){return e?f(e):void 0}function Vn(e,t){return e===`CRON`?`crons`:Bn(t)}function Hn(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 Un(e){if(!e?.trim())return[];let t=e.split(`,`).map(e=>e.trim()).filter(Boolean),n=new Set,r=[];for(let e of t)n.has(e)||(n.add(e),r.push(e));return r}function Wn(e){let t=``;for(let n=0;n<e.length;n+=1){let r=e[n];if(r===`\\`&&n+1<e.length){let r=e[n+1];if(r===`,`||r===`\\`||r===`=`){t+=r,n+=1;continue}}t+=r}return t}function Gn(e){let t=[],n=``;for(let r=0;r<e.length;r+=1){let i=e[r];if(i===`\\`&&r+1<e.length){let t=e[r+1];if(t===`,`||t===`\\`){n+=t,r+=1;continue}}if(i===`,`){t.push(n),n=``;continue}n+=i}return t.push(n),t}function Kn(e){if(!e?.trim())return{};let t=[],n=new Set;for(let r of Gn(e)){let e=r.trim();if(!e)continue;let i=e.indexOf(`=`);if(i<=0)throw Error(`Invalid --env entry: ${e}. Expected KEY=VALUE (use \\= to embed an equals sign in the value).`);let a=e.slice(0,i).trim(),o=e.slice(i+1).trim();if(!a)throw Error(`Invalid --env entry: ${e}. Key must not be empty.`);if(n.has(a))throw Error(`Invalid --env entry: duplicate key ${a}.`);n.add(a),t.push([a,Wn(o)])}return Object.fromEntries(t)}function qn(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 Jn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(Mn.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function Yn(e){let t=e.autoSkillsLoadEnabled===void 0?qn(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):qn(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?Jn(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):Jn(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 Xn(e,t){return e.length<=t?e:t<=3?e.slice(0,t):`${e.slice(0,t-3)}...`}function Zn(e,t){if(t<=0)return[``];let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n.length>0?n:[``]}function Qn(e,t,n=78){let r=Math.max(0,n-4),i=e?e.length+2:0,a=Math.max(r,i,...t.map(e=>e.length)),o=a+2,s=e?` ${Xn(e,Math.max(0,a-2))} `:``,c=e?`┌${s}${`─`.repeat(Math.max(0,o-s.length))}┐`:`┌${`─`.repeat(o)}┐`,l=`└${`─`.repeat(o)}┘`;return[c,...t.flatMap(e=>Zn(e,a).map(e=>`│ ${e.padEnd(a,` `)} │`)),l].join(`
9
- `)}function $n(e){return e.kind===`text`?`inline message (${e.message.length} chars)`:e.source===`file`?`message file (${e.messages.length} messages)`:`inline messages (${e.messages.length} messages)`}function Z(e,t=`-`){return e==null||e===``?t:String(e)}function er(e){return e?`set`:`unset`}function tr(e){return e?`true`:`false`}function nr(e,t){let n=Vn(t.channel,e.sessionStore)??`sessions`,r=t.timeoutMs===void 0?`default`:`${t.timeoutMs}`,i=e.callbackUrl?`enabled`:`disabled`,a=e.streamUrl?`enabled`:`disabled`,o=$n(t.input),s=t.input.kind===`text`?`inline`:e.fromFile??t.input.source,c=oe(),l=Pn(e)?.enabled===!1?`disabled`:`enabled`,u=Fn(e)?.enabled===!1?`disabled`:`enabled`,d=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,f=[...Nn(e.streamEvents)].join(`,`),p=t.autoSkills?.load?.enabled,m=t.autoSkills?.review?.mode,h=e.tokenBudget===`0`?`unlimited`:Z(e.tokenBudget),g=t.artifactsUrlWhitelist?.join(`,`)??`-`,_=e.env?Object.keys(Kn(e.env)):[],v=_.length===0?`-`:`${_.length} key${_.length===1?``:`s`}`;return{banner:Qn(void 0,[`AIMax CLI`,`Stateless Agent Runner`]),contextBox:Qn(`Run Context`,[`time : ${c}`,`dataDir : ${t.dataDir}`,`projectDir : ${Ln(e.projectDir)??`-`}`,`systemAgents : ${t.systemAgentsDir??`/aimax/agents`}`,`agent : ${X(e.agent)??`-`}`,`channel : ${t.channel}`,`user : ${e.user??`-`}`,`message : ${e.message===void 0?`-`:`inline (${e.message.length} chars)`}`,`fromFile : ${Z(e.fromFile)}`,`input : ${o}`,`skillsPaths : ${t.skillsLoadPaths.length>0?t.skillsLoadPaths.join(`,`):`-`}`,`autoSkillLoad: ${p===void 0?`-`:String(p)}`,`autoSkillRev : ${m??`-`}`,`sessionId : ${e.sessionId??`new`}`,`sessionStore : ${n}`,`messageId : ${e.messageId??`-`}`,`workspace : ${C.join(t.dataDir,`workspace`)}`,`baseUrl : ${t.llm.baseUrl}`,`apiKey : ${er(t.llm.apiKey)}`,`authToken : ${er(e.authToken)}`,`model : ${t.llm.model}`,`contextWindow: ${Z(t.llm.contextWindow)}`,`flashModel : ${Z(t.llm.flashModel)}`,`thinking : ${Z(t.llm.thinking)}`,`callbackUrl : ${Z(e.callbackUrl)}`,`streamUrl : ${Z(e.streamUrl)}`,`streamAuth : ${er(e.streamAuthToken)}`,`streamEvents : ${f}`,`artifactUrls : ${g}`,`output : ${t.format}`,`callback : ${i}`,`websocket : ${a}`,`timeoutMs : ${r}`,`pluginsConfig: ${Z(d)}`,`env : ${v}`,`goal : ${e.goal===void 0?`-`:`inline (${e.goal.length} chars)`}`,`goalFile : ${Z(e.goalFile)}`,`tokenBudget : ${h}`,`force : ${tr(e.force)}`,`resumeReqId : ${Z(e.resumeRequestId)}`,`resumeInput : ${e.resumeInputJson===void 0?`-`:`inline (${e.resumeInputJson.length} chars)`}`,`resumeFile : ${Z(e.resumeFromFile)}`,`encryptSess : ${tr(e.encryptSessions)}`,`topicSegment : ${l}`,`titleGen : ${u}`]),logContext:{time:c,channel:t.channel,user:e.user,dataDir:t.dataDir,projectDir:Ln(e.projectDir),systemAgentsDir:t.systemAgentsDir,agent:X(e.agent),workspaceDir:C.join(t.dataDir,`workspace`),sessionId:e.sessionId??`new`,sessionStore:n,messageId:e.messageId,hasMessage:e.message!==void 0,fromFile:e.fromFile,skillsLoadPaths:t.skillsLoadPaths.join(`,`)||void 0,autoSkillsLoadEnabled:p,autoSkillsReviewMode:m,baseUrl:t.llm.baseUrl,hasApiKey:!!t.llm.apiKey,hasAuthToken:!!e.authToken,model:t.llm.model,contextWindow:t.llm.contextWindow,flashModel:t.llm.flashModel,thinking:t.llm.thinking,callbackUrl:e.callbackUrl,streamUrl:e.streamUrl,hasStreamAuthToken:!!e.streamAuthToken,streamEvents:f,artifactsUrlWhitelist:t.artifactsUrlWhitelist?.join(`,`)||void 0,output:t.format,hasCallback:!!e.callbackUrl,hasStream:!!e.streamUrl,timeoutMs:t.timeoutMs,pluginsConfig:d,envKeys:_.length>0?_.join(`,`):void 0,hasGoal:e.goal!==void 0,goalFile:e.goalFile,tokenBudget:h===`-`?void 0:h,force:!!e.force,resumeRequestId:e.resumeRequestId,hasResumeInputJson:e.resumeInputJson!==void 0,resumeFromFile:e.resumeFromFile,encryptSessions:!!e.encryptSessions,topicSegmentation:l,titleGeneration:u,inputKind:t.input.kind,inputSource:s,inputSummary:o}}}async function rr(e,t){let n=In(e),r=zn(e.channel),i=G({apiFormat:e.apiFormat,baseUrl:e.baseUrl,apiKey:e.apiKey,authToken:e.authToken,model:e.model,contextWindow:e.contextWindow?Number(e.contextWindow):void 0,flashModel:e.flashModel,thinking:e.thinking});return{dataDir:n,systemAgentsDir:Rn(e),channel:r,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:i,input:t,skillsLoadPaths:Hn(e.skillsLoadPaths),workdirAllowlist:Un(e.workdirAllowlist),artifactsUrlWhitelist:nn(e.artifactsUrlWhitelist),autoSkills:Yn(e)}}function ir(e){if(e.kind===`text`)return e.message;if(e.messages.length!==1)return null;let[t]=e.messages;if(t.role!==`user`)return null;if(typeof t.content==`string`)return t.content;if(t.content.length===0)return null;let n=[];for(let e of t.content){if(e.type!==`text`)return null;n.push(e.text)}return n.join(`
10
- `)}async function ar(e,t){if(!e.sessionId)return null;let n=ir(t);if(!n)return null;let r=await l(In(e),e.sessionId,{storeName:Bn(e.sessionStore),encryptSessions:e.encryptSessions});return!r||r.status!==`pending`||!x(n,r.request)?null:{requestId:r.request.requestId,inputText:n}}function or(e){let t=[],n=null;return e.callbackUrl&&t.push(new Vt(e.callbackUrl)),e.streamUrl&&(n=new Jt(e.streamUrl,Nn(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new Bt(t),websocketSink:n}}async function Q(e,t){N.info(`dispatching external event`,Er(t)),await e.sink.send(t)}function sr(e){let t={sessionId:e.sessionId,messageId:e.messageId,parentSessionId:e.parentSessionId,depth:e.depth,scope:e.scope,phase:e.phase,...e.details};if(e.level===`error`){N.error(e.message,t);return}if(e.level===`warn`){N.warn(e.message,t);return}N.info(e.message,t)}function cr(e,t,n,r,i){return{sink:e,websocketSink:t,channel:n,defaultMessageId:r,user:i}}function lr(e){let t=new AbortController,n=n=>{N.warn(`run abort signal received`,{signal:n,uptimeMs:Math.round(process.uptime()*1e3),alreadyAborted:t.signal.aborted,...e?.()}),t.abort()},r=()=>n(`SIGTERM`),i=()=>n(`SIGINT`);return process.once(`SIGTERM`,r),process.once(`SIGINT`,i),{controller:t,cleanup:()=>{process.off(`SIGTERM`,r),process.off(`SIGINT`,i)}}}function ur(e){return{activeSessionId:e??`pending`,finalResult:null,loggerSessionId:void 0}}function dr(e,t,n,r){!r||n.loggerSessionId===r||(ve(e,{messageId:t.messageId,sessionId:r,sessionStoreName:Vn(t.channel,t.sessionStore)}),n.loggerSessionId=r)}function fr(e,t){e.activeSessionId=t.sessionId??e.activeSessionId}function pr(e,t){return e.messageId??t}async function mr(e,t,n){if(!await c(e.dataDir)){if(await $(t,e.format,n.activeSessionId,e.dataDir,`checking`),(await i(e.dataDir)).performedBootstrap){await $(t,e.format,n.activeSessionId,e.dataDir,`initializing`),await $(t,e.format,n.activeSessionId,e.dataDir,`initialized`);return}await $(t,e.format,n.activeSessionId,e.dataDir,`ready`)}}async function $(e,t,n,r,i){let a={type:`bootstrap`,phase:i,dataDir:r};t===`text`&&I(a),await Q(e,{sessionId:n,channel:e.channel,messageId:e.defaultMessageId,user:e.user,type:`progress`,event:a})}function hr(e,t,n,r){return async i=>{if(fr(n,i),dr(e.dataDir,{...r,channel:e.channel},n,i.sessionId),y(i)){sr(i);return}if(i.type===`stream_text_delta`){e.format===`text`&&I(i),await t.websocketSink?.sendTextDelta({sessionId:n.activeSessionId,channel:e.channel,messageId:pr(i,t.defaultMessageId),user:t.user,text:i.text});return}e.format===`text`&&I(i);let a=pr(i,t.defaultMessageId);if(i.type===`hitl_requested`){await Q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:a,user:t.user,type:`hitl`,request:i.request}),await Q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:a,user:t.user,type:`progress`,event:i});return}if(i.type===`start`){await Q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:a,user:t.user,type:`start`,message:i.message});return}if(i.type===`session_reset`){await Q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:a,user:t.user,type:`session_reset`,action:i.action,previousSessionId:i.previousSessionId,message:i.message});return}await Q(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:a,user:t.user,type:`progress`,event:i})}}function gr(e){let t=An(e);return{confirm:(e,n)=>t.confirm(e),select:(e,n,r)=>t.select?t.select(e,n):Promise.resolve(void 0)}}function _r(e,t,n,r,i,a){let o=Et(),s={dataDir:t.dataDir,projectDir:Ln(e.projectDir),systemAgentsDir:t.systemAgentsDir,agentPolicy:X(e.agent)?{requestedAgentName:X(e.agent)}:void 0,sessionStoreName:Vn(t.channel,e.sessionStore),sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,workdirAllowlist:t.workdirAllowlist,artifactsUrlWhitelist:t.artifactsUrlWhitelist,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,abortSignal:n.signal,pendingGoal:a,encryptSessions:e.encryptSessions??!1,topicSegmentation:Pn(e),titleGeneration:Fn(e),env:Kn(e.env),...o?{memory:{core:o}}:{},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,onLog:be,createPiExtensionDialogBridge:gr};return t.input.kind===`messages`?{...s,messages:t.input.messages}:{...s,message:t.input.message}}async function vr(e,t,n,r){if(t.activeSessionId=r.sessionId,t.finalResult=r,r.error){await Q(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:r.error});return}await Q(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`done`,result:tn(r)})}async function yr(e,t,n,r){await Q(e,{sessionId:t.finalResult?.sessionId??t.activeSessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:`Fatal: ${r.message}`})}function br(e,t){let n=nr(e,t);N.info([`run command started`,n.banner,n.contextBox].join(`
11
- `),n.logContext),t.format===`text`&&(P(n.banner),P(``),P(n.contextBox),P(``))}function xr(e,t,n){return L(t,n),t.error?N.error(`run command failed: ${t.error}`):N.info(`run command succeeded`),e.end(),t.error?1:0}function Sr(e){let t=ye();if(!t)return;let n=`[${oe()}] [ERROR] ${e}\n`;try{S.appendFileSync(C.join(t.logDir,`app.log`),n),S.appendFileSync(C.join(t.logDir,`errors.log`),n)}catch{}}async function Cr(e,t){let n=`run command error: ${t.message}`;N.error(n),Sr(n),F(`Fatal: ${t.message}`),e.end(),await xe(),process.exit(1)}async function wr(e){if(e.resumeInputJson&&e.resumeFromFile)throw Error(`--resume-input-json and --resume-from-file are mutually exclusive`);if(!e.resumeFromFile)return e.resumeInputJson;try{return await T.readFile(e.resumeFromFile,`utf-8`)}catch(e){throw Error(`Failed to read resume input file: ${e.message}`)}}async function Tr(n){let r=In(n);try{await ut(r,n,async i=>{let a=ur(n.sessionId);dr(r,{...n,channel:zn(n.channel)},a,n.sessionId),n.encryptSessions&&N.info(`--encrypt-sessions run mount state after logger initialization`,{dataDir:r,mounted:i?.mounted??!1,plainDir:i?.plainDir,encryptedDir:i?.encryptedDir});let o=new Ce(`run command`),s=await wr(n);if(n.resumeRequestId||s||n.resumeFromFile){if(!n.sessionId||!n.resumeRequestId||!s)throw Error(`--session-id, --resume-request-id, and exactly one of --resume-input-json or --resume-from-file must be provided together`);await Dn({dataDir:n.dataDir,projectDir:n.projectDir,systemAgentsDir:n.systemAgentsDir,sessionId:n.sessionId,sessionStore:n.sessionStore,requestId:n.resumeRequestId,inputJson:s,channel:n.channel,baseUrl:n.baseUrl,apiKey:n.apiKey,authToken:n.authToken,model:n.model,contextWindow:n.contextWindow,flashModel:n.flashModel,thinking:n.thinking,callbackUrl:n.callbackUrl,streamUrl:n.streamUrl,streamAuthToken:n.streamAuthToken,streamEvents:n.streamEvents,timeout:n.timeout,output:n.output,pluginsConfig:n.pluginsConfig,artifactsUrlWhitelist:n.artifactsUrlWhitelist,skillsLoadPaths:n.skillsLoadPaths,workdirAllowlist:n.workdirAllowlist,autoSkillsLoadEnabled:n.autoSkillsLoadEnabled,autoSkillsReviewMode:n.autoSkillsReviewMode,messageId:n.messageId,user:n.user,goal:n.goal,goalFile:n.goalFile,tokenBudget:n.tokenBudget,force:n.force,encryptSessions:n.encryptSessions,disableTopicSegmentation:n.disableTopicSegmentation,disableTitle:n.disableTitle});return}let c;try{c=await zt({message:n.message,fromFile:n.fromFile,messages:n.messages})}catch(e){await Cr(o,e);return}let l=await ar(n,c);if(l){await Dn({dataDir:n.dataDir,projectDir:n.projectDir,systemAgentsDir:n.systemAgentsDir,sessionId:n.sessionId,sessionStore:n.sessionStore,requestId:l.requestId,inputText:l.inputText,channel:n.channel,baseUrl:n.baseUrl,apiKey:n.apiKey,authToken:n.authToken,model:n.model,contextWindow:n.contextWindow,flashModel:n.flashModel,thinking:n.thinking,callbackUrl:n.callbackUrl,streamUrl:n.streamUrl,streamAuthToken:n.streamAuthToken,streamEvents:n.streamEvents,timeout:n.timeout,output:n.output,pluginsConfig:n.pluginsConfig,artifactsUrlWhitelist:n.artifactsUrlWhitelist,skillsLoadPaths:n.skillsLoadPaths,workdirAllowlist:n.workdirAllowlist,autoSkillsLoadEnabled:n.autoSkillsLoadEnabled,autoSkillsReviewMode:n.autoSkillsReviewMode,messageId:n.messageId,user:n.user,goal:n.goal,goalFile:n.goalFile,tokenBudget:n.tokenBudget,force:n.force,encryptSessions:n.encryptSessions,disableTopicSegmentation:n.disableTopicSegmentation,disableTitle:n.disableTitle});return}let u=n.channel??`WEB`,{controller:d,cleanup:f}=lr(()=>({activeSessionId:a.activeSessionId,finalSessionId:a.finalResult?.sessionId,messageId:n.messageId,channel:u,user:n.user})),m=null;try{let r=await rr(n,c);u=r.channel,br(n,r);let i=or(n);m=i.sink,N.info(`external sink configured`,{callbackUrl:n.callbackUrl,streamUrl:n.streamUrl,streamEvents:n.streamEvents});let s=cr(m,i.websocketSink,r.channel,n.messageId,n.user);await mr(r,s,a);let l,f=null;if(n.goal||n.goalFile){let i;i=n.goalFile?await T.readFile(n.goalFile,`utf-8`):n.goal;let a=Xt(i),o=Bn(n.sessionStore),s=n.tokenBudget===void 0?void 0:n.tokenBudget===`0`||n.tokenBudget===``?null:Number(n.tokenBudget);s!=null&&(Number.isNaN(s)||s<=0)&&(F(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));try{if(n.sessionId){let e=await p(r.dataDir,n.sessionId,{storeName:o}),i=await t({dataDir:r.dataDir,sessionId:n.sessionId,objective:a,tokenBudget:s,force:n.force,storeName:o});f=Qt({sessionId:n.sessionId,before:e,result:i})}else l={objective:a,tokenBudget:s??null}}catch(t){throw t instanceof e&&(F(t.message),F(`Existing: ${t.existingObjectivePreview}`),process.exit(2)),t}}let h=n.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,g=await K(r.dataDir,h),v=hr(r,s,a,n);f&&await v(f);let y=await _(_r(n,r,d,v,g,l));dr(r.dataDir,{...n,channel:r.channel},a,y.sessionId),await vr(s,a,n.messageId,y),process.exitCode=xr(o,y,r.format)}catch(e){let t=e;m&&await yr(cr(m,null,u,n.messageId,n.user),a,n.messageId,t),await Cr(o,t)}finally{await m?.close(),f()}})}finally{await xe()}}function Er(e){return{eventType:e.type,sessionId:e.sessionId,messageId:e.messageId,channel:e.channel,user:e.user,progressType:e.type===`progress`?e.event.type:void 0,textLength:e.type===`done`?e.result.text.length:void 0,hasError:e.type===`error`?!0:e.type===`done`?!!e.result.error:void 0}}function Dr(e){e.command(`run`).description(`Run an agent task`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--project-dir <path>`,`Current project directory used as the default cwd context`).option(`--system-agents-dir <path>`,`System agent definition directory (overrides AIMAX_SYSTEM_AGENTS_DIR, default: /aimax/agents)`).option(`--agent <name>`,`Custom agent name to run as the root agent`).option(`--user <id>`,`User identifier propagated to external callback and stream payloads`).option(`--message <text>`,`User message to send to the agent`).option(`--from-file <path>`,`Load structured Message JSON from a file`).option(`--skillsLoadPaths <paths>`,`Comma-separated absolute skill load paths`).option(`--workdir-allowlist <paths>`,`Comma-separated additional roots allowed as cwd for exec-style tools`).option(`--auto-skills-load-enabled <boolean>`,`Enable learned auto-skill loading for the main agent (overrides AIMAX_AUTO_SKILLS_LOAD_ENABLED)`).option(`--auto-skills-review-mode <mode>`,`Auto-skill review mode: off, gate, dry_run, or write (overrides AIMAX_AUTO_SKILLS_REVIEW_MODE)`).option(`-s, --session-id <id>`,`Resume an existing session by ID`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).option(`--message-id <id>`,`Message ID for correlating events`).option(`-c, --channel <channel>`,`Channel name (default: WEB)`,`WEB`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-format <format>`,`LLM API format: openai-completions or anthropic-messages (overrides AIMAX_API_FORMAT)`).option(`--api-key <key>`,`LLM API key (overrides AIMAX_API_KEY / AIMAX_LLM_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(`--thinking <level>`,`Explicit thinking level: minimal, low, medium, high, or xhigh (overrides AIMAX_THINKING)`).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(`--artifacts-url-whitelist <urls>`,`Comma-separated URL artifact hostnames or URLs to collect; unset collects all URL artifacts`).option(`--timeout <ms>`,`Execution timeout in milliseconds`).option(`--output <format>`,`Output format: text (default) or json`,`text`).option(`--plugins-config <path>`,`Plugins config file path`).option(`--env <kvlist>`,`Session-scoped env vars injected into the run. Comma-separated KEY=VALUE pairs. Backslash-escape "," and "=" inside values. Available to plugins via api.runtime.session.env and merged into child process environments spawned by the exec/process tools.`).option(`--goal <text>`,`Set or replace the thread goal objective before running`).option(`--goal-file <path>`,`Read goal objective from a file`).option(`--token-budget <n>`,`Token budget for the goal (positive integer, or 0 for unlimited)`).option(`--force`,`Replace existing goal with a different objective`).option(`--resume-request-id <id>`,`Resume a pending HITL request from aimax run`).option(`--resume-input-json <json>`,`Structured HITL resume payload used with --resume-request-id`).option(`--resume-from-file <path>`,`Load structured HITL resume payload from a file (alternative to --resume-input-json)`).option(`--encrypt-sessions`,`Enable gocryptfs-backed encryption for the .aimax data directory`).option(`--disable-topic-segmentation`,`Disable smart topic segmentation for this run`).option(`--disable-title`,`Skip LLM session title generation for new sessions (title falls back to a truncated first message; overrides AIMAX_DISABLE_TITLE)`).action(async e=>{await Tr(e)})}export{P as _,Vt as a,N as b,Ot as c,Ne as d,I as f,F as g,Ae as h,Jt as i,G as l,je as m,Dr as n,Bt as o,Me as p,kn as r,K as s,Tr as t,ut as u,Ce as v,xe as x,ve as y};