@xship/cli 0.0.137 → 0.0.139

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.
@@ -28,7 +28,7 @@
28
28
  },
29
29
  {
30
30
  "description": "轻量档 | 低延迟 | 高频短任务",
31
- "group": "grp_pzxnceygmqlp",
31
+ "group": "grp_irydsgijuckh",
32
32
  "group_name": "",
33
33
  "hidden": false,
34
34
  "id": "claude-haiku-4-5-20251001",
@@ -37,7 +37,7 @@
37
37
  },
38
38
  {
39
39
  "description": "100 万上下文 | 12.8 万输出 | 低延迟 | 高频轻量任务",
40
- "group": "grp_6eg2dq9ywgrg",
40
+ "group": "grp_pzxnceygmqlp",
41
41
  "group_name": "",
42
42
  "hidden": false,
43
43
  "id": "claude-haiku-5-5",
@@ -55,7 +55,7 @@
55
55
  },
56
56
  {
57
57
  "description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
58
- "group": "grp_6lyxfgbs440g",
58
+ "group": "grp_6eg2dq9ywgrg",
59
59
  "group_name": "",
60
60
  "hidden": false,
61
61
  "id": "claude-opus-4-7",
@@ -73,7 +73,7 @@
73
73
  },
74
74
  {
75
75
  "description": "100 万上下文 | 12.8 万输出 | 自适应思考五档 | Agent 编程",
76
- "group": "grp_6eg2dq9ywgrg",
76
+ "group": "grp_irydsgijuckh",
77
77
  "group_name": "",
78
78
  "hidden": false,
79
79
  "id": "claude-opus-5",
@@ -91,7 +91,7 @@
91
91
  },
92
92
  {
93
93
  "description": "100 万上下文 | Agent 编程 | 长上下文不加价",
94
- "group": "grp_rld6af0zorqd",
94
+ "group": "grp_irydsgijuckh",
95
95
  "group_name": "",
96
96
  "hidden": false,
97
97
  "id": "claude-sonnet-4-6",
@@ -100,7 +100,7 @@
100
100
  },
101
101
  {
102
102
  "description": "100 万上下文 | Agent 编程 | 工具调用 | 知识工作",
103
- "group": "grp_rld6af0zorqd",
103
+ "group": "grp_6co8aqwefsoh",
104
104
  "group_name": "",
105
105
  "hidden": false,
106
106
  "id": "claude-sonnet-5",
@@ -109,7 +109,7 @@
109
109
  },
110
110
  {
111
111
  "description": "100 万上下文 | 12.8 万输出 | Agent 编程 | 知识工作",
112
- "group": "grp_6lyxfgbs440g",
112
+ "group": "grp_6eg2dq9ywgrg",
113
113
  "group_name": "",
114
114
  "hidden": false,
115
115
  "id": "claude-sonnet-5-5",
@@ -118,15 +118,6 @@
118
118
  }
119
119
  ],
120
120
  "codex": [
121
- {
122
- "description": "100 万上下文 | 12.8 万输出 | 复杂专业负载",
123
- "group": "grp_irydsgijuckh",
124
- "group_name": "",
125
- "hidden": false,
126
- "id": "gpt-5.5",
127
- "name": "gpt-5.5",
128
- "recommended": false
129
- },
130
121
  {
131
122
  "description": "105 万上下文 | 12.8 万输出 | 大批量低成本档",
132
123
  "group": "grp_irydsgijuckh",
@@ -138,7 +129,7 @@
138
129
  },
139
130
  {
140
131
  "description": "105 万上下文 | 12.8 万输出 | 前沿档",
141
- "group": "grp_squ2qzjnehps",
132
+ "group": "grp_bsbtt432saoq",
142
133
  "group_name": "",
143
134
  "hidden": false,
144
135
  "id": "gpt-5.6-sol",
@@ -156,7 +147,7 @@
156
147
  },
157
148
  {
158
149
  "description": "105 万上下文 | 12.8 万输出 | 思考强度至 max | 计算机操作 / 编码 / 科学基准接近饱和",
159
- "group": "grp_6co8aqwefsoh",
150
+ "group": "grp_irydsgijuckh",
160
151
  "group_name": "",
161
152
  "hidden": false,
162
153
  "id": "gpt-6-astra",
@@ -165,7 +156,7 @@
165
156
  },
166
157
  {
167
158
  "description": "转发至 gpt-6-sol | 实际由 gpt-6-sol 响应 | 105 万上下文 | 12.8 万输出",
168
- "group": "grp_6co8aqwefsoh",
159
+ "group": "grp_mb5v069lpnze",
169
160
  "group_name": "",
170
161
  "hidden": false,
171
162
  "id": "gpt-6-luna",
@@ -183,7 +174,7 @@
183
174
  },
184
175
  {
185
176
  "description": "105 万上下文 | 12.8 万输出 | 文字与图像输入 | 工具调用、联网搜索、结构化输出 | 工具调用使用 Responses API",
186
- "group": "grp_6co8aqwefsoh",
177
+ "group": "grp_irydsgijuckh",
187
178
  "group_name": "",
188
179
  "hidden": false,
189
180
  "id": "gpt-6.1-sol",
@@ -284,7 +275,7 @@
284
275
  },
285
276
  {
286
277
  "description": "约 100 万上下文 | 深度推理 | 文本、图像、音视频输入",
287
- "group": "grp_z5khwusxuh2j",
278
+ "group": "grp_3pi5kyqkp51b",
288
279
  "group_name": "",
289
280
  "hidden": false,
290
281
  "id": "gemini-4-argon",
@@ -322,7 +313,7 @@
322
313
  },
323
314
  {
324
315
  "description": "50 万上下文 | 长时 Agent | 编码与视觉项目",
325
- "group": "grp_irydsgijuckh",
316
+ "group": "grp_l34dwliv4yas",
326
317
  "group_name": "",
327
318
  "hidden": false,
328
319
  "id": "grok-4.7",
@@ -28,7 +28,7 @@
28
28
  },
29
29
  {
30
30
  "description": "轻量档 | 低延迟 | 高频短任务",
31
- "group": "grp_pzxnceygmqlp",
31
+ "group": "grp_irydsgijuckh",
32
32
  "group_name": "",
33
33
  "hidden": false,
34
34
  "id": "claude-haiku-4-5-20251001",
@@ -37,7 +37,7 @@
37
37
  },
38
38
  {
39
39
  "description": "100 万上下文 | 12.8 万输出 | 低延迟 | 高频轻量任务",
40
- "group": "grp_6eg2dq9ywgrg",
40
+ "group": "grp_pzxnceygmqlp",
41
41
  "group_name": "",
42
42
  "hidden": false,
43
43
  "id": "claude-haiku-5-5",
@@ -55,7 +55,7 @@
55
55
  },
56
56
  {
57
57
  "description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
58
- "group": "grp_6lyxfgbs440g",
58
+ "group": "grp_6eg2dq9ywgrg",
59
59
  "group_name": "",
60
60
  "hidden": false,
61
61
  "id": "claude-opus-4-7",
@@ -73,7 +73,7 @@
73
73
  },
74
74
  {
75
75
  "description": "100 万上下文 | 12.8 万输出 | 自适应思考五档 | Agent 编程",
76
- "group": "grp_6eg2dq9ywgrg",
76
+ "group": "grp_irydsgijuckh",
77
77
  "group_name": "",
78
78
  "hidden": false,
79
79
  "id": "claude-opus-5",
@@ -91,7 +91,7 @@
91
91
  },
92
92
  {
93
93
  "description": "100 万上下文 | Agent 编程 | 长上下文不加价",
94
- "group": "grp_rld6af0zorqd",
94
+ "group": "grp_irydsgijuckh",
95
95
  "group_name": "",
96
96
  "hidden": false,
97
97
  "id": "claude-sonnet-4-6",
@@ -100,7 +100,7 @@
100
100
  },
101
101
  {
102
102
  "description": "100 万上下文 | Agent 编程 | 工具调用 | 知识工作",
103
- "group": "grp_rld6af0zorqd",
103
+ "group": "grp_6co8aqwefsoh",
104
104
  "group_name": "",
105
105
  "hidden": false,
106
106
  "id": "claude-sonnet-5",
@@ -109,7 +109,7 @@
109
109
  },
110
110
  {
111
111
  "description": "100 万上下文 | 12.8 万输出 | Agent 编程 | 知识工作",
112
- "group": "grp_6lyxfgbs440g",
112
+ "group": "grp_6eg2dq9ywgrg",
113
113
  "group_name": "",
114
114
  "hidden": false,
115
115
  "id": "claude-sonnet-5-5",
@@ -118,15 +118,6 @@
118
118
  }
119
119
  ],
