quantex-cli 0.0.1-beta.6 → 0.0.1-beta.8

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/README.md CHANGED
@@ -56,6 +56,16 @@ quantex u claude
56
56
  quantex update --all
57
57
  ```
58
58
 
59
+ `quantex update --all` 会优先使用 Quantex 记录的安装来源进行批量更新:
60
+
61
+ - 通过 Bun 安装的 agent 会合并为一条 `bun update -g ...`
62
+ - 通过 npm 安装的 agent 会合并为一条 `npm update -g ...`
63
+ - 通过 Homebrew 安装的 agent 会按记录的 formula/cask 标识逐个更新
64
+ - 通过 winget 安装的 agent 会按 `winget` 记录的包 ID 逐个更新
65
+ - 通过脚本、直装二进制或仅在 PATH 中探测到的 agent 不会被自动更新
66
+
67
+ 这意味着混合安装场景仍然安全,不会把通过其他方式安装的 agent 错误地塞进 Bun、npm、brew 或 winget 的更新命令;对非托管来源,Quantex 会明确提示需要手动更新。
68
+
59
69
  ### 卸载 Agent
60
70
 
61
71
  ```bash
@@ -70,12 +80,27 @@ quantex list
70
80
  quantex ls
71
81
  ```
72
82
 
83
+ `list` 会显示每个 agent 的安装状态、当前版本、是否支持托管更新,以及安装来源。例如:
84
+
85
+ - `managed update` 表示 Quantex 能按记录的安装器执行更新
86
+ - `manual update` 表示当前来源不支持自动更新
87
+ - `managed via bun (...)`、`managed via brew (...)` 表示有明确的来源记录
88
+ - `detected in PATH` 表示命令存在,但不是由当前 Quantex 状态文件追踪到的安装
89
+
73
90
  ### 查看 Agent 详情
74
91
 
75
92
  ```bash
76
93
  quantex info claude
77
94
  ```
78
95
 
96
+ `info` 会按当前平台列出安装方式,并明确区分:
97
+
98
+ - `managed/<installer>`,例如 `managed/bun`、`managed/brew`
99
+ - `unmanaged/script`,例如 `curl | bash`、`irm | iex`
100
+ - `unmanaged/binary`,保留给未来真正的二进制直装场景
101
+
102
+ 如果 agent 已安装,`info` 还会显示当前记录的 `Source` 和 `Lifecycle`。
103
+
79
104
  ### 快捷启动 Agent
80
105
 
81
106
  ```bash
@@ -111,6 +136,13 @@ quantex config reset
111
136
  quantex doctor
112
137
  ```
113
138
 
139
+ `doctor` 会检查:
140
+
141
+ - `bun`、`npm`、`brew`、`winget` 这些托管安装器是否可用
142
+ - 已安装 agent 的版本状态
143
+ - 已安装 agent 的生命周期和来源,例如 `managed; managed via bun (...)`
144
+ - 当前环境是否缺少任何可用于托管安装/更新的安装器
145
+
114
146
  ## 配置
115
147
 
116
148
  配置文件位于 `~/.quantex/config.json`,支持以下配置项:
@@ -121,6 +153,34 @@ quantex doctor
121
153
  }
122
154
  ```
123
155
 
156
+ `defaultPackageManager` 会影响托管安装方式的尝试顺序。比如某个 agent 同时支持 Bun 和 npm 时,设置为 `npm` 后,Quantex 会先尝试 npm,再按 agent 定义中的其余安装方式顺序回退。
157
+
158
+ 这里的 `defaultPackageManager` 只影响托管安装器的选择顺序,不影响 `script` / `binary` 这类非托管安装方式。
159
+
160
+ ## 状态文件
161
+
162
+ 除了配置文件外,Quantex 还会在 `~/.quantex/state.json` 中记录运行时状态,例如 agent 的实际安装来源。
163
+
164
+ 当前安装来源会区分为:
165
+
166
+ - 托管安装器:`bun`、`npm`、`brew`、`winget`
167
+ - 非托管安装:`script`
168
+ - 预留类型:`binary`
169
+
170
+ 这个状态文件主要用于:
171
+
172
+ - 让 `update --all` 先生成更新计划,再按 Bun、npm、brew、winget 分组执行
173
+ - 在混合安装场景下避免误用错误的更新方式
174
+ - 支撑 `list`、`info`、`doctor` 输出安装来源和是否可托管更新
175
+ - 为后续的卸载、诊断和迁移能力保留扩展空间
176
+
177
+ 术语约定:
178
+
179
+ - `packages.npm` 指 agent 对应的 npm 包名
180
+ - 安装方法里的 `packageName` 指安装器专用标识;对 npm/bun 是包名,对 Homebrew 是 formula/cask 标识,对 winget 是 package ID
181
+
182
+ 如果某个 agent 是在旧版本 Quantex 中安装的,或者不是通过 Quantex 安装的,首次更新时可能仍会走逐个更新;一旦 Quantex 成功更新并记录来源,后续 `update --all` 就可以复用批量更新路径。
183
+
124
184
  ## 开发
125
185
 
