@gencode/cli 0.15.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/bin.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{program-CODUGjyo.js → program-Bd8KnLF6.js} +2 -2
- package/dist/program.js +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @gencode/cli
|
|
2
2
|
|
|
3
|
+
## 0.15.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 973ae34: HTTP callback events are now queued asynchronously, so a slow callback endpoint no longer delays `aimax run` or `aimax resume` task execution. The CLI drains the queue before exit, preserving callback order through `start`, progress, and final `done` / `error` events.
|
|
8
|
+
- bb18ff9: AIMax no longer saves the runtime system prompt into session data. New `aimax run` executions do not create or overwrite `<dataDir>/.aimax/<sessionStore>/<sessionId>/system-prompt.txt`, and `aimax export-html` ignores any legacy `system-prompt.txt` files that may already exist, so exported HTML no longer shows historical system prompts. Transcript export remains available, and the existing `<dataDir>/.aimax/<sessionStore>/<sessionId>/session-tools.json` tools snapshot continues to power the Available Tools section. Deprecated snapshot APIs such as `persistSystemPromptSnapshot`, `loadSystemPromptSnapshot`, and `persistSessionExportSnapshots` are retained for compatibility, but system prompt persistence/reading is disabled: the system prompt helpers no-op or return `null`, and the export snapshot helper only writes tools. If your deployment has old `system-prompt.txt` files, clean them with an operations-approved filesystem cleanup job.
|
|
9
|
+
- Updated dependencies [bb18ff9]
|
|
10
|
+
- @gencode/agents@0.17.1
|
|
11
|
+
|
|
3
12
|
## 0.15.0
|
|
4
13
|
|
|
5
14
|
### Minor Changes
|
package/dist/bin.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import"./pkg-path-D6anqptM.js";import{a as e,i as t,o as n,t as r}from"./program-
|
|
2
|
+
import"./pkg-path-D6anqptM.js";import{a as e,i as t,o as n,t as r}from"./program-Bd8KnLF6.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&&t(s,{messageId:u(process.argv)}),a({proc:process,logError:t=>e.error(t),shutdown:n,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 t=Date.now()-o;return e.info(`AIMax CLI exited (total uptime: ${t}ms)`),n()});export{};
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./pkg-path-D6anqptM.js";import{n as e,r as t,t as n}from"./program-
|
|
1
|
+
import"./pkg-path-D6anqptM.js";import{n as e,r as t,t as n}from"./program-Bd8KnLF6.js";export{n as createProgram,t as executeRun,e as getDataDir};
|
|
@@ -4,7 +4,7 @@ import{createRequire as e}from"node:module";import{Command as t}from"commander";
|
|
|
4
4
|
`),I(`session: ${e.sessionId}`),I(`duration: ${e.durationMs}ms`),I(`tokens: input=${e.usage.input} output=${e.usage.output} total=${e.usage.total}`),e.context&&(I(`context: ${e.context.snapshotPath}`),I(`tool-results: ${e.context.toolResultsDir}`)),e.error&&L(`error: ${e.error}`)}function yt(e,t){if(t===`json`){I(JSON.stringify(e,null,2));return}if(e.length===0){I(`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:—]`;I(`${t.id} ${e} [${t.channel}]${n} ${t.title}`)}}function bt(e,t){if(t===`json`){I(JSON.stringify(e,null,2));return}I(`session: ${e.id}`),e.metadata&&(I(`title: ${e.metadata.title}`),I(`channel: ${e.metadata.channel}`),I(`created: ${e.metadata.createdAt}`),I(`updated: ${e.metadata.updatedAt}`)),I(`transcript: ${e.transcriptPath}`),I(`entries: ${e.transcriptEntryCount}`),I(`context: ${e.contextSnapshotPath}`),I(`session-memory: ${e.sessionMemoryPath}`),I(`collapse-log: ${e.collapseLogPath}`),I(`read-states: ${e.readStateCount}`),I(`tool-results: ${e.toolResultRefCount}`),I(`tool-results-dir: ${e.toolResultsDir}`)}function xt(e,t){if(t===`json`){I(JSON.stringify(e,null,2));return}I(`session: ${e.id}`),I(`transcript: ${e.paths.transcriptPath}`),I(`context: ${e.paths.contextSnapshotPath}`),I(`session-memory: ${e.paths.sessionMemoryPath}`),I(`collapse-log: ${e.paths.collapseLogPath}`),I(`tool-results-dir: ${e.paths.toolResultsDir}`),I(`transcript-entries: ${e.transcript.length}`),I(`read-states: ${e.context.readStates.length}`),I(`tool-results: ${e.context.toolResults.length}`),I(`collapse-spans: ${e.context.compaction.collapseSpans.length}`)}function St(e,t){if(t===`json`){I(JSON.stringify(e,null,2));return}I(`Bootstrap completed.`),I(`dataDir: ${e.dataDir}`),I(`created dirs: ${e.createdDirs.length}`),I(`created files: ${e.createdFiles.length}`),I(`skipped dirs: ${e.skippedDirs.length}`),I(`skipped files: ${e.skippedFiles.length}`)}const Ct=`.aimax`,wt=`${Ct}.pre-gocryptfs.`,Tt=[`app.log`,`errors.log`],Et=[`logs`],Dt=[`fusermount3`,`fusermount`,`umount`],Ot=[{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 kt(e){return C.join(e,`.aimax.enc`)}function At(e){return C.join(e,Ct)}function jt(e){return C.join(e,`${wt}${process.pid}.${Date.now()}`)}function Mt(e){return C.join(e,`${Ct}.plaintext-restore.${process.pid}.${Date.now()}`)}function Nt(e){return e.replace(/\\([0-7]{3})/g,(e,t)=>String.fromCharCode(Number.parseInt(t,8)))}async function z(e){try{let t=await It.read(),n=C.resolve(e);for(let e of t.split(`
|
|
5
5
|
`)){if(!e.trim())continue;let t=e.split(` `);if(t.length>=5&&C.resolve(Nt(t[4]??``))===n)return!0}return!1}catch{return!1}}function Pt(e){try{let t=x.readFileSync(`/proc/self/mountinfo`,`utf-8`),n=C.resolve(e);for(let e of t.split(`
|
|
6
6
|
`)){if(!e.trim())continue;let t=e.split(` `);if(t.length>=5&&C.resolve(Nt(t[4]??``))===n)return!0}return!1}catch{return!1}}async function Ft(){return await D.readFile(`/proc/self/mountinfo`,`utf-8`)}const It={read:Ft};async function B(e){try{return await D.stat(e),!0}catch(e){if(e.code===`ENOENT`)return!1;throw e}}async function V(e){await D.mkdir(e,{recursive:!0})}async function Lt(e){if(await V(e),(await D.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 Rt(e){return await B(e)?(await D.readdir(e)).length===0:!0}async function H(e){if(await B(e))return(await D.readdir(e)).length}async function zt(e){if(!await B(e))return!1;let t=await D.readdir(e,{withFileTypes:!0});for(let e of t)if(!(e.isDirectory()&&Et.includes(e.name))&&!(e.isFile()&&Tt.some(t=>e.name.startsWith(t))))return!0;return!1}async function Bt(e){let t=await D.readdir(e,{withFileTypes:!0});for(let n of t){if(n.isDirectory()&&Et.includes(n.name)){await D.rm(C.join(e,n.name),{recursive:!0,force:!0}).catch(()=>{});continue}n.isFile()&&Tt.some(e=>n.name.startsWith(e))&&await D.rm(C.join(e,n.name),{force:!0}).catch(()=>{})}}async function Vt(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 Ht(e){return(await D.readdir(e,{withFileTypes:!0})).filter(e=>e.isDirectory()&&e.name.startsWith(wt)).map(t=>C.join(e,t.name)).sort()}async function Ut(e,t){if(!await B(t))return null;let n=jt(e);return F.info(`--encrypt-sessions moving plaintext .aimax aside before migration`,{plainDir:t,backupDir:n}),await D.rename(t,n),n}async function U(e,t,n){F.info(`--encrypt-sessions copying plaintext backup into encrypted mount`,{backupDir:e,plainDir:t,force:n}),await D.cp(e,t,{recursive:!0,force:n})}async function Wt(e,t){if(e.length===0)return[];await V(t);let n=[];for(let r of e)await B(r)&&(await U(r,t,!0),await D.rm(r,{recursive:!0,force:!0}),F.info(`--encrypt-sessions restored interrupted plaintext backup after failed migration`,{backupDir:r,plainDir:t}),n.push(r));return n}async function Gt(e){let t=kt(e),n=At(e),r=await B(t);if(!r)return;let i=r&&await B(C.join(t,`gocryptfs.conf`)),a=await B(n),o=a?await z(n):!1,s=await Rt(n);if(F.info(`plaintext .aimax restore check for disabled --encrypt-sessions`,{dataDir:e,encryptedDir:t,plainDir:n,encryptedDirExists:r,encryptedDirInitialized:i,plainDirExists:a,plainDirMountPoint:o,plainDirEntryCount:await H(n)}),!i){F.warn(`plaintext .aimax restore skipped because .aimax.enc is not initialized`,{encryptedDir:t,plainDir:n}),await V(n);return}if(o){F.warn(`plaintext .aimax restore skipped because .aimax is already a mount point`,{plainDir:n,encryptedDir:t});return}if(await zt(n)){F.info(`plaintext .aimax restore skipped because plaintext .aimax already contains data`,{plainDir:n,encryptedDir:t,plainDirEntryCount:await H(n)});return}s||(F.info(`plaintext .aimax clearing ephemeral files before restore`,{plainDir:n,encryptedDir:t,plainDirEntryCount:await H(n)}),await Bt(n));try{await Jt()}catch(e){F.warn(`plaintext .aimax restore unavailable; continuing with plaintext .aimax`,{error:e instanceof Error?e.message:String(e),plainDir:n,encryptedDir:t}),await V(n);return}let c=Mt(e),l=!1;try{await Lt(n),await Yt(t,n),l=!0,await D.rm(c,{recursive:!0,force:!0}),await V(c),await D.cp(n,c,{recursive:!0,force:!0}),F.info(`plaintext .aimax restore copied encrypted history to staging directory`,{plainDir:n,encryptedDir:t,restoreDir:c,restoredEntryCount:await H(c)}),await Zt(n),l=!1,await D.rm(n,{recursive:!0,force:!0}),await D.rename(c,n),F.info(`plaintext .aimax restore completed for disabled --encrypt-sessions`,{plainDir:n,encryptedDir:t})}catch(e){l&&await Zt(n).catch(e=>{F.warn(`plaintext .aimax restore failed to unmount during rollback`,{error:e instanceof Error?e.message:String(e),plainDir:n,encryptedDir:t})}),await D.rm(c,{recursive:!0,force:!0}).catch(()=>{}),await V(n).catch(()=>{}),F.warn(`plaintext .aimax restore failed; continuing with existing plaintext .aimax`,{error:e instanceof Error?e.message:String(e),plainDir:n,encryptedDir:t})}}async function Kt(e){let t=C.join(ke.tmpdir(),`aimax-gocryptfs-pass.${process.pid}.${Date.now()}`);await D.writeFile(t,`wizard_aimax@2026
|
|
7
|
-
`,{mode:384});try{return await e(t)}finally{await D.rm(t,{force:!0})}}async function qt(e){let t=e.includes(`-init`)?`init`:`mount`;F.info(`--encrypt-sessions starting gocryptfs ${t}`);try{await tn(`gocryptfs`,e),F.info(`--encrypt-sessions completed gocryptfs ${t}`)}catch(n){let r=n instanceof Error?n.message:String(n);throw F.warn(`--encrypt-sessions failed gocryptfs ${t}`,{error:r}),Error(`gocryptfs ${e.join(` `)} failed: ${r}`)}}async function Jt(){F.info(`--encrypt-sessions checking encryption dependencies`),await rn(`gocryptfs`,`required for --encrypt-sessions`),F.info(`--encrypt-sessions dependency available`,{command:`gocryptfs`});for(let e of Dt)if(await nn(e)){F.info(`--encrypt-sessions unmount dependency available`,{command:e});return}throw Error(`--encrypt-sessions requires one of ${Dt.join(`, `)} to be installed for secure unmount cleanup.`)}async function Yt(e,t){F.info(`--encrypt-sessions mounting encrypted .aimax`,{encryptedDir:e,plainDir:t}),await Kt(async n=>{await qt([`-q`,`-passfile`,n,e,t])})}async function Xt(e){F.info(`--encrypt-sessions initializing encrypted .aimax directory`,{encryptedDir:e}),await Kt(async t=>{await qt([`-q`,`-init`,`-passfile`,t,e])})}async function Zt(e){let t=[];F.info(`--encrypt-sessions unmounting encrypted .aimax`,{plainDir:e});for(let n of Ot)try{if(F.info(`--encrypt-sessions attempting encrypted .aimax unmount`,{command:n.label,plainDir:e}),await tn(n.command,[...n.args,e]),!await z(e)){F.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),F.warn(`--encrypt-sessions unmount command returned success but mountpoint remains`,{command:n.label,plainDir:e})}catch(r){let i=an(n.label,r);t.push(i),F.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 Qt(e){for(let t of Ot)try{if(je(t.command,[...t.args,e],{stdio:`ignore`}),!Pt(e))return}catch{}}function $t(e){let t=!1,n=()=>{t||(t=!0,Qt(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 en(e){let t=kt(e),n=At(e),r=await B(n),i=await B(t),a=i&&await B(C.join(t,`gocryptfs.conf`)),o=r?await z(n):!1;F.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 Jt()}catch(e){return F.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 F.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 Ht(e),l.length>0&&F.warn(`--encrypt-sessions found interrupted pre-gocryptfs migration backups`,{count:l.length}),!await B(t))if(F.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 Ut(e,n):c=await Ut(e,n),await V(t),await Xt(t),await V(n),await Yt(t,n),f=!0,d=$t(n),F.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 D.rm(u,{recursive:!0,force:!0}),F.info(`--encrypt-sessions removed residual plaintext backup after migration`,{backupDir:u}),null);for(let e of l)await D.rm(e,{recursive:!0,force:!0}),F.info(`--encrypt-sessions removed resumed plaintext migration backup`,{backupDir:e});l=[]}else c&&=(await U(c,n,!0),await D.rm(c,{recursive:!0,force:!0}),F.info(`--encrypt-sessions removed plaintext migration backup`,{backupDir:c}),null);else if(F.info(`--encrypt-sessions encrypted .aimax directory exists; mounting existing encrypted data`,{encryptedDir:t,plainDir:n,resumedBackupCount:l.length,plainDirEntryCount:await H(n)}),await Vt(t),l.length>0?u=await Ut(e,n):await Rt(n)||(c=await Ut(e,n)),await Lt(n),await Yt(t,n),f=!0,d=$t(n),F.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 D.rm(u,{recursive:!0,force:!0}),F.info(`--encrypt-sessions removed residual plaintext backup after migration`,{backupDir:u}),null);for(let e of l)await D.rm(e,{recursive:!0,force:!0}),F.info(`--encrypt-sessions removed resumed plaintext migration backup`,{backupDir:e});l=[]}else c&&=(await U(c,n,!0),await D.rm(c,{recursive:!0,force:!0}),F.info(`--encrypt-sessions removed plaintext migration backup`,{backupDir:c}),null);return F.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){F.info(`--encrypt-sessions cleanup skipped because encrypted .aimax is not mounted`,{plainDir:n,encryptedDir:t});return}f=!1,F.info(`--encrypt-sessions cleanup started`,{plainDir:n,encryptedDir:t});try{await Zt(n),F.info(`--encrypt-sessions cleanup completed`,{plainDir:n,encryptedDir:t})}catch(e){F.warn(`--encrypt-sessions failed to unmount encrypted .aimax; continuing shutdown`,{error:e instanceof Error?e.message:String(e)})}}}}catch(e){d?.release(),f&&await Zt(n).catch(e=>{F.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 Rt(n)&&(await D.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await D.rename(c,n).catch(()=>{}),F.info(`--encrypt-sessions restored plaintext backup after failed migration`,{backupDir:c,plainDir:n})),u&&await B(u)&&await Rt(n)&&(await D.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await D.rename(u,n).catch(()=>{}),F.info(`--encrypt-sessions restored residual plaintext backup after failed migration`,{backupDir:u,plainDir:n}));let r=await Wt(l,n).catch(e=>(F.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)),F.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 W(e,t,n){if(!t.encryptSessions)return await Gt(e),n();F.info(`--encrypt-sessions wrapper starting encrypted .aimax preparation`,{dataDir:e});let r=await en(e);F.info(`--encrypt-sessions wrapper prepared encrypted .aimax state`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir});try{return F.info(`--encrypt-sessions wrapper entering protected operation`,{dataDir:e,mounted:r.mounted}),await n(r)}finally{F.info(`--encrypt-sessions wrapper starting cleanup`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir}),await r.cleanup(),F.info(`--encrypt-sessions wrapper finished cleanup`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir})}}async function tn(e,t){await new Promise((n,r)=>{Ae(e,t,{encoding:`utf-8`},e=>{if(e){r(e);return}n()})})}async function nn(e){try{return await tn(`sh`,[`-c`,`command -v "${e}" >/dev/null 2>&1`]),!0}catch{return!1}}async function rn(e,t){if(!await nn(e))throw Error(`--encrypt-sessions requires ${e}: ${t}.`)}function an(e,t){return`${e} failed: ${t instanceof Error?t.message:String(t)}`}function on(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{St(await W(e.dataDir,e,async()=>i(e.dataDir)),t)}catch(e){L(`Error bootstrapping data directory: ${e.message}`),process.exit(1)}})}function sn(e){return Me.sm4_encrypt_ecb(e)}function cn(e){return sn(e)}const ln=[`minimal`,`low`,`medium`,`high`,`xhigh`];function un(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(ln.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of ${ln.join(`, `)}.`)}}function dn(e={}){let t=fn(e.apiFormat??process.env.AIMAX_API_FORMAT),n=e.baseUrl??process.env.AIMAX_BASE_URL,r=process.env.AIMAX_AUTH_TOKEN,i=e.authToken?cn(e.authToken):r?cn(r):e.apiKey??process.env.AIMAX_API_KEY,a=e.model??process.env.AIMAX_MODEL,o=[];if(n||o.push(`--base-url / AIMAX_BASE_URL`),i||o.push(`--api-key / AIMAX_API_KEY`),a||o.push(`--model / AIMAX_MODEL`),o.length>0)throw Error(`Missing required LLM configuration: ${o.join(`, `)}`);return{apiFormat:t,baseUrl:n,apiKey:i,model:a,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?un(process.env.AIMAX_THINKING,`AIMAX_THINKING`):un(e.thinking,`--thinking`)}}function fn(e){if(!e||e===`openai-completions`||e===`anthropic-messages`)return e;throw Error(`Unsupported LLM API format: ${e}`)}const pn=[`off`,`fallback`];function mn(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 hn(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 gn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(pn.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of ${pn.join(`, `)}.`)}}function _n(){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 vn(e){return Object.values(e).some(e=>e!==void 0)}function yn(e={}){if(!(!vn(e)&&!_n()))return{knowledgeController:{enabled:e.kcEnabled??mn(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?gn(process.env.AIMAX_MEMORY_KC_SEARCH_MODE,`AIMAX_MEMORY_KC_SEARCH_MODE`)??`off`:gn(e.kcSearchMode,`kcSearchMode`),topK:e.kcTopK??hn(process.env.AIMAX_MEMORY_KC_TOP_K,`AIMAX_MEMORY_KC_TOP_K`),scoreThreshold:e.kcScoreThreshold??hn(process.env.AIMAX_MEMORY_KC_SCORE_THRESHOLD,`AIMAX_MEMORY_KC_SCORE_THRESHOLD`),timeoutMs:e.kcTimeoutMs??hn(process.env.AIMAX_MEMORY_KC_TIMEOUT_MS,`AIMAX_MEMORY_KC_TIMEOUT_MS`),syncEnabled:e.kcSyncEnabled??mn(process.env.AIMAX_MEMORY_KC_SYNC_ENABLED,`AIMAX_MEMORY_KC_SYNC_ENABLED`)}}}function bn(e,t){return t?C.resolve(t):C.join(e,`.aimax`,`plugins.json`)}async function G(e,t){let n=bn(e,t);try{let e=await D.readFile(n,`utf-8`);return JSON.parse(e)}catch(e){if(e.code===`ENOENT`)return;throw e}}async function K(e,t,n){let r=bn(e,n);await D.mkdir(C.dirname(r),{recursive:!0}),await D.writeFile(r,JSON.stringify(t,null,2),`utf-8`)}function q(e){return typeof e==`object`&&!!e}function xn(e){return q(e)&&e.type===`text`&&typeof e.text==`string`&&(e.textSignature===void 0||typeof e.textSignature==`string`)}function Sn(e){return q(e)&&e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`}function Cn(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 wn(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 Tn(e){return typeof e==`string`||Array.isArray(e)&&e.every(e=>xn(e)||Sn(e))}function En(e){return Array.isArray(e)&&e.every(e=>xn(e)||Cn(e)||wn(e))}function Dn(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 On(e){return!q(e)||typeof e.role!=`string`?!1:e.role===`user`?Tn(e.content):e.role===`assistant`?En(e.content)&&typeof e.api==`string`&&typeof e.provider==`string`&&typeof e.model==`string`&&Dn(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=>xn(e)||Sn(e))&&typeof e.isError==`boolean`:!1}async function kn(e){let t;try{t=await D.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 An(n,`Message file`)}function An(e,t=`Messages input`){let n=Array.isArray(e)?e:[e];if(n.length===0||!n.every(e=>On(e)))throw Error(`${t} must contain one Message object or an array of Message objects`);return n}async function jn(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 kn(e.fromFile),source:`file`}:e.messages===void 0?{kind:`text`,message:e.message}:{kind:`messages`,messages:An(e.messages),source:`inline`}}var Mn=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()}))}},Nn=class{constructor(e){this.url=e}async send(e){await this.post(this.toPayload(e))}async close(){}async post(e){let t=Date.now(),n=Pn(e);F.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){F.error(`callback event failed`,{callbackUrl:this.url,httpStatus:a.status,durationMs:o,timedOut:i,...n});return}F.info(`callback event delivered`,{callbackUrl:this.url,httpStatus:a.status,durationMs:o,...n})}catch(e){let r=Date.now()-t;F.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 Pn(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 Fn(e,t){if(t.kind===`none`)return e;let n=new URL(e);return n.searchParams.set(`authToken`,t.token),n.toString()}const In=5e3,Ln=5e3;function Rn(){let e=globalThis.WebSocket;if(!e)throw Error(`WebSocket is not available in this runtime`);return e}function zn(e){return e?{kind:`query_token`,token:e}:{kind:`none`}}function Bn(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 Vn(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 Hn=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 Un(this.ensureConnected(),In,`WebSocket connection timed out after ${In}ms`);let e=Rn();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){F.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 Un(this.ensureConnected(),In,`WebSocket connection timed out after ${In}ms`);let e=Rn();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){F.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=Rn();if(e.readyState!==t.CLOSED)try{await Un(new Promise(t=>{Bn(e,`close`,()=>t()),e.close()}),Ln,`WebSocket close timed out after ${Ln}ms`)}catch(e){F.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=Rn();if(this.socket&&this.socket.readyState===e.OPEN)return;if(this.connectPromise){await this.connectPromise;return}let t=new e(Fn(this.url,zn(this.authToken)));this.connectPromise=new Promise((e,n)=>{Bn(t,`open`,()=>{this.socket=t,Vn(t,`close`,()=>{this.socket===t&&(this.socket=null)}),e()}),Bn(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 Un(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 Wn(e){let t=e.trim();if(!t)throw Error(`Goal objective cannot be empty`);return t}function Gn(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 Kn(e){let t=Gn(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 qn(e){let t=e?.packageRoot??Jn(),n=C.join(t,`models`),r=C.join(n,...`Xenova/bge-small-zh-v1.5`.split(`/`));if(x.existsSync(C.join(r,`config.json`)))return n}function Jn(){let e=C.dirname(Ne(import.meta.url));return C.basename(e)===`src`||C.basename(e)===`dist`?C.resolve(e,`..`):e}function Yn(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 Xn(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=Zn(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 Zn(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 Qn=[`start`,`text`,`done`,`error`,`hitl`],$n=[`off`,`gate`,`dry_run`,`write`];function er(e){if(!e?.trim())return new Set(Qn);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(Qn)}function tr(e){if(e.disableTopicSegmentation===!0||process.env.AIMAX_DISABLE_TOPIC_SEGMENTATION===`true`)return{enabled:!1};let t=qn();return t?{embeddingModelDir:t}:void 0}function nr(e){return e.disableTitle===!0||process.env.AIMAX_DISABLE_TITLE===`true`?{enabled:!1}:void 0}function rr(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir or AIMAX_DATA_DIR`);return t}function ir(e){return e?.trim()||void 0}function ar(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 or(e){return e?y(e):void 0}function sr(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 cr(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 lr(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if($n.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function ur(e){let t=e.autoSkillsLoadEnabled===void 0?cr(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):cr(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?lr(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):lr(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 dr(e,t){if(e.inputText&&t){let n=be(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 fr(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 pr(e){let t=await ie(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 mr(e){let t=rr(e),n=e.channel??`WEB`,r=dn({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:ar(e),channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,skillsLoadPaths:sr(e.skillsLoadPaths),artifactsUrlWhitelist:Xn(e.artifactsUrlWhitelist),autoSkills:ur(e)}}function hr(e){let t=[],n=null;return e.callbackUrl&&t.push(new Nn(e.callbackUrl)),e.streamUrl&&(n=new Hn(e.streamUrl,er(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new Mn(t),websocketSink:n}}async function gr(e){let{dataDir:t,sessionId:n,sessionStoreName:r,toolCallId:i,toolName:a,resolution:o,encryptSessions:s}=e;if(!i||!a||!ve(a))return;let c=(e,t)=>{switch(e){case`request_approval`:return d(t);case`clarify`:return f(t);case`request_review`:return p(t);default:return JSON.stringify({action:t.action,values:t.values})}};await ue(t,n,e=>{let t=e.findIndex(e=>e.role===`tool_result`&&e.toolCallId===i&&e.toolName===a);if(t===-1)return e;let n=e.slice(0,t+1);return n[t]={...n[t],content:c(a,o),isError:!1},n},{storeName:r,encryptSessions:s})}async function _r(e){let{dataDir:t,sessionId:n,sessionStoreName:r,result:i,encryptSessions:a}=e;await ue(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 vr(){let e=yn();return e?{core:e}:void 0}async function yr(e){let t=rr(e);await W(t,e,async()=>{P(t,{messageId:e.messageId,sessionId:e.sessionId,sessionStoreName:or(e.sessionStore)});let i=new dt(`resume command`),a=null;try{let t=await mr(e),o=or(e.sessionStore),c=null;if(e.goal||e.goalFile){let i;i=e.goalFile?await D.readFile(e.goalFile,`utf-8`):e.goal;let a=Wn(i),s=e.tokenBudget===void 0?void 0:e.tokenBudget===`0`||e.tokenBudget===``?null:Number(e.tokenBudget);s!=null&&(Number.isNaN(s)||s<=0)&&(L(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));try{let n=await b(t.dataDir,e.sessionId,{storeName:o}),i=await r({dataDir:t.dataDir,sessionId:e.sessionId,objective:a,tokenBudget:s,force:e.force,storeName:o});c=Kn({sessionId:e.sessionId,before:n,result:i})}catch(e){throw e instanceof n&&(L(e.message),L(`Existing: ${e.existingObjectivePreview}`),process.exit(2)),e}}F.info(`resume command started`,{sessionId:e.sessionId,requestId:e.requestId,channel:t.channel,dataDir:t.dataDir});let l=await ee(t.dataDir,e.sessionId,{storeName:o,encryptSessions:e.encryptSessions}),u=l?null:await te(t.dataDir,e.sessionId,{storeName:o,encryptSessions:e.encryptSessions});if(!l&&!u)throw Error(`No pending HITL or UI tool request found for session "${e.sessionId}"`);if(l){if(l.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${l.request.requestId}", got "${e.requestId}"`);if(l.status===`expired`)throw Error(`HITL request has expired`);if(l.status===`cancelled`)throw Error(`HITL request has been cancelled`)}else if(u){if(u.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${u.request.requestId}", got "${e.requestId}"`);if(u.status!==`pending`)throw Error(`UI tool request is already "${u.status}", cannot resume`)}if(l){let n=dr(e,l.request),r=await ce({dataDir:t.dataDir,sessionStoreName:o,sessionId:e.sessionId,requestId:e.requestId,resolution:n}),s=r.state;if(!s)throw Error(`Resolved HITL state was not persisted`);let u=br(n,s.request.kind);await gr({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:o,toolCallId:s.toolContext?.toolCallId,toolName:s.toolContext?.toolName,resolution:n,encryptSessions:e.encryptSessions});let d=hr(e);a=d.sink;let f=e.sessionId,p=async n=>{if(f=n.sessionId??f,!_e(n)){if(n.type===`stream_text_delta`){t.format===`text`&&R(n),await d.websocketSink?.sendTextDelta({sessionId:f,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}t.format===`text`&&R(n),await a?.send({sessionId:f,channel:t.channel,messageId:e.messageId,user:e.user,type:`progress`,event:n})}};c&&await p(c),await p({type:`hitl_resumed`,requestId:e.requestId,resolution:n,sessionId:e.sessionId}),`idempotentReplay`in r&&r.idempotentReplay&&(F.info(`resume command treated as idempotent replay`,{sessionId:e.sessionId,requestId:e.requestId,idempotencyKey:n.idempotencyKey}),vt({sessionId:e.sessionId,text:`Resume request already processed.`,usage:{input:0,output:0,total:0},durationMs:0},t.format),i.end(),process.exit(0));let m=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,h=await G(t.dataDir,m),g;try{g=await de({dataDir:t.dataDir,projectDir:ir(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:o,sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,artifactsUrlWhitelist:t.artifactsUrlWhitelist,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,message:u,encryptSessions:e.encryptSessions??!1,topicSegmentation:tr(e),titleGeneration:nr(e),memory:vr(),hitlResume:{request:s.request,resolution:n,checkpoint:s.checkpoint,toolContext:s.toolContext},plugins:h?{config:h,dataDir:t.dataDir,workspaceDir:C.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:h.llmAllowlist}:void 0,onProgress:p,onLog:ct})}finally{}g.error?await a?.send({sessionId:g.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`error`,message:g.error}):await a?.send({sessionId:g.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`done`,result:Yn(g)}),vt(g,t.format),g.error?F.error(`resume command failed: ${g.error}`):F.info(`resume command succeeded`),i.end(),process.exit(g.error?1:0);return}let d=fr(e,u);if(!await le(t.dataDir,e.sessionId,e.requestId,d,{storeName:o,encryptSessions:e.encryptSessions}))throw Error(`UI tool resume validation failed`);await _r({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:o,result:d,encryptSessions:e.encryptSessions});let f=hr(e);a=f.sink;let p=e.sessionId,m=async n=>{if(p=n.sessionId??p,!_e(n)){if(n.type===`stream_text_delta`){t.format===`text`&&R(n),await f.websocketSink?.sendTextDelta({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}if(t.format===`text`&&R(n),n.type===`start`){await a?.send({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,type:`start`,message:n.message});return}await a?.send({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,type:`progress`,event:n})}},h=await pr({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:o,toolCallId:d.toolCallId,toolName:d.toolName,encryptSessions:e.encryptSessions});c&&await m(c),await m({type:`tool_end`,sessionId:e.sessionId,toolCallId:d.toolCallId,name:d.toolName,input:h,output:JSON.stringify({submitted:!0,values:d.values}),isError:!1});let g=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,_=await G(t.dataDir,g),v=await de({dataDir:t.dataDir,projectDir:ir(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:o,sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,artifactsUrlWhitelist:t.artifactsUrlWhitelist,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,message:`[UI_TOOL_RESUME]
|
|
7
|
+
`,{mode:384});try{return await e(t)}finally{await D.rm(t,{force:!0})}}async function qt(e){let t=e.includes(`-init`)?`init`:`mount`;F.info(`--encrypt-sessions starting gocryptfs ${t}`);try{await tn(`gocryptfs`,e),F.info(`--encrypt-sessions completed gocryptfs ${t}`)}catch(n){let r=n instanceof Error?n.message:String(n);throw F.warn(`--encrypt-sessions failed gocryptfs ${t}`,{error:r}),Error(`gocryptfs ${e.join(` `)} failed: ${r}`)}}async function Jt(){F.info(`--encrypt-sessions checking encryption dependencies`),await rn(`gocryptfs`,`required for --encrypt-sessions`),F.info(`--encrypt-sessions dependency available`,{command:`gocryptfs`});for(let e of Dt)if(await nn(e)){F.info(`--encrypt-sessions unmount dependency available`,{command:e});return}throw Error(`--encrypt-sessions requires one of ${Dt.join(`, `)} to be installed for secure unmount cleanup.`)}async function Yt(e,t){F.info(`--encrypt-sessions mounting encrypted .aimax`,{encryptedDir:e,plainDir:t}),await Kt(async n=>{await qt([`-q`,`-passfile`,n,e,t])})}async function Xt(e){F.info(`--encrypt-sessions initializing encrypted .aimax directory`,{encryptedDir:e}),await Kt(async t=>{await qt([`-q`,`-init`,`-passfile`,t,e])})}async function Zt(e){let t=[];F.info(`--encrypt-sessions unmounting encrypted .aimax`,{plainDir:e});for(let n of Ot)try{if(F.info(`--encrypt-sessions attempting encrypted .aimax unmount`,{command:n.label,plainDir:e}),await tn(n.command,[...n.args,e]),!await z(e)){F.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),F.warn(`--encrypt-sessions unmount command returned success but mountpoint remains`,{command:n.label,plainDir:e})}catch(r){let i=an(n.label,r);t.push(i),F.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 Qt(e){for(let t of Ot)try{if(je(t.command,[...t.args,e],{stdio:`ignore`}),!Pt(e))return}catch{}}function $t(e){let t=!1,n=()=>{t||(t=!0,Qt(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 en(e){let t=kt(e),n=At(e),r=await B(n),i=await B(t),a=i&&await B(C.join(t,`gocryptfs.conf`)),o=r?await z(n):!1;F.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 Jt()}catch(e){return F.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 F.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 Ht(e),l.length>0&&F.warn(`--encrypt-sessions found interrupted pre-gocryptfs migration backups`,{count:l.length}),!await B(t))if(F.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 Ut(e,n):c=await Ut(e,n),await V(t),await Xt(t),await V(n),await Yt(t,n),f=!0,d=$t(n),F.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 D.rm(u,{recursive:!0,force:!0}),F.info(`--encrypt-sessions removed residual plaintext backup after migration`,{backupDir:u}),null);for(let e of l)await D.rm(e,{recursive:!0,force:!0}),F.info(`--encrypt-sessions removed resumed plaintext migration backup`,{backupDir:e});l=[]}else c&&=(await U(c,n,!0),await D.rm(c,{recursive:!0,force:!0}),F.info(`--encrypt-sessions removed plaintext migration backup`,{backupDir:c}),null);else if(F.info(`--encrypt-sessions encrypted .aimax directory exists; mounting existing encrypted data`,{encryptedDir:t,plainDir:n,resumedBackupCount:l.length,plainDirEntryCount:await H(n)}),await Vt(t),l.length>0?u=await Ut(e,n):await Rt(n)||(c=await Ut(e,n)),await Lt(n),await Yt(t,n),f=!0,d=$t(n),F.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 D.rm(u,{recursive:!0,force:!0}),F.info(`--encrypt-sessions removed residual plaintext backup after migration`,{backupDir:u}),null);for(let e of l)await D.rm(e,{recursive:!0,force:!0}),F.info(`--encrypt-sessions removed resumed plaintext migration backup`,{backupDir:e});l=[]}else c&&=(await U(c,n,!0),await D.rm(c,{recursive:!0,force:!0}),F.info(`--encrypt-sessions removed plaintext migration backup`,{backupDir:c}),null);return F.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){F.info(`--encrypt-sessions cleanup skipped because encrypted .aimax is not mounted`,{plainDir:n,encryptedDir:t});return}f=!1,F.info(`--encrypt-sessions cleanup started`,{plainDir:n,encryptedDir:t});try{await Zt(n),F.info(`--encrypt-sessions cleanup completed`,{plainDir:n,encryptedDir:t})}catch(e){F.warn(`--encrypt-sessions failed to unmount encrypted .aimax; continuing shutdown`,{error:e instanceof Error?e.message:String(e)})}}}}catch(e){d?.release(),f&&await Zt(n).catch(e=>{F.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 Rt(n)&&(await D.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await D.rename(c,n).catch(()=>{}),F.info(`--encrypt-sessions restored plaintext backup after failed migration`,{backupDir:c,plainDir:n})),u&&await B(u)&&await Rt(n)&&(await D.rm(n,{recursive:!0,force:!0}).catch(()=>{}),await D.rename(u,n).catch(()=>{}),F.info(`--encrypt-sessions restored residual plaintext backup after failed migration`,{backupDir:u,plainDir:n}));let r=await Wt(l,n).catch(e=>(F.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)),F.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 W(e,t,n){if(!t.encryptSessions)return await Gt(e),n();F.info(`--encrypt-sessions wrapper starting encrypted .aimax preparation`,{dataDir:e});let r=await en(e);F.info(`--encrypt-sessions wrapper prepared encrypted .aimax state`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir});try{return F.info(`--encrypt-sessions wrapper entering protected operation`,{dataDir:e,mounted:r.mounted}),await n(r)}finally{F.info(`--encrypt-sessions wrapper starting cleanup`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir}),await r.cleanup(),F.info(`--encrypt-sessions wrapper finished cleanup`,{dataDir:e,mounted:r.mounted,plainDir:r.plainDir,encryptedDir:r.encryptedDir})}}async function tn(e,t){await new Promise((n,r)=>{Ae(e,t,{encoding:`utf-8`},e=>{if(e){r(e);return}n()})})}async function nn(e){try{return await tn(`sh`,[`-c`,`command -v "${e}" >/dev/null 2>&1`]),!0}catch{return!1}}async function rn(e,t){if(!await nn(e))throw Error(`--encrypt-sessions requires ${e}: ${t}.`)}function an(e,t){return`${e} failed: ${t instanceof Error?t.message:String(t)}`}function on(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{St(await W(e.dataDir,e,async()=>i(e.dataDir)),t)}catch(e){L(`Error bootstrapping data directory: ${e.message}`),process.exit(1)}})}function sn(e){return Me.sm4_encrypt_ecb(e)}function cn(e){return sn(e)}const ln=[`minimal`,`low`,`medium`,`high`,`xhigh`];function un(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(ln.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of ${ln.join(`, `)}.`)}}function dn(e={}){let t=fn(e.apiFormat??process.env.AIMAX_API_FORMAT),n=e.baseUrl??process.env.AIMAX_BASE_URL,r=process.env.AIMAX_AUTH_TOKEN,i=e.authToken?cn(e.authToken):r?cn(r):e.apiKey??process.env.AIMAX_API_KEY,a=e.model??process.env.AIMAX_MODEL,o=[];if(n||o.push(`--base-url / AIMAX_BASE_URL`),i||o.push(`--api-key / AIMAX_API_KEY`),a||o.push(`--model / AIMAX_MODEL`),o.length>0)throw Error(`Missing required LLM configuration: ${o.join(`, `)}`);return{apiFormat:t,baseUrl:n,apiKey:i,model:a,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?un(process.env.AIMAX_THINKING,`AIMAX_THINKING`):un(e.thinking,`--thinking`)}}function fn(e){if(!e||e===`openai-completions`||e===`anthropic-messages`)return e;throw Error(`Unsupported LLM API format: ${e}`)}const pn=[`off`,`fallback`];function mn(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 hn(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 gn(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(pn.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of ${pn.join(`, `)}.`)}}function _n(){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 vn(e){return Object.values(e).some(e=>e!==void 0)}function yn(e={}){if(!(!vn(e)&&!_n()))return{knowledgeController:{enabled:e.kcEnabled??mn(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?gn(process.env.AIMAX_MEMORY_KC_SEARCH_MODE,`AIMAX_MEMORY_KC_SEARCH_MODE`)??`off`:gn(e.kcSearchMode,`kcSearchMode`),topK:e.kcTopK??hn(process.env.AIMAX_MEMORY_KC_TOP_K,`AIMAX_MEMORY_KC_TOP_K`),scoreThreshold:e.kcScoreThreshold??hn(process.env.AIMAX_MEMORY_KC_SCORE_THRESHOLD,`AIMAX_MEMORY_KC_SCORE_THRESHOLD`),timeoutMs:e.kcTimeoutMs??hn(process.env.AIMAX_MEMORY_KC_TIMEOUT_MS,`AIMAX_MEMORY_KC_TIMEOUT_MS`),syncEnabled:e.kcSyncEnabled??mn(process.env.AIMAX_MEMORY_KC_SYNC_ENABLED,`AIMAX_MEMORY_KC_SYNC_ENABLED`)}}}function bn(e,t){return t?C.resolve(t):C.join(e,`.aimax`,`plugins.json`)}async function G(e,t){let n=bn(e,t);try{let e=await D.readFile(n,`utf-8`);return JSON.parse(e)}catch(e){if(e.code===`ENOENT`)return;throw e}}async function K(e,t,n){let r=bn(e,n);await D.mkdir(C.dirname(r),{recursive:!0}),await D.writeFile(r,JSON.stringify(t,null,2),`utf-8`)}function q(e){return typeof e==`object`&&!!e}function xn(e){return q(e)&&e.type===`text`&&typeof e.text==`string`&&(e.textSignature===void 0||typeof e.textSignature==`string`)}function Sn(e){return q(e)&&e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`}function Cn(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 wn(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 Tn(e){return typeof e==`string`||Array.isArray(e)&&e.every(e=>xn(e)||Sn(e))}function En(e){return Array.isArray(e)&&e.every(e=>xn(e)||Cn(e)||wn(e))}function Dn(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 On(e){return!q(e)||typeof e.role!=`string`?!1:e.role===`user`?Tn(e.content):e.role===`assistant`?En(e.content)&&typeof e.api==`string`&&typeof e.provider==`string`&&typeof e.model==`string`&&Dn(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=>xn(e)||Sn(e))&&typeof e.isError==`boolean`:!1}async function kn(e){let t;try{t=await D.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 An(n,`Message file`)}function An(e,t=`Messages input`){let n=Array.isArray(e)?e:[e];if(n.length===0||!n.every(e=>On(e)))throw Error(`${t} must contain one Message object or an array of Message objects`);return n}async function jn(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 kn(e.fromFile),source:`file`}:e.messages===void 0?{kind:`text`,message:e.message}:{kind:`messages`,messages:An(e.messages),source:`inline`}}var Mn=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()}))}},Nn=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=Pn(e);F.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){F.error(`callback event failed`,{callbackUrl:this.url,httpStatus:a.status,durationMs:o,timedOut:i,...n});return}F.info(`callback event delivered`,{callbackUrl:this.url,httpStatus:a.status,durationMs:o,...n})}catch(e){let r=Date.now()-t;F.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 Pn(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 Fn(e,t){if(t.kind===`none`)return e;let n=new URL(e);return n.searchParams.set(`authToken`,t.token),n.toString()}const In=5e3,Ln=5e3;function Rn(){let e=globalThis.WebSocket;if(!e)throw Error(`WebSocket is not available in this runtime`);return e}function zn(e){return e?{kind:`query_token`,token:e}:{kind:`none`}}function Bn(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 Vn(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 Hn=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 Un(this.ensureConnected(),In,`WebSocket connection timed out after ${In}ms`);let e=Rn();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){F.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 Un(this.ensureConnected(),In,`WebSocket connection timed out after ${In}ms`);let e=Rn();if(!this.socket||this.socket.readyState!==e.OPEN)return;this.socket.send(JSON.stringify(t))}catch(e){F.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=Rn();if(e.readyState!==t.CLOSED)try{await Un(new Promise(t=>{Bn(e,`close`,()=>t()),e.close()}),Ln,`WebSocket close timed out after ${Ln}ms`)}catch(e){F.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=Rn();if(this.socket&&this.socket.readyState===e.OPEN)return;if(this.connectPromise){await this.connectPromise;return}let t=new e(Fn(this.url,zn(this.authToken)));this.connectPromise=new Promise((e,n)=>{Bn(t,`open`,()=>{this.socket=t,Vn(t,`close`,()=>{this.socket===t&&(this.socket=null)}),e()}),Bn(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 Un(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 Wn(e){let t=e.trim();if(!t)throw Error(`Goal objective cannot be empty`);return t}function Gn(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 Kn(e){let t=Gn(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 qn(e){let t=e?.packageRoot??Jn(),n=C.join(t,`models`),r=C.join(n,...`Xenova/bge-small-zh-v1.5`.split(`/`));if(x.existsSync(C.join(r,`config.json`)))return n}function Jn(){let e=C.dirname(Ne(import.meta.url));return C.basename(e)===`src`||C.basename(e)===`dist`?C.resolve(e,`..`):e}function Yn(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 Xn(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=Zn(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 Zn(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 Qn=[`start`,`text`,`done`,`error`,`hitl`],$n=[`off`,`gate`,`dry_run`,`write`];function er(e){if(!e?.trim())return new Set(Qn);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(Qn)}function tr(e){if(e.disableTopicSegmentation===!0||process.env.AIMAX_DISABLE_TOPIC_SEGMENTATION===`true`)return{enabled:!1};let t=qn();return t?{embeddingModelDir:t}:void 0}function nr(e){return e.disableTitle===!0||process.env.AIMAX_DISABLE_TITLE===`true`?{enabled:!1}:void 0}function rr(e){let t=e.dataDir??process.env.AIMAX_DATA_DIR;if(!t)throw Error(`Data directory must be specified via --data-dir or AIMAX_DATA_DIR`);return t}function ir(e){return e?.trim()||void 0}function ar(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 or(e){return e?y(e):void 0}function sr(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 cr(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 lr(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if($n.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function ur(e){let t=e.autoSkillsLoadEnabled===void 0?cr(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):cr(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?lr(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):lr(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 dr(e,t){if(e.inputText&&t){let n=be(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 fr(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 pr(e){let t=await ie(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 mr(e){let t=rr(e),n=e.channel??`WEB`,r=dn({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:ar(e),channel:n,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:r,skillsLoadPaths:sr(e.skillsLoadPaths),artifactsUrlWhitelist:Xn(e.artifactsUrlWhitelist),autoSkills:ur(e)}}function hr(e){let t=[],n=null;return e.callbackUrl&&t.push(new Nn(e.callbackUrl)),e.streamUrl&&(n=new Hn(e.streamUrl,er(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new Mn(t),websocketSink:n}}async function gr(e){let{dataDir:t,sessionId:n,sessionStoreName:r,toolCallId:i,toolName:a,resolution:o,encryptSessions:s}=e;if(!i||!a||!ve(a))return;let c=(e,t)=>{switch(e){case`request_approval`:return d(t);case`clarify`:return f(t);case`request_review`:return p(t);default:return JSON.stringify({action:t.action,values:t.values})}};await ue(t,n,e=>{let t=e.findIndex(e=>e.role===`tool_result`&&e.toolCallId===i&&e.toolName===a);if(t===-1)return e;let n=e.slice(0,t+1);return n[t]={...n[t],content:c(a,o),isError:!1},n},{storeName:r,encryptSessions:s})}async function _r(e){let{dataDir:t,sessionId:n,sessionStoreName:r,result:i,encryptSessions:a}=e;await ue(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 vr(){let e=yn();return e?{core:e}:void 0}async function yr(e){let t=rr(e);await W(t,e,async()=>{P(t,{messageId:e.messageId,sessionId:e.sessionId,sessionStoreName:or(e.sessionStore)});let i=new dt(`resume command`),a=null;try{let t=await mr(e),o=or(e.sessionStore),c=null;if(e.goal||e.goalFile){let i;i=e.goalFile?await D.readFile(e.goalFile,`utf-8`):e.goal;let a=Wn(i),s=e.tokenBudget===void 0?void 0:e.tokenBudget===`0`||e.tokenBudget===``?null:Number(e.tokenBudget);s!=null&&(Number.isNaN(s)||s<=0)&&(L(`error: --token-budget must be a positive integer, or 0 for unlimited`),process.exit(1));try{let n=await b(t.dataDir,e.sessionId,{storeName:o}),i=await r({dataDir:t.dataDir,sessionId:e.sessionId,objective:a,tokenBudget:s,force:e.force,storeName:o});c=Kn({sessionId:e.sessionId,before:n,result:i})}catch(e){throw e instanceof n&&(L(e.message),L(`Existing: ${e.existingObjectivePreview}`),process.exit(2)),e}}F.info(`resume command started`,{sessionId:e.sessionId,requestId:e.requestId,channel:t.channel,dataDir:t.dataDir});let l=await ee(t.dataDir,e.sessionId,{storeName:o,encryptSessions:e.encryptSessions}),u=l?null:await te(t.dataDir,e.sessionId,{storeName:o,encryptSessions:e.encryptSessions});if(!l&&!u)throw Error(`No pending HITL or UI tool request found for session "${e.sessionId}"`);if(l){if(l.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${l.request.requestId}", got "${e.requestId}"`);if(l.status===`expired`)throw Error(`HITL request has expired`);if(l.status===`cancelled`)throw Error(`HITL request has been cancelled`)}else if(u){if(u.request.requestId!==e.requestId)throw Error(`Request ID mismatch: pending is "${u.request.requestId}", got "${e.requestId}"`);if(u.status!==`pending`)throw Error(`UI tool request is already "${u.status}", cannot resume`)}if(l){let n=dr(e,l.request),r=await ce({dataDir:t.dataDir,sessionStoreName:o,sessionId:e.sessionId,requestId:e.requestId,resolution:n}),s=r.state;if(!s)throw Error(`Resolved HITL state was not persisted`);let u=br(n,s.request.kind);await gr({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:o,toolCallId:s.toolContext?.toolCallId,toolName:s.toolContext?.toolName,resolution:n,encryptSessions:e.encryptSessions});let d=hr(e);a=d.sink;let f=e.sessionId,p=async n=>{if(f=n.sessionId??f,!_e(n)){if(n.type===`stream_text_delta`){t.format===`text`&&R(n),await d.websocketSink?.sendTextDelta({sessionId:f,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}t.format===`text`&&R(n),await a?.send({sessionId:f,channel:t.channel,messageId:e.messageId,user:e.user,type:`progress`,event:n})}};c&&await p(c),await p({type:`hitl_resumed`,requestId:e.requestId,resolution:n,sessionId:e.sessionId}),`idempotentReplay`in r&&r.idempotentReplay&&(F.info(`resume command treated as idempotent replay`,{sessionId:e.sessionId,requestId:e.requestId,idempotencyKey:n.idempotencyKey}),vt({sessionId:e.sessionId,text:`Resume request already processed.`,usage:{input:0,output:0,total:0},durationMs:0},t.format),i.end(),process.exit(0));let m=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,h=await G(t.dataDir,m),g;try{g=await de({dataDir:t.dataDir,projectDir:ir(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:o,sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,artifactsUrlWhitelist:t.artifactsUrlWhitelist,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,message:u,encryptSessions:e.encryptSessions??!1,topicSegmentation:tr(e),titleGeneration:nr(e),memory:vr(),hitlResume:{request:s.request,resolution:n,checkpoint:s.checkpoint,toolContext:s.toolContext},plugins:h?{config:h,dataDir:t.dataDir,workspaceDir:C.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:h.llmAllowlist}:void 0,onProgress:p,onLog:ct})}finally{}g.error?await a?.send({sessionId:g.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`error`,message:g.error}):await a?.send({sessionId:g.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`done`,result:Yn(g)}),vt(g,t.format),g.error?F.error(`resume command failed: ${g.error}`):F.info(`resume command succeeded`),i.end(),process.exit(g.error?1:0);return}let d=fr(e,u);if(!await le(t.dataDir,e.sessionId,e.requestId,d,{storeName:o,encryptSessions:e.encryptSessions}))throw Error(`UI tool resume validation failed`);await _r({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:o,result:d,encryptSessions:e.encryptSessions});let f=hr(e);a=f.sink;let p=e.sessionId,m=async n=>{if(p=n.sessionId??p,!_e(n)){if(n.type===`stream_text_delta`){t.format===`text`&&R(n),await f.websocketSink?.sendTextDelta({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,text:n.text});return}if(t.format===`text`&&R(n),n.type===`start`){await a?.send({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,type:`start`,message:n.message});return}await a?.send({sessionId:p,channel:t.channel,messageId:e.messageId,user:e.user,type:`progress`,event:n})}},h=await pr({dataDir:t.dataDir,sessionId:e.sessionId,sessionStoreName:o,toolCallId:d.toolCallId,toolName:d.toolName,encryptSessions:e.encryptSessions});c&&await m(c),await m({type:`tool_end`,sessionId:e.sessionId,toolCallId:d.toolCallId,name:d.toolName,input:h,output:JSON.stringify({submitted:!0,values:d.values}),isError:!1});let g=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,_=await G(t.dataDir,g),v=await de({dataDir:t.dataDir,projectDir:ir(e.projectDir),systemAgentsDir:t.systemAgentsDir,sessionStoreName:o,sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,artifactsUrlWhitelist:t.artifactsUrlWhitelist,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,message:`[UI_TOOL_RESUME]
|
|
8
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:e.encryptSessions??!1,topicSegmentation:tr(e),titleGeneration:nr(e),memory:vr(),uiToolResume:d,plugins:_?{config:_,dataDir:t.dataDir,workspaceDir:C.join(t.dataDir,`workspace`),bundledDir:process.env.AIMAX_PLUGINS_BUNDLED_DIR,llmAllowlist:_.llmAllowlist}:void 0,onProgress:m,onLog:ct});await s(t.dataDir,e.sessionId,{storeName:o,encryptSessions:e.encryptSessions}),v.error?await a?.send({sessionId:v.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`error`,message:v.error}):await a?.send({sessionId:v.sessionId,channel:t.channel,messageId:e.messageId,user:e.user,type:`done`,result:Yn(v)}),vt(v,t.format),v.error?F.error(`resume command failed: ${v.error}`):F.info(`resume command succeeded`),i.end(),process.exit(v.error?1:0)}catch(t){let n=t;a&&(n.message.includes(`expired`)&&await a.send({sessionId:e.sessionId,channel:e.channel??`WEB`,messageId:e.messageId,user:e.user,type:`progress`,event:{type:`hitl_expired`,sessionId:e.sessionId,requestId:e.requestId,reason:n.message}}),n.message.includes(`cancelled`)&&await a.send({sessionId:e.sessionId,channel:e.channel??`WEB`,messageId:e.messageId,user:e.user,type:`progress`,event:{type:`hitl_cancelled`,sessionId:e.sessionId,requestId:e.requestId,reason:n.message}}),await a.send({sessionId:e.sessionId,channel:e.channel??`WEB`,messageId:e.messageId,user:e.user,type:`error`,message:`Resume failed: ${n.message}`})),F.error(`resume command error: ${n.message}`),L(`Fatal: ${n.message}`),i.end(),process.exit(1)}finally{await a?.close()}})}function br(e,t){return o(e,t)}function xr(e){e.command(`resume`).description(`Resume a paused HITL session with user input`).requiredOption(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--project-dir <path>`,`Current project directory used as the default cwd context`).option(`--system-agents-dir <path>`,`System agent definition directory (overrides AIMAX_SYSTEM_AGENTS_DIR, default: /aimax/agents)`).requiredOption(`-s, --session-id <id>`,`Session ID to resume`).option(`--session-store <name>`,`Session store directory under .aimax (default: sessions)`).requiredOption(`--request-id <id>`,`HITL request ID to resolve`).option(`--input-json <json>`,`JSON string with the resolution (action, values, etc.)`).option(`--input-text <text>`,`Plain text response for IM channels without rich UI (e.g. '同意', '拒绝')`).option(`--skillsLoadPaths <paths>`,`Comma-separated absolute skill load paths`).option(`--auto-skills-load-enabled <boolean>`,`Enable learned auto-skill loading for the main agent (overrides AIMAX_AUTO_SKILLS_LOAD_ENABLED)`).option(`--auto-skills-review-mode <mode>`,`Auto-skill review mode: off, gate, dry_run, or write (overrides AIMAX_AUTO_SKILLS_REVIEW_MODE)`).option(`--message-id <id>`,`Message ID for correlating events`).option(`--user <id>`,`User identifier propagated to external callback and stream payloads`).option(`-c, --channel <channel>`,`Channel name (default: WEB)`,`WEB`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-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)`).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 yr(e)})}function Sr(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 Cr=[`start`,`text`,`done`,`error`],wr=[`off`,`gate`,`dry_run`,`write`];function Tr(e){if(!e?.trim())return new Set(Cr);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(Cr)}function Er(e){if(e.disableTopicSegmentation===!0||process.env.AIMAX_DISABLE_TOPIC_SEGMENTATION===`true`)return{enabled:!1};let t=qn();return t?{embeddingModelDir:t}:void 0}function Dr(e){return e.disableTitle===!0||process.env.AIMAX_DISABLE_TITLE===`true`?{enabled:!1}:void 0}function Or(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 kr(e){return e?.trim()||void 0}function Ar(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 jr(e){return e?.trim()||void 0}function Mr(e){return e??`WEB`}function Nr(e){return e?y(e):void 0}function Pr(e,t){return e===`CRON`?`crons`:Nr(t)}function Fr(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 Ir(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 Lr(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 Rr(e){if(!e?.trim())return{};let t=[],n=new Set;for(let r of Lr(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,Ir(o)])}return Object.fromEntries(t)}function zr(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 Br(e,t){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(wr.includes(n))return n;throw Error(`Invalid ${t}: ${e}. Must be one of off,gate,dry_run,write.`)}}function Vr(e){let t=e.autoSkillsLoadEnabled===void 0?zr(process.env.AIMAX_AUTO_SKILLS_LOAD_ENABLED,`AIMAX_AUTO_SKILLS_LOAD_ENABLED`):zr(e.autoSkillsLoadEnabled,`--auto-skills-load-enabled`),n=e.autoSkillsReviewMode===void 0?Br(process.env.AIMAX_AUTO_SKILLS_REVIEW_MODE,`AIMAX_AUTO_SKILLS_REVIEW_MODE`):Br(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 Hr(e,t){return e.length<=t?e:t<=3?e.slice(0,t):`${e.slice(0,t-3)}...`}function Ur(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 Wr(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?` ${Hr(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=>Ur(e,a).map(e=>`│ ${e.padEnd(a,` `)} │`)),l].join(`
|
|
9
9
|
`)}function Gr(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 J(e,t=`-`){return e==null||e===``?t:String(e)}function Kr(e){return e?`set`:`unset`}function qr(e){return e?`true`:`false`}function Jr(e,t){let n=Pr(t.channel,e.sessionStore)??`sessions`,r=t.timeoutMs===void 0?`default`:`${t.timeoutMs}`,i=e.callbackUrl?`enabled`:`disabled`,a=e.streamUrl?`enabled`:`disabled`,o=Gr(t.input),s=t.input.kind===`text`?`inline`:e.fromFile??t.input.source,c=qe(),l=Er(e)?.enabled===!1?`disabled`:`enabled`,u=Dr(e)?.enabled===!1?`disabled`:`enabled`,d=e.pluginsConfig??process.env.AIMAX_PLUGINS_CONFIG,f=[...Tr(e.streamEvents)].join(`,`),p=t.autoSkills?.load?.enabled,m=t.autoSkills?.review?.mode,h=e.tokenBudget===`0`?`unlimited`:J(e.tokenBudget),g=t.artifactsUrlWhitelist?.join(`,`)??`-`,_=e.env?Object.keys(Rr(e.env)):[],v=_.length===0?`-`:`${_.length} key${_.length===1?``:`s`}`;return{banner:Wr(void 0,[`AIMax CLI`,`Stateless Agent Runner`]),contextBox:Wr(`Run Context`,[`time : ${c}`,`dataDir : ${t.dataDir}`,`projectDir : ${kr(e.projectDir)??`-`}`,`systemAgents : ${t.systemAgentsDir??`/aimax/agents`}`,`agent : ${jr(e.agent)??`-`}`,`channel : ${t.channel}`,`user : ${e.user??`-`}`,`message : ${e.message===void 0?`-`:`inline (${e.message.length} chars)`}`,`fromFile : ${J(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 : ${Kr(t.llm.apiKey)}`,`authToken : ${Kr(e.authToken)}`,`model : ${t.llm.model}`,`contextWindow: ${J(t.llm.contextWindow)}`,`flashModel : ${J(t.llm.flashModel)}`,`thinking : ${J(t.llm.thinking)}`,`callbackUrl : ${J(e.callbackUrl)}`,`streamUrl : ${J(e.streamUrl)}`,`streamAuth : ${Kr(e.streamAuthToken)}`,`streamEvents : ${f}`,`artifactUrls : ${g}`,`output : ${t.format}`,`callback : ${i}`,`websocket : ${a}`,`timeoutMs : ${r}`,`pluginsConfig: ${J(d)}`,`env : ${v}`,`goal : ${e.goal===void 0?`-`:`inline (${e.goal.length} chars)`}`,`goalFile : ${J(e.goalFile)}`,`tokenBudget : ${h}`,`force : ${qr(e.force)}`,`resumeReqId : ${J(e.resumeRequestId)}`,`resumeInput : ${e.resumeInputJson===void 0?`-`:`inline (${e.resumeInputJson.length} chars)`}`,`resumeFile : ${J(e.resumeFromFile)}`,`encryptSess : ${qr(e.encryptSessions)}`,`topicSegment : ${l}`,`titleGen : ${u}`]),logContext:{time:c,channel:t.channel,user:e.user,dataDir:t.dataDir,projectDir:kr(e.projectDir),systemAgentsDir:t.systemAgentsDir,agent:jr(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 Yr(e,t){let n=Or(e),r=Mr(e.channel),i=dn({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:Ar(e),channel:r,format:e.output===`json`?`json`:`text`,timeoutMs:e.timeout?Number(e.timeout):void 0,llm:i,input:t,skillsLoadPaths:Fr(e.skillsLoadPaths),artifactsUrlWhitelist:Xn(e.artifactsUrlWhitelist),autoSkills:Vr(e)}}function Xr(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
10
|
`)}async function Zr(e,t){if(!e.sessionId)return null;let n=Xr(t);if(!n)return null;let r=await ee(Or(e),e.sessionId,{storeName:Nr(e.sessionStore),encryptSessions:e.encryptSessions});return!r||r.status!==`pending`||!ye(n,r.request)?null:{requestId:r.request.requestId,inputText:n}}function Qr(e){let t=[],n=null;return e.callbackUrl&&t.push(new Nn(e.callbackUrl)),e.streamUrl&&(n=new Hn(e.streamUrl,Tr(e.streamEvents),e.streamAuthToken),t.push(n)),{sink:new Mn(t),websocketSink:n}}async function Y(e,t){F.info(`dispatching external event`,yi(t)),await e.sink.send(t)}function $r(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`){F.error(e.message,t);return}if(e.level===`warn`){F.warn(e.message,t);return}F.info(e.message,t)}function ei(e,t,n,r,i){return{sink:e,websocketSink:t,channel:n,defaultMessageId:r,user:i}}function ti(e){let t=new AbortController,n=n=>{F.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 ni(e){return{activeSessionId:e??`pending`,finalResult:null,loggerSessionId:void 0}}function ri(e,t,n,r){!r||n.loggerSessionId===r||(P(e,{messageId:t.messageId,sessionId:r,sessionStoreName:Pr(t.channel,t.sessionStore)}),n.loggerSessionId=r)}function ii(e,t){e.activeSessionId=t.sessionId??e.activeSessionId}function ai(e,t){return e.messageId??t}async function oi(e,t,n){if(!await m(e.dataDir)){if(await si(t,e.format,n.activeSessionId,e.dataDir,`checking`),(await l(e.dataDir)).performedBootstrap){await si(t,e.format,n.activeSessionId,e.dataDir,`initializing`),await si(t,e.format,n.activeSessionId,e.dataDir,`initialized`);return}await si(t,e.format,n.activeSessionId,e.dataDir,`ready`)}}async function si(e,t,n,r,i){let a={type:`bootstrap`,phase:i,dataDir:r};t===`text`&&R(a),await Y(e,{sessionId:n,channel:e.channel,messageId:e.defaultMessageId,user:e.user,type:`progress`,event:a})}function ci(e,t,n,r){return async i=>{if(ii(n,i),ri(e.dataDir,{...r,channel:e.channel},n,i.sessionId),_e(i)){$r(i);return}if(i.type===`stream_text_delta`){e.format===`text`&&R(i),await t.websocketSink?.sendTextDelta({sessionId:n.activeSessionId,channel:e.channel,messageId:ai(i,t.defaultMessageId),user:t.user,text:i.text});return}e.format===`text`&&R(i);let a=ai(i,t.defaultMessageId);if(i.type===`hitl_requested`){await Y(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:a,user:t.user,type:`hitl`,request:i.request}),await Y(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:a,user:t.user,type:`progress`,event:i});return}if(i.type===`start`){await Y(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:a,user:t.user,type:`start`,message:i.message});return}if(i.type===`session_reset`){await Y(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 Y(t,{sessionId:n.activeSessionId,channel:e.channel,messageId:a,user:t.user,type:`progress`,event:i})}}function li(e){let t=Sr(e);return{confirm:(e,n)=>t.confirm(e),select:(e,n,r)=>t.select?t.select(e,n):Promise.resolve(void 0)}}function ui(e,t,n,r,i,a){let o=yn(),s={dataDir:t.dataDir,projectDir:kr(e.projectDir),systemAgentsDir:t.systemAgentsDir,agentPolicy:jr(e.agent)?{requestedAgentName:jr(e.agent)}:void 0,sessionStoreName:Pr(t.channel,e.sessionStore),sessionId:e.sessionId,messageId:e.messageId,channel:t.channel,llm:t.llm,skillsLoadPaths:t.skillsLoadPaths,artifactsUrlWhitelist:t.artifactsUrlWhitelist,autoSkills:t.autoSkills,timeoutMs:t.timeoutMs,abortSignal:n.signal,pendingGoal:a,encryptSessions:e.encryptSessions??!1,topicSegmentation:Er(e),titleGeneration:Dr(e),env:Rr(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:ct,createPiExtensionDialogBridge:li};return t.input.kind===`messages`?{...s,messages:t.input.messages}:{...s,message:t.input.message}}async function di(e,t,n,r){if(t.activeSessionId=r.sessionId,t.finalResult=r,r.error){await Y(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:r.error});return}await Y(e,{sessionId:r.sessionId,channel:e.channel,messageId:n,user:e.user,type:`done`,result:Yn(r)})}async function fi(e,t,n,r){await Y(e,{sessionId:t.finalResult?.sessionId??t.activeSessionId,channel:e.channel,messageId:n,user:e.user,type:`error`,message:`Fatal: ${r.message}`})}function pi(e,t){let n=Jr(e,t);F.info([`run command started`,n.banner,n.contextBox].join(`
|
|
@@ -14,7 +14,7 @@ The pending UI tool result has been written into the transcript. Continue from t
|
|
|
14
14
|
`):[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(`
|
|
15
15
|
`)}function ma(e){e.command(`summarize`).description(`Summarize one absolute file path or inline content`).option(`--file-path <path>`,`Absolute file path to summarize`).option(`--content <text>`,`Inline text content to summarize when --file-path is not provided`).option(`--query <text>`,`Optional search target or current description to focus the summary`).option(`-d, --data-dir <path>`,`Data directory path (overrides AIMAX_DATA_DIR)`).option(`--base-url <url>`,`LLM API base URL (overrides AIMAX_BASE_URL)`).option(`--api-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)`).option(`--model <name>`,`LLM model name (overrides AIMAX_MODEL)`).option(`--timeout <ms>`,`Execution timeout in milliseconds`).option(`--max-tokens <number>`,`Maximum number of tokens for model output`).option(`--message-id <id>`,`Message ID for log correlation`).action(async e=>{await fa(e)})}const ha={accent:`#8abeb7`,border:`#5f87ff`,borderAccent:`#00d7ff`,borderMuted:`#505050`,success:`#b5bd68`,error:`#cc6666`,warning:`#ffff00`,muted:`#808080`,dim:`#666666`,text:`#d4d4d4`,thinkingText:`#808080`,selectedBg:`#3a3a4a`,userMessageBg:`#343541`,userMessageText:`#d4d4d4`,customMessageBg:`#2d2838`,customMessageText:`#d4d4d4`,customMessageLabel:`#9575cd`,toolPendingBg:`#282832`,toolSuccessBg:`#283228`,toolErrorBg:`#3c2828`,toolTitle:`#d4d4d4`,toolOutput:`#808080`,mdHeading:`#f0c674`,mdLink:`#81a2be`,mdLinkUrl:`#666666`,mdCode:`#8abeb7`,mdCodeBlock:`#b5bd68`,mdCodeBlockBorder:`#808080`,mdQuote:`#808080`,mdQuoteBorder:`#808080`,mdHr:`#808080`,mdListBullet:`#8abeb7`,toolDiffAdded:`#b5bd68`,toolDiffRemoved:`#cc6666`,toolDiffContext:`#808080`,syntaxComment:`#6A9955`,syntaxKeyword:`#569CD6`,syntaxFunction:`#DCDCAA`,syntaxVariable:`#9CDCFE`,syntaxString:`#CE9178`,syntaxNumber:`#B5CEA8`,syntaxType:`#4EC9B0`,syntaxOperator:`#D4D4D4`,syntaxPunctuation:`#D4D4D4`,thinkingOff:`#505050`,thinkingMinimal:`#6e6e6e`,thinkingLow:`#5f87af`,thinkingMedium:`#81a2be`,thinkingHigh:`#b294bb`,thinkingXhigh:`#d183e8`,bashMode:`#b5bd68`},ga=`#18181e`,_a=`#1e1e24`,va=`#3c3728`;function ya(e){if(!e||typeof e!=`object`)return!1;let t=e.role;return t===`user`||t===`assistant`||t===`tool_result`||t===`compaction`}function ba(e){return!e||typeof e!=`object`?!1:typeof e.type==`string`}function xa(e){return{type:`text`,text:e}}function Sa(e){return{type:`thinking`,thinking:e}}function Ca(e,t){let n=e.timestamp,r=typeof n==`string`&&n?n:e.content;return`${e.role}\0${r}\0${t}`}function wa(e,t,n){let r=Ca(e,t);for(let e=0;e<100;e++){let t=We(`sha256`).update(`${r}\0${e}`).digest(`hex`).slice(0,8);if(!n.has(t))return n.add(t),t}let i=We(`sha256`).update(`${r}\0fallback`).digest(`hex`);return n.add(i),i}function Ta(e,t){let n=new Set,r=null,i=[],a={type:`session`,version:3,id:t?.sessionId??Ge(),timestamp:e.find(e=>e.timestamp)?.timestamp??new Date().toISOString(),cwd:t?.cwd??process.cwd()};for(let[t,a]of e.entries()){let e=wa(a,t,n),o={id:e,parentId:r,timestamp:a.timestamp};if(a.role===`user`)i.push({type:`message`,...o,message:{role:`user`,content:[xa(a.content)]}});else if(a.role===`assistant`){let e=[];a.thinking?.trim()&&e.push(Sa(a.thinking.trim())),a.content.trim()&&e.push(xa(a.content));for(let t of a.toolCalls??[])e.push({type:`toolCall`,id:t.id,name:t.name,arguments:t.arguments});a.errorMessage&&e.push(xa(a.errorMessage)),i.push({type:`message`,...o,message:{role:`assistant`,content:e,...a.stopReason?{stopReason:a.stopReason}:{}}})}else if(a.role===`tool_result`){let e=a.content;a.toolResultRef?.preview&&!e.includes(a.toolResultRef.preview)&&(e=`${e}\n\nPreview:\n${a.toolResultRef.preview}`),a.toolResultRef?.storagePath&&(e=`${e}\n\n[Full output: ${a.toolResultRef.storagePath}]`),i.push({type:`message`,...o,message:{role:`toolResult`,toolCallId:a.toolCallId,toolName:a.toolName,content:[xa(e)],isError:a.isError}})}else a.role===`compaction`&&i.push({type:`compaction`,...o,summary:a.content,firstKeptEntryId:r??e,tokensBefore:0});r=e}return{header:a,entries:i,leafId:r}}function Ea(e,t){let n=e.trim().split(`
|
|
16
16
|
`).filter(e=>e.trim()),r=[],i=0;for(let e of n)try{r.push(JSON.parse(e))}catch{i+=1}if(r.length===0)return{data:Ta([],t),skippedLines:i};let a=r[0];if(ba(a)&&a.type===`session`){let e=a,t=r.slice(1).filter(ba);return{data:{header:e,entries:t,leafId:t.length>0?t[t.length-1].id:null},skippedLines:i}}if(r.every(ba)){let e=r;return{data:{header:{type:`session`,version:3,id:t?.sessionId??Ge(),timestamp:e[0]?.timestamp??new Date().toISOString(),cwd:t?.cwd??process.cwd()},entries:e,leafId:e.length>0?e[e.length-1].id:null},skippedLines:i}}return{data:Ta(r.filter(ya),t),skippedLines:i}}function Da(e){let t=e;for(;t!==w(t);){if(S(T(t,`package.json`)))return t;t=w(t)}throw Error(`Could not find @gencode/cli package root`)}function Oa(){let e=Da(w(Ne(import.meta.url))),t=[T(e,`dist`,`export-html`),T(e,`src`,`export-html`)];for(let e of t)if(S(T(e,`template.html`)))return e;throw Error(`export-html template directory not found under ${e}`)}function ka(e){let t=C.resolve(e),n=`${C.sep}.aimax${C.sep}`,r=t.indexOf(n);if(!(r<0))return t.slice(0,r)}function Aa(e){let t=C.dirname(C.resolve(e));return C.basename(t)}async function ja(e){let t=e.dataDir??(e.transcriptPath?ka(e.transcriptPath):void 0),n=e.sessionId??(e.transcriptPath?Aa(e.transcriptPath):void 0);return!t||!n?{}:ne(t,n,e.sessionPathOptions)}const Ma=new Map;function Na(e){let t=Ma.get(e);if(t!==void 0)return t;let n=Se(T(Oa(),e),`utf-8`);return Ma.set(e,n),n}function Pa(){let e=[];for(let[t,n]of Object.entries(ha))e.push(`--${t}: ${n};`);return e.push(`--exportPageBg: ${ga};`),e.push(`--exportCardBg: ${_a};`),e.push(`--exportInfoBg: ${va};`),e.join(`
|
|
17
|
-
`)}function Fa(e){return e.replace(/[&<>"']/g,e=>{switch(e){case`&`:return`&`;case`<`:return`<`;case`>`:return`>`;case`"`:return`"`;case`'`:return`'`;default:return e}})}function Ia(e){let t=Na(`template.html`),n=Na(`template.css`),r=Na(`template.js`),i=Buffer.from(JSON.stringify(e)).toString(`base64`),a=n.replace(`{{THEME_VARS}}`,Pa()).replace(`{{BODY_BG}}`,ga).replace(`{{CONTAINER_BG}}`,_a).replace(`{{INFO_BG}}`,va);return t.replace(`{{CSS}}`,a).replace(`{{JS}}`,r).replace(`{{SESSION_DATA}}`,i)}function La(e,t){return t||`aimax-session-${Te(e,`.jsonl`)}.html`}function Ra(e,t){return`Skipped ${t} malformed JSONL line(s) while exporting ${e}`}function za(e){for(let t of e)console.warn(t)}function Ba(e){return e.replace(/\\/g,`/`)}function Va(e){return e.replace(/[|\\{}()[\]^$+?.]/g,`\\$&`)}function Ha(e){let t=Ba(e),n=`^`;for(let e=0;e<t.length;e+=1){let r=t[e],i=t[e+1];if(r===`*`){i===`*`?t[e+2]===`/`?(n+=`(?:.*\\/)?`,e+=2):(n+=`.*`,e+=1):n+=`[^/]*`;continue}if(r===`?`){n+=`[^/]`;continue}n+=Va(r)}return n+=`$`,new RegExp(n)}function Ua(e){return/[*?[]/.test(e)}function Wa(e,t){let n=Ba(Ee(e)?E(e):E(t,e)).split(`/`),r=[];for(let e of n){if(Ua(e))break;r.push(e)}return E(r.join(`/`)||`/`)}async function Ga(e){let t;try{t=await D.readdir(e,{withFileTypes:!0})}catch(e){let t=e.code;if(t===`ENOENT`||t===`ENOTDIR`)return[];throw e}let n=[];for(let r of t){let t=T(e,r.name);if(r.isDirectory()){n.push(...await Ga(t));continue}r.isFile()&&n.push(t)}return n}async function Ka(e,t,n){let r=[];for await(let i of e(t,{cwd:n}))r.push(i);return r}async function qa(e,t){let n=E(t),r=Ee(e),i=Ha(Ba(r?E(e):e));return(await Ga(Wa(e,n))).map(e=>({file:e,candidate:Ba(r?E(e):De(n,e))})).filter(({candidate:e})=>i.test(e)).map(({file:e})=>r?E(e):Ba(De(n,e)))}async function Ja(e,t){let n=D.glob;return typeof n==`function`?Ka(n,e,t):qa(e,t)}async function Ya(e,t){if(t.options?.includeSnapshots===!1)return e;let n=await ja({dataDir:t.options?.dataDir,sessionId:t.options?.sessionId??e.header.id,transcriptPath:t.inputLabel,sessionPathOptions:t.options?.sessionPathOptions});return
|
|
17
|
+
`)}function Fa(e){return e.replace(/[&<>"']/g,e=>{switch(e){case`&`:return`&`;case`<`:return`<`;case`>`:return`>`;case`"`:return`"`;case`'`:return`'`;default:return e}})}function Ia(e){let t=Na(`template.html`),n=Na(`template.css`),r=Na(`template.js`),i=Buffer.from(JSON.stringify(e)).toString(`base64`),a=n.replace(`{{THEME_VARS}}`,Pa()).replace(`{{BODY_BG}}`,ga).replace(`{{CONTAINER_BG}}`,_a).replace(`{{INFO_BG}}`,va);return t.replace(`{{CSS}}`,a).replace(`{{JS}}`,r).replace(`{{SESSION_DATA}}`,i)}function La(e,t){return t||`aimax-session-${Te(e,`.jsonl`)}.html`}function Ra(e,t){return`Skipped ${t} malformed JSONL line(s) while exporting ${e}`}function za(e){for(let t of e)console.warn(t)}function Ba(e){return e.replace(/\\/g,`/`)}function Va(e){return e.replace(/[|\\{}()[\]^$+?.]/g,`\\$&`)}function Ha(e){let t=Ba(e),n=`^`;for(let e=0;e<t.length;e+=1){let r=t[e],i=t[e+1];if(r===`*`){i===`*`?t[e+2]===`/`?(n+=`(?:.*\\/)?`,e+=2):(n+=`.*`,e+=1):n+=`[^/]*`;continue}if(r===`?`){n+=`[^/]`;continue}n+=Va(r)}return n+=`$`,new RegExp(n)}function Ua(e){return/[*?[]/.test(e)}function Wa(e,t){let n=Ba(Ee(e)?E(e):E(t,e)).split(`/`),r=[];for(let e of n){if(Ua(e))break;r.push(e)}return E(r.join(`/`)||`/`)}async function Ga(e){let t;try{t=await D.readdir(e,{withFileTypes:!0})}catch(e){let t=e.code;if(t===`ENOENT`||t===`ENOTDIR`)return[];throw e}let n=[];for(let r of t){let t=T(e,r.name);if(r.isDirectory()){n.push(...await Ga(t));continue}r.isFile()&&n.push(t)}return n}async function Ka(e,t,n){let r=[];for await(let i of e(t,{cwd:n}))r.push(i);return r}async function qa(e,t){let n=E(t),r=Ee(e),i=Ha(Ba(r?E(e):e));return(await Ga(Wa(e,n))).map(e=>({file:e,candidate:Ba(r?E(e):De(n,e))})).filter(({candidate:e})=>i.test(e)).map(({file:e})=>r?E(e):Ba(De(n,e)))}async function Ja(e,t){let n=D.glob;return typeof n==`function`?Ka(n,e,t):qa(e,t)}async function Ya(e,t){if(t.options?.includeSnapshots===!1)return e;let n=await ja({dataDir:t.options?.dataDir,sessionId:t.options?.sessionId??e.header.id,transcriptPath:t.inputLabel,sessionPathOptions:t.options?.sessionPathOptions});return n.tools?.length?{...e,tools:n.tools}:e}async function Xa(e,t,n){let r=Ea(e,{sessionId:n?.sessionId,cwd:n?.cwd}),i=r.skippedLines>0?[Ra(t,r.skippedLines)]:[],a=r.data;a=await Ya(a,{inputLabel:t,options:n});let o=Ia(a),s=La(t,n?.outputPath);return we(s,o,`utf8`),{outputPath:s,warnings:i}}async function Za(e,t){if(!S(e))throw Error(`File not found: ${e}`);return Xa(Se(e,`utf-8`),e,t)}async function Qa(e,t){let n=await Za(e,t);return za(n.warnings),n.outputPath}async function $a(e,t,n){let r=pe(e,t,n);if(!S(r))throw Error(`Transcript not found: ${r}`);if((await ie(e,t,n)).length===0&&!Se(r,`utf-8`).trim())throw Error(`Nothing to export yet - transcript is empty`);let i=Se(r,`utf-8`),{outputPath:a,sessionId:o,cwd:s,dataDir:c,includeSnapshots:l,...u}=n??{};return Xa(i,r,{outputPath:n?.outputPath,sessionId:t,cwd:n?.cwd,dataDir:e,sessionPathOptions:u,includeSnapshots:n?.includeSnapshots})}async function eo(e,t,n){let r=await $a(e,t,n);return za(r.warnings),r.outputPath}function to(e,t){let n=t.map(t=>{let n=S(T(e,t.fileName))?Ce(T(e,t.fileName)):void 0,r=n?`${Math.round(n.size/1024)} KB`:``,i=t.sourcePath?`<span class="muted">${Fa(t.sourcePath)}</span>`:``;return`<tr><td><a href="${Fa(t.fileName)}">${Fa(t.sessionId)}</a></td><td>${r}</td><td>${i}</td></tr>`}).join(`
|
|
18
18
|
`),r=`<!DOCTYPE html>
|
|
19
19
|
<html lang="zh-CN">
|
|
20
20
|
<head>
|
package/dist/program.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,t}from"./program-
|
|
1
|
+
import{n as e,t}from"./program-Bd8KnLF6.js";export{t as createProgram,e as getDataDir};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gencode/cli",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"aimax": "./dist/bin.js"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"commander": "^14.0.3",
|
|
29
29
|
"gensign-node": "latest",
|
|
30
30
|
"log4js": "^6.9.1",
|
|
31
|
-
"@gencode/agents": "0.17.
|
|
31
|
+
"@gencode/agents": "0.17.1",
|
|
32
32
|
"@gencode/shared": "0.5.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|