120
120
  "codex": [
121
- {
122
- "description": "100 万上下文 | 12.8 万输出 | 复杂专业负载",
123
- "group": "grp_irydsgijuckh",
124
- "group_name": "",
125
- "hidden": false,
126
- "id": "gpt-5.5",
127
- "name": "gpt-5.5",
128
- "recommended": false
129
- },
130
121
  {
131
122
  "description": "105 万上下文 | 12.8 万输出 | 大批量低成本档",
132
123
  "group": "grp_irydsgijuckh",
@@ -138,7 +129,7 @@
138
129
  },
139
130
  {
140
131
  "description": "105 万上下文 | 12.8 万输出 | 前沿档",
141
- "group": "grp_squ2qzjnehps",
132
+ "group": "grp_bsbtt432saoq",
142
133
  "group_name": "",
143
134
  "hidden": false,
144
135
  "id": "gpt-5.6-sol",
@@ -156,7 +147,7 @@
156
147
  },
157
148
  {
158
149
  "description": "105 万上下文 | 12.8 万输出 | 思考强度至 max | 计算机操作 / 编码 / 科学基准接近饱和",
159
- "group": "grp_6co8aqwefsoh",
150
+ "group": "grp_irydsgijuckh",
160
151
  "group_name": "",
161
152
  "hidden": false,
162
153
  "id": "gpt-6-astra",
@@ -165,7 +156,7 @@
165
156
  },
166
157
  {
167
158
  "description": "转发至 gpt-6-sol | 实际由 gpt-6-sol 响应 | 105 万上下文 | 12.8 万输出",
168
- "group": "grp_6co8aqwefsoh",
159
+ "group": "grp_mb5v069lpnze",
169
160
  "group_name": "",
170
161
  "hidden": false,
171
162
  "id": "gpt-6-luna",
@@ -183,7 +174,7 @@
183
174
  },
184
175
  {
185
176
  "description": "105 万上下文 | 12.8 万输出 | 文字与图像输入 | 工具调用、联网搜索、结构化输出 | 工具调用使用 Responses API",
186
- "group": "grp_6co8aqwefsoh",
177
+ "group": "grp_irydsgijuckh",
187
178
  "group_name": "",
188
179
  "hidden": false,
189
180
  "id": "gpt-6.1-sol",
@@ -284,7 +275,7 @@
284
275
  },
285
276
  {
286
277
  "description": "约 100 万上下文 | 深度推理 | 文本、图像、音视频输入",
287
- "group": "grp_z5khwusxuh2j",
278
+ "group": "grp_3pi5kyqkp51b",
288
279
  "group_name": "",
289
280
  "hidden": false,
290
281
  "id": "gemini-4-argon",
@@ -322,7 +313,7 @@
322
313
  },
323
314
  {
324
315
  "description": "50 万上下文 | 长时 Agent | 编码与视觉项目",
325
- "group": "grp_irydsgijuckh",
316
+ "group": "grp_l34dwliv4yas",
326
317
  "group_name": "",
327
318
  "hidden": false,
328
319
  "id": "grok-4.7",
@@ -1 +1 @@
1
- import{chmodSync as e,existsSync as t,mkdirSync as r,readFileSync as n,renameSync as o,writeFileSync as s}from"fs";import{homedir as a}from"os";import{dirname as l,join as i,sep as u}from"path";import{spawnSync as c}from"child_process";import p from"chalk";import{checkForUpdate as d,compareSemver as m,readLocalPackage as f,UPDATE_SOURCES as _}from"../commands/update.js";import{i18n as h}from"./i18n.js";import{isColorEnabled as g}from"./runtime-options.js";import{logger as x}from"../utils/logger.js";import{isHelpRequest as v}from"./cli-help.js";import{brand as y,brandEnvName as S}from"./brand.js";export const UPDATE_CHECK_INTERVAL_MS=216e5;export const INSTALL_RETRY_INTERVAL_MS=36e5;export const INSTALL_TIMEOUT_MS=45e3;function k(e,t){return g()?e(t):t}export function resolveUpdateCachePath(e=process.env){const t=e[S("CONFIG_DIR")]?.trim();if(t)return i(t,"update-state.json");const r=e[S("TEST_HOME")]?.trim();return i(r||a(),y().configDirName,"update-state.json")}export function isGlobalPackageInstall(e){return e.split(u).includes("node_modules")}export function isNpxExecution(e=process.env){return"exec"===e.npm_command||"npx"===e.npm_lifecycle_event}export function isPnpmGlobalInstall(e){return e.includes(`${u}.pnpm${u}`)||e.includes(`${u}pnpm${u}global${u}`)}export function resolveNpmGlobalPrefix(e){const t=`${u}node_modules${u}`,r=e.indexOf(t);if(r<0)return null;const n=e.slice(0,r);return n.endsWith(`${u}lib`)?l(n):n}export function shouldSkipStartupUpdate(e,t=process.env){return"1"===t[S("SKIP_AUTO_UPDATE")]||"1"===t[S("DISABLE_AUTO_UPDATE")]||(!(!["--json","--non-interactive","--dry-run","--help","-h","--version","-v"].some(t=>e.includes(t))&&!v(e))||e.includes("update")||e.includes("completion"))}function A(t,n,a,i,u){try{r(l(t),{recursive:!0,mode:448});const c=`${t}.tmp-${process.pid}`,p={package_name:n,checked_at:a,latest:i.latest,source:i.source,registry:i.registry,errors:i.errors,...void 0===u?{}:{install_attempted_at:u,install_attempted_version:i.latest||void 0}};s(c,JSON.stringify(p),{encoding:"utf-8",mode:384}),o(c,t),e(t,384)}catch(e){x.warn("Failed to persist update check cache:",e)}}export function windowsShellCommand(e,t){return[e,...t.map(e=>`"${e}"`)].join(" ")}const P=(e,t)=>{const r={stdio:"inherit",timeout:45e3,killSignal:"SIGTERM"};return"win32"===process.platform?c(windowsShellCommand(e,t),{...r,shell:!0}):c(e,t,r)},$=(e,t)=>c(process.execPath,[process.argv[1],...e],{stdio:"inherit",env:t});export async function runStartupUpdate(e,r={}){const o=r.env||process.env,s=r.localPackage||f(),a=r.globalInstall??isGlobalPackageInstall(s.root),l=r.npx??isNpxExecution(o);if(!a||l||shouldSkipStartupUpdate(e,o))return{status:"skipped",handled:!1,source:null};const i=r.now??Date.now(),u=r.cachePath||resolveUpdateCachePath(o),c=function(e,r,o){try{if(!t(e))return null;const s=JSON.parse(n(e,"utf-8"));if(s.package_name!==r.name||!Number.isFinite(s.checked_at))return null;const a=s.latest?216e5:6e5;return o-s.checked_at>=a?null:{result:{current:r.version,latest:s.latest,up_to_date:s.latest?m(r.version,s.latest)>=0:null,source:s.source,registry:s.registry,errors:Array.isArray(s.errors)?s.errors:[],error:s.latest?null:(s.errors||[]).map(e=>`${e.source}: ${e.error}`).join("; ")||"unknown"},installAttemptedAt:s.latest&&s.install_attempted_version===s.latest&&Number.isFinite(s.install_attempted_at)?s.install_attempted_at:null}}catch{return null}}(u,s,i);let g=c?.result,x=c?.installAttemptedAt||null;if(g||(g=await d({localPackage:s,fetchFn:r.fetchFn}),A(u,s.name,i,g),x=null),!g.latest)return{status:"unavailable",handled:!1,source:null};if(g.up_to_date)return{status:"current",handled:!1,source:g.source};if(null!==x&&i-x<36e5)return{status:"update_failed",handled:!1,source:g.source};const v=r.output||console.log,y=r.errorOutput||console.error,T=r.installRunner||P,b=isPnpmGlobalInstall(s.root),w=b?"win32"===process.platform?"pnpm.cmd":"pnpm":"win32"===process.platform?"npm.cmd":"npm",I=b?null:resolveNpmGlobalPrefix(s.root);v(k(p.cyan,h.t("update.auto_installing",{version:g.latest})));let E=null,N="unknown";for(const e of _.map(e=>e.registry)){const t=T(w,b?["add","--global",`${s.name}@${g.latest}`,"--registry",e]:["install","--global",...I?["--prefix",I]:[],`${s.name}@${g.latest}`,"--registry",e,"--no-audit","--no-fund","--fetch-timeout=15000","--fetch-retries=1","--fetch-retry-mintimeout=1000","--fetch-retry-maxtimeout=3000"]);if(0===t.status){E=e;break}N=t.error?.message||`exit ${t.status??"unknown"}`}if(!E)return A(u,s.name,i,g,i),y(k(p.yellow,h.t("update.auto_failed",{error:N}))),{status:"update_failed",handled:!1,source:g.source};v(k(p.green,h.t("update.auto_installed",{version:g.latest})));const U=(r.reexecRunner||$)(e,{...o,[S("SKIP_AUTO_UPDATE")]:"1"});return U.error?(y(k(p.yellow,h.t("update.reexec_failed",{error:U.error.message}))),{status:"update_failed",handled:!1,source:g.source}):(process.exitCode=U.status??1,{status:"reexecuted",handled:!0,source:g.source})}
1
+ import{chmodSync as e,existsSync as t,mkdirSync as r,readFileSync as n,renameSync as o,writeFileSync as s}from"fs";import{homedir as a}from"os";import{dirname as l,join as i,sep as u}from"path";import{spawnSync as c}from"child_process";import p from"chalk";import{checkForUpdate as d,readLocalPackage as m,UPDATE_SOURCES as f}from"../commands/update.js";import{i18n as _}from"./i18n.js";import{isColorEnabled as h}from"./runtime-options.js";import{logger as g}from"../utils/logger.js";import{isHelpRequest as x}from"./cli-help.js";import{brand as v,brandEnvName as y}from"./brand.js";export const INSTALL_RETRY_INTERVAL_MS=36e5;export const INSTALL_TIMEOUT_MS=45e3;function k(e,t){return h()?e(t):t}export function resolveUpdateCachePath(e=process.env){const t=e[y("CONFIG_DIR")]?.trim();if(t)return i(t,"update-state.json");const r=e[y("TEST_HOME")]?.trim();return i(r||a(),v().configDirName,"update-state.json")}export function isGlobalPackageInstall(e){return e.split(u).includes("node_modules")}export function isNpxExecution(e=process.env){return"exec"===e.npm_command||"npx"===e.npm_lifecycle_event}export function isPnpmGlobalInstall(e){return e.includes(`${u}.pnpm${u}`)||e.includes(`${u}pnpm${u}global${u}`)}export function resolveNpmGlobalPrefix(e){const t=`${u}node_modules${u}`,r=e.indexOf(t);if(r<0)return null;const n=e.slice(0,r);return n.endsWith(`${u}lib`)?l(n):n}export function shouldSkipStartupUpdate(e,t=process.env){return"1"===t[y("SKIP_AUTO_UPDATE")]||"1"===t[y("DISABLE_AUTO_UPDATE")]||(!(!["--json","--non-interactive","--dry-run","--help","-h","--version","-v"].some(t=>e.includes(t))&&!x(e))||e.includes("update")||e.includes("completion"))}function S(t,n,a,i,u){try{r(l(t),{recursive:!0,mode:448});const c=`${t}.tmp-${process.pid}`,p={package_name:n,checked_at:a,latest:i.latest,source:i.source,registry:i.registry,errors:i.errors,...void 0===u?{}:{install_attempted_at:u,install_attempted_version:i.latest||void 0}};s(c,JSON.stringify(p),{encoding:"utf-8",mode:384}),o(c,t),e(t,384)}catch(e){g.warn("Failed to persist update check cache:",e)}}export function windowsShellCommand(e,t){return[e,...t.map(e=>`"${e}"`)].join(" ")}const $=(e,t)=>{const r={stdio:"inherit",timeout:45e3,killSignal:"SIGTERM"};return"win32"===process.platform?c(windowsShellCommand(e,t),{...r,shell:!0}):c(e,t,r)},P=(e,t)=>c(process.execPath,[process.argv[1],...e],{stdio:"inherit",env:t});export async function runStartupUpdate(e,r={}){const o=r.env||process.env,s=r.localPackage||m(),a=r.globalInstall??isGlobalPackageInstall(s.root),l=r.npx??isNpxExecution(o);if(!a||l||shouldSkipStartupUpdate(e,o))return{status:"skipped",handled:!1,source:null};const i=r.now??Date.now(),u=r.cachePath||resolveUpdateCachePath(o),c=function(e,r){try{if(!t(e))return null;const o=JSON.parse(n(e,"utf-8"));return o.package_name===r.name&&Number.isFinite(o.checked_at)?o:null}catch{return null}}(u,s);let h=function(e,t,r){if(!e||e.latest||r-e.checked_at>=6e5)return null;const n=Array.isArray(e.errors)?e.errors:[];return{current:t.version,latest:null,up_to_date:null,source:e.source,registry:e.registry,errors:n,error:n.map(e=>`${e.source}: ${e.error}`).join("; ")||"unknown"}}(c,s,i),g=null;if(h||(h=await d({localPackage:s,fetchFn:r.fetchFn}),h.latest&&c?.install_attempted_version===h.latest&&Number.isFinite(c.install_attempted_at)&&(g=c.install_attempted_at),S(u,s.name,i,h,g??void 0)),!h.latest)return{status:"unavailable",handled:!1,source:null};if(h.up_to_date)return{status:"current",handled:!1,source:h.source};if(null!==g&&i-g<36e5)return{status:"update_failed",handled:!1,source:h.source};const x=r.output||console.log,v=r.errorOutput||console.error,b=r.installRunner||$,w=isPnpmGlobalInstall(s.root),I=w?"win32"===process.platform?"pnpm.cmd":"pnpm":"win32"===process.platform?"npm.cmd":"npm",T=w?null:resolveNpmGlobalPrefix(s.root);x(k(p.cyan,_.t("update.auto_installing",{version:h.latest})));let N=null,A="unknown";for(const e of f.map(e=>e.registry)){const t=b(I,w?["add","--global",`${s.name}@${h.latest}`,"--registry",e]:["install","--global",...T?["--prefix",T]:[],`${s.name}@${h.latest}`,"--registry",e,"--no-audit","--no-fund","--fetch-timeout=15000","--fetch-retries=1","--fetch-retry-mintimeout=1000","--fetch-retry-maxtimeout=3000"]);if(0===t.status){N=e;break}A=t.error?.message||`exit ${t.status??"unknown"}`}if(!N)return S(u,s.name,i,h,i),v(k(p.yellow,_.t("update.auto_failed",{error:A}))),{status:"update_failed",handled:!1,source:h.source};x(k(p.green,_.t("update.auto_installed",{version:h.latest})));const E=(r.reexecRunner||P)(e,{...o,[y("SKIP_AUTO_UPDATE")]:"1"});return E.error?(v(k(p.yellow,_.t("update.reexec_failed",{error:E.error.message}))),{status:"update_failed",handled:!1,source:h.source}):(process.exitCode=E.status??1,{status:"reexecuted",handled:!0,source:h.source})}
@@ -1 +1 @@
1
- import{execSync as o,spawnSync as t}from"child_process";import{i18n as n}from"./i18n.js";import e from"inquirer";import r from"chalk";import{logger as i}from"../utils/logger.js";import{configManager as l}from"./config.js";import{getAdapter as s,listAdapters as a,TOOL_ADAPTERS as c}from"./tools/registry.js";import{backupBeforeWrite as d,listBackups as p,restoreBackup as u}from"./tools/backup.js";import{existsSync as m,rmSync as f}from"fs";import{dirname as g,join as h}from"path";import{toolHome as w}from"./tools/types.js";import{stringWidth as y}from"../utils/string-width.js";import{resolveModelCatalog as P}from"./model-catalog.js";import{compareVersions as $,getToolMinVersion as T}from"./model-registry.js";import{findInstalls as C,forgetInstalls as v,installLabel as k,mirrorInstallCommand as E,npmMirrorInstallCommand as O}from"./tools/tool-installs.js";import{mirrorInstall as _}from"./tool-upgrade.js";import{CLI_NAME as S}from"./brand.js";import{track as N,trackStep as M}from"./telemetry.js";import{addUserPathDir as j,broadcastEnvChange as U}from"./windows-env.js";export{$ as compareVersions};function b(o){const t=c[o];return{name:t.name,command:t.command,installCommand:t.installCommand,configPath:t.configPath,displayName:t.displayName,...t.hidden?{hidden:!0}:{},...t.isInstalled?{gui:!0}:{}}}function x(){const o=new Set;for(const t of l.listProfiles()){const n=l.getProfile(t);for(const t of[n.api_key,...Object.values(n.tool_api_keys??{})])t?.trim()&&o.add(t.trim())}return[...o]}export const SUPPORTED_TOOLS=Object.fromEntries(Object.keys(c).map(o=>[o,b(o)]));export class ToolManager{static instance;constructor(){}static getInstance(){return ToolManager.instance||(ToolManager.instance=new ToolManager),ToolManager.instance}isToolInstalled(o){if(!SUPPORTED_TOOLS[o])return!1;const t=s(o);if(t?.isInstalled)try{return t.isInstalled()}catch{return!1}return this.isOnPath(o)||null!==this.nativeLauncher(o)}isOnPath(t){const n=SUPPORTED_TOOLS[t];if(!n)return!1;try{const t="win32"===process.platform?`where ${n.command}`:`which ${n.command}`;return o(t,{stdio:"pipe"}),!0}catch{return!1}}nativeLauncher(o){const t=s(o),n=t?.installSpec?.native?.binDir;if(!t||!n)return null;const e="win32"===process.platform?`${t.command}.exe`:t.command,r=h(w(),...n,e);return m(r)?r:null}ensureNativeOnPath(o){if("win32"!==process.platform||this.isOnPath(o))return null;const t=this.nativeLauncher(o);if(!t)return null;const n=g(t);try{if(!j(n))return null}catch(t){return i.logError(`ensureNativeOnPath: ${o}`,t),null}return U(),process.env.Path=`${process.env.Path??""};${n}`,n}async installTool(o){return M(`install:${o}`,()=>this.installToolNow(o))}async installToolNow(t){const i=SUPPORTED_TOOLS[t];if(!i)throw new Error(`Unknown tool: ${t}`);const l=s(t)?.installSpec;if(l&&(l.mirrorScript||l.npmPackage)){const o=E(l);if(await _(l)&&(v(),this.isToolInstalled(t)))return void console.log(r.green("√ "+n.t("wizard.tool_installed")));throw console.log(r.red("× "+n.t("wizard.install_failed"))),console.log(r.yellow(" ! "+n.t("install.manual_command",{tool:i.displayName,command:o}))),l.mirrorScript&&l.npmPackage&&console.log(r.yellow(" ! "+n.t("install.manual_npm",{command:O(l)}))),new Error(`Failed to install ${i.displayName}`)}const a=i.installCommand;console.log(r.gray("$ ")+r.white(a));try{return o(a,{stdio:"inherit"}),v(),void console.log(r.green("√ "+n.t("wizard.tool_installed")))}catch(o){if(console.log(r.red("× "+n.t("wizard.install_failed"))),!/EACCES|EPERM|permission denied/i.test(`${o?.message??""}${o?.stderr??""}`)&&243!==o?.status&&!a.startsWith("npm "))throw new Error(`Failed to install ${i.displayName}: ${o}`);console.log(r.yellow(" ! "+("win32"===process.platform?n.t("install.permission_windows",{command:a}):n.t("install.permission_unix",{command:a}))))}const{action:c}=await e.prompt([{type:"list",name:"action",message:n.t("install.what_next"),choices:[{name:n.t("install.installed_continue"),value:"continue"},{name:n.t("install.cancel_install"),value:"cancel"}]}]);if("cancel"===c)throw new Error(n.t("install.user_cancelled"));if(v(),!this.isToolInstalled(t))throw console.log(r.red("× "+n.t("install.still_not_installed",{tool:i.displayName}))),new Error(`${i.displayName} is not installed`);console.log(r.green("√ "+n.t("install.verified_success",{tool:i.displayName})))}getToolConfig(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);try{return t.getConfig()}catch(t){return i.warn(`Failed to read config for ${o}:`,t),i.logError(`ToolManager.getToolConfig(${o})`,t),null}}updateToolConfig(o,t){const n=s(o);if(!n)throw new Error(`Unknown tool: ${o}`);if(!n.updateConfig)throw new Error(`Tool ${o} does not support raw config updates`);n.updateConfig(t)}forceResetConfig(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);const n=t.forceResetPaths?t.forceResetPaths():this.backupPathsFor(t),e=[];for(const o of n)m(o)&&(d(o),f(o,{force:!0}),e.push(o));return e}loadPrivateConfig(o,t,n,e,r={}){const i=s(o);if(!i)throw new Error(`Unknown tool: ${o}`);r.force&&this.forceResetConfig(o),i.loadPrivateConfig({apiKey:t,baseUrl:l.getBaseUrl(),models:n,settings:l.getToolSettings(o),...e?{catalog:e}:{}})}async applyPrivateConfig(o,t,n,e={}){const r=this.installedVersion(o);return M(`apply:${o}`,()=>this.applyPrivateConfigNow(o,t,n,e),{...r?{tool_version:r}:{},...e.force?{force:!0}:{}})}async applyPrivateConfigNow(o,t,n,e){const r=s(o);if(!r)throw new Error(`Unknown tool: ${o}`);const i=r.wantsModelCatalog?await P(t):null;e.force?this.loadPrivateConfig(o,t,n,i??void 0,{force:!0}):i?this.loadPrivateConfig(o,t,n,i):this.loadPrivateConfig(o,t,n)}applyNotes(o){const t=s(o);if(!t)return[];const e=[];try{t.applyNotes&&e.push(...t.applyNotes())}catch(t){i.logError(`ToolManager.applyNotes(${o})`,t)}const r=this.outdatedVersion(o);if(r){e.push({kind:"action",text:n.t("tools.version_outdated",{current:r.current,min:r.min,upgrade:t.installSpec?`${S} upgrade ${o}`:t.upgradeCommand||t.installCommand})});for(const o of t.upgradeHints?.(r.min)??[])e.push({kind:"action",text:o})}const l=t.installSpec?C(t.installSpec):[];return l.length>1&&e.push({kind:"action",text:n.t("upgrade.duplicates_note",{count:String(l.length),active:k(l[0]),others:l.slice(1).map(k).join("、"),tool:o})}),e}printApplied(o,t=16){const n=SUPPORTED_TOOLS[o]?.displayName??o,e=this.applyNotes(o);for(const o of e.filter(o=>"detail"===o.kind))i.record(`${n}: ${o.text}`);const l=e.filter(o=>"summary"===o.kind).map(o=>o.text).join(";"),s=" ".repeat(Math.max(1,t-y(n)));console.log(r.green("√ "+n)+(l?s+l:""));for(const o of e.filter(o=>"action"===o.kind))console.log(r.yellow(" ! "+o.text))}installedVersion(o){const n=s(o);if(!n)return null;if(n.installSpec)return C(n.installSpec)[0]?.version??null;if(n.installedVersion)try{return n.installedVersion()}catch(t){return i.logError(`ToolManager.installedVersion(${o})`,t),null}if(n.isInstalled)return null;try{const o={encoding:"utf-8",timeout:1e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]},e=`${("win32"===process.platform?t(`${n.command} --version`,{...o,shell:!0}):t(n.command,["--version"],o)).stdout??""}`.match(/(\d+)\.(\d+)\.(\d+)/);return e?e[0]:null}catch{return null}}outdatedVersion(o){const t=T(o);if(!t)return null;const n=this.installedVersion(o);return n&&$(n,t)<0?{current:n,min:t}:null}unloadPrivateConfig(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);try{t.unloadPrivateConfig({savedKeys:x()}),N(`remove:${o}`,"ok")}catch(t){throw N(`remove:${o}`,"fail",{error:t}),t}let e=[];try{e=t.unloadNotes?.()??[]}catch(t){i.logError(`ToolManager.unloadNotes(${o})`,t)}return e.length>0?e:[{kind:"action",text:n.t("config.reopen_hint",{tool:t.displayName})}]}async clearPinnedModels(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);if(l.setToolModel(o,null),!t.clearPinnedModels)return[];const n=l.getApiKeyForTool(o),e=t.wantsModelCatalog&&n?await P(n):null;return t.clearPinnedModels(e??void 0)}supportsClearPinnedModels(o){return Boolean(s(o)?.clearPinnedModels)}holdsOurConfig(o){const t=s(o);if(!t)return!1;const n=x();return t.holdsOurConfig?t.holdsOurConfig(n):Boolean(t.detectCurrentConfig().apiKey)}detectCurrentConfig(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);return t.detectCurrentConfig()}backupPathsFor(o){return o.backupPaths?o.backupPaths():[o.configPath]}listToolBackups(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);return this.backupPathsFor(t).map(o=>({file:o,backups:p(o)}))}restorePrivateConfig(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);return this.backupPathsFor(t).map(o=>({file:o,result:u(o)}))}getInstalledTools(){return Object.keys(SUPPORTED_TOOLS).filter(o=>this.isToolInstalled(o))}getSupportedTools(){return a().filter(o=>!o.hidden).map(o=>b(o.name))}isGitInstalled(){try{const t="win32"===process.platform?"where git":"which git";return o(t,{stdio:"pipe"}),!0}catch{return!1}}}export const toolManager=ToolManager.getInstance();
1
+ import{execSync as o,spawnSync as t}from"child_process";import{i18n as n}from"./i18n.js";import e from"inquirer";import r from"chalk";import{logger as i}from"../utils/logger.js";import{configManager as l}from"./config.js";import{getAdapter as s,listAdapters as a,TOOL_ADAPTERS as c}from"./tools/registry.js";import{backupBeforeWrite as d,listBackups as p,restoreBackup as u}from"./tools/backup.js";import{existsSync as m,rmSync as f}from"fs";import{dirname as g,join as h}from"path";import{toolHome as w}from"./tools/types.js";import{stringWidth as y}from"../utils/string-width.js";import{resolveModelCatalog as P}from"./model-catalog.js";import{compareVersions as $,getToolMinVersion as T}from"./model-registry.js";import{findInstalls as C,forgetInstalls as v,installLabel as k,mirrorInstallCommand as E,npmMirrorInstallCommand as O,npmMirrorVersion as _}from"./tools/tool-installs.js";import{mirrorInstall as S}from"./tool-upgrade.js";import{CLI_NAME as N}from"./brand.js";import{track as M,trackStep as j}from"./telemetry.js";import{addUserPathDir as U,broadcastEnvChange as b}from"./windows-env.js";export{$ as compareVersions};function x(o){const t=c[o];return{name:t.name,command:t.command,installCommand:t.installCommand,configPath:t.configPath,displayName:t.displayName,...t.hidden?{hidden:!0}:{},...t.isInstalled?{gui:!0}:{}}}function I(){const o=new Set;for(const t of l.listProfiles()){const n=l.getProfile(t);for(const t of[n.api_key,...Object.values(n.tool_api_keys??{})])t?.trim()&&o.add(t.trim())}return[...o]}export const SUPPORTED_TOOLS=Object.fromEntries(Object.keys(c).map(o=>[o,x(o)]));export class ToolManager{static instance;constructor(){}static getInstance(){return ToolManager.instance||(ToolManager.instance=new ToolManager),ToolManager.instance}isToolInstalled(o){if(!SUPPORTED_TOOLS[o])return!1;const t=s(o);if(t?.isInstalled)try{return t.isInstalled()}catch{return!1}return this.isOnPath(o)||null!==this.nativeLauncher(o)}isOnPath(t){const n=SUPPORTED_TOOLS[t];if(!n)return!1;try{const t="win32"===process.platform?`where ${n.command}`:`which ${n.command}`;return o(t,{stdio:"pipe"}),!0}catch{return!1}}nativeLauncher(o){const t=s(o),n=t?.installSpec?.native?.binDir;if(!t||!n)return null;const e="win32"===process.platform?`${t.command}.exe`:t.command,r=h(w(),...n,e);return m(r)?r:null}ensureNativeOnPath(o){if("win32"!==process.platform||this.isOnPath(o))return null;const t=this.nativeLauncher(o);if(!t)return null;const n=g(t);try{if(!U(n))return null}catch(t){return i.logError(`ensureNativeOnPath: ${o}`,t),null}return b(),process.env.Path=`${process.env.Path??""};${n}`,n}async installTool(o){return j(`install:${o}`,()=>this.installToolNow(o))}async installToolNow(t){const i=SUPPORTED_TOOLS[t];if(!i)throw new Error(`Unknown tool: ${t}`);const l=s(t)?.installSpec;if(l&&(l.mirrorScript||l.npmPackage)){const o=E(l);if(await S(l)&&(v(),this.isToolInstalled(t)))return void console.log(r.green("√ "+n.t("wizard.tool_installed")));throw console.log(r.red("× "+n.t("wizard.install_failed"))),console.log(r.yellow(" ! "+n.t("install.manual_command",{tool:i.displayName,command:o}))),l.mirrorScript&&l.npmPackage&&console.log(r.yellow(" ! "+n.t("install.manual_npm",{command:O(l,await _(l))}))),new Error(`Failed to install ${i.displayName}`)}const a=i.installCommand;console.log(r.gray("$ ")+r.white(a));try{return o(a,{stdio:"inherit"}),v(),void console.log(r.green("√ "+n.t("wizard.tool_installed")))}catch(o){if(console.log(r.red("× "+n.t("wizard.install_failed"))),!/EACCES|EPERM|permission denied/i.test(`${o?.message??""}${o?.stderr??""}`)&&243!==o?.status&&!a.startsWith("npm "))throw new Error(`Failed to install ${i.displayName}: ${o}`);console.log(r.yellow(" ! "+("win32"===process.platform?n.t("install.permission_windows",{command:a}):n.t("install.permission_unix",{command:a}))))}const{action:c}=await e.prompt([{type:"list",name:"action",message:n.t("install.what_next"),choices:[{name:n.t("install.installed_continue"),value:"continue"},{name:n.t("install.cancel_install"),value:"cancel"}]}]);if("cancel"===c)throw new Error(n.t("install.user_cancelled"));if(v(),!this.isToolInstalled(t))throw console.log(r.red("× "+n.t("install.still_not_installed",{tool:i.displayName}))),new Error(`${i.displayName} is not installed`);console.log(r.green("√ "+n.t("install.verified_success",{tool:i.displayName})))}getToolConfig(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);try{return t.getConfig()}catch(t){return i.warn(`Failed to read config for ${o}:`,t),i.logError(`ToolManager.getToolConfig(${o})`,t),null}}updateToolConfig(o,t){const n=s(o);if(!n)throw new Error(`Unknown tool: ${o}`);if(!n.updateConfig)throw new Error(`Tool ${o} does not support raw config updates`);n.updateConfig(t)}forceResetConfig(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);const n=t.forceResetPaths?t.forceResetPaths():this.backupPathsFor(t),e=[];for(const o of n)m(o)&&(d(o),f(o,{force:!0}),e.push(o));return e}loadPrivateConfig(o,t,n,e,r={}){const i=s(o);if(!i)throw new Error(`Unknown tool: ${o}`);r.force&&this.forceResetConfig(o),i.loadPrivateConfig({apiKey:t,baseUrl:l.getBaseUrl(),models:n,settings:l.getToolSettings(o),...e?{catalog:e}:{}})}async applyPrivateConfig(o,t,n,e={}){const r=this.installedVersion(o);return j(`apply:${o}`,()=>this.applyPrivateConfigNow(o,t,n,e),{...r?{tool_version:r}:{},...e.force?{force:!0}:{}})}async applyPrivateConfigNow(o,t,n,e){const r=s(o);if(!r)throw new Error(`Unknown tool: ${o}`);const i=r.wantsModelCatalog?await P(t):null;e.force?this.loadPrivateConfig(o,t,n,i??void 0,{force:!0}):i?this.loadPrivateConfig(o,t,n,i):this.loadPrivateConfig(o,t,n)}applyNotes(o){const t=s(o);if(!t)return[];const e=[];try{t.applyNotes&&e.push(...t.applyNotes())}catch(t){i.logError(`ToolManager.applyNotes(${o})`,t)}const r=this.outdatedVersion(o);if(r){e.push({kind:"action",text:n.t("tools.version_outdated",{current:r.current,min:r.min,upgrade:t.installSpec?`${N} upgrade ${o}`:t.upgradeCommand||t.installCommand})});for(const o of t.upgradeHints?.(r.min)??[])e.push({kind:"action",text:o})}const l=t.installSpec?C(t.installSpec):[];return l.length>1&&e.push({kind:"action",text:n.t("upgrade.duplicates_note",{count:String(l.length),active:k(l[0]),others:l.slice(1).map(k).join("、"),tool:o})}),e}printApplied(o,t=16){const n=SUPPORTED_TOOLS[o]?.displayName??o,e=this.applyNotes(o);for(const o of e.filter(o=>"detail"===o.kind))i.record(`${n}: ${o.text}`);const l=e.filter(o=>"summary"===o.kind).map(o=>o.text).join(";"),s=" ".repeat(Math.max(1,t-y(n)));console.log(r.green("√ "+n)+(l?s+l:""));for(const o of e.filter(o=>"action"===o.kind))console.log(r.yellow(" ! "+o.text))}installedVersion(o){const n=s(o);if(!n)return null;if(n.installSpec)return C(n.installSpec)[0]?.version??null;if(n.installedVersion)try{return n.installedVersion()}catch(t){return i.logError(`ToolManager.installedVersion(${o})`,t),null}if(n.isInstalled)return null;try{const o={encoding:"utf-8",timeout:1e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]},e=`${("win32"===process.platform?t(`${n.command} --version`,{...o,shell:!0}):t(n.command,["--version"],o)).stdout??""}`.match(/(\d+)\.(\d+)\.(\d+)/);return e?e[0]:null}catch{return null}}outdatedVersion(o){const t=T(o);if(!t)return null;const n=this.installedVersion(o);return n&&$(n,t)<0?{current:n,min:t}:null}unloadPrivateConfig(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);try{t.unloadPrivateConfig({savedKeys:I()}),M(`remove:${o}`,"ok")}catch(t){throw M(`remove:${o}`,"fail",{error:t}),t}let e=[];try{e=t.unloadNotes?.()??[]}catch(t){i.logError(`ToolManager.unloadNotes(${o})`,t)}return e.length>0?e:[{kind:"action",text:n.t("config.reopen_hint",{tool:t.displayName})}]}async clearPinnedModels(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);if(l.setToolModel(o,null),!t.clearPinnedModels)return[];const n=l.getApiKeyForTool(o),e=t.wantsModelCatalog&&n?await P(n):null;return t.clearPinnedModels(e??void 0)}supportsClearPinnedModels(o){return Boolean(s(o)?.clearPinnedModels)}holdsOurConfig(o){const t=s(o);if(!t)return!1;const n=I();return t.holdsOurConfig?t.holdsOurConfig(n):Boolean(t.detectCurrentConfig().apiKey)}detectCurrentConfig(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);return t.detectCurrentConfig()}backupPathsFor(o){return o.backupPaths?o.backupPaths():[o.configPath]}listToolBackups(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);return this.backupPathsFor(t).map(o=>({file:o,backups:p(o)}))}restorePrivateConfig(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);return this.backupPathsFor(t).map(o=>({file:o,result:u(o)}))}getInstalledTools(){return Object.keys(SUPPORTED_TOOLS).filter(o=>this.isToolInstalled(o))}getSupportedTools(){return a().filter(o=>!o.hidden).map(o=>x(o.name))}isGitInstalled(){try{const t="win32"===process.platform?"where git":"which git";return o(t,{stdio:"pipe"}),!0}catch{return!1}}}export const toolManager=ToolManager.getInstance();
@@ -1 +1 @@
1
- import{spawn as t,spawnSync as e}from"child_process";import{rmSync as o}from"fs";import{join as r}from"path";import n from"chalk";import i from"inquirer";import{i18n as a}from"./i18n.js";import{logger as s}from"../utils/logger.js";import{compareVersions as l,getToolMinVersion as c}from"./model-registry.js";import{getAdapter as p}from"./tools/registry.js";import{findInstalls as u,forgetInstalls as m,installLabel as d,npmMirrorInstallCommand as g,npmUninstallCommand as f}from"./tools/tool-installs.js";import{toolHome as w}from"./tools/types.js";import{isNonInteractive as y,shouldAutoConfirm as h}from"./runtime-options.js";import{track as _}from"./telemetry.js";let v="ok",k=async(t,o,r={})=>(console.log(n.gray("$ ")+[t,...o].join(" ")),v=r.idleMs?await runWatched(t,o,r):function(t,o,r){const n=b(t)?e($(t,o),{stdio:"inherit",shell:!0,timeout:r}):e(t,o,{stdio:"inherit",timeout:r});return n.error&&s.logError(`upgrade: ${t}`,n.error),"ETIMEDOUT"===n.error?.code?"timeout":0===n.status?"ok":"fail"}(t,o,r.timeoutMs),"ok"===v);const b=t=>"win32"===process.platform&&!/\.exe$/i.test(t),$=(t,e)=>[t,...e].map(t=>/\s/.test(t)?`"${t}"`:t).join(" ");export function runWatched(e,o,r){return new Promise(n=>{const i=b(e)?t($(e,o),{stdio:["inherit","pipe","pipe"],shell:!0}):t(e,o,{stdio:["inherit","pipe","pipe"]});let a;const l=t=>{a=t,i.kill()};let c;const p=()=>{clearTimeout(c),r.idleMs&&(c=setTimeout(()=>l("stalled"),r.idleMs))},u=r.timeoutMs?setTimeout(()=>l("timeout"),r.timeoutMs):void 0;p(),i.stdout?.on("data",t=>{process.stdout.write(t),p()}),i.stderr?.on("data",t=>{process.stderr.write(t),p()});const m=t=>{clearTimeout(c),clearTimeout(u),n(t)};i.on("error",t=>{s.logError(`upgrade: ${e}`,t),m(a??"fail")}),i.on("close",t=>{a&&process.stdout.write("\n"),m(a??(0===t?"ok":"fail"))})})}export function setUpgradeRunnerForTests(t){k=async(e,o,r)=>{const n=await t(e,o,r);return v="string"==typeof n?n:n?"ok":"fail","ok"===v}}const T={ok:"install.script_failed_npm",fail:"install.script_failed_npm",stalled:"install.script_stalled_npm",timeout:"install.script_timeout_npm"};export async function mirrorInstall(t){if(!t.mirrorScript)return j(t);console.log(n.gray(a.t("install.downloading")));const e=`install-script:${t.command}`,o=Date.now();_(e,"start");const r={idleMs:18e4,timeoutMs:36e5},i="win32"===process.platform?await k("powershell.exe",["-NoProfile","-ExecutionPolicy","Bypass","-Command",`irm ${t.mirrorScript.ps1} -TimeoutSec 30 | iex`],r):await k("sh",["-c",`script=$(curl -fsSL --connect-timeout 15 --max-time 60 ${t.mirrorScript.sh}) && printf '%s\\n' "$script" | sh`],r),s=v;return _(e,"stalled"===s?"timeout":s,{duration_ms:Date.now()-o,..."stalled"===s||"timeout"===s?{detail:{reason:s}}:{}}),i||!t.npmPackage?i:(console.log(n.yellow(" ! "+a.t(T[s],{minutes:String(3)}))),_(e,"fallback"),j(t))}async function j(t){const[e,...o]=g(t).split(" "),r=`install-npm:${t.command}`,i=Date.now();_(r,"start");const s=await k(e,o);return _(r,s?"ok":"fail",{duration_ms:Date.now()-i}),s||"win32"===process.platform||console.log(n.yellow(" ! "+a.t("upgrade.npm_permission",{command:g(t)}))),s}async function M(t,e){switch(e.kind){case"npm":t.npmPackage&&await k("npm",["uninstall","-g",t.npmPackage]);break;case"brew":t.brew&&await k("brew",["uninstall",t.brew]);break;case"native":try{o(e.path,{force:!0});for(const e of t.native?.dataDirs??[])o(r(w(),...e),{recursive:!0,force:!0})}catch(t){s.logError("upgrade: remove native copy",t)}break;default:return!1}return m(),!u(t).some(t=>t.path===e.path)}function D(t,e){switch(e.kind){case"npm":return f(t);case"brew":return`brew uninstall ${t.brew}`;case"native":return a.t("upgrade.delete_paths",{paths:[e.path,...(t.native?.dataDirs??[]).map(t=>r(w(),...t))].join("、")});default:return a.t("upgrade.delete_paths",{paths:e.path})}}export async function upgradeTool(t){const e=Date.now();_(`upgrade:${t}`,"start");try{const o=await async function(t){const e=p(t),o=e?.installSpec;if(!e||!o)throw new Error(a.t("upgrade.unsupported",{tool:t}));const r=e.displayName;m();const g=u(o);if(console.log(n.bold(`\n${r}`)),0===g.length)console.log(a.t("upgrade.not_installed_installing",{tool:r})),await mirrorInstall(o);else{const t=g[0];console.log(n.gray(" "+a.t("upgrade.current",{copy:d(t)})));const e=await async function(t,e){switch(e.kind){case"native":return k(e.path,t.native?.updateArgs??["update"],{timeoutMs:t.native?.updateTimeoutMs});case"npm":return j(t);case"brew":return!!t.brew&&k("brew",["upgrade",t.brew]);default:return!1}}(o,t);e||"other"!==t.kind?e||"npm"===t.kind||"native"===t.kind&&await async function(t){const e=t.native?.mirrorUpdate;if(!e)return!1;console.log(n.yellow(" ! "+a.t("upgrade.native_mirror_trying")));try{const{version:t,manifestVerified:o}=await e();return console.log(n.green(" √ "+a.t(o?"upgrade.native_mirror_done_verified":"upgrade.native_mirror_done",{version:t}))),!0}catch(t){return s.logError("upgrade: native mirror",t),console.log(n.yellow(" ! "+a.t("upgrade.native_mirror_failed",{reason:t instanceof Error?t.message:String(t)}))),!1}}(o)||(console.log(n.yellow(" ! "+a.t("upgrade.fallback_mirror"))),await mirrorInstall(o)):console.log(n.yellow(" ! "+a.t("upgrade.unknown_install",{path:t.path})))}m(),await async function(t,e){const o=u(t);if(o.length<2)return;const r=function(t){return t.reduce((t,e)=>e.version&&(!t.version||l(e.version,t.version)>0)?e:t)}(o),s=o.filter(t=>t!==r);console.log(n.yellow(" ! "+a.t("upgrade.duplicates",{tool:e,keep:d(r),others:s.map(d).join("、")})));let c=h();c||y()||!process.stdin.isTTY||(c=(await i.prompt([{type:"confirm",name:"remove",message:a.t("upgrade.confirm_remove"),default:!0}])).remove);for(const e of s)c&&await M(t,e)?console.log(n.green(" √ "+a.t("upgrade.removed",{copy:d(e)}))):console.log(n.yellow(" ! "+a.t("upgrade.remove_by_hand",{how:D(t,e)})))}(o,r),m();const f=u(o)[0];if(!f)return console.log(n.red(" × "+a.t("upgrade.still_missing",{tool:r}))),!1;const w=c(t);if(w&&f.version&&l(f.version,w)<0){console.log(n.yellow(" ! "+a.t("upgrade.still_old",{copy:d(f),min:w})));for(const t of e.upgradeHints?.(w)??[])console.log(n.yellow(" ! "+t));return!1}return console.log(n.green(" √ "+a.t("upgrade.done",{copy:d(f)}))),!0}(t);return _(`upgrade:${t}`,o?"ok":"fail",{duration_ms:Date.now()-e}),o}catch(o){throw _(`upgrade:${t}`,"fail",{duration_ms:Date.now()-e,error:o}),o}}
1
+ import{spawn as t,spawnSync as e}from"child_process";import{rmSync as o}from"fs";import{join as r}from"path";import n from"chalk";import i from"inquirer";import{i18n as a}from"./i18n.js";import{logger as s}from"../utils/logger.js";import{compareVersions as l,getToolMinVersion as c}from"./model-registry.js";import{getAdapter as p}from"./tools/registry.js";import{findInstalls as u,forgetInstalls as m,installLabel as d,npmMirrorInstallCommand as g,npmMirrorVersion as f,npmUninstallCommand as w}from"./tools/tool-installs.js";import{toolHome as y}from"./tools/types.js";import{isNonInteractive as h,shouldAutoConfirm as _}from"./runtime-options.js";import{track as v}from"./telemetry.js";let k="ok",b=async(t,o,r={})=>(console.log(n.gray("$ ")+[t,...o].join(" ")),k=r.idleMs?await runWatched(t,o,r):function(t,o,r){const n=$(t)?e(T(t,o),{stdio:"inherit",shell:!0,timeout:r}):e(t,o,{stdio:"inherit",timeout:r});return n.error&&s.logError(`upgrade: ${t}`,n.error),"ETIMEDOUT"===n.error?.code?"timeout":0===n.status?"ok":"fail"}(t,o,r.timeoutMs),"ok"===k);const $=t=>"win32"===process.platform&&!/\.exe$/i.test(t),T=(t,e)=>[t,...e].map(t=>/\s/.test(t)?`"${t}"`:t).join(" ");export function runWatched(e,o,r){return new Promise(n=>{const i=$(e)?t(T(e,o),{stdio:["inherit","pipe","pipe"],shell:!0}):t(e,o,{stdio:["inherit","pipe","pipe"]});let a;const l=t=>{a=t,i.kill()};let c;const p=()=>{clearTimeout(c),r.idleMs&&(c=setTimeout(()=>l("stalled"),r.idleMs))},u=r.timeoutMs?setTimeout(()=>l("timeout"),r.timeoutMs):void 0;p(),i.stdout?.on("data",t=>{process.stdout.write(t),p()}),i.stderr?.on("data",t=>{process.stderr.write(t),p()});const m=t=>{clearTimeout(c),clearTimeout(u),n(t)};i.on("error",t=>{s.logError(`upgrade: ${e}`,t),m(a??"fail")}),i.on("close",t=>{a&&process.stdout.write("\n"),m(a??(0===t?"ok":"fail"))})})}export function setUpgradeRunnerForTests(t){b=async(e,o,r)=>{const n=await t(e,o,r);return k="string"==typeof n?n:n?"ok":"fail","ok"===k}}const j={ok:"install.script_failed_npm",fail:"install.script_failed_npm",stalled:"install.script_stalled_npm",timeout:"install.script_timeout_npm"};export async function mirrorInstall(t){if(!t.mirrorScript)return M(t);console.log(n.gray(a.t("install.downloading")));const e=`install-script:${t.command}`,o=Date.now();v(e,"start");const r={idleMs:18e4,timeoutMs:36e5},i="win32"===process.platform?await b("powershell.exe",["-NoProfile","-ExecutionPolicy","Bypass","-Command",`irm ${t.mirrorScript.ps1} -TimeoutSec 30 | iex`],r):await b("sh",["-c",`script=$(curl -fsSL --connect-timeout 15 --max-time 60 ${t.mirrorScript.sh}) && printf '%s\\n' "$script" | sh`],r),s=k;return v(e,"stalled"===s?"timeout":s,{duration_ms:Date.now()-o,..."stalled"===s||"timeout"===s?{detail:{reason:s}}:{}}),i||!t.npmPackage?i:(console.log(n.yellow(" ! "+a.t(j[s],{minutes:String(3)}))),v(e,"fallback"),M(t))}async function M(t){const e=g(t,await f(t)),[o,...r]=e.split(" "),i=`install-npm:${t.command}`,s=Date.now();v(i,"start");const l=await b(o,r);return v(i,l?"ok":"fail",{duration_ms:Date.now()-s}),l||"win32"===process.platform||console.log(n.yellow(" ! "+a.t("upgrade.npm_permission",{command:e}))),l}async function D(t,e){switch(e.kind){case"npm":t.npmPackage&&await b("npm",["uninstall","-g",t.npmPackage]);break;case"brew":t.brew&&await b("brew",["uninstall",t.brew]);break;case"native":try{o(e.path,{force:!0});for(const e of t.native?.dataDirs??[])o(r(y(),...e),{recursive:!0,force:!0})}catch(t){s.logError("upgrade: remove native copy",t)}break;default:return!1}return m(),!u(t).some(t=>t.path===e.path)}function x(t,e){switch(e.kind){case"npm":return w(t);case"brew":return`brew uninstall ${t.brew}`;case"native":return a.t("upgrade.delete_paths",{paths:[e.path,...(t.native?.dataDirs??[]).map(t=>r(y(),...t))].join("、")});default:return a.t("upgrade.delete_paths",{paths:e.path})}}export async function upgradeTool(t){const e=Date.now();v(`upgrade:${t}`,"start");try{const o=await async function(t){const e=p(t),o=e?.installSpec;if(!e||!o)throw new Error(a.t("upgrade.unsupported",{tool:t}));const r=e.displayName;m();const g=u(o);if(console.log(n.bold(`\n${r}`)),0===g.length)console.log(a.t("upgrade.not_installed_installing",{tool:r})),await mirrorInstall(o);else{const t=g[0];console.log(n.gray(" "+a.t("upgrade.current",{copy:d(t)})));const e=await async function(t,e){switch(e.kind){case"native":return b(e.path,t.native?.updateArgs??["update"],{timeoutMs:t.native?.updateTimeoutMs});case"npm":return M(t);case"brew":return!!t.brew&&b("brew",["upgrade",t.brew]);default:return!1}}(o,t);e||"other"!==t.kind?e||"npm"===t.kind||"native"===t.kind&&await async function(t){const e=t.native?.mirrorUpdate;if(!e)return!1;console.log(n.yellow(" ! "+a.t("upgrade.native_mirror_trying")));try{const{version:t,manifestVerified:o}=await e();return console.log(n.green(" √ "+a.t(o?"upgrade.native_mirror_done_verified":"upgrade.native_mirror_done",{version:t}))),!0}catch(t){return s.logError("upgrade: native mirror",t),console.log(n.yellow(" ! "+a.t("upgrade.native_mirror_failed",{reason:t instanceof Error?t.message:String(t)}))),!1}}(o)||(console.log(n.yellow(" ! "+a.t("upgrade.fallback_mirror"))),await mirrorInstall(o)):console.log(n.yellow(" ! "+a.t("upgrade.unknown_install",{path:t.path})))}m(),await async function(t,e){const o=u(t);if(o.length<2)return;const r=function(t){return t.reduce((t,e)=>e.version&&(!t.version||l(e.version,t.version)>0)?e:t)}(o),s=o.filter(t=>t!==r);console.log(n.yellow(" ! "+a.t("upgrade.duplicates",{tool:e,keep:d(r),others:s.map(d).join("、")})));let c=_();c||h()||!process.stdin.isTTY||(c=(await i.prompt([{type:"confirm",name:"remove",message:a.t("upgrade.confirm_remove"),default:!0}])).remove);for(const e of s)c&&await D(t,e)?console.log(n.green(" √ "+a.t("upgrade.removed",{copy:d(e)}))):console.log(n.yellow(" ! "+a.t("upgrade.remove_by_hand",{how:x(t,e)})))}(o,r),m();const f=u(o)[0];if(!f)return console.log(n.red(" × "+a.t("upgrade.still_missing",{tool:r}))),!1;const w=c(t);if(w&&f.version&&l(f.version,w)<0){console.log(n.yellow(" ! "+a.t("upgrade.still_old",{copy:d(f),min:w})));for(const t of e.upgradeHints?.(w)??[])console.log(n.yellow(" ! "+t));return!1}return console.log(n.green(" √ "+a.t("upgrade.done",{copy:d(f)}))),!0}(t);return v(`upgrade:${t}`,o?"ok":"fail",{duration_ms:Date.now()-e}),o}catch(o){throw v(`upgrade:${t}`,"fail",{duration_ms:Date.now()-e,error:o}),o}}
@@ -1 +1 @@
1
- import{existsSync as e,readFileSync as t}from"fs";import{join as o}from"path";import*as r from"@iarna/toml";import{logger as n}from"../../utils/logger.js";import{PROVIDER_KEY as i}from"../brand.js";import{backupBeforeWrite as s,atomicWriteFile as l}from"./backup.js";import{pickModel as d,toolHome as a,withV1 as m}from"./types.js";import{i18n as f}from"../i18n.js";import{getToolDefaultModel as g}from"../model-registry.js";import{gatewayModelSpecs as u,modelBlurb as c,modelFamily as p,prettyModelName as y}from"../gateway-models.js";import{brandInstallScripts as k,mirrorInstallCommand as b}from"./tool-installs.js";import{OFFICIAL_PLUGINS as h}from"./claude-plugins.js";const j=()=>o(o(a(),".grok"),"config.toml"),_=i,w=`${i}-`,A=["low","medium","high","xhigh"];let v=null;const C=e=>`${w}${e}`,x=e=>e===_||e.startsWith(w),M={command:"grok",npmPackage:"@xai-official/grok",mirrorScript:k("grok"),native:{binDir:[".grok","bin"],updateArgs:["update"],updateTimeoutMs:12e4,dataDirs:[[".grok","downloads"]]}};function S(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function E(e,t){return S(e[t])||(e[t]={}),e[t]}function O(){if(!e(j()))return{};const o=t(j(),"utf-8");if(!o.trim())return{};try{const e=r.parse(o);if(!S(e))throw new Error("config.toml root must be a TOML table");return e}catch(e){throw new Error(`Existing ~/.grok/config.toml cannot be parsed; back it up and fix it first: ${e instanceof Error?e.message:String(e)}`)}}function P(e){return S(e.model)?Object.entries(e.model).filter(e=>x(e[0])&&S(e[1])):[]}function N(e,t){let o=u("grok",e.catalog?.clientModels);if(e.catalog){const t=new Set(e.catalog.models);o=o.filter(e=>t.has(e.id))}return o.some(e=>e.id===t)?o:[{id:t},...o]}function $(e,t,o){E(e,"endpoints").models_base_url=m(t.baseUrl);const r=E(e,"model"),n=new Map(P(e));for(const e of n.keys())delete r[e];for(const e of o){const o=C(e.id),i={...n.get(o)??{},name:e.name??y(e.id),model:e.id,base_url:m(t.baseUrl),api_key:t.apiKey,context_window:e.contextWindow??5e5,api_backend:"responses",reasoning_summary:"concise"};"grok"===p(e.id)&&(i.supports_reasoning_effort=!0,i.reasoning_efforts=A);const s=c(e.description);s?i.description=s:delete i.description,r[o]=i}}export const grokAdapter={name:"grok",displayName:"Grok Build",command:"grok",installCommand:b(M),installSpec:M,configPath:j(),wantsModelCatalog:!0,loadPrivateConfig(e){const t=O(),o=d(e.models,g("grok")),n=N(e,o);$(t,e,n);const i=e=>e.name??y(e.id);v={names:n.map(i),defaultName:i(n.find(e=>e.id===o))},E(t,"models").default=C(o),function(e){const t=E(e,"plugins"),o=e=>Array.isArray(e)?e.map(String):[],r=o(t.enabled),n=o(t.disabled),i=h.filter(e=>!r.includes(e)&&!n.includes(e));i.length>0&&(t.disabled=[...n,...i])}(t),s(j()),l(j(),r.stringify(t))},unloadPrivateConfig(){if(!e(j()))return;let t;try{t=O()}catch(e){return void n.logError("grokAdapter.unloadPrivateConfig",e)}if(S(t.model)){for(const[e]of P(t))delete t.model[e];0===Object.keys(t.model).length&&delete t.model}S(t.models)&&"string"==typeof t.models.default&&x(t.models.default)&&(delete t.models.default,0===Object.keys(t.models).length&&delete t.models),S(t.endpoints)&&(delete t.endpoints.models_base_url,0===Object.keys(t.endpoints).length&&delete t.endpoints),function(e){if(!S(e.plugins)||!Array.isArray(e.plugins.disabled))return;const t=e.plugins.disabled.filter(e=>!h.includes(e));t.length>0?e.plugins.disabled=t:delete e.plugins.disabled,0===Object.keys(e.plugins).length&&delete e.plugins}(t),s(j()),l(j(),r.stringify(t))},detectCurrentConfig(){try{const e=O(),t=P(e),o=S(e.models)?e.models.default:void 0,r=t.find(([e])=>e===o)?.[1]??t[0]?.[1],n=r?r.api_key:null;return{apiKey:"string"==typeof n&&n.trim()?n:null}}catch{return{apiKey:null}}},listedModels(){try{const e=P(O());return e.length>0?e.map(([,e])=>String(e.model)):null}catch{return null}},refreshModelMenu(e){const t=O(),o=E(t,"models"),n="string"==typeof o.default?o.default:void 0,i=n?P(t).find(([e])=>e===n)?.[1].model:void 0,a="string"==typeof i&&n!==_&&e.catalog.models.includes(i)?i:d(e.models,g("grok")),m=r.stringify(t);$(t,e,N(e,a)),(void 0===n||x(n))&&(o.default=C(a)),r.stringify(t)!==m&&(s(j()),l(j(),r.stringify(t)))},applyNotes:()=>v?[{kind:"summary",text:f.t("tools.grok.menu_written",{count:String(v.names.length),list:v.names.join(f.t("tools.grok.list_separator")),default:v.defaultName})}]:[],getConfig(){try{return O()}catch(e){return n.logError("grokAdapter.getConfig",e),null}}};
1
+ import{existsSync as e,readFileSync as t}from"fs";import{join as o}from"path";import*as r from"@iarna/toml";import{logger as n}from"../../utils/logger.js";import{PROVIDER_KEY as i}from"../brand.js";import{backupBeforeWrite as s,atomicWriteFile as l}from"./backup.js";import{pickModel as a,toolHome as d,withV1 as m}from"./types.js";import{i18n as f}from"../i18n.js";import{getToolDefaultModel as g}from"../model-registry.js";import{gatewayModelSpecs as u,modelBlurb as c,modelFamily as p,prettyModelName as y}from"../gateway-models.js";import{brandInstallScripts as k,mirrorInstallCommand as b}from"./tool-installs.js";import{OFFICIAL_PLUGINS as h}from"./claude-plugins.js";const j=()=>o(o(d(),".grok"),"config.toml"),_=i,w=`${i}-`,A=["low","medium","high","xhigh"];let v=null;const C=e=>`${w}${e}`,M=e=>e===_||e.startsWith(w),x={command:"grok",npmPackage:"@xai-official/grok",npmMirrorTagStale:!0,mirrorScript:k("grok"),native:{binDir:[".grok","bin"],updateArgs:["update"],updateTimeoutMs:12e4,dataDirs:[[".grok","downloads"]]}};function S(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function E(e,t){return S(e[t])||(e[t]={}),e[t]}function O(){if(!e(j()))return{};const o=t(j(),"utf-8");if(!o.trim())return{};try{const e=r.parse(o);if(!S(e))throw new Error("config.toml root must be a TOML table");return e}catch(e){throw new Error(`Existing ~/.grok/config.toml cannot be parsed; back it up and fix it first: ${e instanceof Error?e.message:String(e)}`)}}function P(e){return S(e.model)?Object.entries(e.model).filter(e=>M(e[0])&&S(e[1])):[]}function N(e,t){let o=u("grok",e.catalog?.clientModels);if(e.catalog){const t=new Set(e.catalog.models);o=o.filter(e=>t.has(e.id))}return o.some(e=>e.id===t)?o:[{id:t},...o]}function $(e,t,o){E(e,"endpoints").models_base_url=m(t.baseUrl);const r=E(e,"model"),n=new Map(P(e));for(const e of n.keys())delete r[e];for(const e of o){const o=C(e.id),i={...n.get(o)??{},name:e.name??y(e.id),model:e.id,base_url:m(t.baseUrl),api_key:t.apiKey,context_window:e.contextWindow??5e5,api_backend:"responses",reasoning_summary:"concise"};"grok"===p(e.id)&&(i.supports_reasoning_effort=!0,i.reasoning_efforts=A);const s=c(e.description);s?i.description=s:delete i.description,r[o]=i}}export const grokAdapter={name:"grok",displayName:"Grok Build",command:"grok",installCommand:b(x),installSpec:x,configPath:j(),wantsModelCatalog:!0,loadPrivateConfig(e){const t=O(),o=a(e.models,g("grok")),n=N(e,o);$(t,e,n);const i=e=>e.name??y(e.id);v={names:n.map(i),defaultName:i(n.find(e=>e.id===o))},E(t,"models").default=C(o),function(e){const t=E(e,"plugins"),o=e=>Array.isArray(e)?e.map(String):[],r=o(t.enabled),n=o(t.disabled),i=h.filter(e=>!r.includes(e)&&!n.includes(e));i.length>0&&(t.disabled=[...n,...i])}(t),s(j()),l(j(),r.stringify(t))},unloadPrivateConfig(){if(!e(j()))return;let t;try{t=O()}catch(e){return void n.logError("grokAdapter.unloadPrivateConfig",e)}if(S(t.model)){for(const[e]of P(t))delete t.model[e];0===Object.keys(t.model).length&&delete t.model}S(t.models)&&"string"==typeof t.models.default&&M(t.models.default)&&(delete t.models.default,0===Object.keys(t.models).length&&delete t.models),S(t.endpoints)&&(delete t.endpoints.models_base_url,0===Object.keys(t.endpoints).length&&delete t.endpoints),function(e){if(!S(e.plugins)||!Array.isArray(e.plugins.disabled))return;const t=e.plugins.disabled.filter(e=>!h.includes(e));t.length>0?e.plugins.disabled=t:delete e.plugins.disabled,0===Object.keys(e.plugins).length&&delete e.plugins}(t),s(j()),l(j(),r.stringify(t))},detectCurrentConfig(){try{const e=O(),t=P(e),o=S(e.models)?e.models.default:void 0,r=t.find(([e])=>e===o)?.[1]??t[0]?.[1],n=r?r.api_key:null;return{apiKey:"string"==typeof n&&n.trim()?n:null}}catch{return{apiKey:null}}},listedModels(){try{const e=P(O());return e.length>0?e.map(([,e])=>String(e.model)):null}catch{return null}},refreshModelMenu(e){const t=O(),o=E(t,"models"),n="string"==typeof o.default?o.default:void 0,i=n?P(t).find(([e])=>e===n)?.[1].model:void 0,d="string"==typeof i&&n!==_&&e.catalog.models.includes(i)?i:a(e.models,g("grok")),m=r.stringify(t);$(t,e,N(e,d)),(void 0===n||M(n))&&(o.default=C(d)),r.stringify(t)!==m&&(s(j()),l(j(),r.stringify(t)))},applyNotes:()=>v?[{kind:"summary",text:f.t("tools.grok.menu_written",{count:String(v.names.length),list:v.names.join(f.t("tools.grok.list_separator")),default:v.defaultName})}]:[],getConfig(){try{return O()}catch(e){return n.logError("grokAdapter.getConfig",e),null}}};
@@ -1 +1 @@
1
- import{spawnSync as r}from"child_process";import{existsSync as t,realpathSync as n,statSync as o}from"fs";import{delimiter as e,dirname as s,isAbsolute as i,join as a}from"path";import{i18n as p}from"../i18n.js";import{toolHome as c}from"./types.js";import{brand as m}from"../brand.js";export const NPM_MIRROR="https://registry.npmmirror.com";export function brandInstallScripts(r){const t=m().installMirror?.scripts;return t?{sh:`${t}/${r}.sh`,ps1:`${t}/${r}.ps1`}:void 0}export function npmMirrorInstallCommand(r){return`npm install -g ${r.npmPackage}@latest --registry=${NPM_MIRROR}`}export function mirrorInstallCommand(r){return r.mirrorScript?"win32"===process.platform?`powershell -NoProfile -ExecutionPolicy Bypass -Command "irm ${r.mirrorScript.ps1} | iex"`:`curl -fsSL ${r.mirrorScript.sh} | sh`:r.npmPackage?npmMirrorInstallCommand(r):""}export function npmUninstallCommand(r){return`npm uninstall -g ${r.npmPackage}`}export function installLabel(r){return p.t("upgrade.install_label",{kind:p.t(`upgrade.kind.${r.kind}`),version:r.version??"?",path:r.path})}let l=t=>{const n={encoding:"utf-8",timeout:1e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]};return`${(/\.cmd$/i.test(t)?r(`"${t}" --version`,{...n,shell:!0}):r(t,["--version"],n)).stdout??""}`};const u=new Map;export function setVersionRunnerForTests(r){l=r,u.clear()}export function forgetInstalls(){u.clear()}function d(r){try{return o(r).isFile()}catch{return!1}}function f(r,o){if(r.native&&(e=s(o),i=a(c(),...r.native.binDir),"win32"===process.platform?e.toLowerCase()===i.toLowerCase():e===i))return"native";var e,i;const p=r.npmPackage?a("node_modules",...r.npmPackage.split("/")):null;if(p&&t(a(s(o),p)))return"npm";let m=o;try{m=n(o)}catch{return"other"}return p&&m.includes(p)?"npm":/[\\/](Cellar|Caskroom)[\\/]/.test(m)?"brew":"other"}export function findInstalls(r){const t=u.get(r.command);if(t)return t;const o="win32"===process.platform?[`${r.command}.exe`,`${r.command}.cmd`]:[r.command],s=new Set,p=[];for(const t of(process.env.PATH??"").split(e))if(t&&i(t))for(const e of o){const o=a(t,e);if(!d(o))continue;let i=o;try{i=n(o)}catch{}const c="win32"===process.platform?i.toLowerCase():i;if(s.has(c))continue;s.add(c);const m=l(o).match(/(\d+)\.(\d+)\.(\d+)/);p.push({path:o,kind:f(r,o),version:m?m[0]:null})}return u.set(r.command,p),p}
1
+ import{spawnSync as t}from"child_process";import{existsSync as r,realpathSync as n,statSync as e}from"fs";import{delimiter as o,dirname as s,isAbsolute as i,join as a}from"path";import{i18n as c}from"../i18n.js";import{toolHome as p}from"./types.js";import{brand as m}from"../brand.js";export const NPM_MIRROR="https://registry.npmmirror.com";export function brandInstallScripts(t){const r=m().installMirror?.scripts;return r?{sh:`${r}/${t}.sh`,ps1:`${r}/${t}.ps1`}:void 0}export function npmMirrorInstallCommand(t,r="latest"){return`npm install -g ${t.npmPackage}@${r} --registry=${NPM_MIRROR}`}const l=/^(\d+)\.(\d+)\.(\d+)$/;function u(t,r){const n=l.exec(t).slice(1).map(Number),e=l.exec(r).slice(1).map(Number);for(let o=0;o<3;o++)if(n[o]!==e[o])return n[o]>e[o]?t:r;return t}async function f(t,r,n){const e=await fetch(t,{signal:AbortSignal.timeout(r),headers:n});if(!e.ok)throw new Error(`HTTP ${e.status}`);return e.json()}export async function npmMirrorVersion(t){if(!t.npmPackage||!t.npmMirrorTagStale)return"latest";let r=d.get(t.npmPackage);return r||d.set(t.npmPackage,r=async function(t){try{const{version:r}=await f(`https://registry.npmjs.org/${t}/latest`,1e4);if("string"==typeof r&&l.test(r))return r}catch{}try{const r=await f(`${NPM_MIRROR}/${t}`,2e4,{accept:"application/vnd.npm.install-v1+json"}),n=Object.keys(r.versions??{}).filter(t=>l.test(t));if(n.length)return n.reduce(u)}catch{}return"latest"}(t.npmPackage)),r}const d=new Map;export function mirrorInstallCommand(t){return t.mirrorScript?"win32"===process.platform?`powershell -NoProfile -ExecutionPolicy Bypass -Command "irm ${t.mirrorScript.ps1} | iex"`:`curl -fsSL ${t.mirrorScript.sh} | sh`:t.npmPackage?npmMirrorInstallCommand(t):""}export function npmUninstallCommand(t){return`npm uninstall -g ${t.npmPackage}`}export function installLabel(t){return c.t("upgrade.install_label",{kind:c.t(`upgrade.kind.${t.kind}`),version:t.version??"?",path:t.path})}let g=r=>{const n={encoding:"utf-8",timeout:1e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]};return`${(/\.cmd$/i.test(r)?t(`"${r}" --version`,{...n,shell:!0}):t(r,["--version"],n)).stdout??""}`};const h=new Map;export function setVersionRunnerForTests(t){g=t,h.clear(),d.clear()}export function forgetInstalls(){h.clear()}function $(t){try{return e(t).isFile()}catch{return!1}}function w(t,e){if(t.native&&(o=s(e),i=a(p(),...t.native.binDir),"win32"===process.platform?o.toLowerCase()===i.toLowerCase():o===i))return"native";var o,i;const c=t.npmPackage?a("node_modules",...t.npmPackage.split("/")):null;if(c&&r(a(s(e),c)))return"npm";let m=e;try{m=n(e)}catch{return"other"}return c&&m.includes(c)?"npm":/[\\/](Cellar|Caskroom)[\\/]/.test(m)?"brew":"other"}export function findInstalls(t){const r=h.get(t.command);if(r)return r;const e="win32"===process.platform?[`${t.command}.exe`,`${t.command}.cmd`]:[t.command],s=new Set,c=[];for(const r of(process.env.PATH??"").split(o))if(r&&i(r))for(const o of e){const e=a(r,o);if(!$(e))continue;let i=e;try{i=n(e)}catch{}const p="win32"===process.platform?i.toLowerCase():i;if(s.has(p))continue;s.add(p);const m=g(e).match(/(\d+)\.(\d+)\.(\d+)/);c.push({path:e,kind:w(t,e),version:m?m[0]:null})}return h.set(t.command,c),c}
@@ -874,7 +874,7 @@
874
874
  },
