@vibeapi/cli 0.0.150 → 0.0.152
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/components.json +1 -1
- package/dist/commands/config.js +1 -1
- package/dist/components.json +1 -1
- package/dist/lib/app-update.js +1 -1
- package/dist/lib/command.d.ts +2 -0
- package/dist/lib/command.js +1 -1
- package/dist/lib/env-cleanup.d.ts +8 -2
- package/dist/lib/env-cleanup.js +1 -1
- package/dist/lib/post-apply.d.ts +5 -0
- package/dist/lib/post-apply.js +1 -1
- package/dist/lib/telemetry.js +1 -1
- package/dist/lib/tool-upgrade.d.ts +4 -0
- package/dist/lib/tool-upgrade.js +1 -1
- package/dist/lib/tools/claude-code.js +1 -1
- package/dist/lib/tools/desktop-app-installer.d.ts +5 -1
- package/dist/lib/tools/desktop-app-installer.js +1 -1
- package/dist/lib/tools/types.d.ts +2 -0
- package/dist/locales/en_US.json +9 -1
- package/dist/locales/zh_CN.json +9 -1
- package/package.json +1 -1
package/components.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": 1,
|
|
3
|
-
"about": "Components
|
|
3
|
+
"about": "Components the CLI installs and upgrades (its list / install / upgrade commands). Read by src/lib/components.ts and by scripts/gen-components-doc.mjs (docs, the install scripts' README). {scripts} = the brand's installMirror.scripts, {agy} = installMirror.agy, {devtools} = the neutral CNB mirror of fnm / uv / Git for Windows.",
|
|
4
4
|
"devtools": "https://cnb.cool/lib/devtools/-/releases/latest/download",
|
|
5
5
|
"components": [
|
|
6
6
|
{
|
package/dist/commands/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import o from"inquirer";import e from"chalk";import{wizard as t}from"../lib/wizard.js";import{toolManager as n,SUPPORTED_TOOLS as l}from"../lib/tool-manager.js";import{i18n as i}from"../lib/i18n.js";import{configManager as r,DEFAULT_PROFILE_NAME as a}from"../lib/config.js";import{confirmAction as s,applyOrDryRun as c,requireTerminal as d}from"../lib/confirm.js";import{canPrompt as f,isDryRun as g,isNonInteractive as p,shouldAutoConfirm as m}from"../lib/runtime-options.js";const _=/^[a-zA-Z0-9._-]+$/;function u(o,e){const t=(o||"").trim();if(!t||!_.test(t))throw new Error(i.t(`config.${e}_invalid_name`,{name:t||"<empty>"}));return t}function y(o,t){console.log("\n"+e.bold(o)),0!==t.length?t.forEach(o=>console.log(" "+o)):console.log(e.gray(" ("+i.t("config.empty_list")+")"))}function v(o,t){if("backups"===t){const t=n.listToolBackups(o).flatMap(o=>{const t=o.file.replace(/^.*[/\\]/,"");return o.backups.length?o.backups.map(o=>`${e.cyan(t)} ${e.gray(o.name.split(".bak-")[1]||o.name)}`):[`${e.cyan(t)} ${e.gray("("+i.t("config.empty_list")+")")}`]});return void y(i.t("config.tool_backups_title",{tool:l[o].displayName}),t)}const r=n.restorePrivateConfig(o).filter(o=>o.result.restored);0!==r.length?(console.log(e.green(i.t("config.config_restored",{tool:l[o].displayName}))),r.forEach(o=>console.log(e.gray(` ${o.file} ← ${o.result.from}`))),console.log(e.yellow(" ! "+i.t("config.reopen_hint",{tool:l[o].displayName})))):console.log(e.yellow(i.t("config.restore_no_backup",{tool:l[o].displayName})))}async function w(a,p,m){if(!l[a])return void console.log(e.red(i.t("config.unknown_tool",{tool:a})));const _=(p[0]||"").toLowerCase();if("backups"!==_&&"list-backups"!==_)if("restore"!==_){if("remove"===_||"unload"===_){const o=l[a].displayName;return void await c({description:i.t("config.remove_dry_run",{tool:o}),json:{action:"remove",tool:a},apply:async()=>{if(!await s({message:i.t("config.confirm_remove",{tool:o,name:a}),defaultValue:!0}))return;const t=n.holdsOurConfig(a),l=n.unloadPrivateConfig(a);t?(console.log(e.green(i.t("config.remove_done",{tool:o}))),l.forEach(o=>console.log(e.yellow(" ! "+o.text)))):console.log(e.gray(i.t("config.remove_nothing",{tool:o})))}})}if("clear-model"===_||"clear-models"===_){const o=l[a].displayName;return n.supportsClearPinnedModels(a)?void await c({description:i.t("config.clear_model_dry_run",{tool:o}),json:{action:"clear_model",tool:a},apply:async()=>{const t=await n.clearPinnedModels(a);0!==t.length?(console.log(e.green(i.t("config.clear_model_done",{tool:o}))),t.forEach(o=>console.log(e.gray(` - ${o}`))),console.log(e.gray(i.t("config.clear_model_restart_hint",{tool:o})))):console.log(e.yellow(i.t("config.clear_model_none",{tool:o})))}}):void console.log(e.yellow(i.t("config.clear_model_unsupported",{tool:o})))}if(g())await c({description:i.t("config.tool_apply_dry_run",{tool:l[a].displayName}),json:{action:"apply",tool:a,force:Boolean(m.force)},apply:()=>{}});else{if(!n.isToolInstalled(a)){if(m.nonInteractive)return void console.log(e.yellow(i.t("wizard.tool_not_installed",{tool:l[a].displayName})));if(console.log(e.yellow(i.t("wizard.tool_not_installed",{tool:l[a].displayName}))),!f())return;const{shouldInstall:t}=await o.prompt([{type:"confirm",name:"shouldInstall",message:i.t("wizard.install_tool_confirm"),default:!0}]);if(!t)return void console.log(e.yellow(i.t("wizard.install_skipped")));try{await n.installTool(a)}catch(o){return console.error(e.red(i.t("install.install_failed_detail"))),void(o instanceof Error&&o.message&&console.error(e.gray(o.message)))}}if(m.nonInteractive||m.force){const o=r.getApiKeyForTool(a);if(!o)return void console.log(e.red(i.t("auth.reload_missing_config")));if(m.force&&!m.nonInteractive&&!await s({message:i.t("config.confirm_force",{tool:l[a].displayName}),defaultValue:!1}))return;return await n.applyPrivateConfig(a,o,r.getModelsForTool(a),{force:m.force,takeOver:!0}),m.force&&console.log(e.yellow(i.t("config.force_done",{tool:l[a].displayName,name:a}))),void n.printApplied(a)}d(),await t.showToolMenu(a)}}else await c({description:i.t("config.tool_restore_dry_run",{tool:l[a].displayName}),json:{action:"tool_restore",tool:a},apply:async()=>{await s({message:i.t("config.confirm_restore",{tool:l[a].displayName}),defaultValue:!1})&&v(a,"restore")}});else v(a,"backups")}export async function configCommand(t){const{positional:n,options:d}=function(o){const e=[],t={};(p()||m())&&(t.nonInteractive=!0);for(const n of o)"--non-interactive"===n||"-y"===n?t.nonInteractive=!0:"--force"===n||"-f"===n?t.force=!0:e.push(n);return{positional:e,options:t}}(t),g=n[0],v=n.slice(1);if(g){switch(g){case"profile":return void await async function(o){const t=o[0],n=o[1];if(!t||"list"===t){const o=r.getActiveProfileName(),t=r.listProfiles().map(t=>{const n=t===o;return`${n?e.green("●"):e.gray("○")} ${t}${n?e.gray(" ("+i.t("config.profile_active_label")+")"):""}`});return void y(i.t("config.profile_list_title"),t)}if("create"===t){const o=u(n,"profile");return r.listProfiles().includes(o)?void console.log(e.yellow(i.t("config.profile_exists",{name:o}))):void await c({description:i.t("config.profile_create_dry_run",{name:o}),json:{action:"profile_create",name:o},apply:()=>{r.createProfile(o),console.log(e.green(i.t("config.profile_created",{name:o})))}})}if("use"===t){const o=u(n,"profile");return void await c({description:i.t("config.profile_use_dry_run",{name:o}),json:{action:"profile_use",name:o},apply:()=>{r.setActiveProfile(o),console.log(e.green(i.t("config.profile_activated",{name:o})))}})}if("delete"===t||"remove"===t){const o=u(n,"profile");return o===a&&1===r.listProfiles().length?void console.log(e.yellow(i.t("config.profile_cannot_delete_last"))):void await c({description:i.t("config.profile_delete_dry_run",{name:o}),json:{action:"profile_delete",name:o},apply:async()=>{await s({message:i.t("config.profile_delete_confirm",{name:o}),defaultValue:!1})?(r.deleteProfile(o),console.log(e.green(i.t("config.profile_deleted",{name:o})))):console.log(e.yellow(i.t("config.profile_delete_aborted")))}})}console.log(e.red(i.t("config.unknown_action",{action:t})))}(v);case"preset":return void await async function(o){const t=o[0],n=o[1];if(!t||"list"===t){const o=Object.entries(r.getCustomPresets()).map(([o,t])=>`${e.cyan(o)} ${e.gray(`H:${t.models.haiku} S:${t.models.sonnet} O:${t.models.opus}`)}`);return void y(i.t("config.preset_list_title"),o)}if("save"===t){const o=u(n,"preset");return void await c({description:i.t("config.preset_save_dry_run",{name:o}),json:{action:"preset_save",name:o},apply:()=>{r.saveCustomPreset(o,r.getModels()),console.log(e.green(i.t("config.preset_saved",{name:o})))}})}if("use"===t||"apply"===t){const o=u(n,"preset"),t=r.getCustomPresets()[o];return t?void await c({description:i.t("config.preset_use_dry_run",{name:o}),json:{action:"preset_use",name:o},apply:()=>{r.setModels(t.models),console.log(e.green(i.t("config.preset_applied",{name:o})))}}):void console.log(e.red(i.t("config.preset_not_found",{name:o})))}if("delete"===t||"remove"===t){const o=u(n,"preset");return void await c({description:i.t("config.preset_delete_dry_run",{name:o}),json:{action:"preset_delete",name:o},apply:()=>{r.deleteCustomPreset(o),console.log(e.green(i.t("config.preset_deleted",{name:o})))}})}console.log(e.red(i.t("config.unknown_action",{action:t})))}(v);case"tool-model":return void await async function(o){const t=o[0];if(!t||"list"===t){const o=r.getProfile().tool_models||{},t=Object.entries(o).map(([o,t])=>{const n=Object.entries(t).map(([o,e])=>`${o}=${e}`).join(" ");return`${e.cyan(o)} ${e.gray(n)}`});return void y(i.t("config.tool_model_list_title"),t)}if("set"===t){const t=(o[1]||"").trim(),n=o.length>=4?(o[2]||"").trim():"opus",a=(o.length>=4?o[3]:o[2]||"").trim();return l[t]?a&&_.test(n)?void await c({description:i.t("config.tool_model_set_dry_run",{tool:t,slot:n,model:a}),json:{action:"tool_model_set",tool:t,slot:n,model:a},apply:()=>{r.setToolModel(t,{[n]:a}),console.log(e.green(i.t("config.tool_model_set",{tool:t,slot:n,model:a})))}}):void console.log(e.red(i.t("config.tool_model_usage"))):void console.log(e.red(t?i.t("config.unknown_tool",{tool:t}):i.t("config.tool_model_usage")))}if("clear"===t||"remove"===t){const t=(o[1]||"").trim();return l[t]?void await c({description:i.t("config.tool_model_clear_dry_run",{tool:t}),json:{action:"tool_model_clear",tool:t},apply:()=>{r.setToolModel(t,null),console.log(e.green(i.t("config.tool_model_cleared",{tool:t})))}}):void console.log(e.red(t?i.t("config.unknown_tool",{tool:t}):i.t("config.tool_model_usage")))}console.log(e.red(i.t("config.unknown_action",{action:t})))}(v);case"backup":return void await function(o){return async function(o){const t=o[0],n=o[1];if(!t||"list"===t){const o=r.listBackups().map(o=>{const t=new Date(o.mtimeMs).toISOString();return`${e.cyan(o.name)} ${e.gray(t)}`});return void y(i.t("config.backup_list_title"),o)}if("create"!==t&&"snapshot"!==t)return"restore"===t?n?void await c({description:i.t("config.backup_restore_dry_run",{name:n}),json:{action:"backup_restore",name:n},apply:async()=>{await s({message:i.t("config.backup_restore_confirm",{name:n}),defaultValue:!1})?(r.restoreBackup(n),console.log(e.green(i.t("config.backup_restored",{name:n})))):console.log(e.yellow(i.t("config.backup_restore_aborted")))}}):void console.log(e.red(i.t("config.backup_restore_missing_name"))):void console.log(e.red(i.t("config.unknown_action",{action:t})));await c({description:i.t("config.backup_create_dry_run"),json:{action:"backup_create",name:n??null},apply:()=>{const o=r.createBackup(n);console.log(e.green(i.t("config.backup_created",{path:o})))}})}(o)}(v)}"claude-code"!==g&&"claude-code"!==v[0]?l[g]?await w(g,v,d):(console.error(e.red(i.t("config.unknown_command",{command:g}))),console.log(e.gray(i.t("config.usage_hint"))),Object.values(l).filter(o=>!o.hidden).forEach(o=>{console.log(e.gray(` - ${o.name}: ${o.displayName}`))})):await w("claude-code",v,d)}else await async function(t){if(t.nonInteractive||!f())return void console.log(e.red(i.t("config.requires_argument")));const{selectedTool:n}=await o.prompt([{type:"list",name:"selectedTool",message:i.t("wizard.select_tool"),choices:Object.values(l).filter(o=>!o.hidden).map(o=>({name:`${o.displayName} (${o.name})`,value:o.name}))}]);await w(n,[],t)}(d)}
|
|
1
|
+
import o from"inquirer";import e from"chalk";import{wizard as t}from"../lib/wizard.js";import{runFollowUps as n}from"../lib/post-apply.js";import{toolManager as l,SUPPORTED_TOOLS as i}from"../lib/tool-manager.js";import{i18n as r}from"../lib/i18n.js";import{configManager as a,DEFAULT_PROFILE_NAME as s}from"../lib/config.js";import{confirmAction as c,applyOrDryRun as d,requireTerminal as f}from"../lib/confirm.js";import{canPrompt as g,isDryRun as p,isNonInteractive as m,shouldAutoConfirm as _}from"../lib/runtime-options.js";const u=/^[a-zA-Z0-9._-]+$/;function y(o,e){const t=(o||"").trim();if(!t||!u.test(t))throw new Error(r.t(`config.${e}_invalid_name`,{name:t||"<empty>"}));return t}function v(o,t){console.log("\n"+e.bold(o)),0!==t.length?t.forEach(o=>console.log(" "+o)):console.log(e.gray(" ("+r.t("config.empty_list")+")"))}function w(o,t){if("backups"===t){const t=l.listToolBackups(o).flatMap(o=>{const t=o.file.replace(/^.*[/\\]/,"");return o.backups.length?o.backups.map(o=>`${e.cyan(t)} ${e.gray(o.name.split(".bak-")[1]||o.name)}`):[`${e.cyan(t)} ${e.gray("("+r.t("config.empty_list")+")")}`]});return void v(r.t("config.tool_backups_title",{tool:i[o].displayName}),t)}const n=l.restorePrivateConfig(o).filter(o=>o.result.restored);0!==n.length?(console.log(e.green(r.t("config.config_restored",{tool:i[o].displayName}))),n.forEach(o=>console.log(e.gray(` ${o.file} ← ${o.result.from}`))),console.log(e.yellow(" ! "+r.t("config.reopen_hint",{tool:i[o].displayName})))):console.log(e.yellow(r.t("config.restore_no_backup",{tool:i[o].displayName})))}async function b(s,m,_){if(!i[s])return void console.log(e.red(r.t("config.unknown_tool",{tool:s})));const u=(m[0]||"").toLowerCase();if("backups"!==u&&"list-backups"!==u)if("restore"!==u){if("remove"===u||"unload"===u){const o=i[s].displayName;return void await d({description:r.t("config.remove_dry_run",{tool:o}),json:{action:"remove",tool:s},apply:async()=>{if(!await c({message:r.t("config.confirm_remove",{tool:o,name:s}),defaultValue:!0}))return;const t=l.holdsOurConfig(s),n=l.unloadPrivateConfig(s);t?(console.log(e.green(r.t("config.remove_done",{tool:o}))),n.forEach(o=>console.log(e.yellow(" ! "+o.text)))):console.log(e.gray(r.t("config.remove_nothing",{tool:o})))}})}if("clear-model"===u||"clear-models"===u){const o=i[s].displayName;return l.supportsClearPinnedModels(s)?void await d({description:r.t("config.clear_model_dry_run",{tool:o}),json:{action:"clear_model",tool:s},apply:async()=>{const t=await l.clearPinnedModels(s);0!==t.length?(console.log(e.green(r.t("config.clear_model_done",{tool:o}))),t.forEach(o=>console.log(e.gray(` - ${o}`))),console.log(e.gray(r.t("config.clear_model_restart_hint",{tool:o})))):console.log(e.yellow(r.t("config.clear_model_none",{tool:o})))}}):void console.log(e.yellow(r.t("config.clear_model_unsupported",{tool:o})))}if(p())await d({description:r.t("config.tool_apply_dry_run",{tool:i[s].displayName}),json:{action:"apply",tool:s,force:Boolean(_.force)},apply:()=>{}});else{if(!l.isToolInstalled(s)){if(_.nonInteractive)return void console.log(e.yellow(r.t("wizard.tool_not_installed",{tool:i[s].displayName})));if(console.log(e.yellow(r.t("wizard.tool_not_installed",{tool:i[s].displayName}))),!g())return;const{shouldInstall:t}=await o.prompt([{type:"confirm",name:"shouldInstall",message:r.t("wizard.install_tool_confirm"),default:!0}]);if(!t)return void console.log(e.yellow(r.t("wizard.install_skipped")));try{await l.installTool(s)}catch(o){return console.error(e.red(r.t("install.install_failed_detail"))),void(o instanceof Error&&o.message&&console.error(e.gray(o.message)))}}if(_.nonInteractive||_.force){const o=a.getApiKeyForTool(s);if(!o)return void console.log(e.red(r.t("auth.reload_missing_config")));if(_.force&&!_.nonInteractive&&!await c({message:r.t("config.confirm_force",{tool:i[s].displayName}),defaultValue:!1}))return;return await l.applyPrivateConfig(s,o,a.getModelsForTool(s),{force:_.force,takeOver:!0}),_.force&&console.log(e.yellow(r.t("config.force_done",{tool:i[s].displayName,name:s}))),l.printApplied(s),void await n([s])}f(),await t.showToolMenu(s)}}else await d({description:r.t("config.tool_restore_dry_run",{tool:i[s].displayName}),json:{action:"tool_restore",tool:s},apply:async()=>{await c({message:r.t("config.confirm_restore",{tool:i[s].displayName}),defaultValue:!1})&&w(s,"restore")}});else w(s,"backups")}export async function configCommand(t){const{positional:n,options:l}=function(o){const e=[],t={};(m()||_())&&(t.nonInteractive=!0);for(const n of o)"--non-interactive"===n||"-y"===n?t.nonInteractive=!0:"--force"===n||"-f"===n?t.force=!0:e.push(n);return{positional:e,options:t}}(t),f=n[0],p=n.slice(1);if(f){switch(f){case"profile":return void await async function(o){const t=o[0],n=o[1];if(!t||"list"===t){const o=a.getActiveProfileName(),t=a.listProfiles().map(t=>{const n=t===o;return`${n?e.green("●"):e.gray("○")} ${t}${n?e.gray(" ("+r.t("config.profile_active_label")+")"):""}`});return void v(r.t("config.profile_list_title"),t)}if("create"===t){const o=y(n,"profile");return a.listProfiles().includes(o)?void console.log(e.yellow(r.t("config.profile_exists",{name:o}))):void await d({description:r.t("config.profile_create_dry_run",{name:o}),json:{action:"profile_create",name:o},apply:()=>{a.createProfile(o),console.log(e.green(r.t("config.profile_created",{name:o})))}})}if("use"===t){const o=y(n,"profile");return void await d({description:r.t("config.profile_use_dry_run",{name:o}),json:{action:"profile_use",name:o},apply:()=>{a.setActiveProfile(o),console.log(e.green(r.t("config.profile_activated",{name:o})))}})}if("delete"===t||"remove"===t){const o=y(n,"profile");return o===s&&1===a.listProfiles().length?void console.log(e.yellow(r.t("config.profile_cannot_delete_last"))):void await d({description:r.t("config.profile_delete_dry_run",{name:o}),json:{action:"profile_delete",name:o},apply:async()=>{await c({message:r.t("config.profile_delete_confirm",{name:o}),defaultValue:!1})?(a.deleteProfile(o),console.log(e.green(r.t("config.profile_deleted",{name:o})))):console.log(e.yellow(r.t("config.profile_delete_aborted")))}})}console.log(e.red(r.t("config.unknown_action",{action:t})))}(p);case"preset":return void await async function(o){const t=o[0],n=o[1];if(!t||"list"===t){const o=Object.entries(a.getCustomPresets()).map(([o,t])=>`${e.cyan(o)} ${e.gray(`H:${t.models.haiku} S:${t.models.sonnet} O:${t.models.opus}`)}`);return void v(r.t("config.preset_list_title"),o)}if("save"===t){const o=y(n,"preset");return void await d({description:r.t("config.preset_save_dry_run",{name:o}),json:{action:"preset_save",name:o},apply:()=>{a.saveCustomPreset(o,a.getModels()),console.log(e.green(r.t("config.preset_saved",{name:o})))}})}if("use"===t||"apply"===t){const o=y(n,"preset"),t=a.getCustomPresets()[o];return t?void await d({description:r.t("config.preset_use_dry_run",{name:o}),json:{action:"preset_use",name:o},apply:()=>{a.setModels(t.models),console.log(e.green(r.t("config.preset_applied",{name:o})))}}):void console.log(e.red(r.t("config.preset_not_found",{name:o})))}if("delete"===t||"remove"===t){const o=y(n,"preset");return void await d({description:r.t("config.preset_delete_dry_run",{name:o}),json:{action:"preset_delete",name:o},apply:()=>{a.deleteCustomPreset(o),console.log(e.green(r.t("config.preset_deleted",{name:o})))}})}console.log(e.red(r.t("config.unknown_action",{action:t})))}(p);case"tool-model":return void await async function(o){const t=o[0];if(!t||"list"===t){const o=a.getProfile().tool_models||{},t=Object.entries(o).map(([o,t])=>{const n=Object.entries(t).map(([o,e])=>`${o}=${e}`).join(" ");return`${e.cyan(o)} ${e.gray(n)}`});return void v(r.t("config.tool_model_list_title"),t)}if("set"===t){const t=(o[1]||"").trim(),n=o.length>=4?(o[2]||"").trim():"opus",l=(o.length>=4?o[3]:o[2]||"").trim();return i[t]?l&&u.test(n)?void await d({description:r.t("config.tool_model_set_dry_run",{tool:t,slot:n,model:l}),json:{action:"tool_model_set",tool:t,slot:n,model:l},apply:()=>{a.setToolModel(t,{[n]:l}),console.log(e.green(r.t("config.tool_model_set",{tool:t,slot:n,model:l})))}}):void console.log(e.red(r.t("config.tool_model_usage"))):void console.log(e.red(t?r.t("config.unknown_tool",{tool:t}):r.t("config.tool_model_usage")))}if("clear"===t||"remove"===t){const t=(o[1]||"").trim();return i[t]?void await d({description:r.t("config.tool_model_clear_dry_run",{tool:t}),json:{action:"tool_model_clear",tool:t},apply:()=>{a.setToolModel(t,null),console.log(e.green(r.t("config.tool_model_cleared",{tool:t})))}}):void console.log(e.red(t?r.t("config.unknown_tool",{tool:t}):r.t("config.tool_model_usage")))}console.log(e.red(r.t("config.unknown_action",{action:t})))}(p);case"backup":return void await function(o){return async function(o){const t=o[0],n=o[1];if(!t||"list"===t){const o=a.listBackups().map(o=>{const t=new Date(o.mtimeMs).toISOString();return`${e.cyan(o.name)} ${e.gray(t)}`});return void v(r.t("config.backup_list_title"),o)}if("create"!==t&&"snapshot"!==t)return"restore"===t?n?void await d({description:r.t("config.backup_restore_dry_run",{name:n}),json:{action:"backup_restore",name:n},apply:async()=>{await c({message:r.t("config.backup_restore_confirm",{name:n}),defaultValue:!1})?(a.restoreBackup(n),console.log(e.green(r.t("config.backup_restored",{name:n})))):console.log(e.yellow(r.t("config.backup_restore_aborted")))}}):void console.log(e.red(r.t("config.backup_restore_missing_name"))):void console.log(e.red(r.t("config.unknown_action",{action:t})));await d({description:r.t("config.backup_create_dry_run"),json:{action:"backup_create",name:n??null},apply:()=>{const o=a.createBackup(n);console.log(e.green(r.t("config.backup_created",{path:o})))}})}(o)}(p)}"claude-code"!==f&&"claude-code"!==p[0]?i[f]?await b(f,p,l):(console.error(e.red(r.t("config.unknown_command",{command:f}))),console.log(e.gray(r.t("config.usage_hint"))),Object.values(i).filter(o=>!o.hidden).forEach(o=>{console.log(e.gray(` - ${o.name}: ${o.displayName}`))})):await b("claude-code",p,l)}else await async function(t){if(t.nonInteractive||!g())return void console.log(e.red(r.t("config.requires_argument")));const{selectedTool:n}=await o.prompt([{type:"list",name:"selectedTool",message:r.t("wizard.select_tool"),choices:Object.values(i).filter(o=>!o.hidden).map(o=>({name:`${o.displayName} (${o.name})`,value:o.name}))}]);await b(n,[],t)}(l)}
|
package/dist/components.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": 1,
|
|
3
|
-
"about": "Components
|
|
3
|
+
"about": "Components the CLI installs and upgrades (its list / install / upgrade commands). Read by src/lib/components.ts and by scripts/gen-components-doc.mjs (docs, the install scripts' README). {scripts} = the brand's installMirror.scripts, {agy} = installMirror.agy, {devtools} = the neutral CNB mirror of fnm / uv / Git for Windows.",
|
|
4
4
|
"devtools": "https://cnb.cool/lib/devtools/-/releases/latest/download",
|
|
5
5
|
"components": [
|
|
6
6
|
{
|
package/dist/lib/app-update.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import t from"chalk";import e from"inquirer";import{existsSync as r,mkdirSync as n,readFileSync as a,writeFileSync as o}from"fs";import{join as
|
|
1
|
+
import t from"chalk";import e from"inquirer";import{existsSync as r,mkdirSync as n,readFileSync as a,writeFileSync as o}from"fs";import{join as p}from"path";import{CLI_NAME as l}from"./brand.js";import{configManager as i}from"./config.js";import{i18n as s}from"./i18n.js";import{canPrompt as u,hasExplicitYes as d,isJsonMode as c}from"./runtime-options.js";import{track as f}from"./telemetry.js";import{compareVersions as m}from"./model-registry.js";import{listAdapters as g}from"./tools/registry.js";import{logger as _}from"../utils/logger.js";function y(){return p(i.getConfigDir(),"app-releases.json")}function w(){try{if(!r(y()))return{};const t=JSON.parse(a(y(),"utf-8"));return t&&"object"==typeof t?t:{}}catch{return{}}}function h(t,e){try{n(i.getConfigDir(),{recursive:!0}),o(y(),JSON.stringify({...w(),[t]:e},null,2))}catch(t){_.logError("app-update.writeCache",t)}}function v(){return g().flatMap(t=>[...t.appInstaller?[{name:t.name,displayName:t.displayName,appInstaller:t.appInstaller,installedVersion:t.installedVersion,runningApp:t.runningApp,tool:t.name}]:[],...(t.companionApps??[]).map(e=>({...e,tool:t.name}))])}export function appTools(){return v().map(t=>t.name)}export function getApp(t){return v().find(e=>e.name===t)}export function appsForTools(t){return v().filter(e=>t.includes(e.tool)).map(t=>t.name)}function k(t){const e=getApp(t);if(!e)throw new Error(`no app installer for ${t}`);return e}function b(t,e,r){try{return e()}catch(e){return _.logError(`app-update.${t}`,e),r}}function q(t){const e=k(t),r=e.appInstaller,n=b("installedPath",()=>null!==r.installedPath(),!1);return{tool:t,name:e.displayName,installed:n,current:n?b("installedVersion",()=>e.installedVersion?.()??null,null):null,running:!!n&&b("isRunning",()=>e.runningApp?.isRunning()??!1,!1),blocker:b("blocker",()=>r.blocker(),"unsupported_platform")}}function x(t,e,r){const n=Boolean(t.installed&&t.current&&e&&m(t.current,e)<0);return{...t,latest:e,outdated:n,...r?{error:r}:{}}}export async function appLatest(t,e={}){const r=w()[t],n=r&&Date.now()-r.checked_at<(r.version?36e5:6e5);if(r&&n&&!e.refresh)return{version:r.version??null,...r.error?{error:r.error}:{}};try{const e=await k(t).appInstaller.latestVersion();return h(t,{version:e,checked_at:Date.now()}),{version:e}}catch(e){const n=e instanceof Error?e.message:String(e);return _.logError(`app-update.latest(${t})`,e),h(t,{error:n,checked_at:Date.now()}),{version:r?.version??null,error:n}}}export async function appStatus(t,e={}){const r=q(t);if(r.blocker&&"classic_install"!==r.blocker)return x(r,null);const{version:n,error:a}=await appLatest(t,e);return x(r,n,a)}export function appStatusWith(t,e){return x(q(t),e.version,e.error)}export function cachedAppStatus(t){const e=q(t);return x(e,e.blocker&&"classic_install"!==e.blocker?null:w()[t]?.version??null)}export function appStatusText(t){return t.installed?t.outdated?s.t("app_update.outdated",{current:t.current,latest:t.latest}):t.current&&t.latest?s.t("app_update.up_to_date",{current:t.current}):t.current??"":t.latest?s.t("app_update.not_installed",{latest:t.latest}):""}export function appUpgradeCommand(t){return`${l} upgrade ${t}`}function C(t){c()?process.stderr.write(t+"\n"):console.log(t)}async function S(t,r=!0){const{ok:n}=await e.prompt([{type:"confirm",name:"ok",message:t,default:r}]);return n}let U={totalMs:12e4,stepMs:1e3};export function setQuitWaitForTests(t){U=t}export async function upgradeApp(e,r={}){const n=Date.now(),a=await appStatus(e,{refresh:r.refresh??!0}),o=a.name,p=(t,r={})=>{const o={...a,result:t,upgraded:"upgraded"===t||"installed"===t,version_after:null,...r};return["up_to_date","unavailable","not_installed","offered"].includes(t)||f(`app-upgrade:${e}`,"failed"===t?"fail":"ok",{duration_ms:Date.now()-n,detail:{result:t,current:a.current,latest:a.latest,...r.reason?{reason:r.reason}:{}}}),o};if(a.blocker)return!r.quiet&&a.installed&&a.outdated&&C(t.yellow(" ! "+s.t("app_update.outdated",{current:a.current,latest:a.latest}))),r.quiet||C(t.yellow(" ! "+s.t(`app_update.blocked_${a.blocker}`,{tool:o,url:k(e).appInstaller.downloadPage,command:appUpgradeCommand(e)}))),p("unavailable",{reason:a.blocker});if(!a.latest)return r.quiet||C(t.yellow(" ! "+s.t("app_update.latest_unknown",{tool:o,reason:a.error??""}))),p("unavailable",{reason:a.error});if(!a.installed&&!r.install)return p("not_installed");const l=Boolean(r.force&&a.installed&&!a.outdated);if(a.installed&&!a.outdated&&!l)return r.quiet||(C(t.green(" √ "+s.t("app_update.already_latest",{tool:o,current:a.current??a.latest}))),C(t.gray(" "+s.t("app_update.force_hint",{command:appUpgradeCommand(e)})))),p("up_to_date");if(l?C(t.yellow(" ! "+s.t("app_update.reinstalling",{tool:o,latest:a.latest,current:a.current??"?"}))):!a.installed||r.askBeforeUpgrade&&!a.running||C(t.yellow(` ! ${o} `+appStatusText(a))),a.installed&&r.askBeforeUpgrade&&!a.running){if(!u()||d())return C(t.gray(" "+s.t("app_update.upgrade_hint",{tool:o,current:a.current??"?",latest:a.latest,command:appUpgradeCommand(e)}))),p("offered");if(!await S(s.t("app_update.upgrade_offer",{tool:o,current:a.current??"?",latest:a.latest})))return C(t.gray(" "+s.t("app_update.declined_hint",{command:appUpgradeCommand(e)}))),p("declined")}let i=!1;if(a.running){if(!u()||d())return C(t.yellow(" ! "+s.t("app_update.running_hint",{tool:o,command:appUpgradeCommand(e)}))),p("left_running");if(!await S(s.t("app_update.offer_quit",{tool:o,latest:a.latest})))return C(t.gray(" "+s.t("app_update.declined_hint",{command:appUpgradeCommand(e)}))),p("declined");const r=k(e).runningApp;if(r?.quit?.())i=!0;else{if(!r?.quitRefused?.()||!await async function(e,r){C(t.yellow(" ! "+s.t("app_update.quit_confirm_in_app",{tool:e,seconds:String(Math.round(U.totalMs/1e3))})));const n=Date.now()+U.totalMs;for(;Date.now()<n;)if(await new Promise(t=>setTimeout(t,U.stepMs)),!r.isRunning())return await new Promise(t=>setTimeout(t,Math.min(1e3,U.stepMs))),!0;return!1}(o,r)){const n=r?.quitRefused?.()?"app_update.quit_refused":"app_update.quit_failed";return C(t.yellow(" ! "+s.t(n,{tool:o,command:appUpgradeCommand(e)}))),p(r?.quitRefused?.()?"left_running":"failed",{reason:r?.quitRefused?.()?"quit_refused":"quit_failed"})}i=!0}}try{const{version:r}=await async function(e){const r=k(e).appInstaller,n=!c()&&Boolean(process.stdout.isTTY);let a=-1;try{return await r.install({downloading:n=>C(t.gray(" "+s.t("app_update.downloading",{tool:k(e).displayName,version:n,size:String(r.sizeMb())}))),percent:e=>{!n||e-a<5||(a=e,process.stdout.write(t.gray(`\r ${e}%`)),e>=100&&process.stdout.write("\n"))},verifying:()=>{n&&a>=0&&a<100&&process.stdout.write("\n"),a=100,C(t.gray(" "+s.t("app_update.verifying",{vendor:r.vendor})))},installing:()=>C(t.gray(" "+s.t("app_update.installing"))),elevate:async()=>!(!u()||!d()&&!await S(s.t("app_update.elevate_offer",{tool:k(e).displayName}))||(C(t.gray(" "+s.t("app_update.elevating"))),0))})}finally{n&&a>=0&&a<100&&process.stdout.write("\n")}}(e);return C(t.green(" √ "+(l?s.t("app_update.reinstalled",{tool:o,version:r}):a.installed?s.t("app_update.upgraded",{tool:o,from:a.current??"?",to:r}):s.t("app_update.installed",{tool:o,version:r})))),i&&!k(e).runningApp?.launch?.()&&C(t.yellow(" ! "+s.t("setup.reopen_hint",{tool:o}))),p(a.installed?"upgraded":"installed",{version_after:r,current:a.current})}catch(r){const n=r instanceof Error?r.message:String(r);return _.logError(`app-update.install(${e})`,r),C(t.yellow(" ! "+(a.installed?s.t("app_update.upgrade_failed",{tool:o,reason:n,current:a.current??"?",command:appUpgradeCommand(e)}):s.t("app_update.install_failed",{tool:o,reason:n,command:appUpgradeCommand(e)})))),i&&k(e).runningApp?.launch?.(),p("failed",{reason:n})}}
|
package/dist/lib/command.d.ts
CHANGED
|
@@ -18,5 +18,7 @@ export declare class Command {
|
|
|
18
18
|
private rejectUnknownCommand;
|
|
19
19
|
private suggestCommand;
|
|
20
20
|
private normalizeCommanderError;
|
|
21
|
+
/** The longest known long option `name` starts with, when more text follows it (`--keysk-…` → `--key`). */
|
|
22
|
+
private gluedOption;
|
|
21
23
|
getProgram(): Commander;
|
|
22
24
|
}
|
package/dist/lib/command.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i18n as
|
|
1
|
+
import{i18n as n,detectSystemLang as o}from"./i18n.js";import{configManager as r}from"./config.js";import{runModelRefresh as t}from"./model-refresh.js";import{refreshClientConfig as e}from"./client-config-sync.js";import{normalizeBaseUrl as i}from"./gateway-addresses.js";import s from"chalk";import{setRuntimeOptions as m,detectColorPreferenceFromEnv as a,isDryRun as c}from"./runtime-options.js";import{runStartupUpdate as d}from"./auto-update.js";import{buildProgram as l}from"./program.js";import{firstCommandWord as u,isHelpRequest as p,renderHelpTopic as g}from"./cli-help.js";import{reportCliError as f,usageError as h,CliError as _}from"./errors.js";import{CLI_NAME as y}from"./brand.js";import{dryRunUnsupportedCommand as w}from"./dry-run.js";import{flushTelemetry as j,installClientHeaders as k,maskSecrets as v,setTelemetryCommand as C,track as x}from"./telemetry.js";export{buildProgram}from"./program.js";const A=new Set(["setup","init","auth","enter","config"]);export class Command{program;configuring=!1;constructor(){const t=r.isLangChosen()?r.getLang():o();n.loadFromConfig(t),this.program=l()}preflightArgs(n){const o=o=>n.includes(o),t=!o("--no-color")&&a();if(m({nonInteractive:o("--non-interactive"),json:o("--json"),yes:o("--yes")||o("-y"),dryRun:o("--dry-run"),color:t}),t||(s.level=0),this.configuring=!1,p(n))return;let e;for(let o=0;o<n.length;o+=1){const r=n[o];"--base"===r&&n[o+1]?(e=n[o+1],o+=1):r.startsWith("--base=")&&(e=r.slice(7))}const c=u(n),d=void 0===c&&!["--version","-v"].some(o);this.configuring=d||void 0!==c&&A.has(c),e&&r.setBaseUrl(i(e)??e,this.configuring&&!o("--dry-run"))}async execute(n){const o=Date.now();let r=!1;try{if(this.preflightArgs(n),k(),p(n)||["--version","-v"].some(o=>n.includes(o))||(C(u(n)??"wizard"),x("command","start",{detail:{args:n.filter(n=>n.startsWith("-")&&!/key/i.test(n))}}),r=!0),"help"===n[0]&&n[1]){const o=g(n[1]);if(o)return void process.stdout.write(o)}if(this.rejectUnknownCommand(n),!p(n)){if(c()&&this.rejectUnsupportedDryRun(n),(await d(n)).handled)return;this.configuring&&await e({timeoutMs:5e3}),await t(n)}if(await this.program.parseAsync(n,{from:"user"}),r){const n=Boolean(process.exitCode)&&0!==process.exitCode;x("command",n?"fail":"ok",{duration_ms:Date.now()-o,...n?{detail:{exit_code:process.exitCode}}:{}})}}catch(t){if("commander.helpDisplayed"===t?.code||"commander.version"===t?.code)return;const e=this.normalizeCommanderError(t,n),i=f(e);if(r){const n=e instanceof _?`${e.type}${e.subtype?"/"+e.subtype:""}`:void 0;x("command",130===i?"cancel":"fail",{duration_ms:Date.now()-o,error:e,detail:{exit_code:i,...n?{type:n}:{}}})}}finally{r&&await j()}}rejectUnsupportedDryRun(o){const r=w(o);if(null!==r)throw h(n.t("runtime.dry_run_unsupported",{command:r,cli:y}),n.t("runtime.dry_run_unsupported_hint",{cli:y}),"dry_run_unsupported")}rejectUnknownCommand(o){const r=u(o);if(!r||"help"===r)return;if(this.program.commands.some(n=>n.name()===r))return;const t=this.suggestCommand(r),e=t?n.t("cli.unknown_hint_suggestion",{command:t}):n.t("cli.unknown_hint");throw h(n.t("cli.error_unknown",{command:r}),e,"unknown_command")}suggestCommand(n){const o=(n,o)=>{const r=Array.from({length:o.length+1},(n,o)=>o);for(let t=1;t<=n.length;t+=1){let e=r[0];r[0]=t;for(let i=1;i<=o.length;i+=1){const s=r[i];r[i]=Math.min(r[i]+1,r[i-1]+1,e+(n[t-1]===o[i-1]?0:1)),e=s}}return r[o.length]};return this.program.commands.map(n=>n.name()).map(r=>({name:r,score:o(n,r)})).filter(({score:o})=>o<=Math.max(2,Math.floor(n.length/2))).sort((n,o)=>n.score-o.score)[0]?.name}normalizeCommanderError(o,r){if(o instanceof _)return o;const t=o?.code,e=o instanceof Error?o.message:String(o);if("commander.unknownOption"===t||"commander.missingArgument"===t||"commander.missingMandatoryOption"===t||"commander.invalidArgument"===t){const o=u(r),i=/'([^']+)'/.exec(e)?.[1]??"",s="commander.unknownOption"===t?"cli.err_unknown_option":"commander.missingArgument"===t?"cli.err_missing_argument":"commander.missingMandatoryOption"===t?"cli.err_missing_option":null,m="commander.unknownOption"===t?this.gluedOption(i):void 0,a=v(i),c=m?n.t("cli.err_glued_option",{name:a,option:m}):s&&i?n.t(s,{name:a}):v(e.replace(/^error:\s*/,""));return h(c,o?n.t("cli.unknown_option_hint",{command:o}):n.t("cli.unknown_option_hint_root"),t)}return o}gluedOption(n){const o=new Set,r=n=>{for(const r of n.options)r.long&&o.add(r.long);for(const o of n.commands)r(o)};return r(this.program),[...o].filter(o=>n.length>o.length&&n.startsWith(o)).sort((n,o)=>o.length-n.length)[0]}getProgram(){return this.program}}
|
|
@@ -34,11 +34,17 @@ export interface EnvCleanupResult {
|
|
|
34
34
|
/**
|
|
35
35
|
* Removes ANTHROPIC_* settings that point at this gateway from shell profiles and the Windows
|
|
36
36
|
* environment (they override the settings.json vibecli writes), after backing each one up.
|
|
37
|
-
* Settings for another service are left alone
|
|
38
|
-
*
|
|
37
|
+
* Settings for another service are left alone here (new-api#174: a profile someone else wrote is
|
|
38
|
+
* not ours to delete unasked); the Claude Code adapter's `followUp()` asks about them in a terminal
|
|
39
|
+
* (user, 11-03: default yes). Runs when Claude Code is configured, after the write plan was
|
|
39
40
|
* confirmed; the plan lists the same sources (`envCleanupPlan`).
|
|
40
41
|
*/
|
|
41
42
|
export declare function cleanupAnthropicEnvVars(): EnvCleanupResult;
|
|
43
|
+
/**
|
|
44
|
+
* Removes the ANTHROPIC_* settings of `sources` (each backed up first): shell / PowerShell profile
|
|
45
|
+
* lines, Windows user and system variables (system ones need an administrator, left in `machineLeft`).
|
|
46
|
+
*/
|
|
47
|
+
export declare function removeEnvSources(sources: EnvSource[]): EnvCleanupResult;
|
|
42
48
|
/** What the last `cleanupAnthropicEnvVars()` did, for the notes after Claude Code is configured. */
|
|
43
49
|
export declare function lastEnvCleanup(): EnvCleanupResult;
|
|
44
50
|
/** Shown in the write plan before Claude Code is configured: profiles whose ANTHROPIC_* lines go. */
|
package/dist/lib/env-cleanup.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as
|
|
1
|
+
import{existsSync as e,mkdirSync as o,readFileSync as r,writeFileSync as n}from"fs";import{join as t}from"path";import{logger as s}from"../utils/logger.js";import{toolHome as c}from"./tools/types.js";import{backupBeforeWrite as i}from"./tools/backup.js";import{configManager as u,savedApiKeys as f}from"./config.js";import{isOurGatewayUrl as l}from"./gateway-addresses.js";import{broadcastEnvChange as a,deleteWindowsEnv as p,readWindowsEnv as m}from"./windows-env.js";export const ANTHROPIC_ENV_VARS=["ANTHROPIC_API_KEY","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_BASE_URL","ANTHROPIC_DEFAULT_HAIKU_MODEL","ANTHROPIC_DEFAULT_SONNET_MODEL","ANTHROPIC_DEFAULT_OPUS_MODEL","ANTHROPIC_DEFAULT_FABLE_MODEL","ANTHROPIC_MODEL","ANTHROPIC_REASONING_MODEL"];export function getShellRcFilePath(){if("win32"===process.platform)return null;const e=c();switch((process.env.SHELL||"").split("/").pop()||""){case"bash":return t(e,".bashrc");case"zsh":return t(e,".zshrc");case"fish":return t(e,".config","fish","config.fish");default:return t(e,".profile")}}function h(e){const o=e.trim().replace(/\s+#.*$/,""),r=o.match(/^(['"])(.*)\1$/);return r?r[2]:o}const v=e=>new RegExp(String.raw`^\s*export\s+${e}=(.*)$`,"gm"),E=e=>new RegExp(String.raw`^[ \t]*\$env:${e}[ \t]*=(.*)$`,"gim");function g(e){if(l(e.ANTHROPIC_BASE_URL))return!0;const o=f();return[e.ANTHROPIC_API_KEY,e.ANTHROPIC_AUTH_TOKEN].some(e=>Boolean(e)&&o.includes(e.trim()))}export function anthropicEnvSources(){const o=[],n=(n,t)=>{if(n&&e(n))try{const e=function(e,o){const r={};for(const n of ANTHROPIC_ENV_VARS)for(const t of e.matchAll(o(n)))r[n]=h(t[1]);return r}(r(n,"utf-8"),t);Object.keys(e).length>0&&o.push({kind:"file",location:n,vars:e,ours:g(e)})}catch(e){s.logError("envCleanup.read",e)}};if("win32"!==process.platform)return n(getShellRcFilePath(),v),o;for(const e of["user","machine"]){const r={};for(const o of ANTHROPIC_ENV_VARS){const n=m(e,o);void 0!==n&&(r[o]=n)}Object.keys(r).length>0&&o.push({kind:"user"===e?"windows-user":"windows-machine",location:"user"===e?"HKCU\\Environment":"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",vars:r,ours:g(r)})}for(const e of function(){const e=c(),o=[];for(const r of[t(e,"Documents"),t(e,"OneDrive","Documents"),t(e,"OneDrive","文档")])for(const e of["PowerShell","WindowsPowerShell"])o.push(t(r,e,"Microsoft.PowerShell_profile.ps1"),t(r,e,"profile.ps1"));return o}())n(e,E);return o}function O(e,o,t){const c=r(e,"utf-8");let u=c;for(const e of o)u=u.replace(new RegExp(t(e).source+String.raw`(\r?\n)?`,t(e).flags),"");return t===v&&(u=u.replace(/^\s*#\s*Claude Code environment variables\s*$\n?/gm,"")),u!==c&&(i(e),n(e,u,"utf-8"),s.debug(`Removed ${o.join(", ")} from ${e}`),!0)}function _(e,r){try{const s=t(u.getConfigDir(),"backups");o(s,{recursive:!0});const c=t(s,`windows-env-${e}-${(new Date).toISOString().replace(/[:.]/g,"-")}.json`);return n(c,JSON.stringify(r,null,2)+"\n",{mode:384}),c}catch(e){return s.logError("envCleanup.backupWindowsValues",e),null}}let A={removed:[],foreign:[],machineLeft:[]};export function cleanupAnthropicEnvVars(){const e=anthropicEnvSources(),o=removeEnvSources(e.filter(e=>e.ours));return o.foreign=e.filter(e=>!e.ours),A=o,o}export function removeEnvSources(e){const o={removed:[],foreign:[],machineLeft:[]};let r=!1;for(const n of e){const e=Object.keys(n.vars);try{if("file"===n.kind){O(n.location,e,n.location.endsWith(".ps1")?E:v)&&o.removed.push(n);continue}const t="windows-user"===n.kind?"user":"machine";_(t,n.vars);const c=[];for(const r of e)try{p(t,r),c.push(r)}catch(e){"machine"===t&&o.machineLeft.push(r),s.logError("envCleanup.deleteWindowsEnv",e)}c.length>0&&(r=!0,o.removed.push({...n,vars:Object.fromEntries(c.map(e=>[e,n.vars[e]]))}))}catch(e){s.logError("envCleanup.removeEnvSources",e)}}r&&a();for(const e of o.removed)for(const[o,r]of Object.entries(e.vars))process.env[o]===r&&delete process.env[o];return o}export function lastEnvCleanup(){return A}export function envCleanupPlan(){return anthropicEnvSources().filter(e=>e.ours)}
|
package/dist/lib/post-apply.d.ts
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
* UAC prompt each, asked in interactive terminals; `--yes` runs them without asking.
|
|
4
4
|
*/
|
|
5
5
|
export declare function runPendingElevations(tools: string[]): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* The adapters' `followUp()` offers (Codex sessions, another service's ANTHROPIC_* variables): asked in a
|
|
8
|
+
* terminal with default yes, done under `--yes`, otherwise only the hint is printed. Also after `config <tool>`.
|
|
9
|
+
*/
|
|
10
|
+
export declare function runFollowUps(tools: string[]): Promise<void>;
|
|
6
11
|
/**
|
|
7
12
|
* What setup and the wizard ask right after writing configs: UAC changes and
|
|
8
13
|
* adapter follow-ups (non-interactive: only their hint), then upgrade tools too
|
package/dist/lib/post-apply.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import o from"chalk";import t from"inquirer";import{i18n as n}from"./i18n.js";import{canPrompt as e,hasExplicitYes as r,shouldAutoConfirm as i}from"./runtime-options.js";import{toolManager as s}from"./tool-manager.js";import{getAdapter as a}from"./tools/registry.js";import{upgradeTool as l}from"./tool-upgrade.js";import{appsForTools as p,upgradeApp as
|
|
1
|
+
import o from"chalk";import t from"inquirer";import{i18n as n}from"./i18n.js";import{canPrompt as e,hasExplicitYes as r,shouldAutoConfirm as i}from"./runtime-options.js";import{toolManager as s}from"./tool-manager.js";import{getAdapter as a}from"./tools/registry.js";import{upgradeTool as l}from"./tool-upgrade.js";import{appsForTools as p,upgradeApp as c}from"./app-update.js";import{logger as f}from"../utils/logger.js";async function u(o){const{ok:n}=await t.prompt([{type:"confirm",name:"ok",message:o,default:!0}]);return n}export async function runPendingElevations(t){const r=e();for(const e of t){const t=a(e)?.pendingElevation?.();if(!t)continue;if(!(i()||r&&await u(t.prompt)))continue;const s=a(e)?.displayName??e;console.log(o.gray(" "+n.t("setup.elevation_running"))),console.log(t.run()?o.green(" √ "+n.t("setup.elevation_done",{tool:s})):o.yellow(" ! "+n.t("setup.elevation_failed",{tool:s})))}}export async function runFollowUps(t){const n=e();for(const e of t){let t;try{t=await(a(e)?.followUp?.())}catch(o){f.logError(`postApplyPrompts.followUp(${e})`,o);continue}if(t)if("run"in t&&(r()||n))if(r()||await u(t.prompt))for(const n of await t.run())console.log("action"===n.kind?o.yellow(" ! "+n.text):o.green(" √ "+n.text));else t.decline();else console.log(o.yellow(" ! "+t.hint))}}export async function postApplyPrompts(t,i={}){const m=new Set;for(const o of i.apps?p(t):[])try{const t=await c(o,{install:i.apps.install,quiet:!0,askBeforeUpgrade:!0});t.upgraded&&t.running&&m.add(o)}catch(t){f.logError(`postApplyPrompts.upgradeApp(${o})`,t)}for(const n of t){const t=await(a(n)?.prepareRuntime?.())??[];for(const n of t)console.log("action"===n.kind?o.yellow(" ! "+n.text):o.green(" √ "+n.text))}await runPendingElevations(t),await runFollowUps(t);const g=e(),d=r(),y=g||d?t.filter(o=>a(o)?.installSpec&&s.outdatedVersion(o)):[];if(y.length>0){const o=y.map(o=>a(o)?.displayName??o).join("、");if(d||await u(n.t("setup.offer_upgrade",{tools:o})))for(const o of y)await l(o)}for(const e of t){const t=a(e);if(m.has(e)||!t?.runningApp?.isRunning())continue;if(d||!g){console.log(o.yellow(" ! "+n.t("setup.reopen_hint",{tool:t.displayName})));continue}if(!await u(n.t("setup.offer_restart",{tool:t.displayName})))continue;const r=t.runningApp.restart();console.log(r?o.green(" √ "+n.t("setup.restarted",{tool:t.displayName})):o.yellow(" ! "+n.t("setup.restart_failed",{tool:t.displayName})))}}
|
package/dist/lib/telemetry.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{randomUUID as e}from"crypto";import{arch as t,homedir as r,release as o}from"os";import{brand as n,brandEnv as s,CLI_NAME as a}from"./brand.js";import{clientVersion as i,installId as c}from"./client-config.js";import{configManager as l}from"./config.js";import{gatewayAddresses as u}from"./gateway-addresses.js";import{INSTALL_ID_HEADER as f}from"./gateway-protocol.js";const d=e();let m="wizard",p=[];const g=new Set;let h=null,y=b;export function telemetryEnabled(){if(process.env.VITEST&&!w)return!1;const e=s("TELEMETRY")?.trim().toLowerCase();return!("0"===e||"false"===e||"off"===e)}let w=!1;export function setTelemetrySenderForTests(e){y=e??b,w=null!==e,p=[]}export function clientHeaders(){const e=`${a}/${i()} (${process.platform} ${o()}; ${t()}) node/${process.versions.node}`;return telemetryEnabled()?{"User-Agent":e,[f]:c()}:{"User-Agent":e}}export function installClientHeaders(){const e=globalThis.fetch;if(!e||e.gatewayHeaders)return;const t=(t,r)=>{try{const o=new URL("string"==typeof t||t instanceof URL?t.toString():t.url);if(new Set([l.getBaseUrl(),...u().map(e=>e.url)].map(e=>new URL(e).host)).has(o.host)){const o=new Headers(r?.headers??(t instanceof Request?t.headers:void 0));for(const[e,t]of Object.entries(clientHeaders()))o.has(e)||o.set(e,t);return e(t,{...r,headers:o})}}catch{}return e(t,r)};t.gatewayHeaders=!0,globalThis.fetch=t}export function telemetryPending(){return g.size>0}function T(){return{install_id:c(),cli_version:i(),brand:n().id,os:process.platform,os_release:o(),arch:t(),node_version:process.versions.node}}export function maskHome(e){const t=r();if(!t||t.length<2)return e;const o=new Set([t,t.replace(/\\/g,"/")]);let n=e;for(const e of o)n=n.split(e).join("~");return n}export function maskSecrets(e){return maskHome(e).replace(
|
|
1
|
+
import{randomUUID as e}from"crypto";import{arch as t,homedir as r,release as o}from"os";import{brand as n,brandEnv as s,CLI_NAME as a}from"./brand.js";import{clientVersion as i,installId as c}from"./client-config.js";import{configManager as l}from"./config.js";import{gatewayAddresses as u}from"./gateway-addresses.js";import{INSTALL_ID_HEADER as f}from"./gateway-protocol.js";const d=e();let m="wizard",p=[];const g=new Set;let h=null,y=b;export function telemetryEnabled(){if(process.env.VITEST&&!w)return!1;const e=s("TELEMETRY")?.trim().toLowerCase();return!("0"===e||"false"===e||"off"===e)}let w=!1;export function setTelemetrySenderForTests(e){y=e??b,w=null!==e,p=[]}export function clientHeaders(){const e=`${a}/${i()} (${process.platform} ${o()}; ${t()}) node/${process.versions.node}`;return telemetryEnabled()?{"User-Agent":e,[f]:c()}:{"User-Agent":e}}export function installClientHeaders(){const e=globalThis.fetch;if(!e||e.gatewayHeaders)return;const t=(t,r)=>{try{const o=new URL("string"==typeof t||t instanceof URL?t.toString():t.url);if(new Set([l.getBaseUrl(),...u().map(e=>e.url)].map(e=>new URL(e).host)).has(o.host)){const o=new Headers(r?.headers??(t instanceof Request?t.headers:void 0));for(const[e,t]of Object.entries(clientHeaders()))o.has(e)||o.set(e,t);return e(t,{...r,headers:o})}}catch{}return e(t,r)};t.gatewayHeaders=!0,globalThis.fetch=t}export function telemetryPending(){return g.size>0}function T(){return{install_id:c(),cli_version:i(),brand:n().id,os:process.platform,os_release:o(),arch:t(),node_version:process.versions.node}}export function maskHome(e){const t=r();if(!t||t.length<2)return e;const o=new Set([t,t.replace(/\\/g,"/")]);let n=e;for(const e of o)n=n.split(e).join("~");return n}export function maskSecrets(e){return maskHome(e).replace(/(sk-[A-Za-z0-9_-]{2})[A-Za-z0-9_-]{8,}([A-Za-z0-9_-]{4})\b/g,"$1…$2").replace(/(Bearer\s+)[A-Za-z0-9._~+/=-]{8,}/gi,"$1…")}export function setTelemetryCommand(e){m=e}export function track(e,t,r={}){if(!telemetryEnabled())return;const o=void 0===r.error?void 0:maskSecrets(r.error instanceof Error?r.error.message:String(r.error)).slice(0,2e3);p.push({ts:Date.now(),session:d,command:m,step:e,status:t,...void 0!==r.duration_ms?{duration_ms:Math.round(r.duration_ms)}:{},...o?{error:o}:{},...r.detail?{detail:r.detail}:{}}),"start"===t?S():h||(h=setTimeout(S,500),h.unref())}export async function trackStep(e,t,r){const o=Date.now();track(e,"start",r?{detail:r}:{});try{const r=await t();return track(e,"ok",{duration_ms:Date.now()-o}),r}catch(t){throw track(e,"fail",{duration_ms:Date.now()-o,error:t}),t}}function S(){if(h&&(clearTimeout(h),h=null),0===p.length)return;const e=p.splice(0,50),t=y("/api/platform/vibecode/telemetry",{...T(),events:e},3e3).then(()=>{},()=>{}).finally(()=>g.delete(t));g.add(t),p.length>0&&S()}export async function flushTelemetry(e=1500){S(),0!==g.size&&await Promise.race([Promise.allSettled([...g]),new Promise(t=>setTimeout(t,e).unref())])}export async function uploadReport(e){try{const t=await y("/api/platform/vibecode/report",{...T(),report:e},2e4),r=t?.data?.code;return"string"==typeof r&&r?r:null}catch{return null}}async function b(e,t,r){const o=l.getApiKey()?.trim(),n=await fetch(new URL(e,l.getBaseUrl()).toString(),{method:"POST",headers:{"Content-Type":"application/json",...clientHeaders(),...o?{Authorization:`Bearer ${o}`}:{}},body:JSON.stringify(t),signal:AbortSignal.timeout(r)});if(!n.ok)throw new Error(`HTTP ${n.status}`);return n.json().catch(()=>null)}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { type ToolInstallSpec } from './tools/tool-installs.js';
|
|
2
2
|
/** How the last runCommand ended (for the support events and the fallback message). */
|
|
3
3
|
export type RunOutcome = 'ok' | 'fail' | 'timeout' | 'stalled';
|
|
4
|
+
/** Last lines of the output, ANSI colors and progress-bar redraws removed. */
|
|
5
|
+
export declare function outputTail(text: string): string;
|
|
6
|
+
/** What the last watched command printed last, cleaned up (empty when it printed nothing). */
|
|
7
|
+
export declare function lastCommandOutput(): string;
|
|
4
8
|
export interface RunLimits {
|
|
5
9
|
/** Stop after this long in total. */
|
|
6
10
|
timeoutMs?: number;
|
package/dist/lib/tool-upgrade.js
CHANGED
|
@@ -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 s}from"./i18n.js";import{logger as a}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
|
|
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 s}from"./i18n.js";import{logger as a}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,findInstallsIncludingNative as m,forgetInstalls as d,installLabel as g,npmMirrorInstallCommand as f,npmMirrorVersion as w,npmUninstallCommand as h}from"./tools/tool-installs.js";import{toolHome as y}from"./tools/types.js";import{isJsonMode as v,isNonInteractive as _,shouldAutoConfirm as k}from"./runtime-options.js";import{track as b}from"./telemetry.js";import{isWindowsPowerShell as $,powerShellEnv as T}from"./powershell-env.js";let j="ok",x="";const M=t=>{x=(x+t.toString("utf-8")).slice(-3e3)};export function outputTail(t){return t.replace(/\x1b\[[0-9;?]*[A-Za-z]/g,"").split(/\r?\n/).map(t=>t.split("\r").pop().trimEnd()).filter(Boolean).join("\n").slice(-1500)}export function lastCommandOutput(){return outputTail(x)}let D=async(t,o,r={})=>(console.log(n.gray("$ ")+[t,...o].join(" ")),x="",j=r.idleMs?await runWatched(t,o,r):function(t,o,r){const n=E(t)?e(P(t,o),{stdio:C(),shell:!0,timeout:r}):e(t,o,{stdio:C(),timeout:r,env:S(t)});return n.error&&a.logError(`upgrade: ${t}`,n.error),"ETIMEDOUT"===n.error?.code?"timeout":0===n.status?"ok":"fail"}(t,o,r.timeoutMs),"ok"===j);const E=t=>"win32"===process.platform&&!/\.exe$/i.test(t),S=t=>$(t)?T():process.env,P=(t,e)=>[t,...e].map(t=>/\s/.test(t)?`"${t}"`:t).join(" "),C=()=>["inherit",v()?2:"inherit","inherit"];export function runWatched(e,o,r){return new Promise(n=>{const i=r.env?{...S(e),...r.env}:S(e),s=E(e)?t(P(e,o),{stdio:["inherit","pipe","pipe"],shell:!0,env:i}):t(e,o,{stdio:["inherit","pipe","pipe"],env:i});let l;const c=t=>{l=t,s.kill()};let p;const u=()=>{clearTimeout(p),r.idleMs&&(p=setTimeout(()=>c("stalled"),r.idleMs))},m=r.timeoutMs?setTimeout(()=>c("timeout"),r.timeoutMs):void 0;u(),s.stdout?.on("data",t=>{(v()?process.stderr:process.stdout).write(t),M(t),u()}),s.stderr?.on("data",t=>{process.stderr.write(t),M(t),u()});const d=t=>{clearTimeout(p),clearTimeout(m),n(t)};s.on("error",t=>{a.logError(`upgrade: ${e}`,t),d(l??"fail")}),s.on("close",t=>{l&&(v()?process.stderr:process.stdout).write("\n"),d(l??(0===t?"ok":"fail"))})})}export function setUpgradeRunnerForTests(t){D=async(e,o,r)=>{const n=await t(e,o,r);return j="string"==typeof n?n:n?"ok":"fail","ok"===j}}const I={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 O(t);console.log(n.gray(s.t("install.downloading")));const e=`install-script:${t.command}`,o=Date.now();b(e,"start");const r={idleMs:18e4,timeoutMs:36e5},i="win32"===process.platform?await D("powershell.exe",["-NoProfile","-ExecutionPolicy","Bypass","-Command",`irm ${t.mirrorScript.ps1} -TimeoutSec 30 | iex`],r):await D("sh",["-c",`script=$(curl -fsSL --connect-timeout 15 --max-time 60 ${t.mirrorScript.sh}) && printf '%s\\n' "$script" | sh`],r),a=j;return b(e,"stalled"===a?"timeout":a,{duration_ms:Date.now()-o,..."stalled"===a||"timeout"===a?{detail:{reason:a}}:{},..."ok"!==a&&lastCommandOutput()?{error:lastCommandOutput()}:{}}),i||!t.npmPackage?i:(console.log(n.yellow(" ! "+s.t(I[a],{minutes:String(3)}))),b(e,"fallback"),O(t))}async function O(t){const e=f(t,await w(t)),[o,...r]=e.split(" "),i=`install-npm:${t.command}`,a=Date.now();b(i,"start");const l=await D(o,r);return b(i,l?"ok":"fail",{duration_ms:Date.now()-a}),l||"win32"===process.platform||console.log(n.yellow(" ! "+s.t("upgrade.npm_permission",{command:e}))),l}async function U(t,e){switch(e.kind){case"npm":t.npmPackage&&await D("npm",["uninstall","-g",t.npmPackage]);break;case"brew":t.brew&&await D("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){a.logError("upgrade: remove native copy",t)}break;default:return!1}return d(),!u(t).some(t=>t.path===e.path)}function A(t,e){switch(e.kind){case"npm":return h(t);case"brew":return`brew uninstall ${t.brew}`;case"native":return s.t("upgrade.delete_paths",{paths:[e.path,...(t.native?.dataDirs??[]).map(t=>r(y(),...t))].join("、")});default:return s.t("upgrade.delete_paths",{paths:e.path})}}export async function upgradeTool(t){const e=Date.now();b(`upgrade:${t}`,"start");try{const o=await async function(t){const e=p(t),o=e?.installSpec;if(!e||!o)throw new Error(s.t("upgrade.unsupported",{tool:t}));const r=e.displayName;d();const f=u(o);if(console.log(n.bold(`\n${r}`)),0===f.length)console.log(s.t("upgrade.not_installed_installing",{tool:r})),await mirrorInstall(o);else{const t=f[0];console.log(n.gray(" "+s.t("upgrade.current",{copy:g(t)})));const e=await async function(t,e){switch(e.kind){case"native":return D(e.path,t.native?.updateArgs??["update"],{timeoutMs:t.native?.updateTimeoutMs});case"npm":return O(t);case"brew":return!!t.brew&&D("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(" ! "+s.t("upgrade.native_mirror_trying")));try{const{version:t,manifestVerified:o}=await e();return console.log(n.green(" √ "+s.t(o?"upgrade.native_mirror_done_verified":"upgrade.native_mirror_done",{version:t}))),!0}catch(t){return a.logError("upgrade: native mirror",t),console.log(n.yellow(" ! "+s.t("upgrade.native_mirror_failed",{reason:t instanceof Error?t.message:String(t)}))),!1}}(o)||(console.log(n.yellow(" ! "+s.t("upgrade.fallback_mirror"))),await mirrorInstall(o)):console.log(n.yellow(" ! "+s.t("upgrade.unknown_install",{path:t.path})))}d(),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),a=o.filter(t=>t!==r);console.log(n.yellow(" ! "+s.t("upgrade.duplicates",{tool:e,keep:g(r),others:a.map(g).join("、")})));let c=k();c||_()||!process.stdin.isTTY||(c=(await i.prompt([{type:"confirm",name:"remove",message:s.t("upgrade.confirm_remove"),default:!0}])).remove);for(const e of a)c&&await U(t,e)?console.log(n.green(" √ "+s.t("upgrade.removed",{copy:g(e)}))):console.log(n.yellow(" ! "+s.t("upgrade.remove_by_hand",{how:A(t,e)})))}(o,r),d();const w=m(o)[0];if(!w)return console.log(n.red(" × "+s.t("upgrade.still_missing",{tool:r}))),!1;w.onPath||console.log(n.gray(" "+s.t("components.new_terminal")));const h=c(t);if(h&&w.version&&l(w.version,h)<0){console.log(n.yellow(" ! "+s.t("upgrade.still_old",{copy:g(w),min:h})));for(const t of e.upgradeHints?.(h)??[])console.log(n.yellow(" ! "+t));return!1}return console.log(n.green(" √ "+s.t("upgrade.done",{copy:g(w)}))),!0}(t);return b(`upgrade:${t}`,o?"ok":"fail",{duration_ms:Date.now()-e}),o}catch(o){throw b(`upgrade:${t}`,"fail",{duration_ms:Date.now()-e,error:o}),o}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{join as e}from"path";import{applyGatewayModels as t,claudeCodeManager as o}from"../claude-code-manager.js";import{backupBeforeWrite as n}from"./backup.js";import{i18n as s}from"../i18n.js";import{baseModelId as a}from"../model-catalog.js";import{gatewayModelSpecs as r,prettyModelName as i,vendorNames as l}from"../gateway-models.js";import{toolHome as
|
|
1
|
+
import{join as e}from"path";import{applyGatewayModels as t,claudeCodeManager as o}from"../claude-code-manager.js";import{backupBeforeWrite as n}from"./backup.js";import{i18n as s}from"../i18n.js";import{baseModelId as a}from"../model-catalog.js";import{gatewayModelSpecs as r,prettyModelName as i,vendorNames as l}from"../gateway-models.js";import{toolHome as c}from"./types.js";import{gatewayAddresses as d,normalizeBaseUrl as u}from"../gateway-addresses.js";import{configManager as m,savedApiKeys as p}from"../config.js";import{envCleanupPlan as f,lastEnvCleanup as g,removeEnvSources as _}from"../env-cleanup.js";import{canPrompt as h,hasExplicitYes as v}from"../runtime-options.js";import{maskHome as C}from"../telemetry.js";import{spawnSync as j}from"child_process";import{existsSync as y,readFileSync as k}from"fs";import{detectManagedOverrides as A}from"./claude-managed.js";import{installOfficialPlugins as O}from"./claude-plugins.js";import{findInstalls as S,mirrorInstallCommand as P,brandInstallScripts as x}from"./tool-installs.js";import{updateNativeFromMirror as b}from"./claude-native-mirror.js";import{brandEnv as T}from"../brand.js";import{claudeFormat as N,claudeProjectFiles as w}from"../sessions/formats.js";const H=e(c(),".claude","settings.json"),L=e(c(),".claude.json");let U,R=null,E=()=>0===j("security",["find-generic-password","-s","Claude Code-credentials"],{stdio:"ignore"}).status;export function setClaudeKeychainProbeForTests(e){E=e}export function claudeAccountLoginPresent(){const t=process.env.CLAUDE_CONFIG_DIR?.trim()||e(c(),".claude");if(y(e(t,".credentials.json")))return!0;if("darwin"!==process.platform||T("TEST_HOME"))return!1;try{return E()}catch{return!1}}function I(){try{const t=JSON.parse(k(e(c(),".claude","settings.json"),"utf-8"));return"string"==typeof t.autoUpdatesChannel?t.autoUpdatesChannel:"latest"}catch{return"latest"}}function M(e){if(!e)return;const t=new Set(e.models);return r("claude-code",e.clientModels).filter(e=>t.has(e.id))}function D(){const e=o.getSettings().env?.ANTHROPIC_BASE_URL;return"string"==typeof e&&e.trim()?claudeCodeAdapter.holdsOurConfig(p())?null:e.trim():null}let B=null;const K={command:"claude",npmPackage:"@anthropic-ai/claude-code",native:{binDir:[".local","bin"],updateArgs:["update"],dataDirs:[[".local","share","claude"]],mirrorUpdate:()=>b(I())},mirrorScript:x("claude-code"),brew:"claude-code"};function F(){return h()&&!v()}export const claudeCodeAdapter={name:"claude-code",displayName:"Claude Code",command:"claude",installCommand:P(K),upgradeCommand:"claude update",installSpec:K,upgradeHints:e=>"stable"===I()?[s.t("tools.claude_code.stable_channel",{min:e})]:[],configPath:H,sessions:{format:N,files:()=>w(e(process.env.CLAUDE_CONFIG_DIR?.trim()||e(c(),".claude"),"projects")),resumeCommand:e=>({command:"claude",args:["--resume",e]})},wantsModelCatalog:!0,loadPrivateConfig(t){B=D(),n(H),n(L),U=M(t.catalog),o.loadPrivateConfig(t.apiKey,t.models,t.catalog?.models,U);const s=e(c(),".local","bin","win32"===process.platform?"claude.exe":"claude"),a=S(claudeCodeAdapter.installSpec)[0]?.path??(y(s)?s:null);R=a?O(a):null},holdsOurConfig(e){const t=o.getSettings().env??{},n="string"==typeof t.ANTHROPIC_AUTH_TOKEN?t.ANTHROPIC_AUTH_TOKEN.trim():"",s="string"==typeof t.ANTHROPIC_BASE_URL?u(t.ANTHROPIC_BASE_URL):null;return!(!n||!e.includes(n))||null!==s&&(d().some(e=>e.url===s)||s===u(m.getBaseUrl()))},planNotes(){const e=[],t=D();t&&e.push(s.t("tools.claude_code.plan_replace_provider",{url:t}));for(const t of f())e.push(s.t("tools.claude_code.plan_env_remove",{location:C(t.location),vars:Object.keys(t.vars).join(", ")}));return e},unloadPrivateConfig(e){const t=o.getSettings().env??{};Boolean(t.ANTHROPIC_AUTH_TOKEN||t.ANTHROPIC_BASE_URL)&&!claudeCodeAdapter.holdsOurConfig(e?.savedKeys??[])||(n(H),o.unloadPrivateConfig())},detectCurrentConfig:()=>o.detectCurrentConfig(),getConfig:()=>({settings:o.getSettings(),mcp:o.getMCPConfig()}),updateConfig(e){const t=e||{};t.settings&&o.saveSettings(t.settings),t.mcp&&o.saveMCPConfig(t.mcp)},clearPinnedModels:e=>(n(H),o.clearPinnedModels(e?.models)),listedModels(){const e=o.getSettings().modelPicker;return Array.isArray(e?.options)?e.options.map(e=>a(String(e.model))):null},refreshModelMenu(e){const s=o.getSettings(),a=t(s,M(e.catalog));JSON.stringify(a)!==JSON.stringify(s)&&(n(H),o.saveSettings(a))},async followUp(){const e=g().foreign;if(0===e.length||!F())return null;const t=e.map(e=>`${C(e.location)}(${Object.keys(e.vars).join(", ")})`).join("、");return{prompt:s.t("tools.claude_code.env_foreign_offer",{where:t}),hint:s.t("tools.claude_code.env_foreign",{location:e.map(e=>C(e.location)).join("、"),vars:[...new Set(e.flatMap(e=>Object.keys(e.vars)))].join(", ")}),async run(){const t=_(e),o=t.removed.map(e=>({kind:"summary",text:s.t("tools.claude_code.env_removed_foreign",{location:C(e.location),vars:Object.keys(e.vars).join(", ")})}));return t.machineLeft.length>0&&o.push({kind:"action",text:s.t("messages.env_vars_machine_left",{vars:t.machineLeft.join(", ")})}),o},decline(){}}},applyNotes(){const e=[];R?.installed.length&&(e.push({kind:"summary",text:s.t("tools.claude_code.plugins_installed",{count:String(R.installed.length)})}),e.push({kind:"detail",text:R.installed.join(", ")})),"git"===R?.skipped?e.push({kind:"action",text:s.t("tools.claude_code.plugins_need_git")}):("marketplace"===R?.skipped||R?.failed.length)&&e.push({kind:"action",text:s.t("tools.claude_code.plugins_failed")}),U&&U.length>0&&(e.push({kind:"summary",text:s.t("tools.claude_code.gateway_models",{count:String(U.length),vendors:l(U.map(e=>e.id)).join(" / ")})}),e.push({kind:"detail",text:U.map(e=>e.name||i(e.id)).join(", ")})),B&&e.push({kind:"summary",text:s.t("tools.claude_code.provider_replaced",{url:B})});const t=g();for(const o of t.removed)e.push({kind:"summary",text:s.t("tools.claude_code.env_removed",{location:C(o.location),vars:Object.keys(o.vars).join(", ")})});for(const o of t.foreign){const t={location:C(o.location),vars:Object.keys(o.vars).join(", ")};e.push(F()?{kind:"detail",text:s.t("tools.claude_code.env_foreign_found",t)}:{kind:"action",text:s.t("tools.claude_code.env_foreign",t)})}t.machineLeft.length>0&&e.push({kind:"action",text:s.t("messages.env_vars_machine_left",{vars:t.machineLeft.join(", ")})});const n=o.getLastKept();n.length>0&&e.push({kind:"summary",text:s.t("tools.claude_code.kept_user_models",{values:n.join(", ")})}),"win32"!==process.platform||process.env.CLAUDE_CODE_GIT_BASH_PATH||0===j("where",["git"],{windowsHide:!0,stdio:"ignore"}).status||e.push({kind:"action",text:s.t("tools.claude_code.no_git_bash")}),claudeAccountLoginPresent()&&e.push({kind:"detail",text:s.t("tools.claude_code.account_login_overridden")});for(const t of A())e.push({kind:"action",text:s.t("tools.claude_code.managed_override",{source:t.source,keys:t.keys.join(", ")})});for(const t of o.getLastTierFallbacks())e.push({kind:"detail",text:s.t("tools.claude_code.tier_fallback",{tier:t.tier,from:t.from,to:t.to})});return e},backupPaths:()=>[H,L],forceResetPaths:()=>[H]};
|
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
* - macOS: the .dmg is attached read-only, the app copied with `ditto` next to the target and swapped in with
|
|
14
14
|
* two renames (the old bundle stays until the new one is in place). A new install goes to /Applications, or
|
|
15
15
|
* ~/Applications when /Applications isn't writable for this user. Write access is checked before downloading.
|
|
16
|
-
* - Windows: `Add-AppxPackage` (per user
|
|
16
|
+
* - Windows: `Add-AppxPackage` (per user). Windows refuses some first installs without an administrator
|
|
17
|
+
* (0x80073D28, 11-03 a customer's fresh Claude Desktop install; upgrades of the same package worked without):
|
|
18
|
+
* then, if `progress.elevate()` agrees, the downloaded package is installed once more through one UAC prompt.
|
|
17
19
|
* - Not as root (sudo) on macOS, not as SYSTEM on Windows: the app would belong to the wrong account. Not over
|
|
18
20
|
* SSH on Windows: a network logon can't deploy MSIX packages.
|
|
19
21
|
*/
|
|
@@ -83,6 +85,8 @@ export interface DesktopInstallProgress {
|
|
|
83
85
|
percent?(percent: number): void;
|
|
84
86
|
verifying?(): void;
|
|
85
87
|
installing?(): void;
|
|
88
|
+
/** Windows asked for an administrator: true = install through a UAC prompt (asked / announced by the caller). */
|
|
89
|
+
elevate?(): Promise<boolean>;
|
|
86
90
|
}
|
|
87
91
|
export interface DesktopAppInstaller {
|
|
88
92
|
mirrorRepo(): string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as t}from"child_process";import{createHash as e}from"crypto";import{accessSync as r,constants as o,createReadStream as n,createWriteStream as s,existsSync as a,mkdirSync as i,mkdtempSync as c,readFileSync as l,renameSync as p,rmSync as u}from"fs";import{cpus as d,tmpdir as f}from"os";import{basename as m,dirname as g,join as
|
|
1
|
+
import{spawnSync as t}from"child_process";import{createHash as e}from"crypto";import{accessSync as r,constants as o,createReadStream as n,createWriteStream as s,existsSync as a,mkdirSync as i,mkdtempSync as c,readFileSync as l,renameSync as p,rmSync as u}from"fs";import{cpus as d,tmpdir as f}from"os";import{basename as m,dirname as g,join as h}from"path";import{Readable as w,Transform as $}from"stream";import{pipeline as S}from"stream/promises";import{logger as A}from"../../utils/logger.js";import{i18n as x}from"../i18n.js";import{powerShellEnv as E}from"../powershell-env.js";import{toolHome as y}from"./types.js";const v=(e,r,o={})=>{const n=t(e,r,{encoding:"utf-8",timeout:o.timeout??12e4,windowsHide:!0,input:o.input,stdio:[void 0===o.input?"ignore":"pipe","pipe","pipe"],maxBuffer:16777216,env:E()});return n.error&&A.logError(`desktop-app: ${e}`,n.error),{status:n.status,stdout:`${n.stdout??""}`,stderr:`${n.stderr??""}`}};let P=v,_=(...t)=>fetch(...t),I=null,k=null,b=null,C=null;export function setDesktopAppDepsForTests(t){void 0!==t.run&&(P=t.run??v),void 0!==t.fetch&&(_=t.fetch??((...t)=>fetch(...t))),void 0!==t.platform&&(I=t.platform),void 0!==t.arm64&&(k=t.arm64),void 0!==t.privileged&&(b=t.privileged),void 0!==t.remote&&(C=t.remote)}export function appPlatform(){return I??process.platform}export function isArm64Machine(){return null!==k?k:"arm64"===process.arch||("win32"===appPlatform()?"ARM64"===process.env.PROCESSOR_ARCHITECTURE||"ARM64"===process.env.PROCESSOR_ARCHITEW6432:"darwin"===appPlatform()&&/\bApple\b/.test(d()[0]?.model??""))}export class DesktopInstallError extends Error{constructor(t){super(t),this.name="DesktopInstallError"}}export const fail=(t,e={})=>{const r={};for(const[t,o]of Object.entries(e))r[t]=o.trim()||x.t("app_update.reason_unknown");throw new DesktopInstallError(x.t(`app_update.error_${t}`,r))};export function parseSha256Sums(t){const e=new Map;for(const r of t.split(/\r?\n/)){const t=/^([0-9a-f]{64})\s+\*?(\S.*)$/i.exec(r.trim());t&&e.set(t[2].trim(),t[1].toLowerCase())}return e}async function T(t,e){const r=await _(t,{signal:AbortSignal.timeout(e)});if(!r.ok)throw new Error(`${t}: HTTP ${r.status}`);return(await r.text()).trim()}function M(t,e){try{const r=l(h(t,"Contents","Info.plist"),"utf-8");return new RegExp(`<key>${e}</key>\\s*<string>([^<]*)</string>`).exec(r)?.[1]??null}catch{return null}}export function macBundleId(t){return M(t,"CFBundleIdentifier")}export function macAppVersion(t){return/^\d+\.\d+\.\d+/.exec(M(t,"CFBundleShortVersionString")??"")?.[0]??null}function R(t){try{return r(t,o.W_OK),!0}catch{return!1}}const F=t=>`'${t.replace(/'/g,"''")}'`;function O(t,e=12e4){return P("powershell.exe",["-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-Command","[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; "+t],{timeout:e})}export function powerShellError(t){return t.replace(/#< CLIXML/g,"").replace(/_x000D__x000A_/g,"\n").replace(/<\/S>/g,"\n").replace(/<[^>]+>/g,"").replace(/_x[0-9A-F]{4}_/g,"").replace(/'/g,"'").replace(/"/g,'"').replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&").split(/\r?\n/).map(t=>t.trim()).find(t=>t&&!/^(At line|At char|所在位置|\+|~|CategoryInfo|FullyQualifiedErrorId)/i.test(t))??""}export function createDesktopAppInstaller(t){const r=()=>t.mirror()?.replace(/\/-\/releases\/latest\/?$/,"")??null,o=()=>t.asset(appPlatform(),isArm64Machine()),d=()=>{const e=appPlatform();return"darwin"!==e&&"win32"!==e?"unsupported_platform":o()?r()?"darwin"===e&&(b??0===process.getuid?.())?"root":"win32"===e&&(null!==b?b:/\\system32\\config\\systemprofile/i.test(process.env.USERPROFILE??"")||!0===process.env.USERNAME?.endsWith("$"))?"system_account":"win32"===e&&(null!==C?C:Boolean(process.env.SSH_CONNECTION||process.env.SSH_CLIENT))?"remote_session":t.extraBlocker?.(e)??null:"no_mirror":"darwin"===e?"unsupported_arch":"unsupported_platform"},E=async(e=8e3)=>{const o=r();if(!o)throw new Error("no mirror");const n=t.versionFile(appPlatform(),isArm64Machine()),s=await T(`${o}/-/releases/latest/download/${n}`,e),a=/^(\d+\.\d+\.\d+)(\.\d+)?$/.exec(s)?.[1];if(!a)throw new Error(`unexpected ${n}: ${s.slice(0,40)}`);return a},v=()=>{for(const e of["/Applications",h(y(),"Applications")])for(const r of t.macApp.installedNames){const o=h(e,r);if(!a(h(o,"Contents","Info.plist")))continue;const n=macBundleId(o);if(null===n||n===t.macApp.bundleId)return o}return null},I=e=>{const r=P("codesign",["--verify","--deep","--strict",e],{timeout:6e5});0!==r.status&&fail("signature",{reason:(r.stderr||r.stdout).trim().split("\n")[0]||`codesign ${r.status}`});const o=P("codesign",["-dv",e]),n=`${o.stdout}\n${o.stderr}`,s=/^TeamIdentifier=(\S+)/m.exec(n)?.[1],a=/^Identifier=(\S+)/m.exec(n)?.[1];s===t.macApp.teamId&&a===t.macApp.bundleId||fail("signature",{reason:`TeamIdentifier=${s??"?"} Identifier=${a??"?"}`});const i=P("spctl",["-a","-t","exec","-vv",e],{timeout:3e5});0!==i.status&&fail("signature",{reason:(i.stderr||i.stdout).trim().split("\n")[0]||`spctl ${i.status}`})},k=()=>{const e=v();let r=e;if(!r){const e=R("/Applications")?"/Applications":h(y(),"Applications");r=h(e,t.macApp.installedNames[0])}const o=g(r);return(a(o)&&!R(o)||e&&!R(e))&&fail("no_permission",{path:r}),{target:r,existing:e}},M=e=>{const r=O(`$s = Get-AuthenticodeSignature -LiteralPath ${F(e)}; [pscustomobject]@{ status = [string]$s.Status; subject = [string]$s.SignerCertificate.Subject } | ConvertTo-Json -Compress`);let o={};try{o=JSON.parse(r.stdout.trim()||"{}")}catch{}if("Valid"!==o.status||!t.windows.signer.test(o.subject??"")){const t=o.status?`${o.status} ${o.subject??""}`:powerShellError(r.stderr)||powerShellError(r.stdout.trim().startsWith("{")?"":r.stdout)||`exit ${r.status}`;fail("signature",{reason:t.trim()})}},N=()=>{const e=O(`Get-AppxPackage | Where-Object { ${t.windows.packageFilter} } | ForEach-Object { $_.Version.ToString() }`,3e4);return/\d+\.\d+\.\d+/.exec(e.stdout)?.[0]??null};return{mirrorRepo:r,assetName:o,blocker:d,latestVersion:E,installedMacApp:v,windowsPackageVersion:N,verifyMacApp:I,verifyWindowsPackage:M,install:async(y={})=>{const v=d();v&&fail("blocked",{reason:x.t(`app_update.reason_${v}`)});const b=r(),C=o();let R;try{R=await E(15e3)}catch(t){fail("download",{reason:t instanceof Error?t.message:String(t)})}const j=t.releaseTag?`${b}/-/releases/download/${t.releaseTag(R)}`:`${b}/-/releases/latest/download`;let B;try{B=parseSha256Sums(await T(`${j}/SHA256SUMS`,15e3)).get(C)}catch(e){A.logError(`${t.id}: SHA256SUMS`,e)}B||fail("no_checksum",{file:C}),"darwin"===appPlatform()&&k();const H=c(h(f(),`${t.id}-`));try{const r=h(H,C);y.downloading?.(R),await async function(t,e,r){let o;try{o=await _(t,{signal:AbortSignal.timeout(18e5)})}catch(t){fail("download",{reason:t instanceof Error?t.message:String(t)})}o.ok&&o.body||fail("download",{reason:`HTTP ${o.status}`});const n=Number(o.headers.get("content-length"))||0;let a=0,i=-1;const c=new $({transform(t,e,o){a+=t.length;const s=n?Math.floor(100*a/n):-1;s>=0&&s!==i&&(i=s,r?.(s)),o(null,t)}});try{await S(w.fromWeb(o.body),c,s(e))}catch(t){u(e,{force:!0}),fail("download",{reason:t instanceof Error?t.message:String(t)})}}(`${j}/${C}`,r,y.percent),y.verifying?.();const o=await async function(t){const r=e("sha256");for await(const e of n(t))r.update(e);return r.digest("hex")}(r);return o!==B&&fail("checksum",{file:C,expected:B.slice(0,12),actual:o.slice(0,12)}),y.installing?.(),"darwin"===appPlatform()?await(async(e,r)=>{const o=h(r,"mnt");i(o,{recursive:!0});const n=P("hdiutil",["attach","-nobrowse","-readonly","-noautoopen","-mountpoint",o,e],{timeout:3e5,input:"Y\n"});0!==n.status&&fail("mount",{reason:(n.stderr||n.stdout).trim().split("\n").pop()??""});let s=null;try{const e=h(o,t.macApp.source);a(e)||fail("bad_package",{reason:t.macApp.source});const{target:r,existing:n}=k(),c=g(r),l=m(r);i(c,{recursive:!0}),s=h(c,`.${l}.${process.pid}.new`),u(s,{recursive:!0,force:!0});const d=P("ditto",[e,s],{timeout:9e5});0!==d.status&&fail("copy",{reason:(d.stderr||d.stdout).trim().split("\n")[0]??""}),I(s);const f=macAppVersion(s);f||fail("bad_package",{reason:"Info.plist"});const w=h(c,`.${l}.${process.pid}.old`);try{n&&p(n,w)}catch(t){throw["EPERM","EACCES"].includes(t.code??"")&&fail("app_management",{path:n}),t}try{p(s,r)}catch(t){throw n&&p(w,n),t}return s=null,u(w,{recursive:!0,force:!0}),{version:f,location:r}}finally{s&&u(s,{recursive:!0,force:!0}),P("hdiutil",["detach",o,"-force"],{timeout:6e4})}})(r,H):await(async(t,e)=>{M(t);const r=O(`$ErrorActionPreference = 'Stop'; Add-AppxPackage -Path ${F(t)} -ForceApplicationShutdown`,9e5);if(0!==r.status){const o=powerShellError(r.stderr)||powerShellError(r.stdout)||`Add-AppxPackage ${r.status}`;/0x80073D28/i.test(`${r.stderr}\n${r.stdout}`)||fail("install",{reason:o}),await(e.elevate?.())||fail("needs_admin");const n=(t=>{const e=h(g(t),"elevated-install.log"),r=`$ErrorActionPreference = 'Stop'; try { Add-AppxPackage -Path ${F(t)} -ForceApplicationShutdown; exit 0 } catch { [IO.File]::WriteAllText(${F(e)}, $_.Exception.Message, [Text.Encoding]::UTF8); exit 1 }`,o=O(`$ErrorActionPreference = 'Stop'; $p = Start-Process -FilePath 'powershell.exe' -ArgumentList @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-EncodedCommand', '${Buffer.from(r,"utf16le").toString("base64")}') -Verb RunAs -Wait -PassThru -WindowStyle Hidden; exit $p.ExitCode`,12e5);if(0===o.status)return null;let n="";try{n=l(e,"utf-8").trim()}catch{}return n||powerShellError(o.stderr)||powerShellError(o.stdout)||`exit ${o.status}`})(t);n&&fail("install",{reason:n}),N()||fail("other_account")}const o=N();return o||fail("install",{reason:"Get-AppxPackage"}),{version:o,location:"MSIX"}})(r,y)}finally{u(H,{recursive:!0,force:!0})}}}}
|
|
@@ -100,6 +100,8 @@ export interface AppInstaller {
|
|
|
100
100
|
percent(percent: number): void;
|
|
101
101
|
verifying(): void;
|
|
102
102
|
installing(): void;
|
|
103
|
+
/** Windows wants an administrator for this install: true = go ahead with a UAC prompt. */
|
|
104
|
+
elevate?(): Promise<boolean>;
|
|
103
105
|
}): Promise<{
|
|
104
106
|
version: string;
|
|
105
107
|
location: string;
|
package/dist/locales/en_US.json
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
"unknown_hint": "Next: run {{cli}} --help to see the available commands.",
|
|
5
5
|
"unknown_hint_suggestion": "Did you mean {{cli}} {{command}}?",
|
|
6
6
|
"err_unknown_option": "Unknown option: {{name}}",
|
|
7
|
+
"err_glued_option": "Unknown option: {{name}}. Put a space between {{option}} and its value",
|
|
7
8
|
"err_missing_argument": "Missing argument: {{name}}",
|
|
8
9
|
"err_missing_option": "Missing required option: {{name}}",
|
|
9
10
|
"unknown_option_hint": "Next: run {{cli}} {{command}} --help to see the correct usage.",
|
|
@@ -427,6 +428,9 @@
|
|
|
427
428
|
"plan_env_remove": "Remove {{vars}} pointing at this site from {{location}} (backed up first)",
|
|
428
429
|
"env_removed": "Removed {{vars}} pointing at this site from {{location}}; new terminals pick this up (backed up)",
|
|
429
430
|
"env_foreign": "{{vars}} in {{location}} point at another service and override Claude Code's settings; {{product}} left them alone. To use {{brand}}, remove them yourself and open a new terminal",
|
|
431
|
+
"env_foreign_found": "{{vars}} in {{location}} point at another service and override Claude Code's settings",
|
|
432
|
+
"env_foreign_offer": "Remove the environment variables pointing at another service, {{where}}? Claude Code uses {{brand}} only without them (they are backed up first)",
|
|
433
|
+
"env_removed_foreign": "Removed {{vars}} from {{location}} (backed up); open a new terminal for it to take effect",
|
|
430
434
|
"plan_replace_provider": "Replace Claude Code's current endpoint {{url}} (not written by {{product}})",
|
|
431
435
|
"provider_replaced": "Replaced the previous endpoint {{url}}; the old file is backed up",
|
|
432
436
|
"gateway_models": "{{count}} more models added to /model ({{vendors}})",
|
|
@@ -1245,6 +1249,10 @@
|
|
|
1245
1249
|
"reinstalled": "Reinstalled {{tool}} {{version}}",
|
|
1246
1250
|
"force_hint": "To reinstall it, run {{command}} --force",
|
|
1247
1251
|
"blocked_remote_session": "This is a remote (SSH) session, where Windows doesn't allow installing {{tool}}: run {{command}} in a terminal on this computer",
|
|
1248
|
-
"reason_remote_session": "Windows apps can't be installed from a remote (SSH) session"
|
|
1252
|
+
"reason_remote_session": "Windows apps can't be installed from a remote (SSH) session",
|
|
1253
|
+
"error_needs_admin": "Windows requires administrator rights for this install (0x80073D28); right-click PowerShell, choose \"Run as administrator\" and run it there",
|
|
1254
|
+
"error_other_account": "the prompt was approved with another administrator account, so the app was installed for that account: approve with the current account (make it an administrator), or use the app from that account",
|
|
1255
|
+
"elevate_offer": "Windows requires administrator rights to install {{tool}}. Show the permission prompt now?",
|
|
1256
|
+
"elevating": "Requesting administrator rights: click Yes in the Windows prompt…"
|
|
1249
1257
|
}
|
|
1250
1258
|
}
|
package/dist/locales/zh_CN.json
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
"unknown_hint": "下一步:运行 {{cli}} --help 查看可用命令。",
|
|
5
5
|
"unknown_hint_suggestion": "你是不是想运行 {{cli}} {{command}}?",
|
|
6
6
|
"err_unknown_option": "未知选项:{{name}}",
|
|
7
|
+
"err_glued_option": "未知选项:{{name}}。{{option}} 和后面的值之间要有空格",
|
|
7
8
|
"err_missing_argument": "缺少参数:{{name}}",
|
|
8
9
|
"err_missing_option": "缺少必填选项:{{name}}",
|
|
9
10
|
"unknown_option_hint": "下一步:运行 {{cli}} {{command}} --help 查看正确用法。",
|
|
@@ -427,6 +428,9 @@
|
|
|
427
428
|
"plan_env_remove": "删除 {{location}} 里指向本站的 {{vars}}(先备份)",
|
|
428
429
|
"env_removed": "已删除 {{location}} 里指向本站的 {{vars}},新开的终端生效(已备份)",
|
|
429
430
|
"env_foreign": "{{location}} 里的 {{vars}} 指向别的服务,会盖过 Claude Code 的配置,{{product}} 没有改它;要用 {{brand}},请自己删掉后重新打开终端",
|
|
431
|
+
"env_foreign_found": "{{location}} 里的 {{vars}} 指向别的服务,会盖过 Claude Code 的配置",
|
|
432
|
+
"env_foreign_offer": "删掉指向别的服务的环境变量 {{where}}?删掉后 Claude Code 才会用 {{brand}}(会先备份)",
|
|
433
|
+
"env_removed_foreign": "已删除 {{location}} 里的 {{vars}}(已备份),重新打开终端后生效",
|
|
430
434
|
"plan_replace_provider": "替换 Claude Code 现在的接入地址 {{url}}(不是 {{product}} 写的)",
|
|
431
435
|
"provider_replaced": "已替换原来的接入地址 {{url}},修改前的文件已备份",
|
|
432
436
|
"gateway_models": "/model 菜单新增 {{count}} 个其他模型({{vendors}})",
|
|
@@ -1245,6 +1249,10 @@
|
|
|
1245
1249
|
"reinstalled": "已重新安装 {{tool}} {{version}}",
|
|
1246
1250
|
"force_hint": "要重新安装就运行 {{command}} --force",
|
|
1247
1251
|
"blocked_remote_session": "这是远程(SSH)登录的会话,Windows 不允许在这里安装 {{tool}}:在这台电脑本机的终端里运行 {{command}}",
|
|
1248
|
-
"reason_remote_session": "远程(SSH)会话里不能安装 Windows 应用"
|
|
1252
|
+
"reason_remote_session": "远程(SSH)会话里不能安装 Windows 应用",
|
|
1253
|
+
"error_needs_admin": "Windows 要求用管理员权限安装(0x80073D28),先右键 PowerShell 选「以管理员身份运行」,在那个窗口里运行",
|
|
1254
|
+
"error_other_account": "授权时用的是另一个管理员账号,应用装给了那个账号:用当前账号授权(把当前账号设为管理员),或在那个账号下使用",
|
|
1255
|
+
"elevate_offer": "Windows 要求用管理员权限安装 {{tool}}。现在弹出授权窗口?",
|
|
1256
|
+
"elevating": "正在请求管理员权限:在弹出的 Windows 窗口里点「是」…"
|
|
1249
1257
|
}
|
|
1250
1258
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeapi/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.152",
|
|
4
4
|
"description": "CLI tool for managing AI coding assistants (Claude Code, Codex, OpenClaw, Hermes, AtomCode, Grok Build) with one unified config",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|