@marsapi/cli 0.0.148 → 0.0.153
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/client-config.snapshot.json +18 -18
- package/components.json +157 -0
- package/dist/client-config.snapshot.json +18 -18
- package/dist/commands/components.js +1 -0
- package/dist/commands/config.js +1 -1
- package/dist/commands/setup.js +1 -1
- package/dist/commands/upgrade.js +1 -1
- package/dist/components.json +157 -0
- package/dist/lib/app-update.js +1 -1
- package/dist/lib/brand.js +1 -1
- package/dist/lib/claude-code-manager.js +1 -1
- package/dist/lib/command.js +1 -1
- package/dist/lib/components.js +1 -0
- package/dist/lib/config.js +1 -1
- package/dist/lib/dry-run.js +1 -1
- package/dist/lib/env-cleanup.js +1 -1
- package/dist/lib/gateway-addresses.js +1 -1
- package/dist/lib/model-registry.js +1 -1
- package/dist/lib/post-apply.js +1 -1
- package/dist/lib/program.js +1 -1
- package/dist/lib/runtime-options.js +1 -1
- package/dist/lib/telemetry.js +1 -1
- package/dist/lib/tool-manager.js +1 -1
- package/dist/lib/tool-upgrade.js +1 -1
- package/dist/lib/tools/chatgpt-desktop.js +1 -1
- package/dist/lib/tools/claude-code.js +1 -1
- package/dist/lib/tools/claude-desktop.js +1 -1
- package/dist/lib/tools/codex.js +1 -1
- package/dist/lib/tools/desktop-app-installer.js +1 -1
- package/dist/lib/tools/desktop-process.js +1 -1
- package/dist/lib/tools/tool-installs.js +1 -1
- package/dist/lib/wizard.js +1 -1
- package/dist/lib/write-plan.js +1 -1
- package/dist/lib/written-values.js +1 -0
- package/dist/locales/en_US.json +149 -6
- package/dist/locales/zh_CN.json +149 -6
- package/package.json +2 -1
package/dist/lib/program.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Command as e,Option as o}from"commander";import{readFileSync as s}from"fs";import{join as t,dirname as n}from"path";import{fileURLToPath as a}from"url";import{i18n as i}from"./i18n.js";import{wizard as r}from"./wizard.js";import{SUPPORTED_TOOLS as c}from"./tool-manager.js";import{DEFAULT_BASE_URL as l}from"./config.js";import{attachCommandHelp as p,helpConfiguration as m}from"./cli-help.js";import{langCommand as u,authCommand as d,doctorCommand as f,configCommand as g,statusCommand as x,refreshCommand as h}from"../commands/index.js";import{logsCommand as y}from"../commands/logs.js";import{completionCommand as $}from"../commands/completion.js";import{benchCommand as b}from"../commands/bench.js";import{updateCommand as k}from"../commands/update.js";import{upgradeCommand as _}from"../commands/upgrade.js";import{codexSessionsCommand as w}from"../commands/codex-sessions.js";import{sessionsExportCommand as v,sessionsListCommand as j,sessionsResumeCommand as O,sessionsShowCommand as S}from"../commands/sessions.js";import{setupCommand as A,DEDICATED_KEYS as E}from"../commands/setup.js";import{baseCommand as G}from"../commands/base.js";import{usageError as z}from"./errors.js";import{requireTerminal as C}from"./confirm.js";import{brand as R,brandEnv as B,CLI_NAME as I}from"./brand.js";const L=(R().gatewayAddresses[1]??R().gatewayAddresses[0]).url,N=(R().gatewayAddresses[2]??R().gatewayAddresses[0]).url;function P(e,o){return i.t(`help.${e}`,o)}function T(e,o){return{command:e,note:P(o)}}function U(e){const o=P(e);return o===`help.${e}`?"":o}function H(e,o=[]){return{when:U(`${e}.when`),prerequisites:U(`${e}.needs`).split("\n").filter(Boolean),alternatives:o.map(([e,o])=>T(e,o))}}function K(e){return e.helpCommand("help [command]",P("help_command"))}export function buildProgram(){const R=new e;R.name(`${I}`).summary(P("root.summary")).description(P("root.description")).configureHelp(m()).allowExcessArguments(!0).optionsGroup(P("group.global_options")).helpOption("-h, --help",P("global.help")).version(function(){try{const e=n(a(import.meta.url));return JSON.parse(s(t(e,"../../package.json"),"utf-8")).version}catch{return"1.0.0"}}(),"-v, --version",P("global.version")).option("--base <url>",P("global.base")).option("--non-interactive",P("global.non_interactive")).option("--json",P("global.json")).option("-y, --yes",P("global.yes")).option("--dry-run",P("global.dry_run")).option("--no-color",P("global.no_color")),R.configureOutput({writeErr:()=>{},outputError:()=>{}}),R.showSuggestionAfterError(),R.exitOverride(e=>{throw e}),R.commandsGroup(P("group.configure"));const U=R.command("setup").summary(P("setup.summary")).description(P("setup.description")).option("--key <key>",P("setup.opt.key"));for(const e of E){const s=new o(`--${e.option} <key>`,P(`setup.opt.${e.option}`));e.hidden&&s.hideHelp(),U.addOption(s)}U.option("--1m",P("setup.opt.one_m")).option("--no-1m",P("setup.opt.no_one_m")).option("--claude-official <on|off>",P("setup.opt.claude_official")).option("--desktop-registry <on|off>",P("setup.opt.desktop_registry")).option("--force",P("setup.opt.force")).option("--install",P("setup.opt.install")).option("--no-install",P("setup.opt.no_install")).option("--all",P("setup.opt.all")).action(async e=>{e.key||E.some(o=>e[o.option])||(e.key=B("SETUP_KEY")?.trim()||void 0,e.fromInstaller=Boolean(e.key));const o=Boolean(e.key||E.some(o=>e[o.option])),s=void 0!==e["1m"]||void 0!==e.claudeOfficial||void 0!==e.desktopRegistry,t=i.t("errors.key_placeholder");if(!o&&!s)throw z(i.t("setup.usage"),`${I} setup --key ${t}`,"missing_key");if(void 0!==e.claudeOfficial&&!["on","off"].includes(String(e.claudeOfficial).toLowerCase()))throw z(i.t("setup.claude_official_invalid",{value:String(e.claudeOfficial)}),`${I} setup --claude-official on|off`,"invalid_value");if(void 0!==e.desktopRegistry&&!["on","off"].includes(String(e.desktopRegistry).toLowerCase()))throw z(i.t("setup.desktop_registry_invalid",{value:String(e.desktopRegistry)}),`${I} setup --desktop-registry on|off`,"invalid_value");await A({key:e.key,...Object.fromEntries(E.map(o=>[o.option,e[o.option]])),all:e.all,oneMillion:e["1m"],claudeOfficial:e.claudeOfficial,desktopRegistry:e.desktopRegistry,force:e.force,install:e.install,fromInstaller:e.fromInstaller})}),p(U,{...H("setup",[[`${I} init`,"setup.alt.init"],[`${I} config <tool>`,"setup.alt.config"],[`${I} auth <key>`,"setup.alt.auth"]]),sections:[{title:P("setup.autodetect_title"),rows:[["Claude",P("setup.autodetect.claude")],["GPT",P("setup.autodetect.gpt")],["Grok",P("setup.autodetect.grok")],["Gemini",P("setup.autodetect.gemini")]]}],examples:[T(`${I} setup --key sk-xxx`,"setup.ex.key"),T(`${I} setup --install --key sk-xxx`,"setup.ex.install"),T(`${I} setup --claudekey sk-a --codexkey sk-b --agykey sk-g`,"setup.ex.split"),T(`${I} setup --force --key sk-xxx`,"setup.ex.force"),T(`${I} setup --base ${L} --key sk-xxx`,"setup.ex.base")]});const M=R.command("init").summary(P("init.summary")).description(P("init.description")).action(async()=>{C(),await r.runFirstTimeSetup()});p(M,{...H("init",[[`${I} setup --key <key>`,"init.alt.setup"],[`${I}`,"init.alt.menu"]]),examples:[T(`${I} init`,"init.ex.run"),T(`${I} init --base ${L}`,"init.ex.base"),T(`${I}`,"init.ex.menu")]});const q=R.command("auth").summary(P("auth.summary")).description(P("auth.description")).argument("[token]",P("auth.arg.token")).action(async e=>{const o=[];e&&o.push(e),await d(o)});K(q);const D=q.command("revoke").description(P("auth.revoke")).action(async()=>{await d(["revoke"])});p(D,{examples:[T(`${I} auth revoke`,"auth.ex.revoke_ask"),T(`${I} auth revoke --yes`,"auth.ex.revoke")]});const F=q.command("reload <tool>").description(P("auth.reload")).action(async e=>{await d(["reload",e])});p(F,{examples:[T(`${I} auth reload claude-code`,"auth.ex.reload"),T(`${I} auth reload claude-code --json`,"auth.ex.reload_json")]}),p(q,{...H("auth",[[`${I} setup --key <key>`,"auth.alt.setup"]]),examples:[T(`${I} auth`,"auth.ex.prompt"),T(`${I} auth sk-xxx --non-interactive`,"auth.ex.save"),T(`${I} auth revoke --yes`,"auth.ex.revoke"),T(`${I} auth reload claude-code`,"auth.ex.reload")]});const J=R.command("config").summary(P("config.summary")).description(P("config.description")).argument("[args...]",P("config.arg.args")).option("-f, --force",P("config.opt.force")).allowUnknownOption(!0).action(async(e=[],o={})=>{await g(o.force?[...e,"--force"]:e)});p(J,{...H("config",[[`${I} setup --force --key <key>`,"config.alt.setup"],[`${I} status`,"config.alt.status"]]),sections:[{title:P("config.subcommands_title"),rows:[["<tool>",P("config.sub.tool")],["<tool> --force",P("config.sub.tool_force")],["<tool> --non-interactive",P("config.sub.tool_non_interactive")],["<tool> remove",P("config.sub.tool_remove")],["<tool> restore",P("config.sub.tool_restore")],["<tool> backups",P("config.sub.tool_backups")],["<tool> clear-model",P("config.sub.tool_clear_model")],["tool-model list",P("config.sub.tool_model_list")],["tool-model set <tool> [slot] <model>",P("config.sub.tool_model_set")],["tool-model clear <tool>",P("config.sub.tool_model_clear")],["profile list",P("config.sub.profile_list")],["profile create <name>",P("config.sub.profile_create")],["profile use <name>",P("config.sub.profile_use")],["profile delete <name>",P("config.sub.profile_delete")],["preset list",P("config.sub.preset_list")],["preset save <name>",P("config.sub.preset_save")],["preset use <name>",P("config.sub.preset_use")],["preset delete <name>",P("config.sub.preset_delete")],["backup list",P("config.sub.backup_list")],["backup create [label]",P("config.sub.backup_create")],["backup restore <name>",P("config.sub.backup_restore")]]},{title:P("config.tools_title"),rows:Object.values(c).filter(e=>!e.hidden).map(e=>[e.name,e.displayName])}],examples:[T(`${I} config codex`,"config.ex.menu"),T(`${I} config claude-code --force`,"config.ex.force"),T(`${I} config tool-model set codex gpt-6-astra`,"config.ex.tool_model"),T(`${I} config profile create work`,"config.ex.profile"),T(`${I} config codex remove`,"config.ex.remove")]});const Y=R.command("base").summary(P("base.summary")).description(P("base.description")).argument("[target]",P("base.arg.target")).action(async e=>{await G(e)});p(Y,{...H("base",[[`${I} doctor`,"base.alt.doctor"],[`${I} bench`,"base.alt.bench"]]),sections:[{title:P("base.targets_title"),rows:[[P("base.target.none_term"),P("base.target.none")],[P("base.target.index_term"),P("base.target.index")],[P("base.target.url_term"),P("base.target.url")],["auto",P("base.target.auto")],["default",P("base.target.default",{url:l})]]}],examples:[T(`${I} base`,"base.ex.list"),T(`${I} base auto`,"base.ex.auto"),T(`${I} base 2`,"base.ex.index"),T(`${I} base ${L}`,"base.ex.url"),T(`${I} base default`,"base.ex.default")]}),R.commandsGroup(P("group.diagnose"));const Q=R.command("status").summary(P("status.summary")).description(P("status.description")).action(async()=>{await x()});p(Q,{...H("status",[[`${I} doctor`,"status.alt.doctor"]]),examples:[T(`${I} status`,"status.ex.show"),T(`${I} status --json`,"status.ex.json")]});const V=R.command("doctor").summary(P("doctor.summary")).description(P("doctor.description")).option("--deep",P("doctor.opt.deep")).option("--report",P("doctor.opt.report")).action(async e=>{await f({deep:e.deep,report:e.report})});p(V,{...H("doctor",[[`${I} base auto`,"doctor.alt.base"],[`${I} logs tail`,"doctor.alt.logs"]]),examples:[T(`${I} doctor`,"doctor.ex.run"),T(`${I} doctor --deep`,"doctor.ex.deep"),T(`${I} doctor --report`,"doctor.ex.report")]});const W=R.command("bench").summary(P("bench.summary")).description(P("bench.description")).option("--samples <n>",P("bench.opt.samples"),"5").option("--stream",P("bench.opt.stream")).option("--model <model>",P("bench.opt.model")).action(async e=>{const o=[];e.samples&&o.push("--samples",e.samples),e.stream&&o.push("--stream"),e.model&&o.push("--model",e.model),await b(o)});p(W,{...H("bench",[[`${I} base`,"bench.alt.base"]]),examples:[T(`${I} bench`,"bench.ex.run"),T(`${I} bench --samples 3`,"bench.ex.samples"),T(`${I} bench --stream`,"bench.ex.stream"),T(`${I} bench --stream --model gpt-6-astra`,"bench.ex.stream_model"),T(`${I} bench --json`,"bench.ex.json")]});const X=R.command("logs").summary(P("logs.summary")).description(P("logs.description")).argument("[action]",P("logs.arg.action")).argument("[file]",P("logs.arg.file")).action(async(e,o)=>{const s=[];e&&s.push(e),o&&s.push(o),await y(s)});p(X,{...H("logs",[[`${I} doctor`,"logs.alt.doctor"]]),sections:[{title:P("logs.actions_title"),rows:[["list",P("logs.action.list")],["tail [file]",P("logs.action.tail")],["path",P("logs.action.path")]]}],examples:[T(`${I} logs`,"logs.ex.list"),T(`${I} logs tail`,"logs.ex.tail"),T(`${I} logs path`,"logs.ex.path")]}),R.commandsGroup(P("group.maintain"));const Z=R.command("upgrade").summary(P("upgrade.summary")).description(P("upgrade.description")).argument("[tools...]",P("upgrade.arg.tools")).option("--force",P("upgrade.opt.force")).action(async(e=[],o={})=>{await _(e,{force:o.force})});p(Z,{...H("upgrade",[[`${I} update`,"upgrade.alt.update"]]),examples:[T(`${I} upgrade`,"upgrade.ex.all"),T(`${I} upgrade claude-code`,"upgrade.ex.one"),T(`${I} upgrade codex agy`,"upgrade.ex.many"),T(`${I} upgrade claude-desktop`,"upgrade.ex.desktop"),T(`${I} upgrade chatgpt --force`,"upgrade.ex.force")]});const ee=R.command("refresh").summary(P("refresh.summary")).description(P("refresh.description")).action(async()=>{await h()});p(ee,{...H("refresh",[[`${I} setup --key ${i.t("errors.key_placeholder")}`,"refresh.alt.setup"]]),examples:[T(`${I} refresh`,"refresh.ex.run"),T(`${I} refresh --base ${N}`,"refresh.ex.base")]});const oe=R.command("update").summary(P("update.summary")).description(P("update.description")).action(async()=>{await k()});p(oe,{...H("update",[[`${I} upgrade`,"update.alt.upgrade"]]),examples:[T(`${I} update`,"update.ex.check"),T(`${I} update --json`,"update.ex.json")]});const se=R.command("codex").summary(P("codex.summary")).description(P("codex.description"));K(se);const te=se.command("sessions").summary(P("codex_sessions.summary")).description(P("codex_sessions.description")).option("--to <provider>",P("codex_sessions.opt.to")).option("--undo <dir>",P("codex_sessions.opt.undo")).action(async e=>{await w(e)});p(se,{...H("codex"),examples:[T(`${I} codex sessions`,"codex_sessions.ex.move"),T(`${I} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]}),p(te,{...H("codex_sessions",[[`${I} codex sessions --undo <dir>`,"codex_sessions.alt.undo"]]),examples:[T(`${I} codex sessions`,"codex_sessions.ex.move"),T(`${I} codex sessions --to custom`,"codex_sessions.ex.to"),T(`${I} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]});const ne=R.command("sessions").summary(P("sessions.summary")).description(P("sessions.description"));K(ne);const ae=ne.command("list",{isDefault:!0}).description(P("sessions.list")).option("--tool <tool>",P("sessions.opt.tool")).option("--dir <path>",P("sessions.opt.dir")).option("--here",P("sessions.opt.here")).option("-n, --limit <count>",P("sessions.opt.limit")).option("--all",P("sessions.opt.all")).action(async e=>{await j(e)}),ie=ne.command("show <id>").description(P("sessions.show")).option("-m, --messages <count>",P("sessions.opt.messages")).action(async(e,o)=>{await S(e,o)}),re=ne.command("resume <id>").description(P("sessions.resume")).option("--run",P("sessions.opt.run")).action(async(e,o)=>{await O(e,o)}),ce=ne.command("export <ids...>").description(P("sessions.export")).option("-o, --output <dir>",P("sessions.opt.output")).option("--tools",P("sessions.opt.tools")).action(async(e,o)=>{await v(e,o)});p(ae,{examples:[T(`${I} sessions list`,"sessions.ex.list"),T(`${I} sessions list --tool codex`,"sessions.ex.codex"),T(`${I} sessions list --here --all`,"sessions.ex.here"),T(`${I} sessions list --json`,"sessions.ex.json")]}),p(ie,{examples:[T(`${I} sessions show 01a0f5fe`,"sessions.ex.show"),T(`${I} sessions show 01a0f5fe -m 20`,"sessions.ex.show_more")]}),p(re,{examples:[T(`${I} sessions resume 01a0f5fe`,"sessions.ex.resume_print"),T(`${I} sessions resume 01a0f5fe --run`,"sessions.ex.resume")]}),p(ce,{examples:[T(`${I} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export"),T(`${I} sessions export 01a0f5fe -o ./sessions --tools`,"sessions.ex.export_tools")]}),p(ne,{...H("sessions",[[`${I} codex sessions`,"sessions.alt.codex_sessions"]]),examples:[T(`${I} sessions`,"sessions.ex.list"),T(`${I} sessions --tool codex --here`,"sessions.ex.here"),T(`${I} sessions show 01a0f5fe`,"sessions.ex.show"),T(`${I} sessions resume 01a0f5fe --run`,"sessions.ex.resume"),T(`${I} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export")]});const le=R.command("lang").summary(P("lang.summary")).description(P("lang.description"));K(le);const pe=le.command("show").description(P("lang.show")).action(async()=>{await u(["show"])}),me=le.command("set <locale>").description(P("lang.set")).action(async e=>{await u(["set",e])}),ue=[T(`${I} lang show`,"lang.ex.show"),T(`${I} lang set en_US`,"lang.ex.set_en"),T(`${I} lang set zh_CN`,"lang.ex.set_zh")];p(le,{...H("lang",[[`${I} enter lang`,"lang.alt.enter"]]),examples:ue}),p(pe,{examples:[ue[0],T(`${I} lang show --json`,"lang.ex.show_json")]}),p(me,{examples:ue.slice(1)});const de=R.command("completion").summary(P("completion.summary")).description(P("completion.description")).argument("<shell>",P("completion.arg.shell")).action(async e=>{await $([e])});p(de,{...H("completion"),examples:[T(`${I} completion bash > ~/.${I}-completion.bash`,"completion.ex.bash"),T(`${I} completion zsh > ~/.${I}-completion.zsh`,"completion.ex.zsh"),T(`${I} completion fish > ~/.config/fish/completions/${I}.fish`,"completion.ex.fish")]});const fe=R.command("enter").summary(P("enter.summary")).description(P("enter.description")).argument("[option]",P("enter.arg.option")).action(async e=>{if(e&&!["lang","language","apikey","api-key","models"].includes(e)||C(),e)switch(e){case"lang":case"language":await r.configLanguage();break;case"apikey":case"api-key":await r.configApiKey();break;case"models":await r.configModels();break;default:await g([e])}else await r.run()});p(fe,{...H("enter",[[`${I}`,"enter.alt.menu"],[`${I} config <tool>`,"enter.alt.config"]]),sections:[{title:P("enter.options_title"),rows:[[P("enter.option.none_term"),P("enter.option.none")],["lang",P("enter.option.lang")],["apikey",P("enter.option.apikey")],["models",P("enter.option.models")],["<tool>",P("enter.option.tool")]]}],examples:[T(`${I} enter`,"enter.ex.menu"),T(`${I} enter models`,"enter.ex.models"),T(`${I} enter codex`,"enter.ex.tool")]}),K(R),R.action(async()=>{C(),await r.run()}),p(R,{examples:[T(`${I}`,"root.ex.menu"),T(`${I} setup --key sk-xxx`,"root.ex.setup"),T(`${I} doctor`,"root.ex.doctor"),T(`${I} base auto`,"root.ex.base"),T(`${I} config codex`,"root.ex.config")]});const ge=e=>{for(const o of e.commands)o.helpOption("-h, --help",P("global.help")),ge(o)};return ge(R),R}
|
|
1
|
+
import{Command as e,Option as o}from"commander";import{readFileSync as s}from"fs";import{join as t,dirname as n}from"path";import{fileURLToPath as a}from"url";import{i18n as i}from"./i18n.js";import{wizard as r}from"./wizard.js";import{SUPPORTED_TOOLS as c}from"./tool-manager.js";import{DEFAULT_BASE_URL as l}from"./config.js";import{attachCommandHelp as p,helpConfiguration as m}from"./cli-help.js";import{langCommand as u,authCommand as d,doctorCommand as f,configCommand as g,statusCommand as x,refreshCommand as h}from"../commands/index.js";import{logsCommand as $}from"../commands/logs.js";import{completionCommand as y}from"../commands/completion.js";import{benchCommand as b}from"../commands/bench.js";import{updateCommand as k}from"../commands/update.js";import{upgradeCommand as _}from"../commands/upgrade.js";import{installCommand as w,listCommand as v}from"../commands/components.js";import{codexSessionsCommand as j}from"../commands/codex-sessions.js";import{sessionsExportCommand as O,sessionsListCommand as S,sessionsResumeCommand as A,sessionsShowCommand as E}from"../commands/sessions.js";import{setupCommand as G,DEDICATED_KEYS as z}from"../commands/setup.js";import{baseCommand as C}from"../commands/base.js";import{usageError as R}from"./errors.js";import{requireTerminal as B}from"./confirm.js";import{brand as I,brandEnv as L,CLI_NAME as N}from"./brand.js";const P=(I().gatewayAddresses[1]??I().gatewayAddresses[0]).url,T=(I().gatewayAddresses[2]??I().gatewayAddresses[0]).url;function U(e,o){return i.t(`help.${e}`,o)}function H(e,o){return{command:e,note:U(o)}}function K(e){const o=U(e);return o===`help.${e}`?"":o}function M(e,o=[]){return{when:K(`${e}.when`),prerequisites:K(`${e}.needs`).split("\n").filter(Boolean),alternatives:o.map(([e,o])=>H(e,o))}}function q(e){return e.helpCommand("help [command]",U("help_command"))}export function buildProgram(){const I=new e;I.name(`${N}`).summary(U("root.summary")).description(U("root.description")).configureHelp(m()).allowExcessArguments(!0).optionsGroup(U("group.global_options")).helpOption("-h, --help",U("global.help")).version(function(){try{const e=n(a(import.meta.url));return JSON.parse(s(t(e,"../../package.json"),"utf-8")).version}catch{return"1.0.0"}}(),"-v, --version",U("global.version")).option("--base <url>",U("global.base")).option("--non-interactive",U("global.non_interactive")).option("--json",U("global.json")).option("-y, --yes",U("global.yes")).option("--dry-run",U("global.dry_run")).option("--no-color",U("global.no_color")),I.configureOutput({writeErr:()=>{},outputError:()=>{}}),I.showSuggestionAfterError(),I.exitOverride(e=>{throw e}),I.commandsGroup(U("group.configure"));const K=I.command("setup").summary(U("setup.summary")).description(U("setup.description")).option("--key <key>",U("setup.opt.key"));for(const e of z){const s=new o(`--${e.option} <key>`,U(`setup.opt.${e.option}`));e.hidden&&s.hideHelp(),K.addOption(s)}K.option("--1m",U("setup.opt.one_m")).option("--no-1m",U("setup.opt.no_one_m")).option("--claude-official <on|off>",U("setup.opt.claude_official")).option("--desktop-registry <on|off>",U("setup.opt.desktop_registry")).option("--force",U("setup.opt.force")).option("--install",U("setup.opt.install")).option("--no-install",U("setup.opt.no_install")).option("--all",U("setup.opt.all")).action(async e=>{e.key||z.some(o=>e[o.option])||(e.key=L("SETUP_KEY")?.trim()||void 0,e.fromInstaller=Boolean(e.key));const o=Boolean(e.key||z.some(o=>e[o.option])),s=void 0!==e["1m"]||void 0!==e.claudeOfficial||void 0!==e.desktopRegistry,t=i.t("errors.key_placeholder");if(!o&&!s)throw R(i.t("setup.usage"),`${N} setup --key ${t}`,"missing_key");if(void 0!==e.claudeOfficial&&!["on","off"].includes(String(e.claudeOfficial).toLowerCase()))throw R(i.t("setup.claude_official_invalid",{value:String(e.claudeOfficial)}),`${N} setup --claude-official on|off`,"invalid_value");if(void 0!==e.desktopRegistry&&!["on","off"].includes(String(e.desktopRegistry).toLowerCase()))throw R(i.t("setup.desktop_registry_invalid",{value:String(e.desktopRegistry)}),`${N} setup --desktop-registry on|off`,"invalid_value");await G({key:e.key,...Object.fromEntries(z.map(o=>[o.option,e[o.option]])),all:e.all,oneMillion:e["1m"],claudeOfficial:e.claudeOfficial,desktopRegistry:e.desktopRegistry,force:e.force,install:e.install,fromInstaller:e.fromInstaller})}),p(K,{...M("setup",[[`${N} init`,"setup.alt.init"],[`${N} config <tool>`,"setup.alt.config"],[`${N} auth <key>`,"setup.alt.auth"]]),sections:[{title:U("setup.autodetect_title"),rows:[["Claude",U("setup.autodetect.claude")],["GPT",U("setup.autodetect.gpt")],["Grok",U("setup.autodetect.grok")],["Gemini",U("setup.autodetect.gemini")]]}],examples:[H(`${N} setup --key sk-xxx`,"setup.ex.key"),H(`${N} setup --install --key sk-xxx`,"setup.ex.install"),H(`${N} setup --claudekey sk-a --codexkey sk-b --agykey sk-g`,"setup.ex.split"),H(`${N} setup --force --key sk-xxx`,"setup.ex.force"),H(`${N} setup --base ${P} --key sk-xxx`,"setup.ex.base")]});const D=I.command("init").summary(U("init.summary")).description(U("init.description")).action(async()=>{B(),await r.runFirstTimeSetup()});p(D,{...M("init",[[`${N} setup --key <key>`,"init.alt.setup"],[`${N}`,"init.alt.menu"]]),examples:[H(`${N} init`,"init.ex.run"),H(`${N} init --base ${P}`,"init.ex.base"),H(`${N}`,"init.ex.menu")]});const F=I.command("auth").summary(U("auth.summary")).description(U("auth.description")).argument("[token]",U("auth.arg.token")).action(async e=>{const o=[];e&&o.push(e),await d(o)});q(F);const J=F.command("revoke").description(U("auth.revoke")).action(async()=>{await d(["revoke"])});p(J,{examples:[H(`${N} auth revoke`,"auth.ex.revoke_ask"),H(`${N} auth revoke --yes`,"auth.ex.revoke")]});const Y=F.command("reload <tool>").description(U("auth.reload")).action(async e=>{await d(["reload",e])});p(Y,{examples:[H(`${N} auth reload claude-code`,"auth.ex.reload"),H(`${N} auth reload claude-code --json`,"auth.ex.reload_json")]}),p(F,{...M("auth",[[`${N} setup --key <key>`,"auth.alt.setup"]]),examples:[H(`${N} auth`,"auth.ex.prompt"),H(`${N} auth sk-xxx --non-interactive`,"auth.ex.save"),H(`${N} auth revoke --yes`,"auth.ex.revoke"),H(`${N} auth reload claude-code`,"auth.ex.reload")]});const Q=I.command("config").summary(U("config.summary")).description(U("config.description")).argument("[args...]",U("config.arg.args")).option("-f, --force",U("config.opt.force")).allowUnknownOption(!0).action(async(e=[],o={})=>{await g(o.force?[...e,"--force"]:e)});p(Q,{...M("config",[[`${N} setup --force --key <key>`,"config.alt.setup"],[`${N} status`,"config.alt.status"]]),sections:[{title:U("config.subcommands_title"),rows:[["<tool>",U("config.sub.tool")],["<tool> --force",U("config.sub.tool_force")],["<tool> --non-interactive",U("config.sub.tool_non_interactive")],["<tool> remove",U("config.sub.tool_remove")],["<tool> restore",U("config.sub.tool_restore")],["<tool> backups",U("config.sub.tool_backups")],["<tool> clear-model",U("config.sub.tool_clear_model")],["tool-model list",U("config.sub.tool_model_list")],["tool-model set <tool> [slot] <model>",U("config.sub.tool_model_set")],["tool-model clear <tool>",U("config.sub.tool_model_clear")],["profile list",U("config.sub.profile_list")],["profile create <name>",U("config.sub.profile_create")],["profile use <name>",U("config.sub.profile_use")],["profile delete <name>",U("config.sub.profile_delete")],["preset list",U("config.sub.preset_list")],["preset save <name>",U("config.sub.preset_save")],["preset use <name>",U("config.sub.preset_use")],["preset delete <name>",U("config.sub.preset_delete")],["backup list",U("config.sub.backup_list")],["backup create [label]",U("config.sub.backup_create")],["backup restore <name>",U("config.sub.backup_restore")]]},{title:U("config.tools_title"),rows:Object.values(c).filter(e=>!e.hidden).map(e=>[e.name,e.displayName])}],examples:[H(`${N} config codex`,"config.ex.menu"),H(`${N} config claude-code --force`,"config.ex.force"),H(`${N} config tool-model set codex gpt-6-astra`,"config.ex.tool_model"),H(`${N} config profile create work`,"config.ex.profile"),H(`${N} config codex remove`,"config.ex.remove")]});const V=I.command("base").summary(U("base.summary")).description(U("base.description")).argument("[target]",U("base.arg.target")).action(async e=>{await C(e)});p(V,{...M("base",[[`${N} doctor`,"base.alt.doctor"],[`${N} bench`,"base.alt.bench"]]),sections:[{title:U("base.targets_title"),rows:[[U("base.target.none_term"),U("base.target.none")],[U("base.target.index_term"),U("base.target.index")],[U("base.target.url_term"),U("base.target.url")],["auto",U("base.target.auto")],["default",U("base.target.default",{url:l})]]}],examples:[H(`${N} base`,"base.ex.list"),H(`${N} base auto`,"base.ex.auto"),H(`${N} base 2`,"base.ex.index"),H(`${N} base ${P}`,"base.ex.url"),H(`${N} base default`,"base.ex.default")]}),I.commandsGroup(U("group.diagnose"));const W=I.command("status").summary(U("status.summary")).description(U("status.description")).action(async()=>{await x()});p(W,{...M("status",[[`${N} doctor`,"status.alt.doctor"]]),examples:[H(`${N} status`,"status.ex.show"),H(`${N} status --json`,"status.ex.json")]});const X=I.command("doctor").summary(U("doctor.summary")).description(U("doctor.description")).option("--deep",U("doctor.opt.deep")).option("--report",U("doctor.opt.report")).action(async e=>{await f({deep:e.deep,report:e.report})});p(X,{...M("doctor",[[`${N} base auto`,"doctor.alt.base"],[`${N} logs tail`,"doctor.alt.logs"]]),examples:[H(`${N} doctor`,"doctor.ex.run"),H(`${N} doctor --deep`,"doctor.ex.deep"),H(`${N} doctor --report`,"doctor.ex.report")]});const Z=I.command("bench").summary(U("bench.summary")).description(U("bench.description")).option("--samples <n>",U("bench.opt.samples"),"5").option("--stream",U("bench.opt.stream")).option("--model <model>",U("bench.opt.model")).action(async e=>{const o=[];e.samples&&o.push("--samples",e.samples),e.stream&&o.push("--stream"),e.model&&o.push("--model",e.model),await b(o)});p(Z,{...M("bench",[[`${N} base`,"bench.alt.base"]]),examples:[H(`${N} bench`,"bench.ex.run"),H(`${N} bench --samples 3`,"bench.ex.samples"),H(`${N} bench --stream`,"bench.ex.stream"),H(`${N} bench --stream --model gpt-6-astra`,"bench.ex.stream_model"),H(`${N} bench --json`,"bench.ex.json")]});const ee=I.command("logs").summary(U("logs.summary")).description(U("logs.description")).argument("[action]",U("logs.arg.action")).argument("[file]",U("logs.arg.file")).action(async(e,o)=>{const s=[];e&&s.push(e),o&&s.push(o),await $(s)});p(ee,{...M("logs",[[`${N} doctor`,"logs.alt.doctor"]]),sections:[{title:U("logs.actions_title"),rows:[["list",U("logs.action.list")],["tail [file]",U("logs.action.tail")],["path",U("logs.action.path")]]}],examples:[H(`${N} logs`,"logs.ex.list"),H(`${N} logs tail`,"logs.ex.tail"),H(`${N} logs path`,"logs.ex.path")]}),I.commandsGroup(U("group.maintain"));const oe=I.command("list").summary(U("list.summary")).description(U("list.description")).option("--refresh",U("list.opt.refresh")).action(async(e={})=>{await v({refresh:e.refresh})});p(oe,{...M("list",[[`${N} doctor`,"list.alt.doctor"]]),examples:[H(`${N} list`,"list.ex.all"),H(`${N} list --refresh`,"list.ex.refresh"),H(`${N} list --json`,"list.ex.json")]});const se=I.command("install").summary(U("install.summary")).description(U("install.description")).argument("<components...>",U("install.arg.components")).option("--force",U("install.opt.force")).action(async(e,o={})=>{await w(e,{force:o.force})});p(se,{...M("install",[[`${N} upgrade`,"install.alt.upgrade"],[`${N} setup --key ${i.t("errors.key_placeholder")}`,"install.alt.setup"]]),examples:[H(`${N} install node uv`,"install.ex.runtimes"),H(`${N} install claude-code codex`,"install.ex.clis"),H(`${N} install chatgpt`,"install.ex.app"),H(`${N} install uv --force`,"install.ex.force"),H(`${N} install node uv --yes --json`,"install.ex.json")]});const te=I.command("upgrade").summary(U("upgrade.summary")).description(U("upgrade.description")).argument("[tools...]",U("upgrade.arg.tools")).option("--force",U("upgrade.opt.force")).action(async(e=[],o={})=>{await _(e,{force:o.force})});p(te,{...M("upgrade",[[`${N} update`,"upgrade.alt.update"]]),examples:[H(`${N} upgrade`,"upgrade.ex.all"),H(`${N} upgrade codex agy`,"upgrade.ex.many"),H(`${N} upgrade claude-desktop`,"upgrade.ex.desktop"),H(`${N} upgrade chatgpt --force`,"upgrade.ex.force"),H(`${N} upgrade node`,"upgrade.ex.runtime")]});const ne=I.command("refresh").summary(U("refresh.summary")).description(U("refresh.description")).action(async()=>{await h()});p(ne,{...M("refresh",[[`${N} setup --key ${i.t("errors.key_placeholder")}`,"refresh.alt.setup"]]),examples:[H(`${N} refresh`,"refresh.ex.run"),H(`${N} refresh --base ${T}`,"refresh.ex.base")]});const ae=I.command("update").summary(U("update.summary")).description(U("update.description")).action(async()=>{await k()});p(ae,{...M("update",[[`${N} upgrade`,"update.alt.upgrade"]]),examples:[H(`${N} update`,"update.ex.check"),H(`${N} update --json`,"update.ex.json")]});const ie=I.command("codex").summary(U("codex.summary")).description(U("codex.description"));q(ie);const re=ie.command("sessions").summary(U("codex_sessions.summary")).description(U("codex_sessions.description")).option("--to <provider>",U("codex_sessions.opt.to")).option("--undo <dir>",U("codex_sessions.opt.undo")).action(async e=>{await j(e)});p(ie,{...M("codex"),examples:[H(`${N} codex sessions`,"codex_sessions.ex.move"),H(`${N} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]}),p(re,{...M("codex_sessions",[[`${N} codex sessions --undo <dir>`,"codex_sessions.alt.undo"]]),examples:[H(`${N} codex sessions`,"codex_sessions.ex.move"),H(`${N} codex sessions --to custom`,"codex_sessions.ex.to"),H(`${N} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]});const ce=I.command("sessions").summary(U("sessions.summary")).description(U("sessions.description"));q(ce);const le=ce.command("list",{isDefault:!0}).description(U("sessions.list")).option("--tool <tool>",U("sessions.opt.tool")).option("--dir <path>",U("sessions.opt.dir")).option("--here",U("sessions.opt.here")).option("-n, --limit <count>",U("sessions.opt.limit")).option("--all",U("sessions.opt.all")).action(async e=>{await S(e)}),pe=ce.command("show <id>").description(U("sessions.show")).option("-m, --messages <count>",U("sessions.opt.messages")).action(async(e,o)=>{await E(e,o)}),me=ce.command("resume <id>").description(U("sessions.resume")).option("--run",U("sessions.opt.run")).action(async(e,o)=>{await A(e,o)}),ue=ce.command("export <ids...>").description(U("sessions.export")).option("-o, --output <dir>",U("sessions.opt.output")).option("--tools",U("sessions.opt.tools")).action(async(e,o)=>{await O(e,o)});p(le,{examples:[H(`${N} sessions list`,"sessions.ex.list"),H(`${N} sessions list --tool codex`,"sessions.ex.codex"),H(`${N} sessions list --here --all`,"sessions.ex.here"),H(`${N} sessions list --json`,"sessions.ex.json")]}),p(pe,{examples:[H(`${N} sessions show 01a0f5fe`,"sessions.ex.show"),H(`${N} sessions show 01a0f5fe -m 20`,"sessions.ex.show_more")]}),p(me,{examples:[H(`${N} sessions resume 01a0f5fe`,"sessions.ex.resume_print"),H(`${N} sessions resume 01a0f5fe --run`,"sessions.ex.resume")]}),p(ue,{examples:[H(`${N} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export"),H(`${N} sessions export 01a0f5fe -o ./sessions --tools`,"sessions.ex.export_tools")]}),p(ce,{...M("sessions",[[`${N} codex sessions`,"sessions.alt.codex_sessions"]]),examples:[H(`${N} sessions`,"sessions.ex.list"),H(`${N} sessions --tool codex --here`,"sessions.ex.here"),H(`${N} sessions show 01a0f5fe`,"sessions.ex.show"),H(`${N} sessions resume 01a0f5fe --run`,"sessions.ex.resume"),H(`${N} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export")]});const de=I.command("lang").summary(U("lang.summary")).description(U("lang.description"));q(de);const fe=de.command("show").description(U("lang.show")).action(async()=>{await u(["show"])}),ge=de.command("set <locale>").description(U("lang.set")).action(async e=>{await u(["set",e])}),xe=[H(`${N} lang show`,"lang.ex.show"),H(`${N} lang set en_US`,"lang.ex.set_en"),H(`${N} lang set zh_CN`,"lang.ex.set_zh")];p(de,{...M("lang",[[`${N} enter lang`,"lang.alt.enter"]]),examples:xe}),p(fe,{examples:[xe[0],H(`${N} lang show --json`,"lang.ex.show_json")]}),p(ge,{examples:xe.slice(1)});const he=I.command("completion").summary(U("completion.summary")).description(U("completion.description")).argument("<shell>",U("completion.arg.shell")).action(async e=>{await y([e])});p(he,{...M("completion"),examples:[H(`${N} completion bash > ~/.${N}-completion.bash`,"completion.ex.bash"),H(`${N} completion zsh > ~/.${N}-completion.zsh`,"completion.ex.zsh"),H(`${N} completion fish > ~/.config/fish/completions/${N}.fish`,"completion.ex.fish")]});const $e=I.command("enter").summary(U("enter.summary")).description(U("enter.description")).argument("[option]",U("enter.arg.option")).action(async e=>{if(e&&!["lang","language","apikey","api-key","models"].includes(e)||B(),e)switch(e){case"lang":case"language":await r.configLanguage();break;case"apikey":case"api-key":await r.configApiKey();break;case"models":await r.configModels();break;default:await g([e])}else await r.run()});p($e,{...M("enter",[[`${N}`,"enter.alt.menu"],[`${N} config <tool>`,"enter.alt.config"]]),sections:[{title:U("enter.options_title"),rows:[[U("enter.option.none_term"),U("enter.option.none")],["lang",U("enter.option.lang")],["apikey",U("enter.option.apikey")],["models",U("enter.option.models")],["<tool>",U("enter.option.tool")]]}],examples:[H(`${N} enter`,"enter.ex.menu"),H(`${N} enter models`,"enter.ex.models"),H(`${N} enter codex`,"enter.ex.tool")]}),q(I),I.action(async()=>{B(),await r.run()}),p(I,{examples:[H(`${N}`,"root.ex.menu"),H(`${N} setup --key sk-xxx`,"root.ex.setup"),H(`${N} doctor`,"root.ex.doctor"),H(`${N} base auto`,"root.ex.base"),H(`${N} config codex`,"root.ex.config")]});const ye=e=>{for(const o of e.commands)o.helpOption("-h, --help",U("global.help")),ye(o)};return ye(I),I}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const n={nonInteractive:!1,json:!1,yes:!1,dryRun:!1,color:!0};let
|
|
1
|
+
const n={nonInteractive:!1,json:!1,yes:!1,dryRun:!1,color:!0};let o={...n};export function setRuntimeOptions(n){o={...o,...n}}export function getRuntimeOptions(){return{...o}}export function isJsonMode(){return o.json}export function isNonInteractive(){return o.nonInteractive||o.json}export function isDryRun(){return o.dryRun}export function shouldAutoConfirm(){return o.yes||o.nonInteractive||o.json}export function canPrompt(){return!isNonInteractive()&&Boolean(process.stdin.isTTY)}export function hasExplicitYes(){return o.yes}export function isColorEnabled(){return o.color}export function resetRuntimeOptions(){o={...n}}export function detectColorPreferenceFromEnv(n=process.env){return(!n.NO_COLOR||"0"===n.NO_COLOR)&&"0"!==n.FORCE_COLOR&&"false"!==n.FORCE_COLOR}export function emitJson(n,o=n=>process.stdout.write(n+"\n")){o(JSON.stringify(n,null,2))}export async function progressToStderr(n){if(!isJsonMode())return n();const o=console.log;console.log=(...n)=>console.error(...n);try{return await n()}finally{console.log=o}}
|
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
|
|
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 p}from"./gateway-protocol.js";const d=e();let f="wizard",m=[];const g=new Set;let h=null,y=S;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??S,w=null!==e,m=[]}export function clientHeaders(){const e=`${a}/${i()} (${process.platform} ${o()}; ${t()}) node/${process.versions.node}`;return telemetryEnabled()?{"User-Agent":e,[p]: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…").replace(/(\b[a-z][a-z0-9+.-]*:\/\/)[^\s/@:]+(?::[^\s/@]*)?@/gi,"$1…@").replace(/\b((?:api[_-]?key|token|password|passwd|secret|auth)\s*[=:]\s*)("?)[^\s"&;,]{6,}\2/gi,"$1$2…$2")}export function setTelemetryCommand(e){f=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);m.push({ts:Date.now(),session:d,command:f,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?b():h||(h=setTimeout(b,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 b(){if(h&&(clearTimeout(h),h=null),0===m.length)return;const e=m.splice(0,50),t=y("/api/platform/vibecode/telemetry",{...T(),events:e},3e3).then(()=>{},()=>{}).finally(()=>g.delete(t));g.add(t),m.length>0&&b()}export async function flushTelemetry(e=1500){b(),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 S(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)}
|
package/dist/lib/tool-manager.js
CHANGED
|
@@ -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{canPrompt as i,shouldAutoConfirm as l}from"./runtime-options.js";import{logger as
|
|
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{canPrompt as i,shouldAutoConfirm as l}from"./runtime-options.js";import{logger as a}from"../utils/logger.js";import{configManager as s,savedApiKeys as c}from"./config.js";import{getAdapter as d,listAdapters as p,TOOL_ADAPTERS as u}from"./tools/registry.js";import{backupBeforeWrite as m,listBackups as f,restoreBackup as g}from"./tools/backup.js";import{existsSync as h,rmSync as w}from"fs";import{dirname as y,join as P}from"path";import{toolHome as v}from"./tools/types.js";import{stringWidth as $}from"../utils/string-width.js";import{resolveModelCatalog as T}from"./model-catalog.js";import{compareVersions as k,getToolMinVersion as C}from"./model-registry.js";import{findInstalls as E,forgetInstalls as O,installLabel as _,mirrorInstallCommand as S,npmMirrorInstallCommand as N,npmMirrorVersion as j}from"./tools/tool-installs.js";import{mirrorInstall as M}from"./tool-upgrade.js";import{upgradeApp as U}from"./app-update.js";import{CLI_NAME as b}from"./brand.js";import{track as x,trackStep as I}from"./telemetry.js";import{addUserPathDir as R,broadcastEnvChange as F}from"./windows-env.js";export{k as compareVersions};function L(o){const t=u[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}:{}}}export const SUPPORTED_TOOLS=Object.fromEntries(Object.keys(u).map(o=>[o,L(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=d(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=d(o),n=t?.installSpec?.native?.binDir;if(!t||!n)return null;const e="win32"===process.platform?`${t.command}.exe`:t.command,r=P(v(),...n,e);return h(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=y(t);try{if(!R(n))return null}catch(t){return a.logError(`ensureNativeOnPath: ${o}`,t),null}return F(),process.env.Path=`${process.env.Path??""};${n}`,n}async installTool(o){return I(`install:${o}`,()=>this.installToolNow(o))}async installToolNow(t){const a=SUPPORTED_TOOLS[t];if(!a)throw new Error(`Unknown tool: ${t}`);const s=d(t)?.appInstaller;if(s&&!s.blocker()){const o=await U(t,{install:!0});if("failed"===o.result||"unavailable"===o.result)throw new Error(`Failed to install ${a.displayName}`);return}const c=d(t)?.installSpec;if(c&&(c.mirrorScript||c.npmPackage)){const o=S(c);if(await M(c)&&(O(),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:a.displayName,command:o}))),c.mirrorScript&&c.npmPackage&&console.log(r.yellow(" ! "+n.t("install.manual_npm",{command:N(c,await j(c))}))),new Error(`Failed to install ${a.displayName}`)}const p=a.installCommand;console.log(r.gray("$ ")+r.white(p));try{return o(p,{stdio:"inherit"}),O(),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&&!p.startsWith("npm "))throw new Error(`Failed to install ${a.displayName}: ${o}`);console.log(r.yellow(" ! "+("win32"===process.platform?n.t("install.permission_windows",{command:p}):n.t("install.permission_unix",{command:p}))))}const{action:u}=!i()||l()?{action:"continue"}: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"===u)throw new Error(n.t("install.user_cancelled"));if(O(),!this.isToolInstalled(t))throw console.log(r.red("× "+n.t("install.still_not_installed",{tool:a.displayName}))),new Error(`${a.displayName} is not installed`);console.log(r.green("√ "+n.t("install.verified_success",{tool:a.displayName})))}getToolConfig(o){const t=d(o);if(!t)throw new Error(`Unknown tool: ${o}`);try{return t.getConfig()}catch(t){return a.warn(`Failed to read config for ${o}:`,t),a.logError(`ToolManager.getToolConfig(${o})`,t),null}}updateToolConfig(o,t){const n=d(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=d(o);if(!t)throw new Error(`Unknown tool: ${o}`);const n=t.forceResetPaths?t.forceResetPaths():this.backupPathsFor(t),e=[];for(const o of n)h(o)&&(m(o),w(o,{force:!0}),e.push(o));return e}loadPrivateConfig(o,t,n,e,r={}){const i=d(o);if(!i)throw new Error(`Unknown tool: ${o}`);r.force&&this.forceResetConfig(o),i.loadPrivateConfig({apiKey:t,baseUrl:s.getBaseUrl(),models:n,settings:s.getToolSettings(o),...e?{catalog:e}:{},...r.takeOver?{takeOver:!0}:{}})}async applyPrivateConfig(o,t,n,e={}){const r=this.installedVersion(o);return I(`apply:${o}`,()=>this.applyPrivateConfigNow(o,t,n,e),{...r?{tool_version:r}:{},...e.force?{force:!0}:{}})}async applyPrivateConfigNow(o,t,n,e){const r=d(o);if(!r)throw new Error(`Unknown tool: ${o}`);const i=r.wantsModelCatalog?await T(t):null,{force:l,takeOver:a}=e;l||a?this.loadPrivateConfig(o,t,n,i??void 0,{force:l,takeOver:a}):i?this.loadPrivateConfig(o,t,n,i):this.loadPrivateConfig(o,t,n)}applyNotes(o){const t=d(o);if(!t)return[];const e=[];try{t.applyNotes&&e.push(...t.applyNotes())}catch(t){a.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?`${b} upgrade ${o}`:t.upgradeCommand||t.installCommand})});for(const o of t.upgradeHints?.(r.min)??[])e.push({kind:"action",text:o})}const i=t.installSpec?E(t.installSpec):[];return i.length>1&&e.push({kind:"action",text:n.t("upgrade.duplicates_note",{count:String(i.length),active:_(i[0]),others:i.slice(1).map(_).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))a.record(`${n}: ${o.text}`);const i=e.filter(o=>"summary"===o.kind).map(o=>o.text).join(";"),l=" ".repeat(Math.max(1,t-$(n)));console.log(r.green("√ "+n)+(i?l+i:""));for(const o of e.filter(o=>"action"===o.kind))console.log(r.yellow(" ! "+o.text))}installedVersion(o){const n=d(o);if(!n)return null;if(n.installSpec)return E(n.installSpec)[0]?.version??null;if(n.installedVersion)try{return n.installedVersion()}catch(t){return a.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=C(o);if(!t)return null;const n=this.installedVersion(o);return n&&k(n,t)<0?{current:n,min:t}:null}unloadPrivateConfig(o){const t=d(o);if(!t)throw new Error(`Unknown tool: ${o}`);try{t.unloadPrivateConfig({savedKeys:c()}),x(`remove:${o}`,"ok")}catch(t){throw x(`remove:${o}`,"fail",{error:t}),t}let e=[];try{e=t.unloadNotes?.()??[]}catch(t){a.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=d(o);if(!t)throw new Error(`Unknown tool: ${o}`);if(s.setToolModel(o,null),!t.clearPinnedModels)return[];const n=s.getApiKeyForTool(o),e=t.wantsModelCatalog&&n?await T(n):null;return t.clearPinnedModels(e??void 0)}supportsClearPinnedModels(o){return Boolean(d(o)?.clearPinnedModels)}holdsOurConfig(o){const t=d(o);if(!t)return!1;const n=c();return t.holdsOurConfig?t.holdsOurConfig(n):Boolean(t.detectCurrentConfig().apiKey)}detectCurrentConfig(o){const t=d(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=d(o);if(!t)throw new Error(`Unknown tool: ${o}`);return this.backupPathsFor(t).map(o=>({file:o,backups:f(o)}))}restorePrivateConfig(o){const t=d(o);if(!t)throw new Error(`Unknown tool: ${o}`);return this.backupPathsFor(t).map(o=>({file:o,result:g(o)}))}getInstalledTools(){return Object.keys(SUPPORTED_TOOLS).filter(o=>this.isToolInstalled(o))}getSupportedTools(){return p().filter(o=>!o.hidden).map(o=>L(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();
|
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 u,
|
|
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{spawnSync as t}from"child_process";import{logger as n}from"../../utils/logger.js";import{brand as e}from"../brand.js";import{powerShellEnv as
|
|
1
|
+
import{spawnSync as t}from"child_process";import{logger as n}from"../../utils/logger.js";import{brand as e}from"../brand.js";import{powerShellEnv as r}from"../powershell-env.js";import{existsSync as i}from"fs";import{join as o}from"path";import{appPlatform as s,createDesktopAppInstaller as a,isArm64Machine as p,macAppVersion as l,macBundleId as c}from"./desktop-app-installer.js";import{toolHome as u}from"./types.js";export const OPENAI_TEAM_ID="2DC432GLL2";const d="com.openai.codex";export const CHATGPT_PACKAGE_FAMILY="OpenAI.Codex_2p2nqsd0c76g0";const g=a({id:"chatgpt-desktop",mirror:()=>e().installMirror?.chatgptDesktop,asset:(t,n)=>"darwin"===t?n?"ChatGPT-mac-arm64.dmg":null:"win32"===t?n?"ChatGPT-win-arm64.msix":"ChatGPT-win-x64.msix":null,versionFile:(t,n)=>"win32"===t?`version-win-${n?"arm64":"x64"}.txt`:"version.txt",macApp:{source:"ChatGPT.app",installedNames:["ChatGPT.app","Codex.app"],bundleId:d,teamId:"2DC432GLL2"},windows:{signer:new RegExp("^CN=50BDFD77-8903-4850-9FFE-6E8522F64D5B$"),packageFilter:`$_.PackageFamilyName -eq '${CHATGPT_PACKAGE_FAMILY}'`},extraBlocker:t=>"darwin"===t&&!g.installedMacApp()&&["/Applications",o(u(),"Applications")].some(t=>{const n=o(t,"ChatGPT.app");return i(o(n,"Contents","Info.plist"))&&c(n)!==d})?"other_app":null});export const chatgptInstaller=g;let h=(e,i,o=3e4)=>{const s=t(e,i,{encoding:"utf-8",timeout:o,windowsHide:!0,stdio:["ignore","pipe","pipe"],env:r()});return s.error&&n.logError(`chatgpt-desktop: ${e}`,s.error),{status:s.status,stdout:`${s.stdout??""}`,stderr:`${s.stderr??""}`}};export function setChatgptProcessRunnerForTests(t){h=t}function m(t,n){return h("powershell.exe",["-NoProfile","-NonInteractive","-Command",t],n)}const f=t=>t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),C="Get-Process -ErrorAction SilentlyContinue | Where-Object { $_.Path -like '*\\WindowsApps\\OpenAI.Codex_*\\app\\ChatGPT.exe' }";function w(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}export function isChatgptRunning(){if("darwin"===s()){const t=g.installedMacApp();return Boolean(t)&&0===h("pgrep",["-f",`^${f(t)}/Contents/MacOS/`]).status}return"win32"===s()&&Number(m(`@(${C}).Count`).stdout.trim())>0}let A=!1;export function chatgptQuitRefused(){return A}export function quitChatgpt(){if(A=!1,"darwin"===s()){const t=g.installedMacApp();if(macQuitRefused(h("osascript",["-e",`tell application id "${d}" to quit`]))&&(A=isChatgptRunning(),A))return!1;for(let t=0;t<30&&isChatgptRunning();t++)w(500);t&&isChatgptRunning()&&h("pkill",["-f",`^${f(t)}/Contents/MacOS/`]),w(1e3)}else{if("win32"!==s())return!1;m([`$p = @(${C})`,"$p | ForEach-Object { [void]$_.CloseMainWindow() }","Start-Sleep -Seconds 3",`@(${C}) | Stop-Process -Force -ErrorAction SilentlyContinue`,"Start-Sleep -Seconds 1"].join("\n"),6e4)}return!isChatgptRunning()}export function launchChatgpt(){if("darwin"===s()){const t=g.installedMacApp();if(!t)return!1;h("open",[t])}else{if("win32"!==s())return!1;m(`Start-Process 'shell:AppsFolder\\${CHATGPT_PACKAGE_FAMILY}!App'`,6e4)}for(let t=0;t<20;t++){if(isChatgptRunning())return!0;w(500)}return!1}export function macQuitRefused(t){return null===t.status||/\(-128\)|-1712/.test(t.stderr??"")}export const chatgptDesktopApp={name:"chatgpt",displayName:"ChatGPT",installedVersion:function(){if("darwin"===s()){const t=g.installedMacApp();return t?l(t):null}return"win32"===s()?g.windowsPackageVersion():null},runningApp:{isRunning:isChatgptRunning,quit:quitChatgpt,quitRefused:chatgptQuitRefused,launch:launchChatgpt},appInstaller:{vendor:"OpenAI",sizeMb:()=>"darwin"===s()?800:p()?1050:1e3,downloadPage:"https://chatgpt.com/download",blocker:g.blocker,latestVersion:()=>g.latestVersion(),installedPath:()=>"darwin"===s()?g.installedMacApp():"win32"!==s()?null:g.windowsPackageVersion()?"MSIX":null,install:t=>g.install(t)}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{join as e}from"path";import{applyGatewayModels as t,claudeCodeManager as o}from"../claude-code-manager.js";import{backupBeforeWrite 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]};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{chmodSync as e,existsSync as t,mkdirSync as o,readdirSync as n,readFileSync as r,rmSync as s}from"fs";import{dirname as i}from"path";import{join as l}from"path";import{randomUUID as a}from"crypto";import{execFileSync as c}from"child_process";import{userInfo as d}from"os";import p from"chalk";import{logger as u}from"../../utils/logger.js";import{track as f}from"../telemetry.js";import{ensureDesktopCli as m,installedDesktopAsarPath as g}from"./claude-desktop-cli.js";import{i18n as y}from"../i18n.js";import{BRAND_NAME as h,brand as k,brandEnv as _,CLI_NAME as b}from"../brand.js";import{backupBeforeWrite as D,atomicWriteFile as w}from"./backup.js";import{toolHome as A}from"./types.js";import{canRestartDesktop as C,isDesktopRunning as E,launchDesktop as v,quitDesktop as M,restartDesktop as O,WINDOWS_PACKAGE_FAMILIES as S}from"./desktop-process.js";import{desktopInstallBlocker as x,fetchLatestDesktopVersion as P,installedMacApp as j,installLatestDesktop as I}from"./claude-desktop-app.js";import{setUserRegistryElevated as L}from"./elevated-reg.js";import{UserActionNeeded as T}from"./types.js";import{baseModelId as $,isClaudeModel as N}from"../model-catalog.js";import{getDefaultModels as R}from"../model-registry.js";import{claudeFormat as G,nestedClaudeProjectFiles as K}from"../sessions/formats.js";import{powerShellEnv as U}from"../powershell-env.js";const F=h;export const CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING="hide_official_login";export const CLAUDE_DESKTOP_FORCE_REGISTRY_SETTING="force_registry";const H=/^[a-f0-9-]{36}$/;function J(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}export function claudeDesktopUserDataDir(){const e=process.env.CLAUDE_USER_DATA_DIR?.trim();if(e)return e;const o=A(),n=Boolean(_("TEST_HOME")?.trim());switch(process.platform){case"darwin":return l(o,"Library","Application Support","Claude-3p");case"win32":{const e=!n&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:l(o,"AppData","Local");return S.map(t=>l(e,"Packages",t,"LocalCache","Local","Claude-3p")).find(e=>t(e))??l(e,"Claude-3p")}default:{const e=!n&&process.env.XDG_CONFIG_HOME?process.env.XDG_CONFIG_HOME:l(o,".config");return l(e,"Claude-3p")}}}const V=()=>l(claudeDesktopUserDataDir(),"configLibrary"),B=()=>l(V(),"_meta.json"),W=e=>l(V(),`${e}.json`),z=()=>l(claudeDesktopUserDataDir(),"claude_desktop_config.json");function q(e){if(!t(e))return null;const o=r(e,"utf-8");if(!o.trim())return null;try{const e=JSON.parse(o);return J(e)?e:null}catch(t){throw new Error(`Existing ${e} cannot be parsed; back it up and fix it first: ${t instanceof Error?t.message:String(t)}`)}}function X(n,r){const s=i(n);t(s)||o(s,{recursive:!0,mode:448}),D(n),w(n,JSON.stringify(r,null,2)+"\n");try{e(n,384)}catch(e){u.logError("claude-desktop.writeJson.chmod",e)}}function Z(){const e=q(B());if(!e)return null;const t=Array.isArray(e.entries)?e.entries.filter(e=>J(e)&&"string"==typeof e.id&&"string"==typeof e.name):[];return{...e,appliedId:"string"==typeof e.appliedId?e.appliedId:"",entries:t}}function Y(e){return e?.entries.find(e=>e.name===F&&H.test(e.id))}const Q={opus:0,fable:1,sonnet:2,haiku:3};function ee(e){let t=/^claude-(opus|sonnet|haiku|fable)-(\d+(?:-\d+)*)/i.exec(e);return t?{family:t[1].toLowerCase(),version:t[2].split("-").map(Number)}:(t=/^claude-(\d+(?:-\d+)*)-(opus|sonnet|haiku)/i.exec(e),t?{family:t[2].toLowerCase(),version:t[1].split("-").map(Number)}:null)}export function humanizeModelId(e){const t=ee(e);return t?`${t.family[0].toUpperCase()+t.family.slice(1)} ${t.version.filter(e=>e<1e7).slice(0,2).join(".")}`:e}function te(e){return ee(e)?.family}export function buildInferenceModels(e,t){const{primary:o,bySlot:n}=function(e){const t=["opus","sonnet","haiku","reasoning"].map(t=>$(e[t]||"")).filter(Boolean);return{primary:t[0]??"",bySlot:t}}(e),r=new Set,s=t?.labels??{};let i;if(t&&t.models.some(N)){i=[...new Set(t.models.filter(N).map($))];for(const e of t.oneMillion)r.add(e)}else{i=[];for(const t of["opus","sonnet","haiku","reasoning"]){const o=(e[t]||"").trim(),n=$(o);n&&(i.includes(n)||i.push(n),/\[1m\]/i.test(o)&&r.add(n))}}const l=e=>Q[te(e)??""]??9;i.sort((e,t)=>{if(e===o)return-1;if(t===o)return 1;const n=l(e)-l(t);if(0!==n)return n;const r=ee(e),s=ee(t);return r&&s?function(e,t){const o=Math.max(e.length,t.length);for(let n=0;n<o;n++){const o=(t[n]??0)-(e[n]??0);if(0!==o)return o}return 0}(r.version,s.version):e.localeCompare(t)});const a=new Set,c=new Map,d=new Set(Object.values(R()).map(e=>$(e||"")));for(const e of n){const t=te(e);t&&i.includes(e)&&!d.has(e)&&!c.has(t)&&c.set(t,e)}return i.map(e=>{const t=te(e),o={name:e,labelOverride:s[e]||humanizeModelId(e)};if(r.has(e)&&(o.supports1m=!0,o.prefer1m=!0),t){o.anthropicFamilyTier=t;const n=c.get(t);n&&n!==e||a.has(t)||(o.isFamilyDefault=!0,a.add(t))}return o})}let oe=null,ne=null,re=null,se=null,ie=null;function le(e){return{inferenceProvider:"gateway",inferenceCredentialKind:"static",inferenceGatewayBaseUrl:(e.baseUrl||"").trim().replace(/\/+$/,""),inferenceGatewayApiKey:e.apiKey,inferenceModels:buildInferenceModels(e.models,e.catalog),disableDeploymentModeChooser:!1!==e.settings?.hide_official_login,chatTabEnabled:!0,chatAdvancedFileAnalysisEnabled:!0,autoModeEnabled:!0,coworkEgressAllowedHosts:["*"],disableEssentialTelemetry:!0,disableNonessentialTelemetry:!0,disableNonessentialServices:!1}}const ae={defaultModelEffort:"medium",modelPrefer1mContext:!0,skipWebFetchPreflight:!0,toolSearchEnabled:!0,builtinBrowserEnabled:!0,isDesktopExtensionEnabled:!0,sshHostAllowlist:["*"],claudeAiImport:{enabled:!0,automatic3pImport:!0,exportEnabled:!0},coworkVmIpv6Enabled:!0,mcpToolTimeoutSec:3600,updateViaUpdatesHost:!0,banner:{enabled:!1}},ce=()=>{if(_("TEST_HOME")?.trim())return null;const e=g();return e?r(e):null};let de=ce,pe=null;export function setDesktopAsarForTests(e){de=void 0===e?ce:()=>e,pe=null}function ue(){if(pe)return pe;let e=null;try{e=de()}catch(e){u.logError("claude-desktop.unsupportedDefaults",e)}return pe=new Set(e?Object.keys(ae).filter(t=>!e.includes(t)):[]),pe}function fe(e){const t=ue();return Object.fromEntries(Object.entries(ae).filter(([o])=>!e(o)&&!t.has(o)))}function me(e){const t={...fe(t=>t in e),...e};for(const e of ue())e in t&&JSON.stringify(t[e])===JSON.stringify(ae[e])&&delete t[e];return t}const ge="SOFTWARE\\Policies\\Claude",ye=`HKCU\\${ge}`,he="HKLM\\SOFTWARE\\Policies\\Claude",ke=`${b}-claude-policy.reg`,_e=e=>c("reg",e,{stdio:["ignore","pipe","pipe"]}).toString();let be=_e;export function setRegRunnerForTests(e){be=e??_e}function De(){return"win32"===process.platform}function we(e){let t;try{t=be(["query",e])}catch{return null}const o=new Map;for(const e of t.split(/\r?\n/)){const t=/^\s{2,}(\S+)\s+(REG_[A-Z_]+)\s*(.*)$/.exec(e);t&&o.set(t[1],t[3])}return o}function Ae(){if(null===we(ye))return;const e=l(claudeDesktopUserDataDir(),ke);try{t(i(e))||o(i(e),{recursive:!0,mode:448}),D(e),be(["export",ye,e,"/y"])}catch(e){u.logError("claude-desktop.snapshotPolicy",e)}}function Ce(e){Ae();for(const[t,o]of Object.entries(e)){const[e,n]="boolean"==typeof o?["REG_DWORD",o?"1":"0"]:"number"==typeof o?["REG_DWORD",String(o)]:"string"==typeof o?["REG_SZ",o]:["REG_SZ",JSON.stringify(o)];be(["add",ye,"/v",t,"/t",e,"/d",n,"/f"])}}function Ee(e){const t=we(ye);if(!t)return;Ae();let o=t.size;for(const n of e)t.has(n)&&(be(["delete",ye,"/v",n,"/f"]),o-=1);o<=0&&be(["delete",ye,"/f"])}function ve(){const e=!Boolean(_("TEST_HOME")?.trim())&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:l(A(),"AppData","Local");return!!t(l(e,"AnthropicClaude"))||S.some(o=>t(l(e,"Packages",o,"LocalCache","Local","Claude-3p")))}const Me=[...Object.keys(le({apiKey:"",baseUrl:"",models:{haiku:"",sonnet:"",opus:"",reasoning:""}})),...Object.keys(ae)];export function detectManagedConfig(){try{if("darwin"===process.platform){let e="";try{e=d().username}catch{}return[e?`/Library/Managed Preferences/${e}/com.anthropic.claudefordesktop.plist`:"","/Library/Managed Preferences/com.anthropic.claudefordesktop.plist"].filter(Boolean).find(e=>t(e))??null}if("win32"===process.platform)return we(he)?he:null;const e="/etc/claude-desktop/managed-settings.json";return t(e)?e:null}catch(e){return u.logError("claude-desktop.detectManagedConfig",e),null}}function Oe(){const e=A();let o;switch(process.platform){case"darwin":o=["/Applications/Claude.app",l(e,"Applications","Claude.app")];break;case"win32":{const t=process.env.LOCALAPPDATA||l(e,"AppData","Local");o=[l(t,"AnthropicClaude"),l(t,"Programs","Claude"),...S.map(e=>l(t,"Packages",e))];break}default:o=["/usr/lib/claude-desktop","/opt/Claude","/usr/bin/claude-desktop",l(e,".local","bin","claude-desktop")]}return o.push(claudeDesktopUserDataDir(),l(claudeDesktopUserDataDir(),"..","Claude")),o.some(e=>t(e))}const Se=/\d+\.\d+\.\d+/;function xe(e){const t=e=>e.split(".").map(Number);return e.sort((e,o)=>{const[n,r]=[t(e),t(o)];for(let e=0;e<3;e++)if(n[e]!==r[e])return r[e]-n[e];return 0})[0]??null}function Pe(){if("darwin"===process.platform){for(const e of["/Applications/Claude.app",l(A(),"Applications","Claude.app")]){const o=l(e,"Contents","Info.plist");if(!t(o))continue;const n=/<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/.exec(r(o,"utf-8")),s=n?Se.exec(n[1])?.[0]:void 0;if(s)return s}return null}if("win32"===process.platform){const e=l(process.env.LOCALAPPDATA||l(A(),"AppData","Local"),"AnthropicClaude");if(t(e)){const t=n(e).map(e=>/^app-(\d+\.\d+\.\d+)$/.exec(e)?.[1]).filter(e=>!!e);if(t.length>0)return xe(t)}const o=S.map(e=>`'${e}'`).join(",");return xe(c("powershell.exe",["-NoProfile","-Command",`Get-AppxPackage | Where-Object { @(${o}) -contains $_.PackageFamilyName } | ForEach-Object { $_.Version.ToString() }`],{encoding:"utf-8",timeout:15e3,windowsHide:!0,stdio:["ignore","pipe","ignore"],env:U()}).split(/\r?\n/).flatMap(e=>Se.exec(e)?.[0]??[]))}if("linux"===process.platform)try{const e=c("dpkg-query",["-W","-f=${Version}","claude-desktop"],{encoding:"utf-8",timeout:5e3,stdio:["ignore","pipe","ignore"]});return Se.exec(e)?.[0]??null}catch{return null}return null}const je="darwin"===process.platform?"open -a Claude":"win32"===process.platform?"Claude":"claude-desktop",Ie="darwin"!==process.platform&&"win32"!==process.platform||!k().installMirror?.claudeDesktop?"https://claude.ai/download":k().installMirror.claudeDesktop,Le="darwin"===process.platform?`open ${Ie}`:"win32"===process.platform?`start ${Ie}`:`xdg-open ${Ie}`;export const claudeDesktopAdapter={name:"claude-desktop",displayName:"Claude Desktop",command:je,installCommand:Le,configPath:B(),sessions:{format:G,files:()=>K(l(claudeDesktopUserDataDir(),"local-agent-mode-sessions"))},isInstalled:Oe,installedVersion:Pe,prepareRuntime:async function(){if(!["win32","darwin","linux"].includes(process.platform)||!Oe())return[];const e=Date.now();try{const t=await m({userDataDir:claudeDesktopUserDataDir(),onDownload:e=>console.log(p.gray(" "+y.t("tools.claude_desktop.code_cli_downloading",{version:e}))),desktopVersion:"darwin"===process.platform?Pe():null,mirrorRepo:k().installMirror?.claudeDesktop?.replace(/\/-\/releases\/latest\/?$/,"")??null});return f("desktop-code-cli","skipped"===t.status?"skip":"ok",{duration_ms:Date.now()-e,detail:{...t}}),"installed"!==t.status?[]:[{kind:"summary",text:y.t("tools.claude_desktop.code_cli_installed",{version:t.version})}]}catch(t){return u.logError("claude-desktop.prepareCodeTabCli",t),f("desktop-code-cli","fail",{duration_ms:Date.now()-e,error:t}),[{kind:"action",text:y.t("tools.claude_desktop.code_cli_failed",{reason:t instanceof Error?t.message:String(t)})}]}},runningApp:C()?{isRunning:E,restart:O,quit:M,launch:v}:void 0,appInstaller:{vendor:"Anthropic",sizeMb:()=>300,downloadPage:"https://claude.ai/download",blocker:x,latestVersion:()=>P(),installedPath(){if("darwin"===process.platform)return j();if("win32"!==process.platform)return null;try{return Pe()?"MSIX":null}catch(e){return u.logError("claude-desktop.installedPath",e),null}},install:e=>I(e)},wantsModelCatalog:!0,loadPrivateConfig(e){const t=Z()??{appliedId:"",entries:[]};let o=Y(t);o||(o={id:a(),name:F},t.entries.push(o));const n=le(e);ne=!0===n.disableDeploymentModeChooser,oe={models:n.inferenceModels,source:e.catalog?e.catalog.oneMillionSource:"slots",groups:e.catalog?.matchedGroups??[]};const r=q(W(o.id))??{};X(W(o.id),{...me(r),...n}),t.appliedId=o.id,X(B(),t);const s=q(z())??{};if("3p"!==s.deploymentMode&&X(z(),{...s,deploymentMode:"3p"}),se=null,ie=null,re=null,De()){const t=we(ye),o=Me.filter(e=>t?.has(e)),r={...fe(e=>t?.has(e)??!1),...n},s=!0===e.settings?.force_registry,i=!s&&ve();try{i?Ee(Me):Ce(r),re=i?"removed":"written"}catch(e){u.logError("claude-desktop.policy",e),se=e instanceof Error?e.message.trim():String(e),(o.length>0||s)&&(ie=i?{action:"remove",values:Object.fromEntries(o.map(e=>[e,null])),deleteKey:o.length===t.size}:{action:"write",values:r,deleteKey:!1})}}},pendingElevation(){const e=ie;return e?{prompt:y.t(`tools.claude_desktop.elevate_${e.action}`),run:()=>{if(!L(ge,e.values,e.deleteKey))return!1;const t=we(ye),o="remove"===e.action?Object.keys(e.values).every(e=>!t?.has(e)):Object.keys(e.values).every(e=>t?.has(e));return o&&(ie=null,se=null),o}}:null},unloadPrivateConfig(){if(De())try{Ee(Me)}catch(e){u.logError("claude-desktop.removePolicy",e)}const e=Z(),t=Y(e);if(!e||!t)return;D(W(t.id)),s(W(t.id),{force:!0});const o=e.entries.filter(e=>e.id!==t.id);0===o.length?(D(B()),s(B(),{force:!0})):X(B(),{...e,entries:o,appliedId:e.appliedId===t.id?o[0].id:e.appliedId})},listedModels(){const e=Z(),t=Y(e);if(!t||e?.appliedId!==t.id)return null;const o=q(W(t.id))?.inferenceModels;return Array.isArray(o)?o.map(e=>String(e.name)):null},refreshModelMenu(e){const t=Z(),o=Y(t);if(!o||t?.appliedId!==o.id)return;const n=q(W(o.id));if(!n)return;const r=buildInferenceModels(e.models,e.catalog),s=JSON.stringify(n.inferenceModels)!==JSON.stringify(r),i={...me(n),inferenceModels:r},l=JSON.stringify(i)!==JSON.stringify(n);ie=null;const a=De()?we(ye):null;if(!a?.has("inferenceModels"))return void(l&&X(W(o.id),i));const c=Me.filter(e=>a.has(e)),d=!0!==e.settings?.force_registry&&ve();if(l&&X(W(o.id),i),d||s)try{d?Ee(Me):Ce({inferenceModels:r})}catch(e){throw u.logError("claude-desktop.refreshModelMenu registry",e),ie=d?{action:"remove",values:Object.fromEntries(c.map(e=>[e,null])),deleteKey:c.length===a.size}:{action:"write",values:{inferenceModels:r},deleteKey:!1},new T(y.t("tools.claude_desktop.refresh_needs_admin"))}},detectCurrentConfig(){try{if(De()){const e=we(ye)?.get("inferenceGatewayApiKey");if(e)return{apiKey:e}}const e=Y(Z());if(!e)return{apiKey:null};const t=q(W(e.id)),o=t?.inferenceGatewayApiKey;return{apiKey:"string"==typeof o&&o?o:null}}catch(e){return u.logError("claude-desktop.detectCurrentConfig",e),{apiKey:null}}},getConfig(){try{const e=Z(),t=Y(e);return{meta:e,applied:t?q(W(t.id)):null,desktop:q(z()),...De()?{policy:Object.fromEntries(we(ye)??[])}:{}}}catch(e){return u.logError("claude-desktop.getConfig",e),null}},clearPinnedModels(){let e=!1;De()&&we(ye)?.has("inferenceModels")&&(Ae(),be(["delete",ye,"/v","inferenceModels","/f"]),e=!0);const t=Y(Z()),o=t?q(W(t.id)):null;if(t&&o&&void 0!==o.inferenceModels){const{inferenceModels:n,...r}=o;X(W(t.id),r),e=!0}return e?["inferenceModels"]:[]},applyNotes(){const e=[];if(oe&&oe.models.length>0){const{models:t,source:o,groups:n}=oe;e.push({kind:"summary",text:y.t("tools.claude_desktop.models_summary",{count:String(t.length),default:t[0].labelOverride??t[0].name})}),e.push({kind:"detail",text:y.t(`tools.claude_desktop.models_written_${o}`,{count:String(t.length),list:t.map(e=>`${e.labelOverride}${e.supports1m?" (1M)":""}`).join(", "),groups:n.join(" / ")})})}null!==ne&&e.push({kind:"detail",text:y.t(ne?"tools.claude_desktop.official_login_hidden":"tools.claude_desktop.official_login_shown")}),C()&&!E()||e.push({kind:"action",text:y.t("tools.claude_desktop.restart_hint")}),ie?(e.push({kind:"action",text:y.t(`tools.claude_desktop.policy_stale_${ie.action}`)}),e.push({kind:"detail",text:se??""})):se?(e.push({kind:"detail",text:y.t("tools.claude_desktop.registry_denied")}),e.push({kind:"detail",text:se})):De()&&re&&e.push({kind:"detail",text:y.t(`tools.claude_desktop.registry_${re}`,{key:ye})});const t=detectManagedConfig();return t&&e.push({kind:"action",text:y.t("tools.claude_desktop.managed_conflict",{path:t})}),e},forceResetPaths(){const e=[B(),z()];try{const t=Y(Z());t&&e.push(W(t.id))}catch{}return e},backupPaths(){const e=[B(),z()];De()&&e.push(l(claudeDesktopUserDataDir(),ke));try{const t=Y(Z());t&&e.push(W(t.id))}catch{}return e}};
|
|
1
|
+
import{chmodSync as e,existsSync as t,mkdirSync as o,readdirSync as n,readFileSync as r,rmSync as s}from"fs";import{dirname as i}from"path";import{join as l}from"path";import{randomUUID as a}from"crypto";import{execFileSync as c}from"child_process";import{userInfo as d}from"os";import u from"chalk";import{logger as p}from"../../utils/logger.js";import{track as f}from"../telemetry.js";import{ensureDesktopCli as m,installedDesktopAsarPath as g}from"./claude-desktop-cli.js";import{i18n as y}from"../i18n.js";import{BRAND_NAME as h,brand as k,brandEnv as _,CLI_NAME as w}from"../brand.js";import{backupBeforeWrite as b,atomicWriteFile as D}from"./backup.js";import{toolHome as A}from"./types.js";import{canRestartDesktop as C,desktopQuitRefused as v,isDesktopRunning as E,launchDesktop as M,quitDesktop as O,restartDesktop as S,WINDOWS_PACKAGE_FAMILIES as x}from"./desktop-process.js";import{desktopInstallBlocker as j,fetchLatestDesktopVersion as P,installedMacApp as I,installLatestDesktop as L}from"./claude-desktop-app.js";import{setUserRegistryElevated as T}from"./elevated-reg.js";import{UserActionNeeded as $}from"./types.js";import{savedApiKeys as G}from"../config.js";import{isOurGatewayUrl as N,noteWrittenGatewayUrl as U}from"../gateway-addresses.js";import{baseModelId as R,isClaudeModel as K}from"../model-catalog.js";import{getDefaultModels as F}from"../model-registry.js";import{claudeFormat as B,nestedClaudeProjectFiles as H}from"../sessions/formats.js";import{powerShellEnv as J}from"../powershell-env.js";const V=h;export const CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING="hide_official_login";export const CLAUDE_DESKTOP_FORCE_REGISTRY_SETTING="force_registry";const W=/^[a-f0-9-]{36}$/;function z(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}export function claudeDesktopUserDataDir(){const e=process.env.CLAUDE_USER_DATA_DIR?.trim();if(e)return e;const o=A(),n=Boolean(_("TEST_HOME")?.trim());switch(process.platform){case"darwin":return l(o,"Library","Application Support","Claude-3p");case"win32":{const e=!n&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:l(o,"AppData","Local");return x.map(t=>l(e,"Packages",t,"LocalCache","Local","Claude-3p")).find(e=>t(e))??l(e,"Claude-3p")}default:{const e=!n&&process.env.XDG_CONFIG_HOME?process.env.XDG_CONFIG_HOME:l(o,".config");return l(e,"Claude-3p")}}}const q=()=>l(claudeDesktopUserDataDir(),"configLibrary"),X=()=>l(q(),"_meta.json"),Z=e=>l(q(),`${e}.json`),Y=()=>l(claudeDesktopUserDataDir(),"claude_desktop_config.json");function Q(e){if(!t(e))return null;const o=r(e,"utf-8");if(!o.trim())return null;try{const e=JSON.parse(o);return z(e)?e:null}catch(t){throw new Error(`Existing ${e} cannot be parsed; back it up and fix it first: ${t instanceof Error?t.message:String(t)}`)}}function ee(n,r){const s=i(n);t(s)||o(s,{recursive:!0,mode:448}),b(n),D(n,JSON.stringify(r,null,2)+"\n");try{e(n,384)}catch(e){p.logError("claude-desktop.writeJson.chmod",e)}}function te(){const e=Q(X());if(!e)return null;const t=Array.isArray(e.entries)?e.entries.filter(e=>z(e)&&"string"==typeof e.id&&"string"==typeof e.name):[];return{...e,appliedId:"string"==typeof e.appliedId?e.appliedId:"",entries:t}}function oe(e){return e?.entries.find(e=>e.name===V&&W.test(e.id))}const ne={opus:0,fable:1,sonnet:2,haiku:3};function re(e){let t=/^claude-(opus|sonnet|haiku|fable)-(\d+(?:-\d+)*)/i.exec(e);return t?{family:t[1].toLowerCase(),version:t[2].split("-").map(Number)}:(t=/^claude-(\d+(?:-\d+)*)-(opus|sonnet|haiku)/i.exec(e),t?{family:t[2].toLowerCase(),version:t[1].split("-").map(Number)}:null)}export function humanizeModelId(e){const t=re(e);return t?`${t.family[0].toUpperCase()+t.family.slice(1)} ${t.version.filter(e=>e<1e7).slice(0,2).join(".")}`:e}function se(e){return re(e)?.family}export function buildInferenceModels(e,t){const{primary:o,bySlot:n}=function(e){const t=["opus","sonnet","haiku","reasoning"].map(t=>R(e[t]||"")).filter(Boolean);return{primary:t[0]??"",bySlot:t}}(e),r=new Set,s=t?.labels??{};let i;if(t&&t.models.some(K)){i=[...new Set(t.models.filter(K).map(R))];for(const e of t.oneMillion)r.add(e)}else{i=[];for(const t of["opus","sonnet","haiku","reasoning"]){const o=(e[t]||"").trim(),n=R(o);n&&(i.includes(n)||i.push(n),/\[1m\]/i.test(o)&&r.add(n))}}const l=e=>ne[se(e)??""]??9;i.sort((e,t)=>{if(e===o)return-1;if(t===o)return 1;const n=l(e)-l(t);if(0!==n)return n;const r=re(e),s=re(t);return r&&s?function(e,t){const o=Math.max(e.length,t.length);for(let n=0;n<o;n++){const o=(t[n]??0)-(e[n]??0);if(0!==o)return o}return 0}(r.version,s.version):e.localeCompare(t)});const a=new Set,c=new Map,d=new Set(Object.values(F()).map(e=>R(e||"")));for(const e of n){const t=se(e);t&&i.includes(e)&&!d.has(e)&&!c.has(t)&&c.set(t,e)}return i.map(e=>{const t=se(e),o={name:e,labelOverride:s[e]||humanizeModelId(e)};if(r.has(e)&&(o.supports1m=!0,o.prefer1m=!0),t){o.anthropicFamilyTier=t;const n=c.get(t);n&&n!==e||a.has(t)||(o.isFamilyDefault=!0,a.add(t))}return o})}let ie=null,le=null,ae=null,ce=null,de=null;function ue(e){return{inferenceProvider:"gateway",inferenceCredentialKind:"static",inferenceGatewayBaseUrl:(e.baseUrl||"").trim().replace(/\/+$/,""),inferenceGatewayApiKey:e.apiKey,inferenceModels:buildInferenceModels(e.models,e.catalog),disableDeploymentModeChooser:!1!==e.settings?.hide_official_login,chatTabEnabled:!0,chatAdvancedFileAnalysisEnabled:!0,autoModeEnabled:!0,coworkEgressAllowedHosts:["*"],disableEssentialTelemetry:!0,disableNonessentialTelemetry:!0,disableNonessentialServices:!1}}const pe={defaultModelEffort:"medium",modelPrefer1mContext:!0,skipWebFetchPreflight:!0,toolSearchEnabled:!0,builtinBrowserEnabled:!0,isDesktopExtensionEnabled:!0,sshHostAllowlist:["*"],claudeAiImport:{enabled:!0,automatic3pImport:!0,exportEnabled:!0},coworkVmIpv6Enabled:!0,mcpToolTimeoutSec:3600,updateViaUpdatesHost:!0,banner:{enabled:!1}},fe=()=>{if(_("TEST_HOME")?.trim())return null;const e=g();return e?r(e):null};let me=fe,ge=null;export function setDesktopAsarForTests(e){me=void 0===e?fe:()=>e,ge=null}function ye(){if(ge)return ge;let e=null;try{e=me()}catch(e){p.logError("claude-desktop.unsupportedDefaults",e)}return ge=new Set(e?Object.keys(pe).filter(t=>!e.includes(t)):[]),ge}function he(e){const t=ye();return Object.fromEntries(Object.entries(pe).filter(([o])=>!e(o)&&!t.has(o)))}function ke(e){const t={...he(t=>t in e),...e};for(const e of ye())e in t&&JSON.stringify(t[e])===JSON.stringify(pe[e])&&delete t[e];return t}const _e="SOFTWARE\\Policies\\Claude",we=`HKCU\\${_e}`,be="HKLM\\SOFTWARE\\Policies\\Claude",De=`${w}-claude-policy.reg`,Ae=e=>c("reg",e,{stdio:["ignore","pipe","pipe"]}).toString();let Ce=Ae;export function setRegRunnerForTests(e){Ce=e??Ae}function ve(){return"win32"===process.platform}function Ee(e){let t;try{t=Ce(["query",e])}catch{return null}const o=new Map;for(const e of t.split(/\r?\n/)){const t=/^\s{2,}(\S+)\s+(REG_[A-Z_]+)\s*(.*)$/.exec(e);t&&o.set(t[1],t[3])}return o}function Me(){if(null===Ee(we))return;const e=l(claudeDesktopUserDataDir(),De);try{t(i(e))||o(i(e),{recursive:!0,mode:448}),b(e),Ce(["export",we,e,"/y"])}catch(e){p.logError("claude-desktop.snapshotPolicy",e)}}function Oe(e){Me();for(const[t,o]of Object.entries(e)){const[e,n]="boolean"==typeof o?["REG_DWORD",o?"1":"0"]:"number"==typeof o?["REG_DWORD",String(o)]:"string"==typeof o?["REG_SZ",o]:["REG_SZ",JSON.stringify(o)];Ce(["add",we,"/v",t,"/t",e,"/d",n,"/f"])}}function Se(e){const t=Ee(we);if(!t)return;Me();let o=t.size;for(const n of e)t.has(n)&&(Ce(["delete",we,"/v",n,"/f"]),o-=1);o<=0&&Ce(["delete",we,"/f"])}function xe(){const e=!Boolean(_("TEST_HOME")?.trim())&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:l(A(),"AppData","Local");return!!t(l(e,"AnthropicClaude"))||x.some(o=>t(l(e,"Packages",o,"LocalCache","Local","Claude-3p")))}const je=[...Object.keys(ue({apiKey:"",baseUrl:"",models:{haiku:"",sonnet:"",opus:"",reasoning:""}})),...Object.keys(pe)];function Pe(e){if(!e||!je.some(t=>e.has(t)))return"none";const t=e.get("inferenceGatewayApiKey")?.trim();return N(e.get("inferenceGatewayBaseUrl"))||t&&G().includes(t)?"ours":"foreign"}function Ie(){const e=Q(Y())?.deploymentMode;if(void 0!==e&&"3p"!==e)return{kind:"mode"};const t=te(),o=t?.entries.find(e=>e.id===t.appliedId);if(!o||o.id===oe(t)?.id)return null;const n=Q(Z(o.id));return n&&(n.inferenceProvider||n.inferenceGatewayBaseUrl)?{kind:"entry",name:o.name}:null}function Le(e){return"mode"===e.kind?y.t("tools.claude_desktop.current_official"):y.t("tools.claude_desktop.current_entry",{name:e.name})}let Te=null,$e=null;export function detectManagedConfig(){try{if("darwin"===process.platform){let e="";try{e=d().username}catch{}return[e?`/Library/Managed Preferences/${e}/com.anthropic.claudefordesktop.plist`:"","/Library/Managed Preferences/com.anthropic.claudefordesktop.plist"].filter(Boolean).find(e=>t(e))??null}if("win32"===process.platform)return Ee(be)?be:null;const e="/etc/claude-desktop/managed-settings.json";return t(e)?e:null}catch(e){return p.logError("claude-desktop.detectManagedConfig",e),null}}function Ge(){const e=A();let o;switch(process.platform){case"darwin":o=["/Applications/Claude.app",l(e,"Applications","Claude.app")];break;case"win32":{const t=process.env.LOCALAPPDATA||l(e,"AppData","Local");o=[l(t,"AnthropicClaude"),l(t,"Programs","Claude"),...x.map(e=>l(t,"Packages",e))];break}default:o=["/usr/lib/claude-desktop","/opt/Claude","/usr/bin/claude-desktop",l(e,".local","bin","claude-desktop")]}return o.push(claudeDesktopUserDataDir(),l(claudeDesktopUserDataDir(),"..","Claude")),o.some(e=>t(e))}const Ne=/\d+\.\d+\.\d+/;function Ue(e){const t=e=>e.split(".").map(Number);return e.sort((e,o)=>{const[n,r]=[t(e),t(o)];for(let e=0;e<3;e++)if(n[e]!==r[e])return r[e]-n[e];return 0})[0]??null}function Re(){if("darwin"===process.platform){for(const e of["/Applications/Claude.app",l(A(),"Applications","Claude.app")]){const o=l(e,"Contents","Info.plist");if(!t(o))continue;const n=/<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/.exec(r(o,"utf-8")),s=n?Ne.exec(n[1])?.[0]:void 0;if(s)return s}return null}if("win32"===process.platform){const e=l(process.env.LOCALAPPDATA||l(A(),"AppData","Local"),"AnthropicClaude");if(t(e)){const t=n(e).map(e=>/^app-(\d+\.\d+\.\d+)$/.exec(e)?.[1]).filter(e=>!!e);if(t.length>0)return Ue(t)}const o=x.map(e=>`'${e}'`).join(",");return Ue(c("powershell.exe",["-NoProfile","-Command",`Get-AppxPackage | Where-Object { @(${o}) -contains $_.PackageFamilyName } | ForEach-Object { $_.Version.ToString() }`],{encoding:"utf-8",timeout:15e3,windowsHide:!0,stdio:["ignore","pipe","ignore"],env:J()}).split(/\r?\n/).flatMap(e=>Ne.exec(e)?.[0]??[]))}if("linux"===process.platform)try{const e=c("dpkg-query",["-W","-f=${Version}","claude-desktop"],{encoding:"utf-8",timeout:5e3,stdio:["ignore","pipe","ignore"]});return Ne.exec(e)?.[0]??null}catch{return null}return null}const Ke="darwin"===process.platform?"open -a Claude":"win32"===process.platform?"Claude":"claude-desktop",Fe="darwin"!==process.platform&&"win32"!==process.platform||!k().installMirror?.claudeDesktop?"https://claude.ai/download":k().installMirror.claudeDesktop,Be="darwin"===process.platform?`open ${Fe}`:"win32"===process.platform?`start ${Fe}`:`xdg-open ${Fe}`;export const claudeDesktopAdapter={name:"claude-desktop",displayName:"Claude Desktop",command:Ke,installCommand:Be,configPath:X(),sessions:{format:B,files:()=>H(l(claudeDesktopUserDataDir(),"local-agent-mode-sessions"))},isInstalled:Ge,installedVersion:Re,prepareRuntime:async function(){if(!["win32","darwin","linux"].includes(process.platform)||!Ge())return[];const e=Date.now();try{const t=await m({userDataDir:claudeDesktopUserDataDir(),onDownload:e=>console.log(u.gray(" "+y.t("tools.claude_desktop.code_cli_downloading",{version:e}))),desktopVersion:"darwin"===process.platform?Re():null,mirrorRepo:k().installMirror?.claudeDesktop?.replace(/\/-\/releases\/latest\/?$/,"")??null});return f("desktop-code-cli","skipped"===t.status?"skip":"ok",{duration_ms:Date.now()-e,detail:{...t}}),"installed"!==t.status?[]:[{kind:"summary",text:y.t("tools.claude_desktop.code_cli_installed",{version:t.version})}]}catch(t){return p.logError("claude-desktop.prepareCodeTabCli",t),f("desktop-code-cli","fail",{duration_ms:Date.now()-e,error:t}),[{kind:"action",text:y.t("tools.claude_desktop.code_cli_failed",{reason:t instanceof Error?t.message:String(t)})}]}},runningApp:C()?{isRunning:E,restart:S,quit:O,quitRefused:v,launch:M}:void 0,appInstaller:{vendor:"Anthropic",sizeMb:()=>300,downloadPage:"https://claude.ai/download",blocker:j,latestVersion:()=>P(),installedPath(){if("darwin"===process.platform)return I();if("win32"!==process.platform)return null;try{return Re()?"MSIX":null}catch(e){return p.logError("claude-desktop.installedPath",e),null}},install:e=>L(e)},wantsModelCatalog:!0,loadPrivateConfig(e){const t=te()??{appliedId:"",entries:[]};let o=oe(t);o||(o={id:a(),name:V},t.entries.push(o));const n=ue(e);U(String(n.inferenceGatewayBaseUrl)),le=!0===n.disableDeploymentModeChooser,ie={models:n.inferenceModels,source:e.catalog?e.catalog.oneMillionSource:"slots",groups:e.catalog?.matchedGroups??[]};const r=Q(Z(o.id))??{};ee(Z(o.id),{...ke(r),...n});const s=Ie();Te=s&&!e.takeOver?Le(s):null,Te||(t.appliedId=o.id),ee(X(),t);const i=Q(Y())??{};Te||"3p"===i.deploymentMode||ee(Y(),{...i,deploymentMode:"3p"}),ce=null,de=null,ae=null,$e=null;const l=!0===e.settings?.force_registry,c=ve()?Ee(we):null;if(ve()&&"foreign"===Pe(c)&&!l)$e=c?.get("inferenceGatewayBaseUrl")||we;else if(ve()){const t=Ee(we),o=je.filter(e=>t?.has(e)),r={...he(e=>t?.has(e)??!1),...n},s=!0===e.settings?.force_registry,i=!s&&xe();try{i?Se(je):Oe(r),ae=i?"removed":"written"}catch(e){p.logError("claude-desktop.policy",e),ce=e instanceof Error?e.message.trim():String(e),(o.length>0||s)&&(de=i?{action:"remove",values:Object.fromEntries(o.map(e=>[e,null])),deleteKey:o.length===t.size}:{action:"write",values:r,deleteKey:!1})}}},pendingElevation(){const e=de;return e?{prompt:y.t(`tools.claude_desktop.elevate_${e.action}`),run:()=>{if(!T(_e,e.values,e.deleteKey))return!1;const t=Ee(we),o="remove"===e.action?Object.keys(e.values).every(e=>!t?.has(e)):Object.keys(e.values).every(e=>t?.has(e));return o&&(de=null,ce=null),o}}:null},unloadPrivateConfig(){if(ve()&&"ours"===Pe(Ee(we)))try{Se(je)}catch(e){p.logError("claude-desktop.removePolicy",e)}const e=te(),t=oe(e);if(!e||!t)return;b(Z(t.id)),s(Z(t.id),{force:!0});const o=e.entries.filter(e=>e.id!==t.id);0===o.length?(b(X()),s(X(),{force:!0})):ee(X(),{...e,entries:o,appliedId:e.appliedId===t.id?o[0].id:e.appliedId})},listedModels(){const e=te(),t=oe(e);if(!t||e?.appliedId!==t.id)return null;const o=Q(Z(t.id))?.inferenceModels;return Array.isArray(o)?o.map(e=>String(e.name)):null},refreshModelMenu(e){const t=te(),o=oe(t);if(!o||t?.appliedId!==o.id)return;const n=Q(Z(o.id));if(!n)return;const r=buildInferenceModels(e.models,e.catalog),s=JSON.stringify(n.inferenceModels)!==JSON.stringify(r),i={...ke(n),inferenceModels:r},l=JSON.stringify(i)!==JSON.stringify(n);de=null;const a=ve()?Ee(we):null,c="foreign"===Pe(a)&&!0!==e.settings?.force_registry;if(!a?.has("inferenceModels")||c)return void(l&&ee(Z(o.id),i));const d=je.filter(e=>a.has(e)),u=!0!==e.settings?.force_registry&&xe();if(l&&ee(Z(o.id),i),u||s)try{u?Se(je):Oe({inferenceModels:r})}catch(e){throw p.logError("claude-desktop.refreshModelMenu registry",e),de=u?{action:"remove",values:Object.fromEntries(d.map(e=>[e,null])),deleteKey:d.length===a.size}:{action:"write",values:{inferenceModels:r},deleteKey:!1},new $(y.t("tools.claude_desktop.refresh_needs_admin"))}},detectCurrentConfig(){try{if(ve()){const e=Ee(we)?.get("inferenceGatewayApiKey");if(e)return{apiKey:e}}const e=oe(te());if(!e)return{apiKey:null};const t=Q(Z(e.id)),o=t?.inferenceGatewayApiKey;return{apiKey:"string"==typeof o&&o?o:null}}catch(e){return p.logError("claude-desktop.detectCurrentConfig",e),{apiKey:null}}},getConfig(){try{const e=te(),t=oe(e);return{meta:e,applied:t?Q(Z(t.id)):null,desktop:Q(Y()),...ve()?{policy:Object.fromEntries(Ee(we)??[])}:{}}}catch(e){return p.logError("claude-desktop.getConfig",e),null}},clearPinnedModels(){let e=!1;ve()&&Ee(we)?.has("inferenceModels")&&(Me(),Ce(["delete",we,"/v","inferenceModels","/f"]),e=!0);const t=oe(te()),o=t?Q(Z(t.id)):null;if(t&&o&&void 0!==o.inferenceModels){const{inferenceModels:n,...r}=o;ee(Z(t.id),r),e=!0}return e?["inferenceModels"]:[]},applyNotes(){const e=[];if(ie&&ie.models.length>0){const{models:t,source:o,groups:n}=ie;e.push({kind:"summary",text:y.t("tools.claude_desktop.models_summary",{count:String(t.length),default:t[0].labelOverride??t[0].name})}),e.push({kind:"detail",text:y.t(`tools.claude_desktop.models_written_${o}`,{count:String(t.length),list:t.map(e=>`${e.labelOverride}${e.supports1m?" (1M)":""}`).join(", "),groups:n.join(" / ")})})}null!==le&&e.push({kind:"detail",text:y.t(le?"tools.claude_desktop.official_login_hidden":"tools.claude_desktop.official_login_shown")}),C()&&!E()||e.push({kind:"action",text:y.t("tools.claude_desktop.restart_hint")}),de?(e.push({kind:"action",text:y.t(`tools.claude_desktop.policy_stale_${de.action}`)}),e.push({kind:"detail",text:ce??""})):ce?(e.push({kind:"detail",text:y.t("tools.claude_desktop.registry_denied")}),e.push({kind:"detail",text:ce})):ve()&&ae&&e.push({kind:"detail",text:y.t(`tools.claude_desktop.registry_${ae}`,{key:we})}),Te&&e.push({kind:"action",text:y.t("tools.claude_desktop.not_switched",{current:Te})}),$e&&e.push({kind:"action",text:y.t("tools.claude_desktop.foreign_policy",{key:we,url:$e})});const t=detectManagedConfig();return t&&e.push({kind:"action",text:y.t("tools.claude_desktop.managed_conflict",{path:t})}),e},planNotes(){const e=[],t=Ie();if(t&&e.push(y.t("tools.claude_desktop.plan_switch",{current:Le(t)})),ve()){const t=Ee(we);"foreign"===Pe(t)&&e.push(y.t("tools.claude_desktop.plan_foreign_policy",{key:we,url:t?.get("inferenceGatewayBaseUrl")||"-"}))}return e},forceResetPaths(){const e=[X(),Y()];try{const t=oe(te());t&&e.push(Z(t.id))}catch{}return e},backupPaths(){const e=[X(),Y()];ve()&&e.push(l(claudeDesktopUserDataDir(),De));try{const t=oe(te());t&&e.push(Z(t.id))}catch{}return e}};
|
package/dist/lib/tools/codex.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash as e}from"crypto";import{existsSync as t,mkdirSync as o,readdirSync as n,readFileSync as r,rmSync as i,statSync as s,writeFileSync as a}from"fs";import{join as l}from"path";import*as c from"@iarna/toml";import{logger as d}from"../../utils/logger.js";import{i18n as u}from"../i18n.js";import{backupBeforeWrite as m,atomicWriteFile as p}from"./backup.js";import{codexHome as f,pickModel as _,toolHome as g,withV1 as x}from"./types.js";import{moveSessionsToProvider as h,NO_STATE_DB as y,runningCodexPids as k}from"../codex-sessions.js";import{codexFormat as b,codexRolloutFiles as v}from"../sessions/formats.js";import{getToolDefaultModel as w}from"../model-registry.js";import{configManager as j}from"../config.js";import{maskHome as C,track as O}from"../telemetry.js";import{buildCodexCatalog as S,catalogRejections as M,codexCatalogPath as A,fillFromOlderEntries as E,installedCodexBinaries as N,loadBundledCodexModels as P,loadPreviousCodexModels as T,previousGatewayModelIds as D}from"./codex-catalog.js";import{gatewayModelSpecs as I,modelFamily as L}from"../gateway-models.js";import{findInstalls as $,mirrorInstallCommand as J,brandInstallScripts as G}from"./tool-installs.js";import{chatgptDesktopApp as R}from"./chatgpt-desktop.js";const K=()=>f(),X=()=>l(K(),"config.toml"),B="sessions_move_declined",U=["browser_use","browser_use_external","computer_use"];function W(e){const t=e.features;if(!V(t)||!U.every(e=>!1===t[e]))return!1;for(const e of U)delete t[e];return!0}export function codexWorkModeOn(){try{const e=ee();return e.model_provider===F&&V(e.desktop)&&"STEPS_PROSE"===e.desktop.conversationDetailMode}catch{return!1}}function q(){try{if(V(ee().desktop))return!0}catch{}if("darwin"===process.platform)return["/Applications",l(g(),"Applications")].some(e=>["ChatGPT.app","Codex.app"].some(o=>t(l(e,o))));if("win32"===process.platform){const e=l(process.env.LOCALAPPDATA||l(g(),"AppData","Local"),"Packages");try{return n(e).some(e=>/^OpenAI\.(Codex|ChatGPT)/i.test(e))}catch{return!1}}return t("/usr/lib/chatgpt/ChatGPT")}export function codexConfigPath(){return X()}const z=()=>l(K(),"auth.json"),Y="OPENAI_API_KEY",F="custom",H=1e6,Q=9e5;export const CODEX_ONE_MILLION_CONTEXT_SETTING="one_million_context";function V(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function Z(e,t){return V(e[t])||(e[t]={}),e[t]}function ee(){if(!t(X()))return{};const e=r(X(),"utf-8");if(!e.trim())return{};try{const t=c.parse(e);if(!V(t))throw new Error("config.toml root must be a TOML table");return t}catch(e){throw new Error(`Existing ~/.codex/config.toml cannot be parsed; back it up and fix it first: ${e instanceof Error?e.message:String(e)}`)}}function te(){if(!t(z()))return{};try{const e=JSON.parse(r(z(),"utf-8"));return V(e)?e:{}}catch{return{}}}let oe=null;function ne(e){const t=e.profiles;if(V(t)){for(const[e,o]of Object.entries(t))V(o)&&2===Object.keys(o).length&&o.model_provider===F&&o.model===e&&delete t[e];0===Object.keys(t).length&&delete e.profiles}}let re=null;const ie=()=>l(j.getConfigDir(),"codex-catalog-check.json");function se(e){const o=A();t(o)&&r(o,"utf-8")===e||(m(o),p(o,e))}function ae(t,n){if(0===n.length)return[];const i=function(t,o){const n=e("sha256").update(t);for(const e of o)try{const t=s(e);n.update(`\0${e}\0${t.size}\0${t.mtimeMs}`)}catch{n.update(`\0${e}`)}return n.digest("hex")}(t,n);if(function(e){try{return JSON.parse(r(ie(),"utf-8")).signature===e}catch{return!1}}(i))return[];const l=M(A(),n);return 0===l.length&&function(e){try{o(j.getConfigDir(),{recursive:!0}),a(ie(),JSON.stringify({signature:e})+"\n")}catch(e){d.logError("codexAdapter.rememberAccepted",e)}}(i),l}function le(e,t,o){const n=!1!==t.settings?.one_million_context;!function(e){e.model_context_window===H&&delete e.model_context_window,e.model_auto_compact_token_limit===Q&&delete e.model_auto_compact_token_limit}(e);const r=()=>{e.model_catalog_json===A()&&delete e.model_catalog_json,n&&(e.model_context_window=H,e.model_auto_compact_token_limit=Q)},s=P()??T();if(!s)return d.logError("codexAdapter.writeModelCatalog",new Error("no Codex binary found; model catalog skipped")),re="skipped",void r();const a=t.catalog,l=e=>S({bundled:e,specs:I("codex",a?.clientModels),...a?{keyModels:a.models}:{},gatewayAvailable:a?.models??D(),oneMillion:n,selectedModel:o,..."gateway"===a?.oneMillionSource?{claudeOneMillion:a.oneMillion}:{}}),c=e=>JSON.stringify(e,null,2)+"\n";let u=l(s);se(c(u));const m=N(),p=ae(c(u),m);if(p.length>0){const e=Date.now();let t=!1;for(const e of p){const o=P(e.bin);if(o){for(const e of[{models:E(u.models,o)},{models:E(l(o).models,o)}])if(se(c(e)),0===ae(c(e),m).length){u=e,t=!0;break}if(t)break}}if(O("codex-catalog",t?"fallback":"fail",{duration_ms:Date.now()-e,error:p[0].error,detail:{rejected_by:p.map(e=>({version:e.version,path:C(e.bin)}))}}),!t)return re={rejectedBy:p[0]},i(A(),{force:!0}),void r()}re={listed:u.models.filter(e=>"list"===e.visibility).map(e=>({id:String(e.slug),name:String(e.display_name??e.slug)}))},e.model_catalog_json=A()}export function codexCatalogRejection(){let e;try{e=ee()}catch{return null}return e.model_catalog_json===A()&&t(A())?M(A())[0]??null:null}export function setCodexOneMillionContext(e,t){const o=ee(),n=c.stringify(o),r="string"==typeof o.model?o.model:w("codex");le(o,{settings:{[CODEX_ONE_MILLION_CONTEXT_SETTING]:e},catalog:t},r);const i=c.stringify(o);i!==n&&(m(X()),p(X(),i))}const ce={command:"codex",npmPackage:"@openai/codex",native:{binDir:"win32"===process.platform?["AppData","Local","Programs","OpenAI","Codex","bin"]:[".local","bin"],updateArgs:["update"],updateTimeoutMs:12e4,dataDirs:[[".codex","packages","standalone"]]},mirrorScript:G("codex"),brew:"codex"};export const codexAdapter={name:"codex",companionApps:[R],displayName:"Codex",command:"codex",installCommand:J(ce),installSpec:ce,configPath:X(),sessions:{format:b,files:()=>[...v(l(f(),"sessions")),...v(l(f(),"archived_sessions"))],resumeCommand:e=>({command:"codex",args:["resume",e]})},wantsModelCatalog:!0,listedModels(){if(ee().model_catalog_json!==A())return null;try{return(JSON.parse(r(A(),"utf-8")).models??[]).filter(e=>"list"===e.visibility).map(e=>String(e.slug))}catch{return null}},refreshModelMenu(e){if(ee().model_catalog_json!==A())return;setCodexOneMillionContext(!1!==e.settings?.one_million_context,e.catalog);const t=ee(),o=function(e,t){const o=V(e.model_providers)?e.model_providers[F]:void 0;return!(!V(o)||o.base_url!==t||!0===o.supports_standalone_web_search||(o.supports_standalone_web_search=!0,0))}(t,x(e.baseUrl));(W(t)||o)&&(m(X()),p(X(),c.stringify(t)))},async followUp(){if(ee().model_provider!==F)return null;const e=await h(F,{dryRun:!0}),t=Math.max(e.moved.length,e.dbRows);if(0===t)return null;const o=j.getToolSettings("codex")[B];if("number"==typeof o&&t<=o)return null;const n={count:String(t)};return k().length>0?{hint:u.t("tools.codex.sessions_hidden_running",n)}:{prompt:u.t("tools.codex.sessions_offer",n),hint:u.t("tools.codex.sessions_hidden",n),async run(){const e=await h(F),t=[...new Set(e.moved.map(e=>e.from))].join("、")||"-",o=String(Math.max(e.moved.length,e.dbRows)),n=[{kind:"summary",text:u.t("codex_sessions.moved",{count:o,from:t,target:F})},{kind:"summary",text:u.t("codex_sessions.backup",{dir:e.backupDir??""})}];return e.dbSkipped&&e.dbSkipped!==y&&n.push({kind:"action",text:u.t("codex_sessions.db_skipped",{reason:e.dbSkipped})}),n},decline(){j.setToolSetting("codex",B,t)}}},applyNotes(){if("skipped"===re)return 0===$(ce).length?[]:[{kind:"action",text:u.t("tools.codex.catalog_skipped")}];if(!re)return[];if("rejectedBy"in re){const{bin:e,version:t}=re.rejectedBy;return[{kind:"action",text:u.t("tools.codex.catalog_rejected",{path:e,version:t??"?"})}]}const e=new Map;for(const t of re.listed)e.set(L(t.id),(e.get(L(t.id))??0)+1);const t=["gpt","claude","gemini","other","grok"].filter(t=>e.has(t)).map(t=>`${u.t(`tools.model_family.${t}`)} ${e.get(t)}`).join(" · ");return[{kind:"summary",text:u.t("tools.codex.catalog_written",{count:String(re.listed.length),breakdown:t})},{kind:"detail",text:re.listed.map(e=>e.name).join(", ")},...codexWorkModeOn()||q()?[{kind:"action",text:u.t(codexWorkModeOn()?"tools.codex.work_mode_on":"tools.codex.work_mode_hint")}]:[]]},loadPrivateConfig(e){const t=w("codex"),o=_(e.models,t),n=function(e){return/(?:^|\/)claude(?:-|$)/i.test(e)}(o)?t:o,r=x(e.baseUrl),i=ee();i.model=n,i.model_provider=F,i.model_reasoning_effort="high",le(i,e,n);const s=Z(i,"model_providers"),a=V(s[F])?{...s[F]}:{};delete a.env_key;const{experimental_bearer_token:l,...d}=a;s[F]={...d,name:"custom",wire_api:"responses",requires_openai_auth:!0,supports_standalone_web_search:!0,base_url:r},ne(i),Z(Z(i,"tui"),"model_availability_nux")[n]=4;const u=Z(i,"features");u.goals=!0,u.js_repl=!1,W(i),m(X()),p(X(),c.stringify(i)),function(e){const t=e.trim();if(!t)return;const o={...te(),auth_mode:"apikey",[Y]:t};m(z()),p(z(),JSON.stringify(o,null,2)+"\n",384)}(e.apiKey)},holdsOurConfig(e){const t=te()[Y];return"string"==typeof t&&e.includes(t.trim())},unloadPrivateConfig(e){if(oe=function(e){const t=te(),o="string"==typeof t[Y]?t[Y].trim():"";if(!o)return V(t.tokens)?"chatgpt":null;if(!e.includes(o))return"other_key";const{[Y]:n,auth_mode:r,...s}=t;return m(z()),V(s.tokens)?(p(z(),JSON.stringify({...s,auth_mode:"chatgpt"},null,2)+"\n",384),"chatgpt"):(i(z(),{force:!0}),"signed_out")}(e?.savedKeys??[]),!t(X()))return;let o;try{o=ee()}catch(e){return void d.logError("codexAdapter.unloadPrivateConfig",e)}const n=o.model_providers;V(n)&&(delete n[F],0===Object.keys(n).length&&delete o.model_providers),o.model_provider===F&&delete o.model_provider,o.model_catalog_json===A()&&delete o.model_catalog_json,W(o),ne(o),m(X()),p(X(),c.stringify(o))},unloadNotes(){switch(oe){case"chatgpt":return[{kind:"action",text:u.t("tools.codex.unload_chatgpt_restored")}];case"other_key":return[{kind:"action",text:u.t("tools.codex.unload_other_key")}];default:return[{kind:"action",text:u.t("tools.codex.unload_sign_in")}]}},detectCurrentConfig(){const e=te()[Y];return{apiKey:"string"==typeof e&&e.trim()?e.trim():null}},getConfig(){try{return ee()}catch(e){return d.logError("codexAdapter.getConfig",e),null}},backupPaths:()=>[X(),z(),A()]};export function codexAuthProblem(){try{const e=ee(),t=e.model_providers?.[F];if(e.model_provider!==F||!t)return null;if("string"==typeof t.experimental_bearer_token&&t.experimental_bearer_token)return"stale_bearer";const o=te();return!0===t.requires_openai_auth&&"chatgpt"===o.auth_mode?"chatgpt_login":null}catch{return null}}
|
|
1
|
+
import{createHash as e}from"crypto";import{existsSync as t,mkdirSync as o,readdirSync as r,readFileSync as n,rmSync as s,statSync as i,writeFileSync as l}from"fs";import{join as a}from"path";import*as c from"@iarna/toml";import{logger as d}from"../../utils/logger.js";import{i18n as u}from"../i18n.js";import{backupBeforeWrite as m,atomicWriteFile as p}from"./backup.js";import{codexHome as f,pickModel as _,toolHome as g,withV1 as x}from"./types.js";import{moveSessionsToProvider as h,NO_STATE_DB as y,runningCodexPids as k}from"../codex-sessions.js";import{codexFormat as b,codexRolloutFiles as v}from"../sessions/formats.js";import{getGatewayModelRules as w,getToolDefaultModel as j}from"../model-registry.js";import{claimField as S}from"../written-values.js";import{configManager as C}from"../config.js";import{maskHome as O,track as M}from"../telemetry.js";import{buildCodexCatalog as A,catalogRejections as E,codexCatalogPath as N,fillFromOlderEntries as P,installedCodexBinaries as T,loadBundledCodexModels as D,loadPreviousCodexModels as $,previousGatewayModelIds as I}from"./codex-catalog.js";import{gatewayModelSpecs as L,modelFamily as J}from"../gateway-models.js";import{isOurGatewayUrl as G,noteWrittenGatewayUrl as R}from"../gateway-addresses.js";import{findInstalls as K,mirrorInstallCommand as X,brandInstallScripts as B}from"./tool-installs.js";import{chatgptDesktopApp as U}from"./chatgpt-desktop.js";const W=()=>f(),q=()=>a(W(),"config.toml"),z="sessions_move_declined",Y=["browser_use","browser_use_external","computer_use"],F="desktop_features_restored";function H(e){if(!0===C.getToolSetting("codex",F))return!1;const t=e.features,o=ae(t)&&Y.every(e=>!1===t[e]);if(C.setToolSetting("codex",F,!0),!o)return!1;for(const e of Y)delete t[e];return!0}export function codexWorkModeOn(){try{const e=de();return e.model_provider===ee&&ae(e.desktop)&&"STEPS_PROSE"===e.desktop.conversationDetailMode}catch{return!1}}function Q(){try{if(ae(de().desktop))return!0}catch{}if("darwin"===process.platform)return["/Applications",a(g(),"Applications")].some(e=>["ChatGPT.app","Codex.app"].some(o=>t(a(e,o))));if("win32"===process.platform){const e=a(process.env.LOCALAPPDATA||a(g(),"AppData","Local"),"Packages");try{return r(e).some(e=>/^OpenAI\.(Codex|ChatGPT)/i.test(e))}catch{return!1}}return t("/usr/lib/chatgpt/ChatGPT")}export function codexConfigPath(){return q()}const V=()=>a(W(),"auth.json"),Z="OPENAI_API_KEY",ee="custom",te="high",oe=["gpt-5.5","gpt-5.6-sol","gpt-6-astra"],re=["high","xhigh"],ne={goals:!0,js_repl:!1};let se=[];const ie=1e6,le=9e5;export const CODEX_ONE_MILLION_CONTEXT_SETTING="one_million_context";function ae(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function ce(e,t){return ae(e[t])||(e[t]={}),e[t]}function de(){if(!t(q()))return{};const e=n(q(),"utf-8");if(!e.trim())return{};try{const t=c.parse(e);if(!ae(t))throw new Error("config.toml root must be a TOML table");return t}catch(e){throw new Error(`Existing ~/.codex/config.toml cannot be parsed; back it up and fix it first: ${e instanceof Error?e.message:String(e)}`)}}function ue(){if(!t(V()))return{};try{const e=JSON.parse(n(V(),"utf-8"));return ae(e)?e:{}}catch{return{}}}let me=null;function pe(e){const t=e.profiles;if(ae(t)){for(const[e,o]of Object.entries(t))ae(o)&&2===Object.keys(o).length&&o.model_provider===ee&&o.model===e&&delete t[e];0===Object.keys(t).length&&delete e.profiles}}let fe=null;const _e=()=>a(C.getConfigDir(),"codex-catalog-check.json");function ge(e){const o=N();t(o)&&n(o,"utf-8")===e||(m(o),p(o,e))}function xe(t,r){if(0===r.length)return[];const s=function(t,o){const r=e("sha256").update(t);for(const e of o)try{const t=i(e);r.update(`\0${e}\0${t.size}\0${t.mtimeMs}`)}catch{r.update(`\0${e}`)}return r.digest("hex")}(t,r);if(function(e){try{return JSON.parse(n(_e(),"utf-8")).signature===e}catch{return!1}}(s))return[];const a=E(N(),r);return 0===a.length&&function(e){try{o(C.getConfigDir(),{recursive:!0}),l(_e(),JSON.stringify({signature:e})+"\n")}catch(e){d.logError("codexAdapter.rememberAccepted",e)}}(s),a}function he(e,t,o){const r=!1!==t.settings?.one_million_context;!function(e){e.model_context_window===ie&&delete e.model_context_window,e.model_auto_compact_token_limit===le&&delete e.model_auto_compact_token_limit}(e);const n=()=>{e.model_catalog_json===N()&&delete e.model_catalog_json,r&&(e.model_context_window=ie,e.model_auto_compact_token_limit=le)},i=D()??$();if(!i)return d.logError("codexAdapter.writeModelCatalog",new Error("no Codex binary found; model catalog skipped")),fe="skipped",void n();const l=t.catalog,a=e=>A({bundled:e,specs:L("codex",l?.clientModels),...l?{keyModels:l.models}:{},gatewayAvailable:l?.models??I(),oneMillion:r,selectedModel:o,..."gateway"===l?.oneMillionSource?{claudeOneMillion:l.oneMillion}:{}}),c=e=>JSON.stringify(e,null,2)+"\n";let u=a(i);ge(c(u));const m=T(),p=xe(c(u),m);if(p.length>0){const e=Date.now();let t=!1;for(const e of p){const o=D(e.bin);if(o){for(const e of[{models:P(u.models,o)},{models:P(a(o).models,o)}])if(ge(c(e)),0===xe(c(e),m).length){u=e,t=!0;break}if(t)break}}if(M("codex-catalog",t?"fallback":"fail",{duration_ms:Date.now()-e,error:p[0].error,detail:{rejected_by:p.map(e=>({version:e.version,path:O(e.bin)}))}}),!t)return fe={rejectedBy:p[0]},s(N(),{force:!0}),void n()}fe={listed:u.models.filter(e=>"list"===e.visibility).map(e=>({id:String(e.slug),name:String(e.display_name??e.slug)}))},e.model_catalog_json=N()}export function codexCatalogRejection(){let e;try{e=de()}catch{return null}return e.model_catalog_json===N()&&t(N())?E(N())[0]??null:null}export function setCodexOneMillionContext(e,t){const o=de(),r=c.stringify(o),n="string"==typeof o.model?o.model:j("codex");he(o,{settings:{[CODEX_ONE_MILLION_CONTEXT_SETTING]:e},catalog:t},n);const s=c.stringify(o);s!==r&&(m(q()),p(q(),s))}const ye={command:"codex",npmPackage:"@openai/codex",native:{binDir:"win32"===process.platform?["AppData","Local","Programs","OpenAI","Codex","bin"]:[".local","bin"],updateArgs:["update"],updateTimeoutMs:12e4,dataDirs:[[".codex","packages","standalone"]]},mirrorScript:B("codex"),brew:"codex"};function ke(e){const t=ae(e.model_providers)?e.model_providers[ee]:void 0;if(!ae(t))return null;const o="string"==typeof t.base_url?t.base_url.trim():"";return o&&!G(o)?o:null}let be=null;function ve(){if("skipped"===fe)return 0===K(ye).length?[]:[{kind:"action",text:u.t("tools.codex.catalog_skipped")}];if(!fe)return[];if("rejectedBy"in fe){const{bin:e,version:t}=fe.rejectedBy;return[{kind:"action",text:u.t("tools.codex.catalog_rejected",{path:e,version:t??"?"})}]}const e=new Map;for(const t of fe.listed)e.set(J(t.id),(e.get(J(t.id))??0)+1);const t=["gpt","claude","gemini","other","grok"].filter(t=>e.has(t)).map(t=>`${u.t(`tools.model_family.${t}`)} ${e.get(t)}`).join(" · ");return[{kind:"summary",text:u.t("tools.codex.catalog_written",{count:String(fe.listed.length),breakdown:t})},{kind:"detail",text:fe.listed.map(e=>e.name).join(", ")},...codexWorkModeOn()||Q()?[{kind:"action",text:u.t(codexWorkModeOn()?"tools.codex.work_mode_on":"tools.codex.work_mode_hint")}]:[]]}export const codexAdapter={name:"codex",companionApps:[U],displayName:"Codex",command:"codex",installCommand:X(ye),installSpec:ye,configPath:q(),sessions:{format:b,files:()=>[...v(a(f(),"sessions")),...v(a(f(),"archived_sessions"))],resumeCommand:e=>({command:"codex",args:["resume",e]})},wantsModelCatalog:!0,listedModels(){if(de().model_catalog_json!==N())return null;try{return(JSON.parse(n(N(),"utf-8")).models??[]).filter(e=>"list"===e.visibility).map(e=>String(e.slug))}catch{return null}},refreshModelMenu(e){if(de().model_catalog_json!==N())return;setCodexOneMillionContext(!1!==e.settings?.one_million_context,e.catalog);const t=de(),o=function(e,t){const o=ae(e.model_providers)?e.model_providers[ee]:void 0;return!(!ae(o)||o.base_url!==t||!0===o.supports_standalone_web_search||(o.supports_standalone_web_search=!0,0))}(t,x(e.baseUrl));(H(t)||o)&&(m(q()),p(q(),c.stringify(t)))},async followUp(){if(de().model_provider!==ee)return null;const e=await h(ee,{dryRun:!0}),t=Math.max(e.moved.length,e.dbRows);if(0===t)return null;const o=C.getToolSettings("codex")[z];if("number"==typeof o&&t<=o)return null;const r={count:String(t)};return k().length>0?{hint:u.t("tools.codex.sessions_hidden_running",r)}:{prompt:u.t("tools.codex.sessions_offer",r),hint:u.t("tools.codex.sessions_hidden",r),async run(){const e=await h(ee),t=[...new Set(e.moved.map(e=>e.from))].join("、")||"-",o=String(Math.max(e.moved.length,e.dbRows)),r=[{kind:"summary",text:u.t("codex_sessions.moved",{count:o,from:t,target:ee})},{kind:"summary",text:u.t("codex_sessions.backup",{dir:e.backupDir??""})}];return e.dbSkipped&&e.dbSkipped!==y&&r.push({kind:"action",text:u.t("codex_sessions.db_skipped",{reason:e.dbSkipped})}),r},decline(){C.setToolSetting("codex",z,t)}}},applyNotes(){const e=[];return be&&e.push({kind:"summary",text:u.t("tools.codex.provider_replaced",{url:be})}),se.length>0&&e.push({kind:"summary",text:u.t("tools.codex.kept_user_settings",{values:se.join(", ")})}),[...e,...ve()]},planNotes(){let e;try{e=de()}catch{return[]}const t=[],o=ke(e);return o?t.push(u.t("tools.codex.plan_replace_provider",{url:o})):"string"==typeof e.model_provider&&e.model_provider!==ee&&t.push(u.t("tools.codex.plan_switch_provider",{provider:e.model_provider})),t},loadPrivateConfig(e){const t=j("codex"),o=_(e.models,t),r=function(e){return/(?:^|\/)claude(?:-|$)/i.test(e)}(o)?t:o,n=x(e.baseUrl),s=de();se=[];const i=w().retired,l="string"==typeof s.model&&i.includes(s.model)?void 0:s.model;S("codex.model",l,r,{explicit:r!==t,legacy:oe})?s.model=r:se.push(`model = ${String(s.model)}`),s.model_provider=ee,S("codex.model_reasoning_effort",s.model_reasoning_effort,te,{legacy:re})?s.model_reasoning_effort=te:se.push(`model_reasoning_effort = ${String(s.model_reasoning_effort)}`);const a="string"==typeof s.model?s.model:r;he(s,e,a);const d=ce(s,"model_providers");be=ke(s),R(n);const u=ae(d[ee])?{...d[ee]}:{};delete u.env_key;const{experimental_bearer_token:f,...g}=u;d[ee]={...g,name:"custom",wire_api:"responses",requires_openai_auth:!0,supports_standalone_web_search:!0,base_url:n},pe(s),ce(ce(s,"tui"),"model_availability_nux")[a]=4;const h=ce(s,"features");for(const[e,t]of Object.entries(ne))(S(`codex.features.${e}`,h[e],String(t),{legacy:[String(t)]})||h[e]===t)&&(h[e]=t);H(s),m(q()),p(q(),c.stringify(s)),function(e){const t=e.trim();if(!t)return;const o={...ue(),auth_mode:"apikey",[Z]:t};m(V()),p(V(),JSON.stringify(o,null,2)+"\n",384)}(e.apiKey)},holdsOurConfig(e){const t=ue()[Z];return"string"==typeof t&&e.includes(t.trim())},unloadPrivateConfig(e){if(me=function(e){const t=ue(),o="string"==typeof t[Z]?t[Z].trim():"";if(!o)return ae(t.tokens)?"chatgpt":null;if(!e.includes(o))return"other_key";const{[Z]:r,auth_mode:n,...i}=t;return m(V()),ae(i.tokens)?(p(V(),JSON.stringify({...i,auth_mode:"chatgpt"},null,2)+"\n",384),"chatgpt"):(s(V(),{force:!0}),"signed_out")}(e?.savedKeys??[]),!t(q()))return;let o;try{o=de()}catch(e){return void d.logError("codexAdapter.unloadPrivateConfig",e)}const r=o.model_providers;ae(r)&&ae(r[ee])&&G(r[ee].base_url)&&ae(r)&&(delete r[ee],0===Object.keys(r).length&&delete o.model_providers,o.model_provider===ee&&delete o.model_provider),o.model_catalog_json===N()&&delete o.model_catalog_json,H(o),pe(o),m(q()),p(q(),c.stringify(o))},unloadNotes(){switch(me){case"chatgpt":return[{kind:"action",text:u.t("tools.codex.unload_chatgpt_restored")}];case"other_key":return[{kind:"action",text:u.t("tools.codex.unload_other_key")}];default:return[{kind:"action",text:u.t("tools.codex.unload_sign_in")}]}},detectCurrentConfig(){const e=ue()[Z];return{apiKey:"string"==typeof e&&e.trim()?e.trim():null}},getConfig(){try{return de()}catch(e){return d.logError("codexAdapter.getConfig",e),null}},backupPaths:()=>[q(),V(),N()]};export function codexAuthProblem(){try{const e=de(),t=e.model_providers?.[ee];if(e.model_provider!==ee||!t)return null;if("string"==typeof t.experimental_bearer_token&&t.experimental_bearer_token)return"stale_bearer";const o=ue();return!0===t.requires_openai_auth&&"chatgpt"===o.auth_mode?"chatgpt_login":null}catch{return 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})}}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as e}from"child_process";import{logger as t}from"../../utils/logger.js";import{powerShellEnv as r}from"../powershell-env.js";export const WINDOWS_PACKAGE_FAMILIES=["Claude_pzs8sxrjxfjjc","AnthropicPBC.Claude_fnn82j28hfe8t"];const o="Get-Process -Name claude -ErrorAction SilentlyContinue | Where-Object { $_.Path -and ($_.Path -like '*\\AnthropicClaude\\*' -or $_.Path -like '*\\Programs\\Claude\\*' -or $_.Path -like '*\\WindowsApps\\*Claude*') }";let s=(o,s,n=3e4)=>{const i=e(o,s,{encoding:"utf-8",timeout:n,windowsHide:!0,stdio:["ignore","pipe","pipe"],env:r()});return i.error&&t.logError(`desktop-process: ${o}`,i.error),{status:i.status,stdout:`${i.stdout??""}`}};export function setDesktopProcessRunnerForTests(e){s=e}function n(e,t){return s("powershell.exe",["-NoProfile","-NonInteractive","-Command",e],t)}function i(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}export function isDesktopRunning(){return"darwin"===process.platform?0===s("pgrep",["-x","Claude"]).status:"win32"===process.platform&&Number(n(`@(${o}).Count`).stdout.trim())>0}export function canRestartDesktop(){return"darwin"===process.platform||"win32"===process.platform}export function quitDesktop(){if("darwin"===process.platform){s("osascript",["-e",'quit app "Claude"']);for(let e=0;e<30&&isDesktopRunning();e++)i(500);isDesktopRunning()&&s("pkill",["-x","Claude"]),i(1e3)}else{if("win32"!==process.platform)return!1;n([`$p = @(${o})`,"$p | ForEach-Object { [void]$_.CloseMainWindow() }","Start-Sleep -Seconds 3","$p | Where-Object { -not $_.HasExited } | Stop-Process -Force -ErrorAction SilentlyContinue","Start-Sleep -Seconds 1"].join("\n"),6e4)}return!isDesktopRunning()}export function launchDesktop(){if("darwin"===process.platform)s("open",["-a","Claude"]);else{if("win32"!==process.platform)return!1;n(["$squirrel = Join-Path $env:LOCALAPPDATA 'AnthropicClaude\\claude.exe'","$programs = Join-Path $env:LOCALAPPDATA 'Programs\\Claude\\Claude.exe'","if (Test-Path $squirrel) { Start-Process $squirrel }","elseif (Test-Path $programs) { Start-Process $programs }",`else { $pkg = Get-AppxPackage | Where-Object { @(${WINDOWS_PACKAGE_FAMILIES.map(e=>`'${e}'`).join(",")}) -contains $_.PackageFamilyName } | Select-Object -First 1`," if ($pkg) { $id = (Get-AppxPackageManifest $pkg).Package.Applications.Application.Id | Select-Object -First 1",' Start-Process "shell:AppsFolder\\$($pkg.PackageFamilyName)!$id" } }'].join("\n"),6e4)}for(let e=0;e<20;e++){if(isDesktopRunning())return!0;i(500)}return!1}export function restartDesktop(){return!!canRestartDesktop()
|
|
1
|
+
import{spawnSync as e}from"child_process";import{logger as t}from"../../utils/logger.js";import{powerShellEnv as r}from"../powershell-env.js";export const WINDOWS_PACKAGE_FAMILIES=["Claude_pzs8sxrjxfjjc","AnthropicPBC.Claude_fnn82j28hfe8t"];const o="Get-Process -Name claude -ErrorAction SilentlyContinue | Where-Object { $_.Path -and ($_.Path -like '*\\AnthropicClaude\\*' -or $_.Path -like '*\\Programs\\Claude\\*' -or $_.Path -like '*\\WindowsApps\\*Claude*') }";let s=(o,s,n=3e4)=>{const i=e(o,s,{encoding:"utf-8",timeout:n,windowsHide:!0,stdio:["ignore","pipe","pipe"],env:r()});return i.error&&t.logError(`desktop-process: ${o}`,i.error),{status:i.status,stdout:`${i.stdout??""}`,stderr:`${i.stderr??""}`}};export function setDesktopProcessRunnerForTests(e){s=e}function n(e,t){return s("powershell.exe",["-NoProfile","-NonInteractive","-Command",e],t)}function i(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}export function isDesktopRunning(){return"darwin"===process.platform?0===s("pgrep",["-x","Claude"]).status:"win32"===process.platform&&Number(n(`@(${o}).Count`).stdout.trim())>0}export function canRestartDesktop(){return"darwin"===process.platform||"win32"===process.platform}let a=!1;export function desktopQuitRefused(){return a}export function quitDesktop(){if(a=!1,"darwin"===process.platform){const e=s("osascript",["-e",'quit app "Claude"']);if((null===e.status||/\(-128\)|-1712/.test(e.stderr??""))&&isDesktopRunning())return a=!0,!1;for(let e=0;e<30&&isDesktopRunning();e++)i(500);isDesktopRunning()&&s("pkill",["-x","Claude"]),i(1e3)}else{if("win32"!==process.platform)return!1;n([`$p = @(${o})`,"$p | ForEach-Object { [void]$_.CloseMainWindow() }","Start-Sleep -Seconds 3","$p | Where-Object { -not $_.HasExited } | Stop-Process -Force -ErrorAction SilentlyContinue","Start-Sleep -Seconds 1"].join("\n"),6e4)}return!isDesktopRunning()}export function launchDesktop(){if("darwin"===process.platform)s("open",["-a","Claude"]);else{if("win32"!==process.platform)return!1;n(["$squirrel = Join-Path $env:LOCALAPPDATA 'AnthropicClaude\\claude.exe'","$programs = Join-Path $env:LOCALAPPDATA 'Programs\\Claude\\Claude.exe'","if (Test-Path $squirrel) { Start-Process $squirrel }","elseif (Test-Path $programs) { Start-Process $programs }",`else { $pkg = Get-AppxPackage | Where-Object { @(${WINDOWS_PACKAGE_FAMILIES.map(e=>`'${e}'`).join(",")}) -contains $_.PackageFamilyName } | Select-Object -First 1`," if ($pkg) { $id = (Get-AppxPackageManifest $pkg).Package.Applications.Application.Id | Select-Object -First 1",' Start-Process "shell:AppsFolder\\$($pkg.PackageFamilyName)!$id" } }'].join("\n"),6e4)}for(let e=0;e<20;e++){if(isDesktopRunning())return!0;i(500)}return!1}export function restartDesktop(){return!!canRestartDesktop()&&!(!quitDesktop()&&a)&&launchDesktop()}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as t}from"child_process";import{existsSync as
|
|
1
|
+
import{spawnSync as t}from"child_process";import{existsSync as n,realpathSync as r,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 n=m().installMirror?.scripts;return n?{sh:`${n}/${t}.sh`,ps1:`${n}/${t}.ps1`}:void 0}export function npmMirrorInstallCommand(t,n="latest"){return`npm install -g ${t.npmPackage}@${n} --registry=${NPM_MIRROR}`}const l=/^(\d+)\.(\d+)\.(\d+)$/;function u(t,n){const r=l.exec(t).slice(1).map(Number),e=l.exec(n).slice(1).map(Number);for(let o=0;o<3;o++)if(r[o]!==e[o])return r[o]>e[o]?t:n;return t}async function f(t,n,r){const e=await fetch(t,{signal:AbortSignal.timeout(n),headers:r});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 n=d.get(t.npmPackage);return n||d.set(t.npmPackage,n=async function(t){try{const{version:n}=await f(`https://registry.npmjs.org/${t}/latest`,1e4);if("string"==typeof n&&l.test(n))return n}catch{}try{const n=await f(`${NPM_MIRROR}/${t}`,2e4,{accept:"application/vnd.npm.install-v1+json"}),r=Object.keys(n.versions??{}).filter(t=>l.test(t));if(r.length)return r.reduce(u)}catch{}return"latest"}(t.npmPackage)),n}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 h=n=>{const r={encoding:"utf-8",timeout:1e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]};return`${(/\.cmd$/i.test(n)?t(`"${n}" --version`,{...r,shell:!0}):t(n,["--version"],r)).stdout??""}`};const g=new Map;export function setVersionRunnerForTests(t){h=t,g.clear(),d.clear()}export function forgetInstalls(){g.clear()}function $(t,n){return"win32"===process.platform?t.toLowerCase()===n.toLowerCase():t===n}function w(t){try{return e(t).isFile()}catch{return!1}}function v(t,e){if(t.native&&$(s(e),a(p(),...t.native.binDir)))return"native";const o=t.npmPackage?a("node_modules",...t.npmPackage.split("/")):null;if(o&&n(a(s(e),o)))return"npm";let i=e;try{i=r(e)}catch{return"other"}return o&&i.includes(o)?"npm":/[\\/](Cellar|Caskroom)[\\/]/.test(i)?"brew":"other"}export function findInstalls(t){const n=g.get(t.command);if(n)return n;const e="win32"===process.platform?[`${t.command}.exe`,`${t.command}.cmd`]:[t.command],s=new Set,c=[];for(const n of(process.env.PATH??"").split(o))if(n&&i(n))for(const o of e){const e=a(n,o);if(!w(e))continue;let i=e;try{i=r(e)}catch{}const p="win32"===process.platform?i.toLowerCase():i;if(s.has(p))continue;s.add(p);const m=h(e).match(/(\d+)\.(\d+)\.(\d+)/);c.push({path:e,kind:v(t,e),version:m?m[0]:null})}return g.set(t.command,c),c}export function findInstallsIncludingNative(t){const n=findInstalls(t).map(t=>({...t,onPath:!0}));if(!t.native)return n;const r=a(p(),...t.native.binDir),e="win32"===process.platform?[`${t.command}.exe`]:[t.command];for(const t of e){const e=a(r,t);if(!w(e)||n.some(t=>$(t.path,e)))continue;const o=h(e).match(/(\d+)\.(\d+)\.(\d+)/);n.push({path:e,kind:"native",version:o?o[0]:null,onPath:!1})}return n}
|