875
875
  "update": {
876
876
  "summary": "Check for a newer {{product}}",
877
- "description": "Checks {{updateSources}} in turn and prints the install command when a newer version exists.\nA global install also checks at startup (every 6 hours) and, when there is a newer version, installs it and reruns the command.",
877
+ "description": "Checks {{updateSources}} in turn and prints the install command when a newer version exists.\nA global install also checks at every start and, when there is a newer version, installs it and reruns the command.",
878
878
  "ex": {
879
879
  "check": "Check for a new version",
880
880
  "json": "Print JSON"
@@ -874,7 +874,7 @@
874
874
  },
875
875
  "update": {
876
876
  "summary": "检查 {{product}} 是否有新版本",
877
- "description": "依次查询这些来源:{{updateSources}}。有新版本时给出安装命令。\n全局安装的 {{product}} 启动时也会检查(每 6 小时一次),有新版本时自动安装并重新运行当前命令。",
877
+ "description": "依次查询这些来源:{{updateSources}}。有新版本时给出安装命令。\n全局安装的 {{product}} 每次启动时也会检查,有新版本时自动安装并重新运行当前命令。",
878
878
  "ex": {
879
879
  "check": "检查新版本",
880
880
  "json": "输出 JSON"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xship/cli",
3
- "version": "0.0.137",
3
+ "version": "0.0.139",
4
4
  "description": "Configure Claude Code, Codex, Grok Build and other coding tools for Xship AI with one command",
5
5
  "main": "dist/index.js",
6
6
  "bin": {