126
186
  ```bash
@@ -0,0 +1,3 @@
1
+ import{r as e,t}from"./config-DvtBCQbQ.mjs";import{mkdir as n}from"node:fs/promises";import{join as r}from"node:path";import i from"node:process";function a(e){return{packageName:e,type:`bun`}}function o(e){return{packageName:e,type:`npm`}}function s(e,t){return{packageName:e,packageTargetKind:t,type:`brew`}}function ee(e){return{packageName:e,packageTargetKind:`id`,type:`winget`}}function c(e){return{command:e,type:`script`}}const l={name:`claude`,displayName:`Claude Code`,description:`Anthropic 官方 AI 编程助手 CLI`,homepage:`https://code.claude.com/docs`,packages:{npm:`@anthropic-ai/claude-code`},binaryName:`claude`,platforms:{windows:[a(),o(),c(`irm https://claude.ai/install.ps1 | iex`),ee(`Anthropic.ClaudeCode`)],macos:[a(),o(),c(`curl -fsSL https://claude.ai/install.sh | bash`),s(`claude-code`,`cask`)],linux:[a(),o(),c(`curl -fsSL https://claude.ai/install.sh | bash`),s(`claude-code`,`cask`)]}},u={name:`codex`,displayName:`Codex CLI`,description:`OpenAI 官方 AI 编程助手 CLI`,homepage:`https://developers.openai.com/codex`,packages:{npm:`@openai/codex`},binaryName:`codex`,platforms:{windows:[a(),o()],macos:[a(),o(),s(`codex`)],linux:[a(),o(),s(`codex`)]}},d={name:`copilot`,displayName:`GitHub Copilot CLI`,description:`GitHub Copilot 命令行工具`,homepage:`https://github.com/features/copilot/cli`,packages:{npm:`@github/copilot`},binaryName:`copilot`,platforms:{windows:[ee(`GitHub.Copilot`)],macos:[a(),o(),c(`curl -fsSL https://gh.io/copilot-install | bash`),s(`copilot-cli`)],linux:[a(),o(),c(`curl -fsSL https://gh.io/copilot-install | bash`),s(`copilot-cli`)]}},te={name:`cursor`,lookupAliases:[`agent`],displayName:`Cursor CLI`,description:`Cursor AI 编程助手命令行工具`,homepage:`https://cursor.com/docs/cli`,binaryName:`agent`,platforms:{windows:[c(`irm 'https://cursor.com/install?win32=true' | iex`)],macos:[c(`curl https://cursor.com/install -fsS | bash`)],linux:[c(`curl https://cursor.com/install -fsS | bash`)]}},f={name:`droid`,displayName:`Droid`,description:`Factory AI 软件工程 Agent CLI`,homepage:`https://docs.factory.ai/cli/getting-started/overview`,packages:{npm:`droid`},binaryName:`droid`,platforms:{windows:[a(),o(),c(`irm https://app.factory.ai/cli/windows | iex`)],macos:[a(),o(),c(`curl -fsSL https://app.factory.ai/cli | sh`),s(`droid`,`cask`)],linux:[a(),o(),c(`curl -fsSL https://app.factory.ai/cli | sh`),s(`droid`,`cask`)]}},p={name:`gemini`,displayName:`Gemini CLI`,description:`Google 开源 AI 编程助手 CLI`,homepage:`https://geminicli.com`,packages:{npm:`@google/gemini-cli`},binaryName:`gemini`,platforms:{windows:[a(),o()],macos:[a(),o(),s(`gemini-cli`)],linux:[a(),o(),s(`gemini-cli`)]}},m={name:`opencode`,displayName:`OpenCode`,description:`开源 AI 编程 CLI`,homepage:`https://opencode.ai`,packages:{npm:`opencode-ai`},binaryName:`opencode`,platforms:{windows:[a(),o()],macos:[a(),o(),c(`curl -fsSL https://opencode.ai/install | bash`),s(`anomalyco/tap/opencode`)],linux:[a(),o(),c(`curl -fsSL https://opencode.ai/install | bash`),s(`anomalyco/tap/opencode`)]}},h={name:`pi`,displayName:`Pi`,description:`极简可扩展的终端编程 Agent`,homepage:`https://pi.dev`,packages:{npm:`@mariozechner/pi-coding-agent`},binaryName:`pi`,platforms:{windows:[a(),o()],macos:[a(),o()],linux:[a(),o()]}},g=[l,u,d,te,f,p,m,h];function _(){return g}function v(e){return g.find(t=>t.name===e||(t.lookupAliases?.includes(e)??!1))}function y(e){return v(e)}const ne={installedAgents:{}};function b(){return r(t(),`state.json`)}async function x(){try{return{installedAgents:(await Bun.file(b()).json()).installedAgents??{}}}catch{return{...ne}}}async function S(e){await n(t(),{recursive:!0}),await Bun.write(b(),`${JSON.stringify(e,null,2)}\n`)}async function C(e){return(await x()).installedAgents[e]}async function w(e){let t=await x();t.installedAgents[e.agentName]=e,await S(t)}async function T(e){let t=await x();delete t.installedAgents[e],await S(t)}function E(){switch(i.platform){case`win32`:return`windows`;case`darwin`:return`macos`;default:return`linux`}}async function D(e){try{let t=Bun.spawn([e,`--version`],{stdout:`pipe`,stderr:`pipe`});return await t.exited,t.exitCode===0}catch{return!1}}async function O(){return D(`bun`)}async function k(){return D(`npm`)}async function A(){return D(`brew`)}async function j(){return D(`winget`)}async function M(e){try{let t=i.platform===`win32`?`where`:`which`,n=Bun.spawn([t,e],{stdout:`pipe`,stderr:`pipe`});return await n.exited,n.exitCode===0}catch{return!1}}const re={binary:{canInstall:!0,canLookupLatestVersion:!1,canUninstall:!1,canUpdate:!1,lifecycle:`unmanaged`},brew:{canInstall:!0,canLookupLatestVersion:!1,canUninstall:!0,canUpdate:!0,lifecycle:`managed`},bun:{canInstall:!0,canLookupLatestVersion:!0,canUninstall:!0,canUpdate:!0,lifecycle:`managed`},npm:{canInstall:!0,canLookupLatestVersion:!0,canUninstall:!0,canUpdate:!0,lifecycle:`managed`},script:{canInstall:!0,canLookupLatestVersion:!1,canUninstall:!1,canUpdate:!1,lifecycle:`unmanaged`},winget:{canInstall:!0,canLookupLatestVersion:!1,canUninstall:!0,canUpdate:!0,lifecycle:`managed`}};function N(e){return re[e]}function P(e){return N(e).lifecycle===`managed`}function F(e){return N(e).lifecycle}function I(e){return N(e).canUpdate}function ie(e){return N(e).canUninstall}function L(e){return N(e).canLookupLatestVersion}function R(e,t){return e?t===`cask`?` (${e} cask)`:t===`id`?` (${e} id)`:` (${e})`:``}function z(e,t){return t.packageName||e.packages?.npm||void 0}function B(e){return e?I(e.installType):!1}function ae(e){return!!e&&L(e.installType)}function oe(e){return e.length>0&&e.every(e=>L(e.type))}function se(e){return P(e.type)?`${F(e.type)}/${e.type}${R(e.packageName,e.packageTargetKind)}`:e.type===`script`?`unmanaged/script`:`unmanaged/binary`}function ce(e){return e?P(e.installType)?`managed via ${e.installType}${R(e.packageName,e.packageTargetKind)}`:e.installType===`script`?`script installer`:`binary installer`:`detected in PATH`}function le(e){return B(e)?`managed update`:`manual update`}function ue(e,t){if(t.type===`bun`){let n=z(e,t);return n?`bun add -g ${n}`:``}if(t.type===`npm`){let n=z(e,t);return n?`npm i -g ${n}`:``}return t.type===`brew`?t.packageName?t.packageTargetKind===`cask`?`brew install --cask ${t.packageName}`:`brew install ${t.packageName}`:``:t.type===`winget`?t.packageName?`winget install --id ${t.packageName} -e`:``:t.command??``}function de(e,t,n){if(t)return ae(t)&&(t.packageName||e.packages?.npm)||void 0;if(!(!e.packages?.npm||!oe(n)))return e.packages.npm}async function V(e){let t=E(),n=typeof e==`function`?e(t):e;try{let e;return e=i.platform===`win32`?Bun.spawn([`powershell.exe`,`-Command`,n],{stdio:[`inherit`,`inherit`,`inherit`]}):Bun.spawn([`sh`,`-c`,n],{stdio:[`inherit`,`inherit`,`inherit`]}),await e.exited,e.exitCode===0}catch{return!1}}function fe(e){return e===`cask`?[`--cask`]:[]}async function H(e,t,n){try{let r=Bun.spawn([`brew`,e,...fe(n),t],{stdio:[`inherit`,`inherit`,`inherit`]});return await r.exited,r.exitCode===0}catch{return!1}}async function pe(e,t){return H(`install`,e,t)}async function U(e,t){return H(`upgrade`,e,t)}async function me(e){for(let t of e)if(!await U(t.packageName,t.packageTargetKind))return!1;return!0}async function he(e,t){return H(`uninstall`,e,t)}async function ge(e){try{let t=Bun.spawn([`bun`,`add`,`-g`,e],{stdio:[`inherit`,`inherit`,`inherit`]});return await t.exited,t.exitCode===0}catch{return!1}}async function _e(e){try{let t=Bun.spawn([`bun`,`update`,`-g`,e],{stdio:[`inherit`,`inherit`,`inherit`]});return await t.exited,t.exitCode===0}catch{return!1}}async function ve(e){if(e.length===0)return!0;try{let t=Bun.spawn([`bun`,`update`,`-g`,...e],{stdio:[`inherit`,`inherit`,`inherit`]});return await t.exited,t.exitCode===0}catch{return!1}}async function ye(e){try{let t=Bun.spawn([`bun`,`remove`,`-g`,e],{stdio:[`inherit`,`inherit`,`inherit`]});return await t.exited,t.exitCode===0}catch{return!1}}async function be(e){try{let t=Bun.spawn([`npm`,`i`,`-g`,e],{stdio:[`inherit`,`inherit`,`inherit`]});return await t.exited,t.exitCode===0}catch{return!1}}async function xe(e){try{let t=Bun.spawn([`npm`,`update`,`-g`,e],{stdio:[`inherit`,`inherit`,`inherit`]});return await t.exited,t.exitCode===0}catch{return!1}}async function Se(e){if(e.length===0)return!0;try{let t=Bun.spawn([`npm`,`update`,`-g`,...e],{stdio:[`inherit`,`inherit`,`inherit`]});return await t.exited,t.exitCode===0}catch{return!1}}async function Ce(e){try{let t=Bun.spawn([`npm`,`uninstall`,`-g`,e],{stdio:[`inherit`,`inherit`,`inherit`]});return await t.exited,t.exitCode===0}catch{return!1}}async function W(e,t){try{let n=Bun.spawn([`winget`,e,`--id`,t,`-e`],{stdio:[`inherit`,`inherit`,`inherit`]});return await n.exited,n.exitCode===0}catch{return!1}}async function we(e){return W(`install`,e)}async function G(e){return W(`upgrade`,e)}async function Te(e){for(let t of e)if(!await G(t.packageName))return!1;return!0}async function Ee(e){return W(`uninstall`,e)}const De={brew:{type:`brew`,isAvailable:async()=>A(),install:async(e,t)=>pe(e,t),uninstall:async(e,t)=>he(e,t),update:async(e,t)=>U(e,t),updateMany:async e=>me(e)},bun:{type:`bun`,isAvailable:async()=>O(),install:async e=>ge(e),uninstall:async e=>ye(e),update:async e=>_e(e),updateMany:async e=>ve(e.map(e=>e.packageName))},npm:{type:`npm`,isAvailable:async()=>k(),install:async e=>be(e),uninstall:async e=>Ce(e),update:async e=>xe(e),updateMany:async e=>Se(e.map(e=>e.packageName))},winget:{type:`winget`,isAvailable:async()=>j(),install:async e=>we(e),uninstall:async e=>Ee(e),update:async e=>G(e),updateMany:async e=>Te(e.map(e=>({packageName:e.packageName})))}};function K(e){return De[e]}async function Oe(){return(await e()).defaultPackageManager}async function q(e){let t=E(),n=e.platforms[t];if(!n)return[];let r=await Oe();return r?[...n.filter(e=>e.type===r),...n.filter(e=>e.type!==r)]:[...n]}async function J(e,t,n,r){let i=K(e);return await i.isAvailable()?r===`install`?i.install(t,n):r===`update`?i.update(t,n):i.uninstall(t,n):!1}async function Y(e,t,n){if(P(t.type)){let r=z(e,t);return r?J(t.type,r,t.packageTargetKind,n):!1}return n===`update`&&!I(t.type)||!t.command?!1:V(t.command)}async function X(e,t){return P(e.installType)?e.packageName?J(e.installType,e.packageName,e.packageTargetKind,t):!1:t!==`install`||!e.command?!1:V(e.command)}async function Z(e,t){let n={agentName:e.name,installType:t.type,packageName:z(e,t),packageTargetKind:t.packageTargetKind,command:`command`in t?t.command:void 0};return await w(n),n}async function ke(e){let t=await q(e);for(let n of t)if(await Y(e,n,`install`))return{success:!0,installedState:await Z(e,n)};return{success:!1}}async function Ae(e,t){if(t&&await X(t,`update`))return await w(t),{success:!0,installedState:t};let n=await q(e);for(let t of n)if(await Y(e,t,`update`))return{success:!0,installedState:await Z(e,t)};return{success:!1}}async function je(e,t){let n=[...new Map(t.filter(e=>e.packageName).map(e=>[`${e.packageTargetKind??`package`}:${e.packageName}`,e])).values()],r=K(e);return await r.isAvailable()?r.updateMany(n):!1}async function Me(e){let t=await C(e.name);if(!t)return!1;let n=await X(t,`uninstall`);return n&&await T(e.name),n}const Ne=/v?(\d+\.\d+\.\d+(?:-[a-z0-9.]+)?)/i;async function Q(e){try{let t=Bun.spawn([e,`--version`],{stdout:`pipe`,stderr:`pipe`});if(await t.exited,t.exitCode!==0)return;let n=(await new Response(t.stdout).text()).trim().split(`
2
+ `)[0],r=n.match(Ne);return r?r[1]:n||void 0}catch{return}}async function Pe(e){try{let t=await fetch(`https://registry.npmjs.org/${e}/latest`);return t.ok?(await t.json()).version:void 0}catch{return}}async function Fe(e){try{let t=i.platform===`win32`?`where`:`which`,n=Bun.spawn([t,e],{stdout:`pipe`,stderr:`pipe`});return await n.exited,n.exitCode===0?(await new Response(n.stdout).text()).trim().split(`
3
+ `)[0]:void 0}catch{return}}async function $(e){let[t,n,r]=await Promise.all([q(e),C(e.name),M(e.binaryName)]),[i,a,o]=await Promise.all([r?Q(e.binaryName):Promise.resolve(void 0),r?Fe(e.binaryName):Promise.resolve(void 0),Le(e,n,t)]);return{agent:e,methods:t,installedState:n,inPath:r,installedVersion:i,latestVersion:o,binaryPath:a,sourceLabel:ce(n),updateLabel:le(n),lifecycle:n?F(n.installType):`unmanaged`}}async function Ie(e){return Promise.all(e.map($))}async function Le(e,t,n){let r=de(e,t,n);if(r)return Pe(r)}function Re(e){return y(e)}async function ze(e){let t=Re(e);if(t)return{agent:t,inspection:await $(t)}}async function Be(){return Ie(_())}export{C as A,m as B,P as C,O as D,A as E,w as F,u as G,f as H,v as I,l as K,y as L,x as M,T as N,k as O,S as P,_ as R,N as S,M as T,te as U,p as V,d as W,se as _,Ie as a,I as b,Pe as c,Me as d,Ae as f,ue as g,B as h,$ as i,b as j,j as k,q as l,K as m,Re as n,Fe as o,je as p,ze as r,Q as s,Be as t,ke as u,L as v,E as w,F as x,ie as y,h as z};
package/dist/cli.mjs CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bun
2
- import{a as e,n as t}from"./detect-BJHrcpbU.mjs";import{t as n}from"./package-manager-DmASCUc5.mjs";import r from"node:process";import{program as i}from"commander";import a from"picocolors";import o from"prompts";async function s(r,i){let s=e(r);if(!s)return console.log(a.red(`Unknown agent: ${r}`)),1;if(!await t(s.binaryName)){if(!(await o({type:`confirm`,name:`install`,message:`${s.displayName} is not installed. Would you like to install it?`,initial:!0})).install)return console.log(a.yellow(`Installation cancelled.`)),1;if(console.log(a.cyan(`Installing ${s.displayName}...`)),!await n(s))return console.log(a.red(`Failed to install ${s.displayName}.`)),1}try{let e=Bun.spawn([s.binaryName,...i],{stdio:[`inherit`,`inherit`,`inherit`]});return await e.exited,e.exitCode??1}catch(e){return console.log(a.red(`Failed to launch ${s.displayName}: ${e instanceof Error?e.message:String(e)}`)),1}}const c=r.argv[2],l=new Set([`install`,`i`,`update`,`u`,`uninstall`,`rm`,`list`,`ls`,`info`,`config`,`doctor`,`help`,`--help`,`--version`,`-v`]);if(c&&!c.startsWith(`-`)&&!l.has(c)&&e(c)){let e=await s(c,r.argv.slice(3));r.exit(e)}i.name(`quantex`).description(`统一的 AI Agent CLI 管理工具`).version(`0.0.0`),i.command(`install <agent>`).alias(`i`).description(`安装指定 agent`).action(async e=>{let{installCommand:t}=await import(`./install-BLn1aiE5.mjs`);await t(e)}),i.command(`update`).argument(`[agent]`,`Agent name or alias`).option(`--all`,`更新所有已安装的 agent`).alias(`u`).description(`更新指定 agent`).action(async(e,t)=>{let{updateCommand:n}=await import(`./update-DoBRq8gT.mjs`);await n(e,t.all??!1)}),i.command(`uninstall <agent>`).alias(`rm`).description(`卸载指定 agent`).action(async e=>{let{uninstallCommand:t}=await import(`./uninstall-D29UTIoi.mjs`);await t(e)}),i.command(`list`).alias(`ls`).description(`列出所有支持的 agent`).action(async()=>{let{listCommand:e}=await import(`./list-COKEGeC4.mjs`);await e()}),i.command(`info <agent>`).description(`查看 agent 详细信息`).action(async e=>{let{infoCommand:t}=await import(`./info-C0nvLNok.mjs`);await t(e)}),i.command(`config`).argument(`[action]`,`Action: get, set, reset`).argument(`[key]`,`Config key`).argument(`[value]`,`Config value`).description(`配置管理`).action(async(e,t,n)=>{let{configCommand:r}=await import(`./config-qSZAkW83.mjs`);await r(e,t,n)}),i.command(`doctor`).description(`检查环境`).action(async()=>{let{doctorCommand:e}=await import(`./doctor-C3rLMGrs.mjs`);await e()}),i.parse();export{};
2
+ import{L as e,r as t,u as n}from"./agents-BGk1FtW_.mjs";import r from"node:process";import{program as i}from"commander";import a from"picocolors";import o from"prompts";async function s(e,r){let i=await t(e);if(!i)return console.log(a.red(`Unknown agent: ${e}`)),1;let{agent:s,inspection:c}=i;if(!c.inPath){if(!(await o({type:`confirm`,name:`install`,message:`${s.displayName} is not installed. Would you like to install it?`,initial:!0})).install)return console.log(a.yellow(`Installation cancelled.`)),1;if(console.log(a.cyan(`Installing ${s.displayName}...`)),!(await n(s)).success)return console.log(a.red(`Failed to install ${s.displayName}.`)),1}try{let e=Bun.spawn([s.binaryName,...r],{stdio:[`inherit`,`inherit`,`inherit`]});return await e.exited,e.exitCode??1}catch(e){return console.log(a.red(`Failed to launch ${s.displayName}: ${e instanceof Error?e.message:String(e)}`)),1}}const c=await Bun.file(new URL(`../package.json`,import.meta.url)).json();i.name(`quantex`).description(`统一的 AI Agent CLI 管理工具`).version(c.version??`0.0.0`),i.command(`install <agent>`).alias(`i`).description(`安装指定 agent`).action(async e=>{let{installCommand:t}=await import(`./install-Dq2l4GZ0.mjs`);await t(e)}),i.command(`update`).argument(`[agent]`,`Agent name or alias`).option(`--all`,`更新所有已安装的 agent`).alias(`u`).description(`更新指定 agent`).action(async(e,t)=>{let{updateCommand:n}=await import(`./update-CzN4A4KH.mjs`);await n(e,t.all??!1)}),i.command(`uninstall <agent>`).alias(`rm`).description(`卸载指定 agent`).action(async e=>{let{uninstallCommand:t}=await import(`./uninstall-C0tbY6DM.mjs`);await t(e)}),i.command(`list`).alias(`ls`).description(`列出所有支持的 agent`).action(async()=>{let{listCommand:e}=await import(`./list-T8JHHWWE.mjs`);await e()}),i.command(`info <agent>`).description(`查看 agent 详细信息`).action(async e=>{let{infoCommand:t}=await import(`./info-DeMHOB7s.mjs`);await t(e)}),i.command(`config`).argument(`[action]`,`Action: get, set, reset`).argument(`[key]`,`Config key`).argument(`[value]`,`Config value`).description(`配置管理`).action(async(e,t,n)=>{let{configCommand:r}=await import(`./config-D6elxlPI.mjs`);await r(e,t,n)}),i.command(`doctor`).description(`检查环境`).action(async()=>{let{doctorCommand:e}=await import(`./doctor-DO48gMqu.mjs`);await e()});const l=r.argv[2],u=new Set([...i.commands.map(e=>e.name()),...i.commands.flatMap(e=>e.aliases()),`help`,`--help`,`--version`,`-v`]);if(l&&!l.startsWith(`-`)&&!u.has(l)&&e(l)){let e=await s(l,r.argv.slice(3));r.exit(e)}i.parse();export{};
@@ -0,0 +1,3 @@
1
+ import{a as e,i as t,r as n}from"./config-DvtBCQbQ.mjs";import r from"picocolors";async function i(i,a,o){if(!i){let e=await n();console.log(r.bold(`
2
+ Current Configuration:
3
+ `)),console.log(JSON.stringify(e,null,2)),console.log();return}switch(i){case`get`:{if(!a){console.log(r.red(`Please specify a key`));return}let e=(await n())[a];console.log(e===void 0?r.gray(`(not set)`):String(e));break}case`set`:{if(!a||o===void 0){console.log(r.red(`Please specify both key and value`));return}let e={};try{e=await n()}catch{}e[a]=o,await t(e),console.log(r.green(`Set ${a} = ${o}`));break}case`reset`:await t(e),console.log(r.green(`Configuration reset to defaults.`));break;default:console.log(r.red(`Unknown action: ${i}`)),console.log(`Available actions: get, set, reset`)}}export{i as configCommand};
@@ -0,0 +1 @@
1
+ import{mkdir as e}from"node:fs/promises";import{homedir as t}from"node:os";import{join as n}from"node:path";import{loadConfig as r}from"c12";const i={defaultPackageManager:`bun`};function a(){return n(t(),`.quantex`)}function o(){return n(a(),`config.json`)}async function s(){let{config:e}=await r({name:`quantex`,defaults:i,configFile:o()});return e}async function c(t){await e(a(),{recursive:!0}),await Bun.write(o(),`${JSON.stringify(t,null,2)}\n`)}export{i as a,c as i,o as n,s as r,a as t};
@@ -0,0 +1,3 @@
1
+ import{D as e,E as t,O as n,k as r,t as i}from"./agents-BGk1FtW_.mjs";import a from"picocolors";async function o(){console.log(a.bold(`
2
+ Quantex CLI Environment Check
3
+ `)),console.log(a.bold(`Managed Installers:`));let o=await e();console.log(` Bun: ${o?a.green(`available`):a.red(`not found`)}`);let s=await n();console.log(` npm: ${s?a.green(`available`):a.red(`not found`)}`);let c=await t();console.log(` brew: ${c?a.green(`available`):a.red(`not found`)}`);let l=await r();console.log(` winget:${l?a.green(`available`):a.red(`not found`)}`),console.log(`\n${a.bold(`Installed Agents:`)}`);let u=await i(),d=!1;for(let e of u)if(e.inPath){d=!0;let t=e.installedVersion&&e.latestVersion&&e.installedVersion!==e.latestVersion;console.log(` ${e.agent.displayName}: ${e.installedVersion??`unknown`} [${e.lifecycle}; ${e.sourceLabel}]${t?a.yellow(` (update available: ${e.latestVersion})`):``}`)}d||console.log(a.dim(` No agents installed`)),console.log(`\n${a.bold(`Issues:`)}`);let f=[];if(!o&&!s&&!c&&!l&&f.push(`No managed installer found. Install bun, npm, brew, or winget.`),f.length===0)console.log(a.green(` No issues found.`));else for(let e of f)console.log(a.yellow(` - ${e}`));console.log()}export{o as doctorCommand};
package/dist/index.d.mts CHANGED
@@ -1,33 +1,67 @@
1
1
  //#region src/agents/types.d.ts
2
2
  type Platform = 'windows' | 'macos' | 'linux';
3
- type InstallType = 'bun' | 'npm' | 'binary';
4
- interface InstallMethod {
5
- type: InstallType;
3
+ type ManagedInstallType = 'bun' | 'npm' | 'brew' | 'winget';
4
+ type InstallType = ManagedInstallType | 'script' | 'binary';
5
+ type PackageTargetKind = 'package' | 'cask' | 'id';
6
+ interface BaseInstallMethod {
7
+ command?: string;
8
+ packageName?: string;
9
+ packageTargetKind?: PackageTargetKind;
10
+ }
11
+ interface ManagedInstallMethod extends BaseInstallMethod {
12
+ command?: never;
13
+ type: ManagedInstallType;
14
+ }
15
+ interface ScriptInstallMethod extends BaseInstallMethod {
16
+ command: string;
17
+ type: 'script';
18
+ }
19
+ interface BinaryInstallMethod extends BaseInstallMethod {
6
20
  command: string;
7
- priority: number;
21
+ type: 'binary';
22
+ }
23
+ type InstallMethod = ManagedInstallMethod | ScriptInstallMethod | BinaryInstallMethod;
24
+ interface AgentPackageMetadata {
25
+ npm?: string;
8
26
  }
9
27
  interface AgentDefinition {
10
28
  name: string;
11
- aliases: string[];
29
+ lookupAliases?: string[];
12
30
  displayName: string;
13
31
  description: string;
14
32
  homepage: string;
15
- package: string;
33
+ packages?: AgentPackageMetadata;
16
34
  platforms: Partial<Record<Platform, InstallMethod[]>>;
17
35
  binaryName: string;
18
36
  }
19
37
  //#endregion
20
- //#region src/agents/claude.d.ts
38
+ //#region src/agents/definitions/claude.d.ts
21
39
  declare const claude: AgentDefinition;
22
40
  //#endregion
23
- //#region src/agents/codex.d.ts
41
+ //#region src/agents/definitions/codex.d.ts
24
42
  declare const codex: AgentDefinition;
25
43
  //#endregion
26
- //#region src/agents/opencode.d.ts
44
+ //#region src/agents/definitions/copilot.d.ts
45
+ declare const copilot: AgentDefinition;
46
+ //#endregion
47
+ //#region src/agents/definitions/cursor.d.ts
48
+ declare const cursor: AgentDefinition;
49
+ //#endregion
50
+ //#region src/agents/definitions/droid.d.ts
51
+ declare const droid: AgentDefinition;
52
+ //#endregion
53
+ //#region src/agents/definitions/gemini.d.ts
54
+ declare const gemini: AgentDefinition;
55
+ //#endregion
56
+ //#region src/agents/definitions/opencode.d.ts
27
57
  declare const opencode: AgentDefinition;
28
58
  //#endregion
59
+ //#region src/agents/definitions/pi.d.ts
60
+ declare const pi: AgentDefinition;
61
+ //#endregion
29
62
  //#region src/agents/index.d.ts
30
63
  declare function getAllAgents(): AgentDefinition[];
64
+ declare function getAgentByLookupName(name: string): AgentDefinition | undefined;
31
65
  declare function getAgentByNameOrAlias(name: string): AgentDefinition | undefined;
32
66
  //#endregion
33
67
  //#region src/config/index.d.ts
@@ -36,13 +70,134 @@ interface QuantexConfig {
36
70
  [key: string]: unknown;
37
71
  }
38
72
  declare function getConfigDir(): string;
73
+ declare function getConfigFilePath(): string;
39
74
  declare function loadConfig(): Promise<QuantexConfig>;
75
+ declare function saveConfig(config: Record<string, unknown>): Promise<void>;
76
+ //#endregion
77
+ //#region src/state/index.d.ts
78
+ interface InstalledAgentState {
79
+ agentName: string;
80
+ installType: InstallType;
81
+ packageName?: string;
82
+ packageTargetKind?: PackageTargetKind;
83
+ command?: string;
84
+ }
85
+ interface QuantexState {
86
+ installedAgents: Record<string, InstalledAgentState>;
87
+ }
88
+ declare function getStateFilePath(): string;
89
+ declare function loadState(): Promise<QuantexState>;
90
+ declare function saveState(state: QuantexState): Promise<void>;
91
+ declare function getInstalledAgentState(agentName: string): Promise<InstalledAgentState | undefined>;
92
+ declare function setInstalledAgentState(agentState: InstalledAgentState): Promise<void>;
93
+ declare function removeInstalledAgentState(agentName: string): Promise<void>;
94
+ //#endregion
95
+ //#region src/inspection/agents.d.ts
96
+ interface AgentInspection {
97
+ agent: AgentDefinition;
98
+ methods: InstallMethod[];
99
+ installedState?: InstalledAgentState;
100
+ inPath: boolean;
101
+ installedVersion?: string;
102
+ latestVersion?: string;
103
+ binaryPath?: string;
104
+ sourceLabel: string;
105
+ updateLabel: string;
106
+ lifecycle: 'managed' | 'unmanaged';
107
+ }
108
+ declare function inspectAgent(agent: AgentDefinition): Promise<AgentInspection>;
109
+ declare function inspectAllAgents(agents: AgentDefinition[]): Promise<AgentInspection[]>;
110
+ //#endregion
111
+ //#region src/package-manager/installers.d.ts
112
+ interface ManagedPackageSpec {
113
+ packageName: string;
114
+ packageTargetKind?: PackageTargetKind;
115
+ }
116
+ interface ManagedInstaller {
117
+ type: ManagedInstallType;
118
+ isAvailable: () => Promise<boolean>;
119
+ install: (packageName: string, packageTargetKind?: PackageTargetKind) => Promise<boolean>;
120
+ uninstall: (packageName: string, packageTargetKind?: PackageTargetKind) => Promise<boolean>;
121
+ update: (packageName: string, packageTargetKind?: PackageTargetKind) => Promise<boolean>;
122
+ updateMany: (packages: ManagedPackageSpec[]) => Promise<boolean>;
123
+ }
124
+ declare function getManagedInstaller(type: ManagedInstallType): ManagedInstaller;
40
125
  //#endregion
41
126
  //#region src/package-manager/index.d.ts
42
- declare function installAgent(agent: AgentDefinition): Promise<boolean>;
43
- declare function updateAgent(agent: AgentDefinition): Promise<boolean>;
127
+ interface AgentOperationResult {
128
+ success: boolean;
129
+ installedState?: InstalledAgentState;
130
+ }
131
+ declare function getOrderedInstallMethods(agent: AgentDefinition): Promise<InstallMethod[]>;
132
+ declare function installAgent(agent: AgentDefinition): Promise<AgentOperationResult>;
133
+ declare function updateAgent(agent: AgentDefinition, preferredState?: InstalledAgentState): Promise<AgentOperationResult>;
134
+ declare function updateAgentsByType(type: ManagedInstallType, packages: ManagedPackageSpec[]): Promise<boolean>;
44
135
  declare function uninstallAgent(agent: AgentDefinition): Promise<boolean>;
45
136
  //#endregion
137
+ //#region src/package-manager/capabilities.d.ts
138
+ interface InstallerCapabilities {
139
+ canInstall: true;
140
+ canLookupLatestVersion: boolean;
141
+ canUninstall: boolean;
142
+ canUpdate: boolean;
143
+ lifecycle: 'managed' | 'unmanaged';
144
+ }
145
+ declare function getInstallerCapabilities(type: InstallType): InstallerCapabilities;
146
+ declare function isManagedInstallType(type: InstallType): type is ManagedInstallType;
147
+ declare function getInstallLifecycle(type: InstallType): 'managed' | 'unmanaged';
148
+ declare function canUpdateInstallType(type: InstallType): boolean;
149
+ declare function canUninstallInstallType(type: InstallType): boolean;
150
+ declare function canLookupLatestVersionForInstallType(type: InstallType): boolean;
151
+ //#endregion
152
+ //#region src/planning/updates.d.ts
153
+ interface UpdatePlanEntry {
154
+ inspection: AgentInspection;
155
+ installerType?: ManagedInstallType;
156
+ strategy: 'grouped' | 'manual';
157
+ }
158
+ interface UpdatePlan {
159
+ entries: UpdatePlanEntry[];
160
+ grouped: Record<ManagedInstallType, UpdatePlanEntry[]>;
161
+ manual: UpdatePlanEntry[];
162
+ upToDate: AgentInspection[];
163
+ }
164
+ declare function createUpdatePlan(inspections: AgentInspection[]): UpdatePlan;
165
+ declare function isInspectionUpdateAvailable(inspection: Pick<AgentInspection, 'installedVersion' | 'latestVersion'>): boolean;
166
+ //#endregion
167
+ //#region src/services/agents.d.ts
168
+ interface ResolvedAgentInspection {
169
+ agent: AgentDefinition;
170
+ inspection: AgentInspection;
171
+ }
172
+ declare function resolveAgent(agentName: string): AgentDefinition | undefined;
173
+ declare function resolveAgentInspection(agentName: string): Promise<ResolvedAgentInspection | undefined>;
174
+ declare function inspectRegisteredAgents(): Promise<AgentInspection[]>;
175
+ //#endregion
176
+ //#region src/services/update.d.ts
177
+ interface PendingAgentUpdate {
178
+ agent: AgentDefinition;
179
+ inspection: AgentInspection;
180
+ state?: InstalledAgentState;
181
+ }
182
+ interface ManagedUpdateBucket {
183
+ type: ManagedInstallType;
184
+ packages: ManagedPackageSpec[];
185
+ updates: PendingAgentUpdate[];
186
+ }
187
+ interface PlannedAgentUpdates {
188
+ entries: PendingAgentUpdate[];
189
+ grouped: ManagedUpdateBucket[];
190
+ manual: PendingAgentUpdate[];
191
+ upToDate: AgentInspection[];
192
+ }
193
+ interface SingleAgentUpdateStatus {
194
+ agent: AgentDefinition;
195
+ inspection: AgentInspection;
196
+ updateAvailable: boolean;
197
+ }
198
+ declare function getSingleAgentUpdateStatus(agent: AgentDefinition): Promise<SingleAgentUpdateStatus>;
199
+ declare function planAgentUpdates(): Promise<PlannedAgentUpdates>;
200
+ //#endregion
46
201
  //#region src/utils/detect.d.ts
47
202
  declare function getPlatform(): Platform;
48
203
  declare function isBunAvailable(): Promise<boolean>;
@@ -60,4 +215,4 @@ declare function getInstalledVersion(binaryName: string): Promise<string | undef
60
215
  declare function getLatestVersion(packageName: string): Promise<string | undefined>;
61
216
  declare function getBinaryPath(binaryName: string): Promise<string | undefined>;
62
217
  //#endregion
63
- export { type AgentDefinition, type InstallMethod, type Platform, type QuantexConfig, claude, codex, execCommand, getAgentByNameOrAlias, getAllAgents, getBinaryPath, getConfigDir, getInstalledVersion, getLatestVersion, getPlatform, installAgent, isBinaryInPath, isBunAvailable, isNpmAvailable, loadConfig, opencode, uninstallAgent, updateAgent };
218
+ export { type AgentDefinition, type AgentInspection, type AgentOperationResult, type AgentPackageMetadata, type BinaryInstallMethod, type InstallMethod, type InstallType, type InstalledAgentState, type ManagedInstallMethod, type ManagedInstallType, type ManagedInstaller, type ManagedPackageSpec, type ManagedUpdateBucket, type PackageTargetKind, type PendingAgentUpdate, type PlannedAgentUpdates, type Platform, type QuantexConfig, type QuantexState, type ResolvedAgentInspection, type ScriptInstallMethod, type SingleAgentUpdateStatus, type UpdatePlan, type UpdatePlanEntry, canLookupLatestVersionForInstallType, canUninstallInstallType, canUpdateInstallType, claude, codex, copilot, createUpdatePlan, cursor, droid, execCommand, gemini, getAgentByLookupName, getAgentByNameOrAlias, getAllAgents, getBinaryPath, getConfigDir, getConfigFilePath, getInstallLifecycle, getInstalledAgentState, getInstalledVersion, getInstallerCapabilities, getLatestVersion, getManagedInstaller, getOrderedInstallMethods, getPlatform, getSingleAgentUpdateStatus, getStateFilePath, inspectAgent, inspectAllAgents, inspectRegisteredAgents, installAgent, isBinaryInPath, isBunAvailable, isInspectionUpdateAvailable, isManagedInstallType, isNpmAvailable, loadConfig, loadState, opencode, pi, planAgentUpdates, removeInstalledAgentState, resolveAgent, resolveAgentInspection, saveConfig, saveState, setInstalledAgentState, uninstallAgent, updateAgent, updateAgentsByType };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{a as e,c as t,i as n,l as r,n as i,o as a,r as o,s,t as c}from"./detect-BJHrcpbU.mjs";import{n as l,t as u}from"./config-DthGTKaK.mjs";import{n as d,r as f,t as p}from"./package-manager-DmASCUc5.mjs";import{n as m,r as h,t as g}from"./version-G_0-W0JG.mjs";async function _(e,t){try{let n=Bun.spawn([e,...t],{stdio:[`inherit`,`inherit`,`inherit`]});return await n.exited,{success:n.exitCode===0,exitCode:n.exitCode??1}}catch{return{success:!1,exitCode:1}}}export{r as claude,t as codex,_ as execCommand,e as getAgentByNameOrAlias,a as getAllAgents,g as getBinaryPath,u as getConfigDir,m as getInstalledVersion,h as getLatestVersion,c as getPlatform,p as installAgent,i as isBinaryInPath,o as isBunAvailable,n as isNpmAvailable,l as loadConfig,s as opencode,d as uninstallAgent,f as updateAgent};
1
+ import{A as e,B as t,C as n,D as r,F as i,G as a,H as o,I as s,K as c,L as l,M as u,N as d,O as f,P as p,R as m,S as h,T as g,U as _,V as v,W as y,a as b,b as x,c as S,d as C,f as w,i as T,j as E,l as D,m as O,n as k,o as A,p as j,r as M,s as N,t as P,u as F,v as I,w as L,x as R,y as z,z as B}from"./agents-BGk1FtW_.mjs";import{i as V,n as H,r as U,t as W}from"./config-DvtBCQbQ.mjs";import{i as G,n as K,r as q,t as J}from"./update-DIDtiDmr.mjs";async function Y(e,t){try{let n=Bun.spawn([e,...t],{stdio:[`inherit`,`inherit`,`inherit`]});return await n.exited,{success:n.exitCode===0,exitCode:n.exitCode??1}}catch{return{success:!1,exitCode:1}}}export{I as canLookupLatestVersionForInstallType,z as canUninstallInstallType,x as canUpdateInstallType,c as claude,a as codex,y as copilot,q as createUpdatePlan,_ as cursor,o as droid,Y as execCommand,v as gemini,s as getAgentByLookupName,l as getAgentByNameOrAlias,m as getAllAgents,A as getBinaryPath,W as getConfigDir,H as getConfigFilePath,R as getInstallLifecycle,e as getInstalledAgentState,N as getInstalledVersion,h as getInstallerCapabilities,S as getLatestVersion,O as getManagedInstaller,D as getOrderedInstallMethods,L as getPlatform,J as getSingleAgentUpdateStatus,E as getStateFilePath,T as inspectAgent,b as inspectAllAgents,P as inspectRegisteredAgents,F as installAgent,g as isBinaryInPath,r as isBunAvailable,G as isInspectionUpdateAvailable,n as isManagedInstallType,f as isNpmAvailable,U as loadConfig,u as loadState,t as opencode,B as pi,K as planAgentUpdates,d as removeInstalledAgentState,k as resolveAgent,M as resolveAgentInspection,V as saveConfig,p as saveState,i as setInstalledAgentState,C as uninstallAgent,w as updateAgent,j as updateAgentsByType};
@@ -0,0 +1,2 @@
1
+ import{_ as e,g as t,r as n}from"./agents-BGk1FtW_.mjs";import r from"picocolors";async function i(i){let a=await n(i);if(!a){console.log(r.red(`Unknown agent: ${i}`));return}let{agent:o,inspection:s}=a;console.log(r.bold(`\n${o.displayName}\n`)),console.log(` Name: ${o.name}`),console.log(` Aliases: ${o.lookupAliases?.join(`, `)??`-`}`),console.log(` Description: ${o.description}`),console.log(` Package: ${o.packages?.npm??`-`}`),console.log(` Binary: ${o.binaryName}`),console.log(` Installed: ${s.inPath?r.green(`Yes`):r.red(`No`)}`),s.inPath&&console.log(` Source: ${s.sourceLabel}`),s.installedState&&console.log(` Lifecycle: ${s.lifecycle}`),s.installedVersion&&console.log(` Version: ${s.installedVersion}`),s.latestVersion&&console.log(` Latest: ${s.latestVersion}`),s.binaryPath&&console.log(` Path: ${s.binaryPath}`),console.log(r.bold(`
2
+ Install Methods:`));for(let n of s.methods)console.log(` ${r.green(`+`)} [${e(n)}] ${t(o,n)}`);console.log()}export{i as infoCommand};
@@ -0,0 +1 @@
1
+ import{r as e,u as t}from"./agents-BGk1FtW_.mjs";import n from"picocolors";async function r(r){let i=await e(r);if(!i){console.log(n.red(`Unknown agent: ${r}`));return}let{agent:a,inspection:o}=i;if(o.inPath){console.log(n.yellow(`${a.displayName} is already installed.`));return}console.log(n.cyan(`Installing ${a.displayName}...`)),(await t(a)).success?console.log(n.green(`${a.displayName} installed successfully!`)):console.log(n.red(`Failed to install ${a.displayName}.`))}export{r as installCommand};
@@ -0,0 +1,3 @@
1
+ import{t as e}from"./agents-BGk1FtW_.mjs";import t from"picocolors";async function n(){let n=await e();console.log(t.bold(`
2
+ AI Agents:
3
+ `));for(let e of n){let n=e.agent.displayName.padEnd(18),r=e.inPath?t.green(`installed`):t.gray(`not installed`),i=e.inPath?t.dim(e.installedVersion??`unknown version`):``,a=e.inPath?t.cyan(e.updateLabel):``,o=e.inPath?t.dim(e.sourceLabel):``;console.log(` ${n} ${r} ${i}${a?` ${a}`:``}${o?` ${o}`:``}`)}console.log()}export{n as listCommand};
@@ -0,0 +1 @@
1
+ import{d as e,n as t}from"./agents-BGk1FtW_.mjs";import n from"picocolors";async function r(r){let i=t(r);if(!i){console.log(n.red(`Unknown agent: ${r}`));return}console.log(n.cyan(`Uninstalling ${i.displayName}...`)),await e(i)?console.log(n.green(`${i.displayName} uninstalled successfully!`)):console.log(n.red(`Failed to uninstall ${i.displayName}.`))}export{r as uninstallCommand};
@@ -0,0 +1 @@
1
+ import{f as e,h as t,n,p as r}from"./agents-BGk1FtW_.mjs";import{n as i,t as a}from"./update-DIDtiDmr.mjs";import o from"picocolors";async function s(e,t){if(t){await c();return}if(!e){console.log(o.red(`Please specify an agent name or use --all flag`));return}let r=n(e);if(!r){console.log(o.red(`Unknown agent: ${e}`));return}await u(r)}async function c(){let e=await i();for(let t of e.upToDate)console.log(o.green(`${t.agent.displayName} is up to date (${t.installedVersion??`unknown`})`));for(let t of e.entries){let e=t.inspection;console.log(o.cyan(`Updating ${e.agent.displayName}...${f(e.installedVersion,e.latestVersion)}`))}for(let t of e.grouped)await l(t.type,t.packages,t.updates);for(let t of e.manual)await d(t.agent,t.state,!1)}async function l(e,t,n){if(n.length!==0){if(await r(e,t)){for(let{agent:e}of n)console.log(o.green(`${e.displayName} updated successfully!`));return}for(let{agent:e,state:t}of n)await d(e,t,!1)}}async function u(e){let{inspection:t,updateAvailable:n}=await a(e);if(!t.inPath){console.log(o.red(`${e.displayName} is not installed.`));return}if(!n){console.log(o.green(`${e.displayName} is up to date (${t.installedVersion??`unknown`})`));return}console.log(o.cyan(`Updating ${e.displayName}...${f(t.installedVersion,t.latestVersion)}`)),await d(e,t.installedState,!1)}async function d(n,r,i=!0){if(i){let{inspection:e}=await a(n);console.log(o.cyan(`Updating ${n.displayName}...${f(e.installedVersion,e.latestVersion)}`))}if(r&&!t(r)){console.log(o.yellow(`${n.displayName} uses an unmanaged install source and cannot be updated automatically.`));return}(await e(n,r)).success?console.log(o.green(`${n.displayName} updated successfully!`)):console.log(o.red(`Failed to update ${n.displayName}.`))}function f(e,t){return e?` (${e} -> ${t??`latest`})`:``}export{s as updateCommand};
@@ -0,0 +1 @@
1
+ import{C as e,h as t,i as n,t as r}from"./agents-BGk1FtW_.mjs";function i(e){let t={bun:[],npm:[],brew:[],winget:[]},n=[],r=[];for(let i of e){if(!i.inPath)continue;if(!a(i)){r.push(i);continue}let e=o(i);if(e){let n={inspection:i,installerType:e,strategy:`grouped`};t[e].push(n);continue}n.push({inspection:i,strategy:`manual`})}return{entries:[...t.bun,...t.npm,...t.brew,...t.winget,...n],grouped:t,manual:n,upToDate:r}}function a(e){return e.installedVersion&&e.latestVersion?e.installedVersion!==e.latestVersion:!0}function o(n){if(!(!n.installedState||!n.installedState.packageName)&&t(n.installedState)&&e(n.installedState.installType))return n.installedState.installType}const s=[`bun`,`npm`,`brew`,`winget`];async function c(e){let t=await n(e);return{agent:e,inspection:t,updateAvailable:a(t)}}async function l(){let e=i(await r()),t=s.map(t=>u(t,e.grouped[t])).filter(e=>e!==void 0);return{entries:e.entries.map(e=>d(e.inspection)),grouped:t,manual:e.manual.map(e=>d(e.inspection)),upToDate:e.upToDate}}function u(e,t){if(t.length===0)return;let n=t.map(e=>d(e.inspection));return{type:e,packages:n.flatMap(e=>e.state?.packageName?[{packageName:e.state.packageName,packageTargetKind:e.state.packageTargetKind}]:[]),updates:n}}function d(e){return{agent:e.agent,inspection:e,state:e.installedState}}export{a as i,l as n,i as r,c as t};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "quantex-cli",
3
3
  "type": "module",
4
- "version": "0.0.1-beta.6",
4
+ "version": "0.0.1-beta.8",
5
5
  "packageManager": "bun@1.3.11",
6
6
  "description": "统一的 AI Agent CLI 管理工具,支持安装、更新、卸载、查询、快捷启动主流 AI 编程助手",
7
7
  "author": "Drswith <drswith@outlook.com>",
@@ -1 +0,0 @@
1
- import{homedir as e}from"node:os";import{join as t}from"node:path";import{loadConfig as n}from"c12";const r={defaultPackageManager:`bun`};function i(){return t(e(),`.quantex`)}async function a(){let{config:e}=await n({name:`quantex`,defaults:r,configFile:t(i(),`config.json`)});return e}export{a as n,r,i as t};
@@ -1,3 +0,0 @@
1
- import{n as e,r as t,t as n}from"./config-DthGTKaK.mjs";import{join as r}from"node:path";import i from"picocolors";async function a(a,o,s){if(!a){let t=await e();console.log(i.bold(`
2
- Current Configuration:
3
- `)),console.log(JSON.stringify(t,null,2)),console.log();return}switch(a){case`get`:{if(!o){console.log(i.red(`Please specify a key`));return}let t=(await e())[o];console.log(t===void 0?i.gray(`(not set)`):String(t));break}case`set`:{if(!o||s===void 0){console.log(i.red(`Please specify both key and value`));return}let e=r(n(),`config.json`),t={};try{t=await Bun.file(e).json()}catch{}t[o]=s,await Bun.write(e,JSON.stringify(t,null,2)),console.log(i.green(`Set ${o} = ${s}`));break}case`reset`:{let e=r(n(),`config.json`);await Bun.write(e,JSON.stringify(t,null,2)),console.log(i.green(`Configuration reset to defaults.`));break}default:console.log(i.red(`Unknown action: ${a}`)),console.log(`Available actions: get, set, reset`)}}export{a as configCommand};
@@ -1 +0,0 @@
1
- import e from"node:process";const t={name:`claude`,aliases:[`claude`],displayName:`Claude Code`,description:`Anthropic 官方 AI 编程助手 CLI`,homepage:`https://code.claude.com/docs`,package:`@anthropic-ai/claude-code`,binaryName:`claude`,platforms:{windows:[{type:`bun`,command:`bun add -g @anthropic-ai/claude-code`,priority:1},{type:`npm`,command:`npm i -g @anthropic-ai/claude-code`,priority:2},{type:`binary`,command:`irm https://claude.ai/install.ps1 | iex`,priority:3},{type:`binary`,command:`winget install Anthropic.ClaudeCode`,priority:4}],macos:[{type:`bun`,command:`bun add -g @anthropic-ai/claude-code`,priority:1},{type:`npm`,command:`npm i -g @anthropic-ai/claude-code`,priority:2},{type:`binary`,command:`curl -fsSL https://claude.ai/install.sh | bash`,priority:3},{type:`binary`,command:`brew install --cask claude-code`,priority:4}],linux:[{type:`bun`,command:`bun add -g @anthropic-ai/claude-code`,priority:1},{type:`npm`,command:`npm i -g @anthropic-ai/claude-code`,priority:2},{type:`binary`,command:`curl -fsSL https://claude.ai/install.sh | bash`,priority:3},{type:`binary`,command:`brew install --cask claude-code`,priority:4}]}},n={name:`codex`,aliases:[`codex`],displayName:`Codex CLI`,description:`OpenAI 官方 AI 编程助手 CLI`,homepage:`https://developers.openai.com/codex`,package:`@openai/codex`,binaryName:`codex`,platforms:{windows:[{type:`bun`,command:`bun add -g @openai/codex`,priority:1},{type:`npm`,command:`npm i -g @openai/codex`,priority:2}],macos:[{type:`bun`,command:`bun add -g @openai/codex`,priority:1},{type:`npm`,command:`npm i -g @openai/codex`,priority:2},{type:`binary`,command:`brew install codex`,priority:3}],linux:[{type:`bun`,command:`bun add -g @openai/codex`,priority:1},{type:`npm`,command:`npm i -g @openai/codex`,priority:2},{type:`binary`,command:`brew install codex`,priority:3}]}},r={name:`copilot`,aliases:[`copilot`],displayName:`GitHub Copilot CLI`,description:`GitHub Copilot 命令行工具`,homepage:`https://github.com/features/copilot/cli`,package:`@github/copilot`,binaryName:`copilot`,platforms:{windows:[{type:`binary`,command:`winget install GitHub.Copilot`,priority:3}],macos:[{type:`bun`,command:`bun add -g @github/copilot`,priority:1},{type:`npm`,command:`npm i -g @github/copilot`,priority:2},{type:`binary`,command:`curl -fsSL https://gh.io/copilot-install | bash`,priority:3},{type:`binary`,command:`brew install copilot-cli`,priority:4}],linux:[{type:`bun`,command:`bun add -g @github/copilot`,priority:1},{type:`npm`,command:`npm i -g @github/copilot`,priority:2},{type:`binary`,command:`curl -fsSL https://gh.io/copilot-install | bash`,priority:3},{type:`binary`,command:`brew install copilot-cli`,priority:4}]}},i={name:`cursor`,aliases:[`cursor`,`agent`],displayName:`Cursor CLI`,description:`Cursor AI 编程助手命令行工具`,homepage:`https://cursor.com/docs/cli`,package:``,binaryName:`agent`,platforms:{windows:[{type:`binary`,command:`irm 'https://cursor.com/install?win32=true' | iex`,priority:1}],macos:[{type:`binary`,command:`curl https://cursor.com/install -fsS | bash`,priority:1}],linux:[{type:`binary`,command:`curl https://cursor.com/install -fsS | bash`,priority:1}]}},a={name:`droid`,aliases:[`droid`],displayName:`Droid`,description:`Factory AI 软件工程 Agent CLI`,homepage:`https://docs.factory.ai/cli/getting-started/overview`,package:`droid`,binaryName:`droid`,platforms:{windows:[{type:`bun`,command:`bun add -g droid`,priority:1},{type:`npm`,command:`npm i -g droid`,priority:2},{type:`binary`,command:`irm https://app.factory.ai/cli/windows | iex`,priority:3}],macos:[{type:`bun`,command:`bun add -g droid`,priority:1},{type:`npm`,command:`npm i -g droid`,priority:2},{type:`binary`,command:`curl -fsSL https://app.factory.ai/cli | sh`,priority:3},{type:`binary`,command:`brew install --cask droid`,priority:4}],linux:[{type:`bun`,command:`bun add -g droid`,priority:1},{type:`npm`,command:`npm i -g droid`,priority:2},{type:`binary`,command:`curl -fsSL https://app.factory.ai/cli | sh`,priority:3},{type:`binary`,command:`brew install --cask droid`,priority:4}]}},o={name:`gemini`,aliases:[`gemini`],displayName:`Gemini CLI`,description:`Google 开源 AI 编程助手 CLI`,homepage:`https://geminicli.com`,package:`@google/gemini-cli`,binaryName:`gemini`,platforms:{windows:[{type:`bun`,command:`bun add -g @google/gemini-cli`,priority:1},{type:`npm`,command:`npm i -g @google/gemini-cli`,priority:2}],macos:[{type:`bun`,command:`bun add -g @google/gemini-cli`,priority:1},{type:`npm`,command:`npm i -g @google/gemini-cli`,priority:2},{type:`binary`,command:`brew install gemini-cli`,priority:3}],linux:[{type:`bun`,command:`bun add -g @google/gemini-cli`,priority:1},{type:`npm`,command:`npm i -g @google/gemini-cli`,priority:2},{type:`binary`,command:`brew install gemini-cli`,priority:3}]}},s={name:`opencode`,aliases:[`opencode`],displayName:`OpenCode`,description:`开源 AI 编程 CLI`,homepage:`https://opencode.ai`,package:`opencode-ai`,binaryName:`opencode`,platforms:{windows:[{type:`bun`,command:`bun add -g opencode-ai`,priority:1},{type:`npm`,command:`npm i -g opencode-ai`,priority:2}],macos:[{type:`bun`,command:`bun add -g opencode-ai`,priority:1},{type:`npm`,command:`npm i -g opencode-ai`,priority:2},{type:`binary`,command:`curl -fsSL https://opencode.ai/install | bash`,priority:3},{type:`binary`,command:`brew install anomalyco/tap/opencode`,priority:4}],linux:[{type:`bun`,command:`bun add -g opencode-ai`,priority:1},{type:`npm`,command:`npm i -g opencode-ai`,priority:2},{type:`binary`,command:`curl -fsSL https://opencode.ai/install | bash`,priority:3},{type:`binary`,command:`brew install anomalyco/tap/opencode`,priority:4}]}},c=[t,n,r,i,a,o,s,{name:`pi`,aliases:[`pi`],displayName:`Pi`,description:`极简可扩展的终端编程 Agent`,homepage:`https://pi.dev`,package:`@mariozechner/pi-coding-agent`,binaryName:`pi`,platforms:{windows:[{type:`bun`,command:`bun add -g @mariozechner/pi-coding-agent`,priority:1},{type:`npm`,command:`npm i -g @mariozechner/pi-coding-agent`,priority:2}],macos:[{type:`bun`,command:`bun add -g @mariozechner/pi-coding-agent`,priority:1},{type:`npm`,command:`npm i -g @mariozechner/pi-coding-agent`,priority:2}],linux:[{type:`bun`,command:`bun add -g @mariozechner/pi-coding-agent`,priority:1},{type:`npm`,command:`npm i -g @mariozechner/pi-coding-agent`,priority:2}]}}];function l(){return c}function u(e){return c.find(t=>t.name===e||t.aliases.includes(e))}function d(){switch(e.platform){case`win32`:return`windows`;case`darwin`:return`macos`;default:return`linux`}}async function f(){try{let e=Bun.spawn([`bun`,`--version`],{stdout:`pipe`,stderr:`pipe`});return await e.exited,e.exitCode===0}catch{return!1}}async function p(){try{let e=Bun.spawn([`npm`,`--version`],{stdout:`pipe`,stderr:`pipe`});return await e.exited,e.exitCode===0}catch{return!1}}async function m(t){try{let n=e.platform===`win32`?`where`:`which`,r=Bun.spawn([n,t],{stdout:`pipe`,stderr:`pipe`});return await r.exited,r.exitCode===0}catch{return!1}}export{u as a,n as c,p as i,t as l,m as n,l as o,f as r,s,d as t};
@@ -1,3 +0,0 @@
1
- import{i as e,n as t,o as n,r}from"./detect-BJHrcpbU.mjs";import{n as i,r as a}from"./version-G_0-W0JG.mjs";import o from"picocolors";async function s(){console.log(o.bold(`
2
- Silver CLI Environment Check
3
- `)),console.log(o.bold(`Package Managers:`));let s=await r();console.log(` Bun: ${s?o.green(`available`):o.red(`not found`)}`);let c=await e();console.log(` npm: ${c?o.green(`available`):o.red(`not found`)}`),console.log(`\n${o.bold(`Installed Agents:`)}`);let l=n(),u=!1;for(let e of l)if(await t(e.binaryName)){u=!0;let t=await i(e.binaryName),n=await a(e.package),r=t&&n&&t!==n;console.log(` ${e.displayName}: ${t??`unknown`}${r?o.yellow(` (update available: ${n})`):``}`)}u||console.log(o.dim(` No agents installed`)),console.log(`\n${o.bold(`Issues:`)}`);let d=[];if(!s&&!c&&d.push(`No package manager found. Install bun or npm.`),d.length===0)console.log(o.green(` No issues found.`));else for(let e of d)console.log(o.yellow(` - ${e}`));console.log()}export{s as doctorCommand};
@@ -1,2 +0,0 @@
1
- import{a as e,n as t,t as n}from"./detect-BJHrcpbU.mjs";import{n as r,r as i,t as a}from"./version-G_0-W0JG.mjs";import o from"picocolors";async function s(s){let c=e(s);if(!c){console.log(o.red(`Unknown agent: ${s}`));return}let l=await t(c.binaryName),u=l?await r(c.binaryName):void 0,d=await i(c.package),f=l?await a(c.binaryName):void 0,p=n();console.log(o.bold(`\n${c.displayName}\n`)),console.log(` Name: ${c.name}`),console.log(` Aliases: ${c.aliases.join(`, `)}`),console.log(` Description: ${c.description}`),console.log(` Package: ${c.package}`),console.log(` Binary: ${c.binaryName}`),console.log(` Installed: ${l?o.green(`Yes`):o.red(`No`)}`),u&&console.log(` Version: ${u}`),d&&console.log(` Latest: ${d}`),f&&console.log(` Path: ${f}`),console.log(o.bold(`
2
- Install Methods:`));let m=c.platforms[p]??[];for(let e of m)console.log(` ${o.green(`+`)} [${e.type}] ${e.command}`);console.log()}export{s as infoCommand};
@@ -1 +0,0 @@
1
- import{a as e,n as t}from"./detect-BJHrcpbU.mjs";import{t as n}from"./package-manager-DmASCUc5.mjs";import r from"picocolors";async function i(i){let a=e(i);if(!a){console.log(r.red(`Unknown agent: ${i}`));return}if(await t(a.binaryName)){console.log(r.yellow(`${a.displayName} is already installed.`));return}console.log(r.cyan(`Installing ${a.displayName}...`)),await n(a)?console.log(r.green(`${a.displayName} installed successfully!`)):console.log(r.red(`Failed to install ${a.displayName}.`))}export{i as installCommand};
@@ -1,3 +0,0 @@
1
- import{n as e,o as t}from"./detect-BJHrcpbU.mjs";import{n}from"./version-G_0-W0JG.mjs";import r from"picocolors";async function i(){let i=t();console.log(r.bold(`
2
- AI Agents:
3
- `));for(let t of i){let i=await e(t.binaryName),a=i?await n(t.binaryName):void 0,o=t.displayName.padEnd(16),s=i?r.green(`installed`):r.gray(`not installed`),c=a?r.dim(a):``;console.log(` ${o} ${s} ${c}`)}console.log()}export{i as listCommand};
@@ -1 +0,0 @@
1
- import{i as e,r as t,t as n}from"./detect-BJHrcpbU.mjs";import r from"node:process";async function i(e){let t=n(),i=typeof e==`function`?e(t):e;try{let e;return e=r.platform===`win32`?Bun.spawn([`powershell.exe`,`-Command`,i],{stdio:[`inherit`,`inherit`,`inherit`]}):Bun.spawn([`sh`,`-c`,i],{stdio:[`inherit`,`inherit`,`inherit`]}),await e.exited,e.exitCode===0}catch{return!1}}async function a(e){try{let t=Bun.spawn([`bun`,`add`,`-g`,e],{stdio:[`inherit`,`inherit`,`inherit`]});return await t.exited,t.exitCode===0}catch{return!1}}async function o(e){try{let t=Bun.spawn([`bun`,`update`,`-g`,e],{stdio:[`inherit`,`inherit`,`inherit`]});return await t.exited,t.exitCode===0}catch{return!1}}async function s(e){try{let t=Bun.spawn([`bun`,`remove`,`-g`,e],{stdio:[`inherit`,`inherit`,`inherit`]});return await t.exited,t.exitCode===0}catch{return!1}}async function c(e){try{let t=Bun.spawn([`npm`,`i`,`-g`,e],{stdio:[`inherit`,`inherit`,`inherit`]});return await t.exited,t.exitCode===0}catch{return!1}}async function l(e){try{let t=Bun.spawn([`npm`,`update`,`-g`,e],{stdio:[`inherit`,`inherit`,`inherit`]});return await t.exited,t.exitCode===0}catch{return!1}}async function u(e){try{let t=Bun.spawn([`npm`,`uninstall`,`-g`,e],{stdio:[`inherit`,`inherit`,`inherit`]});return await t.exited,t.exitCode===0}catch{return!1}}function d(e){let t=n(),r=e.platforms[t];return r?[...r].sort((e,t)=>e.priority-t.priority):[]}async function f(n){let r=d(n);for(let o of r)if(o.type===`bun`){if(!await t())continue;if(await a(n.package))return!0}else if(o.type===`npm`){if(!await e())continue;if(await c(n.package))return!0}else if(o.type===`binary`&&await i(o.command))return!0;return!1}async function p(n){let r=d(n);for(let a of r)if(a.type===`bun`){if(!await t())continue;if(await o(n.package))return!0}else if(a.type===`npm`){if(!await e())continue;if(await l(n.package))return!0}else if(a.type===`binary`&&await i(a.command))return!0;return!1}async function m(n){let r=!1;if(await t()){let e=await s(n.package);r||=e}if(await e()){let e=await u(n.package);r||=e}return r}export{m as n,p as r,f as t};
@@ -1 +0,0 @@
1
- import{a as e}from"./detect-BJHrcpbU.mjs";import{n as t}from"./package-manager-DmASCUc5.mjs";import n from"picocolors";async function r(r){let i=e(r);if(!i){console.log(n.red(`Unknown agent: ${r}`));return}console.log(n.cyan(`Uninstalling ${i.displayName}...`)),await t(i)?console.log(n.green(`${i.displayName} uninstalled successfully!`)):console.log(n.red(`Failed to uninstall ${i.displayName}.`))}export{r as uninstallCommand};
@@ -1 +0,0 @@
1
- import{a as e,n as t,o as n}from"./detect-BJHrcpbU.mjs";import{r}from"./package-manager-DmASCUc5.mjs";import{n as i,r as a}from"./version-G_0-W0JG.mjs";import o from"picocolors";async function s(r,i){if(i){let e=n();for(let n of e)await t(n.binaryName)&&await c(n);return}if(!r){console.log(o.red(`Please specify an agent name or use --all flag`));return}let a=e(r);if(!a){console.log(o.red(`Unknown agent: ${r}`));return}await c(a)}async function c(e){let t=await i(e.binaryName),n=await a(e.package);if(t&&n&&t===n){console.log(o.green(`${e.displayName} is up to date (${t})`));return}let s=t?` (${t} -> ${n??`latest`})`:``;console.log(o.cyan(`Updating ${e.displayName}...${s}`)),await r(e)?console.log(o.green(`${e.displayName} updated successfully!`)):console.log(o.red(`Failed to update ${e.displayName}.`))}export{s as updateCommand};
@@ -1,2 +0,0 @@
1
- import e from"node:process";async function t(e){try{let t=Bun.spawn([e,`--version`],{stdout:`pipe`,stderr:`pipe`});return await t.exited,t.exitCode===0&&(await new Response(t.stdout).text()).trim()||void 0}catch{return}}async function n(e){try{let t=await fetch(`https://registry.npmjs.org/${e}/latest`);return t.ok?(await t.json()).version:void 0}catch{return}}async function r(t){try{let n=e.platform===`win32`?`where`:`which`,r=Bun.spawn([n,t],{stdout:`pipe`,stderr:`pipe`});return await r.exited,r.exitCode===0?(await new Response(r.stdout).text()).trim().split(`
2
- `)[0]:void 0}catch{return}}export{t as n,n as r,r as t};