ccjk 12.0.7 → 12.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/dist/chunks/agent-teams.mjs +0 -136
- package/dist/chunks/agent.mjs +0 -1439
- package/dist/chunks/agents.mjs +0 -3778
- package/dist/chunks/api-cli.mjs +0 -132
- package/dist/chunks/api-providers.mjs +0 -129
- package/dist/chunks/api.mjs +0 -112
- package/dist/chunks/auto-bootstrap.mjs +0 -358
- package/dist/chunks/auto-init.mjs +0 -7584
- package/dist/chunks/auto-updater.mjs +0 -410
- package/dist/chunks/banner.mjs +0 -188
- package/dist/chunks/bash.mjs +0 -187
- package/dist/chunks/boost.mjs +0 -397
- package/dist/chunks/ccjk-agents.mjs +0 -414
- package/dist/chunks/ccjk-all.mjs +0 -1028
- package/dist/chunks/ccjk-config.mjs +0 -261
- package/dist/chunks/ccjk-hooks.mjs +0 -1074
- package/dist/chunks/ccjk-mcp.mjs +0 -761
- package/dist/chunks/ccjk-setup.mjs +0 -763
- package/dist/chunks/ccjk-skills.mjs +0 -514
- package/dist/chunks/ccr.mjs +0 -98
- package/dist/chunks/ccu.mjs +0 -40
- package/dist/chunks/check-updates.mjs +0 -108
- package/dist/chunks/claude-code-config-manager.mjs +0 -750
- package/dist/chunks/claude-code-incremental-manager.mjs +0 -623
- package/dist/chunks/claude-config.mjs +0 -236
- package/dist/chunks/claude-wrapper.mjs +0 -85
- package/dist/chunks/cleanup-migration.mjs +0 -20
- package/dist/chunks/cli-hook.mjs +0 -2285
- package/dist/chunks/cloud-sync.mjs +0 -29
- package/dist/chunks/codex-config-switch.mjs +0 -451
- package/dist/chunks/codex-provider-manager.mjs +0 -236
- package/dist/chunks/codex-uninstaller.mjs +0 -404
- package/dist/chunks/codex.mjs +0 -2077
- package/dist/chunks/commands.mjs +0 -108
- package/dist/chunks/commands2.mjs +0 -413
- package/dist/chunks/commit.mjs +0 -138
- package/dist/chunks/completion.mjs +0 -515
- package/dist/chunks/config-consolidator.mjs +0 -172
- package/dist/chunks/config-switch.mjs +0 -317
- package/dist/chunks/config.mjs +0 -379
- package/dist/chunks/config2.mjs +0 -477
- package/dist/chunks/config3.mjs +0 -470
- package/dist/chunks/constants.mjs +0 -133
- package/dist/chunks/context-loader.mjs +0 -343
- package/dist/chunks/context.mjs +0 -372
- package/dist/chunks/convoy-manager.mjs +0 -880
- package/dist/chunks/dashboard.mjs +0 -476
- package/dist/chunks/doctor.mjs +0 -964
- package/dist/chunks/evolution.mjs +0 -382
- package/dist/chunks/features.mjs +0 -698
- package/dist/chunks/fish.mjs +0 -181
- package/dist/chunks/fs-operations.mjs +0 -192
- package/dist/chunks/health-alerts.mjs +0 -304
- package/dist/chunks/health-check.mjs +0 -532
- package/dist/chunks/help.mjs +0 -340
- package/dist/chunks/hook-installer.mjs +0 -45
- package/dist/chunks/index.mjs +0 -24
- package/dist/chunks/index10.mjs +0 -1171
- package/dist/chunks/index11.mjs +0 -1008
- package/dist/chunks/index12.mjs +0 -193
- package/dist/chunks/index13.mjs +0 -218
- package/dist/chunks/index14.mjs +0 -663
- package/dist/chunks/index2.mjs +0 -19
- package/dist/chunks/index3.mjs +0 -19092
- package/dist/chunks/index4.mjs +0 -8
- package/dist/chunks/index5.mjs +0 -7600
- package/dist/chunks/index6.mjs +0 -171
- package/dist/chunks/index7.mjs +0 -3583
- package/dist/chunks/index8.mjs +0 -19
- package/dist/chunks/index9.mjs +0 -616
- package/dist/chunks/init.mjs +0 -1606
- package/dist/chunks/installer.mjs +0 -690
- package/dist/chunks/installer2.mjs +0 -179
- package/dist/chunks/interview.mjs +0 -2927
- package/dist/chunks/json-config.mjs +0 -60
- package/dist/chunks/linux.mjs +0 -3863
- package/dist/chunks/macos.mjs +0 -69
- package/dist/chunks/main.mjs +0 -635
- package/dist/chunks/manager.mjs +0 -1048
- package/dist/chunks/marketplace.mjs +0 -949
- package/dist/chunks/mcp-cli.mjs +0 -204
- package/dist/chunks/mcp-performance.mjs +0 -187
- package/dist/chunks/mcp.mjs +0 -1231
- package/dist/chunks/menu.mjs +0 -652
- package/dist/chunks/metrics-display.mjs +0 -153
- package/dist/chunks/migrator.mjs +0 -178
- package/dist/chunks/monitor.mjs +0 -1856
- package/dist/chunks/notification.mjs +0 -1864
- package/dist/chunks/onboarding.mjs +0 -385
- package/dist/chunks/package.mjs +0 -3
- package/dist/chunks/paradigm.mjs +0 -74
- package/dist/chunks/permission-manager.mjs +0 -132
- package/dist/chunks/permissions.mjs +0 -265
- package/dist/chunks/persistence-manager.mjs +0 -794
- package/dist/chunks/persistence.mjs +0 -667
- package/dist/chunks/platform.mjs +0 -391
- package/dist/chunks/plugin.mjs +0 -1936
- package/dist/chunks/powershell.mjs +0 -213
- package/dist/chunks/prompts.mjs +0 -241
- package/dist/chunks/providers.mjs +0 -260
- package/dist/chunks/quick-actions.mjs +0 -320
- package/dist/chunks/quick-provider.mjs +0 -682
- package/dist/chunks/quick-setup.mjs +0 -412
- package/dist/chunks/remote.mjs +0 -497
- package/dist/chunks/session.mjs +0 -878
- package/dist/chunks/sessions.mjs +0 -106
- package/dist/chunks/silent-updater.mjs +0 -396
- package/dist/chunks/simple-config.mjs +0 -98
- package/dist/chunks/skill.mjs +0 -117
- package/dist/chunks/skill2.mjs +0 -9003
- package/dist/chunks/skills-sync.mjs +0 -6460
- package/dist/chunks/skills.mjs +0 -567
- package/dist/chunks/slash-commands.mjs +0 -207
- package/dist/chunks/smart-defaults.mjs +0 -412
- package/dist/chunks/smart-guide.mjs +0 -194
- package/dist/chunks/startup.mjs +0 -487
- package/dist/chunks/stats.mjs +0 -410
- package/dist/chunks/status.mjs +0 -289
- package/dist/chunks/team.mjs +0 -63
- package/dist/chunks/thinking.mjs +0 -626
- package/dist/chunks/trace.mjs +0 -57
- package/dist/chunks/uninstall.mjs +0 -849
- package/dist/chunks/update.mjs +0 -167
- package/dist/chunks/upgrade-manager.mjs +0 -204
- package/dist/chunks/version-checker.mjs +0 -881
- package/dist/chunks/vim.mjs +0 -903
- package/dist/chunks/windows.mjs +0 -14
- package/dist/chunks/workflows.mjs +0 -633
- package/dist/chunks/wsl.mjs +0 -129
- package/dist/chunks/zero-config.mjs +0 -374
- package/dist/chunks/zsh.mjs +0 -182
- package/dist/cli.d.mts +0 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.mjs +0 -2199
- package/dist/i18n/locales/en/agent-teams.json +0 -18
- package/dist/i18n/locales/en/agentBrowser.json +0 -79
- package/dist/i18n/locales/en/agents.json +0 -135
- package/dist/i18n/locales/en/api.json +0 -63
- package/dist/i18n/locales/en/ccjk-agents.json +0 -33
- package/dist/i18n/locales/en/ccjk-all.json +0 -23
- package/dist/i18n/locales/en/ccjk-skills.json +0 -22
- package/dist/i18n/locales/en/ccjk.json +0 -276
- package/dist/i18n/locales/en/ccr.json +0 -65
- package/dist/i18n/locales/en/claude-md.json +0 -73
- package/dist/i18n/locales/en/cli.json +0 -152
- package/dist/i18n/locales/en/cloud-setup.json +0 -31
- package/dist/i18n/locales/en/cloud-sync.json +0 -147
- package/dist/i18n/locales/en/cloud.json +0 -40
- package/dist/i18n/locales/en/cloudPlugins.json +0 -118
- package/dist/i18n/locales/en/codex.json +0 -127
- package/dist/i18n/locales/en/cometix.json +0 -29
- package/dist/i18n/locales/en/common.json +0 -68
- package/dist/i18n/locales/en/config.json +0 -108
- package/dist/i18n/locales/en/configuration.json +0 -226
- package/dist/i18n/locales/en/context.json +0 -85
- package/dist/i18n/locales/en/dashboard.json +0 -78
- package/dist/i18n/locales/en/errors.json +0 -26
- package/dist/i18n/locales/en/evolution.json +0 -54
- package/dist/i18n/locales/en/hooks.json +0 -74
- package/dist/i18n/locales/en/hooksSync.json +0 -133
- package/dist/i18n/locales/en/installation.json +0 -83
- package/dist/i18n/locales/en/interview.json +0 -104
- package/dist/i18n/locales/en/language.json +0 -19
- package/dist/i18n/locales/en/lsp.json +0 -78
- package/dist/i18n/locales/en/marketplace.json +0 -116
- package/dist/i18n/locales/en/mcp.json +0 -178
- package/dist/i18n/locales/en/memory.json +0 -92
- package/dist/i18n/locales/en/menu.json +0 -143
- package/dist/i18n/locales/en/multi-config.json +0 -79
- package/dist/i18n/locales/en/notification.json +0 -307
- package/dist/i18n/locales/en/permissions.json +0 -95
- package/dist/i18n/locales/en/persistence.json +0 -127
- package/dist/i18n/locales/en/plugins.json +0 -146
- package/dist/i18n/locales/en/quick-actions.json +0 -78
- package/dist/i18n/locales/en/registry.json +0 -54
- package/dist/i18n/locales/en/remote.json +0 -93
- package/dist/i18n/locales/en/sandbox.json +0 -44
- package/dist/i18n/locales/en/setup.json +0 -44
- package/dist/i18n/locales/en/shencha.json +0 -14
- package/dist/i18n/locales/en/skills.json +0 -100
- package/dist/i18n/locales/en/skillsSync.json +0 -74
- package/dist/i18n/locales/en/smartGuide.json +0 -49
- package/dist/i18n/locales/en/stats.json +0 -20
- package/dist/i18n/locales/en/subagent.json +0 -69
- package/dist/i18n/locales/en/superpowers.json +0 -117
- package/dist/i18n/locales/en/team.json +0 -7
- package/dist/i18n/locales/en/thinking.json +0 -65
- package/dist/i18n/locales/en/tools.json +0 -42
- package/dist/i18n/locales/en/uninstall.json +0 -56
- package/dist/i18n/locales/en/updater.json +0 -29
- package/dist/i18n/locales/en/vim.json +0 -169
- package/dist/i18n/locales/en/workflow.json +0 -55
- package/dist/i18n/locales/en/workspace.json +0 -108
- package/dist/i18n/locales/zh-CN/agent-teams.json +0 -18
- package/dist/i18n/locales/zh-CN/agentBrowser.json +0 -79
- package/dist/i18n/locales/zh-CN/agents.json +0 -135
- package/dist/i18n/locales/zh-CN/api.json +0 -63
- package/dist/i18n/locales/zh-CN/ccjk-agents.json +0 -33
- package/dist/i18n/locales/zh-CN/ccjk-all.json +0 -23
- package/dist/i18n/locales/zh-CN/ccjk-skills.json +0 -22
- package/dist/i18n/locales/zh-CN/ccjk.json +0 -276
- package/dist/i18n/locales/zh-CN/ccr.json +0 -65
- package/dist/i18n/locales/zh-CN/claude-md.json +0 -73
- package/dist/i18n/locales/zh-CN/cli.json +0 -152
- package/dist/i18n/locales/zh-CN/cloud-setup.json +0 -31
- package/dist/i18n/locales/zh-CN/cloud-sync.json +0 -147
- package/dist/i18n/locales/zh-CN/cloud.json +0 -40
- package/dist/i18n/locales/zh-CN/cloudPlugins.json +0 -118
- package/dist/i18n/locales/zh-CN/codex.json +0 -127
- package/dist/i18n/locales/zh-CN/cometix.json +0 -29
- package/dist/i18n/locales/zh-CN/common.json +0 -68
- package/dist/i18n/locales/zh-CN/config.json +0 -108
- package/dist/i18n/locales/zh-CN/configuration.json +0 -224
- package/dist/i18n/locales/zh-CN/context.json +0 -85
- package/dist/i18n/locales/zh-CN/dashboard.json +0 -78
- package/dist/i18n/locales/zh-CN/errors.json +0 -26
- package/dist/i18n/locales/zh-CN/evolution.json +0 -54
- package/dist/i18n/locales/zh-CN/hooks.json +0 -74
- package/dist/i18n/locales/zh-CN/hooksSync.json +0 -133
- package/dist/i18n/locales/zh-CN/installation.json +0 -83
- package/dist/i18n/locales/zh-CN/interview.json +0 -104
- package/dist/i18n/locales/zh-CN/language.json +0 -19
- package/dist/i18n/locales/zh-CN/lsp.json +0 -78
- package/dist/i18n/locales/zh-CN/marketplace.json +0 -116
- package/dist/i18n/locales/zh-CN/mcp.json +0 -178
- package/dist/i18n/locales/zh-CN/memory.json +0 -92
- package/dist/i18n/locales/zh-CN/menu.json +0 -143
- package/dist/i18n/locales/zh-CN/multi-config.json +0 -79
- package/dist/i18n/locales/zh-CN/notification.json +0 -307
- package/dist/i18n/locales/zh-CN/permissions.json +0 -95
- package/dist/i18n/locales/zh-CN/persistence.json +0 -127
- package/dist/i18n/locales/zh-CN/plugins.json +0 -146
- package/dist/i18n/locales/zh-CN/quick-actions.json +0 -78
- package/dist/i18n/locales/zh-CN/registry.json +0 -54
- package/dist/i18n/locales/zh-CN/remote.json +0 -93
- package/dist/i18n/locales/zh-CN/sandbox.json +0 -44
- package/dist/i18n/locales/zh-CN/setup.json +0 -44
- package/dist/i18n/locales/zh-CN/shencha.json +0 -14
- package/dist/i18n/locales/zh-CN/skills.json +0 -100
- package/dist/i18n/locales/zh-CN/skillsSync.json +0 -74
- package/dist/i18n/locales/zh-CN/smartGuide.json +0 -49
- package/dist/i18n/locales/zh-CN/stats.json +0 -20
- package/dist/i18n/locales/zh-CN/subagent.json +0 -69
- package/dist/i18n/locales/zh-CN/superpowers.json +0 -117
- package/dist/i18n/locales/zh-CN/team.json +0 -7
- package/dist/i18n/locales/zh-CN/thinking.json +0 -65
- package/dist/i18n/locales/zh-CN/tools.json +0 -42
- package/dist/i18n/locales/zh-CN/uninstall.json +0 -56
- package/dist/i18n/locales/zh-CN/updater.json +0 -29
- package/dist/i18n/locales/zh-CN/vim.json +0 -169
- package/dist/i18n/locales/zh-CN/workflow.json +0 -55
- package/dist/i18n/locales/zh-CN/workspace.json +0 -108
- package/dist/index.d.mts +0 -5295
- package/dist/index.d.ts +0 -5295
- package/dist/index.mjs +0 -4941
- package/dist/shared/ccjk.B364Fu0N.mjs +0 -1819
- package/dist/shared/ccjk.BAGoDD49.mjs +0 -36
- package/dist/shared/ccjk.BBtCGd_g.mjs +0 -899
- package/dist/shared/ccjk.BFQ7yr5S.mjs +0 -16
- package/dist/shared/ccjk.BFxsJM0k.mjs +0 -599
- package/dist/shared/ccjk.BIxuVL3_.mjs +0 -25
- package/dist/shared/ccjk.BRZ9ww8S.mjs +0 -142
- package/dist/shared/ccjk.BoApaI4j.mjs +0 -28
- package/dist/shared/ccjk.BrPUmTqm.mjs +0 -266
- package/dist/shared/ccjk.BtB1e5jm.mjs +0 -171
- package/dist/shared/ccjk.BwfbSKN2.mjs +0 -1051
- package/dist/shared/ccjk.BxSmJ8B7.mjs +0 -243
- package/dist/shared/ccjk.Bx_rmYfN.mjs +0 -69
- package/dist/shared/ccjk.C2jHOZVP.mjs +0 -52
- package/dist/shared/ccjk.CL4Yat0G.mjs +0 -303
- package/dist/shared/ccjk.COweQ1RR.mjs +0 -5
- package/dist/shared/ccjk.CePkJq2S.mjs +0 -223
- package/dist/shared/ccjk.CfKKcvWy.mjs +0 -126
- package/dist/shared/ccjk.Cjgrln_h.mjs +0 -297
- package/dist/shared/ccjk.Cjj8SVrn.mjs +0 -54
- package/dist/shared/ccjk.CxpGa6MC.mjs +0 -2724
- package/dist/shared/ccjk.D5MFQT7w.mjs +0 -400
- package/dist/shared/ccjk.D6ycHbak.mjs +0 -270
- package/dist/shared/ccjk.D8ZLYSZZ.mjs +0 -299
- package/dist/shared/ccjk.DG_o24cZ.mjs +0 -88
- package/dist/shared/ccjk.DLLw-h4Y.mjs +0 -460
- package/dist/shared/ccjk.DOwtZMk8.mjs +0 -4019
- package/dist/shared/ccjk.DS7UESmF.mjs +0 -2451
- package/dist/shared/ccjk.DTdjs-qK.mjs +0 -1447
- package/dist/shared/ccjk.DXRAZcix.mjs +0 -66
- package/dist/shared/ccjk.DsYaCCx4.mjs +0 -317
- package/dist/shared/ccjk.J8YiPsOw.mjs +0 -259
- package/dist/shared/ccjk.KfSWcGlE.mjs +0 -38
- package/dist/shared/ccjk.RyizuzOI.mjs +0 -21
- package/dist/shared/ccjk.SPoXMvZD.mjs +0 -1242
- package/dist/shared/ccjk.T_cX87dY.mjs +0 -15
- package/dist/shared/ccjk.UIvifqNE.mjs +0 -1486
- package/dist/shared/ccjk._dESH4Rk.mjs +0 -111
- package/dist/shared/ccjk.bQ7Dh1g4.mjs +0 -249
- package/dist/shared/ccjk.c-ETfBZ_.mjs +0 -617
- package/dist/shared/ccjk.gDEDGD_t.mjs +0 -38
- package/dist/shared/ccjk.hoqrwWdN.mjs +0 -333
- package/dist/shared/ccjk.waa2ikKJ.mjs +0 -351
|
@@ -1,881 +0,0 @@
|
|
|
1
|
-
import { exec } from 'node:child_process';
|
|
2
|
-
import * as fs from 'node:fs';
|
|
3
|
-
import * as path from 'node:path';
|
|
4
|
-
import process__default from 'node:process';
|
|
5
|
-
import { promisify } from 'node:util';
|
|
6
|
-
import { s as semverExports } from '../shared/ccjk.CxpGa6MC.mjs';
|
|
7
|
-
import { g as getPlatform, f as findCommandPath, a as getHomebrewCommandPaths } from './platform.mjs';
|
|
8
|
-
import '../shared/ccjk.BAGoDD49.mjs';
|
|
9
|
-
import 'node:os';
|
|
10
|
-
import './main.mjs';
|
|
11
|
-
import 'module';
|
|
12
|
-
import 'node:stream';
|
|
13
|
-
import 'node:readline';
|
|
14
|
-
import '../shared/ccjk.bQ7Dh1g4.mjs';
|
|
15
|
-
|
|
16
|
-
function getHome() {
|
|
17
|
-
return process__default.env.HOME || process__default.env.USERPROFILE || "";
|
|
18
|
-
}
|
|
19
|
-
const INSTALLATION_SOURCES = [
|
|
20
|
-
// ==================== macOS Sources ====================
|
|
21
|
-
{
|
|
22
|
-
type: "homebrew-cask",
|
|
23
|
-
name: "Homebrew Cask",
|
|
24
|
-
priority: 100,
|
|
25
|
-
// Highest priority on macOS
|
|
26
|
-
platforms: ["macos"],
|
|
27
|
-
pathPatterns: [
|
|
28
|
-
/\/Caskroom\/claude-code\//,
|
|
29
|
-
/\/opt\/homebrew\/Caskroom\//,
|
|
30
|
-
/\/usr\/local\/Caskroom\//
|
|
31
|
-
],
|
|
32
|
-
commonPaths: [
|
|
33
|
-
"/opt/homebrew/Caskroom/claude-code",
|
|
34
|
-
"/usr/local/Caskroom/claude-code"
|
|
35
|
-
],
|
|
36
|
-
getUpdateCommand: () => ({ command: "brew", args: ["upgrade", "--cask", "claude-code"] }),
|
|
37
|
-
isRecommended: true,
|
|
38
|
-
description: "Official recommended installation method for macOS"
|
|
39
|
-
},
|
|
40
|
-
// ==================== Cross-platform Sources ====================
|
|
41
|
-
{
|
|
42
|
-
type: "curl",
|
|
43
|
-
name: "Official Installer (curl)",
|
|
44
|
-
priority: 90,
|
|
45
|
-
// High priority - official method
|
|
46
|
-
platforms: ["macos", "linux"],
|
|
47
|
-
pathPatterns: [
|
|
48
|
-
// ~/.local/bin/claude (Linux/macOS curl default)
|
|
49
|
-
new RegExp(`${getHome().replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\.local/bin/claude`),
|
|
50
|
-
// ~/.claude/bin/claude (alternative location)
|
|
51
|
-
new RegExp(`${getHome().replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\.claude/`),
|
|
52
|
-
// Generic patterns
|
|
53
|
-
/\.local\/bin\/claude$/,
|
|
54
|
-
/\.claude\/bin\/claude$/,
|
|
55
|
-
/\.claude\/local\/bin\/claude$/
|
|
56
|
-
],
|
|
57
|
-
commonPaths: [
|
|
58
|
-
`${getHome()}/.local/bin/claude`,
|
|
59
|
-
`${getHome()}/.claude/bin/claude`,
|
|
60
|
-
`${getHome()}/.claude/local/bin/claude`
|
|
61
|
-
],
|
|
62
|
-
getUpdateCommand: () => ({
|
|
63
|
-
command: "sh",
|
|
64
|
-
args: ["-c", "curl -fsSL https://claude.ai/install.sh | sh"]
|
|
65
|
-
}),
|
|
66
|
-
isRecommended: true,
|
|
67
|
-
description: "Official curl installer from claude.ai"
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
type: "npm",
|
|
71
|
-
name: "npm Global",
|
|
72
|
-
priority: 50,
|
|
73
|
-
// Medium priority
|
|
74
|
-
platforms: ["macos", "linux", "windows"],
|
|
75
|
-
pathPatterns: [
|
|
76
|
-
/\/node_modules\/@anthropic-ai\/claude-code/,
|
|
77
|
-
/\/npm\//,
|
|
78
|
-
/\/fnm_multishells\//,
|
|
79
|
-
/\/\.nvm\//,
|
|
80
|
-
/\/\.volta\//,
|
|
81
|
-
/\/\.asdf\/installs\/nodejs\//,
|
|
82
|
-
/\/\.nodenv\//,
|
|
83
|
-
/\/\.n\/bin\//
|
|
84
|
-
],
|
|
85
|
-
commonPaths: [
|
|
86
|
-
"/usr/local/bin/claude",
|
|
87
|
-
"/usr/bin/claude",
|
|
88
|
-
`${getHome()}/.npm-global/bin/claude`,
|
|
89
|
-
// Node version manager paths
|
|
90
|
-
`${getHome()}/.nvm/versions/node`,
|
|
91
|
-
`${getHome()}/.fnm/node-versions`,
|
|
92
|
-
`${getHome()}/.volta/bin/claude`,
|
|
93
|
-
`${getHome()}/.asdf/shims/claude`
|
|
94
|
-
],
|
|
95
|
-
getUpdateCommand: () => ({ command: "npm", args: ["update", "-g", "@anthropic-ai/claude-code"] }),
|
|
96
|
-
isRecommended: false,
|
|
97
|
-
description: "npm global installation"
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
type: "npm-homebrew-node",
|
|
101
|
-
name: "npm via Homebrew Node",
|
|
102
|
-
priority: 45,
|
|
103
|
-
// Slightly lower than regular npm
|
|
104
|
-
platforms: ["macos"],
|
|
105
|
-
pathPatterns: [
|
|
106
|
-
/\/Cellar\/node\//,
|
|
107
|
-
/\/opt\/homebrew\/lib\/node_modules\//,
|
|
108
|
-
/\/usr\/local\/lib\/node_modules\//
|
|
109
|
-
],
|
|
110
|
-
commonPaths: [
|
|
111
|
-
"/opt/homebrew/Cellar/node",
|
|
112
|
-
"/usr/local/Cellar/node",
|
|
113
|
-
"/opt/homebrew/lib/node_modules/@anthropic-ai/claude-code",
|
|
114
|
-
"/usr/local/lib/node_modules/@anthropic-ai/claude-code"
|
|
115
|
-
],
|
|
116
|
-
getUpdateCommand: () => ({ command: "npm", args: ["update", "-g", "@anthropic-ai/claude-code"] }),
|
|
117
|
-
isRecommended: false,
|
|
118
|
-
description: "npm installation via Homebrew-managed Node.js"
|
|
119
|
-
},
|
|
120
|
-
// ==================== Future Linux Sources ====================
|
|
121
|
-
{
|
|
122
|
-
type: "snap",
|
|
123
|
-
name: "Snap Package",
|
|
124
|
-
priority: 80,
|
|
125
|
-
platforms: ["linux"],
|
|
126
|
-
pathPatterns: [
|
|
127
|
-
/\/snap\/claude-code\//,
|
|
128
|
-
/\/snap\/bin\/claude/
|
|
129
|
-
],
|
|
130
|
-
commonPaths: [
|
|
131
|
-
"/snap/bin/claude",
|
|
132
|
-
"/snap/claude-code/current/bin/claude"
|
|
133
|
-
],
|
|
134
|
-
getUpdateCommand: () => ({ command: "snap", args: ["refresh", "claude-code"] }),
|
|
135
|
-
isRecommended: false,
|
|
136
|
-
description: "Snap package (future support)"
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
type: "flatpak",
|
|
140
|
-
name: "Flatpak",
|
|
141
|
-
priority: 75,
|
|
142
|
-
platforms: ["linux"],
|
|
143
|
-
pathPatterns: [
|
|
144
|
-
/\/flatpak\//,
|
|
145
|
-
/com\.anthropic\.claude/
|
|
146
|
-
],
|
|
147
|
-
commonPaths: [
|
|
148
|
-
`${getHome()}/.local/share/flatpak/exports/bin/com.anthropic.claude`,
|
|
149
|
-
"/var/lib/flatpak/exports/bin/com.anthropic.claude"
|
|
150
|
-
],
|
|
151
|
-
getUpdateCommand: () => ({ command: "flatpak", args: ["update", "com.anthropic.claude"] }),
|
|
152
|
-
isRecommended: false,
|
|
153
|
-
description: "Flatpak package (future support)"
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
type: "apt",
|
|
157
|
-
name: "APT Package",
|
|
158
|
-
priority: 85,
|
|
159
|
-
platforms: ["linux"],
|
|
160
|
-
pathPatterns: [
|
|
161
|
-
/\/usr\/bin\/claude$/,
|
|
162
|
-
/\/usr\/local\/bin\/claude$/
|
|
163
|
-
],
|
|
164
|
-
commonPaths: [
|
|
165
|
-
"/usr/bin/claude",
|
|
166
|
-
"/usr/local/bin/claude"
|
|
167
|
-
],
|
|
168
|
-
getUpdateCommand: () => ({ command: "apt", args: ["upgrade", "claude-code"] }),
|
|
169
|
-
isRecommended: false,
|
|
170
|
-
description: "APT package (future support)"
|
|
171
|
-
}
|
|
172
|
-
];
|
|
173
|
-
function detectSourceFromPath(path, platform) {
|
|
174
|
-
const sortedSources = [...INSTALLATION_SOURCES].filter((s) => s.platforms.includes(platform)).sort((a, b) => b.priority - a.priority);
|
|
175
|
-
for (const source of sortedSources) {
|
|
176
|
-
for (const pattern of source.pathPatterns) {
|
|
177
|
-
if (pattern.test(path)) {
|
|
178
|
-
return source;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
return null;
|
|
183
|
-
}
|
|
184
|
-
function getCommonPathsForPlatform(platform) {
|
|
185
|
-
const paths = [];
|
|
186
|
-
for (const source of INSTALLATION_SOURCES) {
|
|
187
|
-
if (source.platforms.includes(platform)) {
|
|
188
|
-
paths.push(...source.commonPaths);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
return [...new Set(paths)];
|
|
192
|
-
}
|
|
193
|
-
function findInstallationByCommonPaths(platform) {
|
|
194
|
-
const sortedSources = [...INSTALLATION_SOURCES].filter((s) => s.platforms.includes(platform)).sort((a, b) => b.priority - a.priority);
|
|
195
|
-
for (const source of sortedSources) {
|
|
196
|
-
for (const commonPath of source.commonPaths) {
|
|
197
|
-
if (fs.existsSync(commonPath)) {
|
|
198
|
-
const stats = fs.statSync(commonPath);
|
|
199
|
-
if (stats.isDirectory()) {
|
|
200
|
-
const possibleBinaries = findClaudeBinaryInDirectory(commonPath);
|
|
201
|
-
if (possibleBinaries.length > 0) {
|
|
202
|
-
return { path: possibleBinaries[0], source };
|
|
203
|
-
}
|
|
204
|
-
} else if (stats.isFile()) {
|
|
205
|
-
return { path: commonPath, source };
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return null;
|
|
211
|
-
}
|
|
212
|
-
function findClaudeBinaryInDirectory(dir, depth = 0) {
|
|
213
|
-
if (depth > 3)
|
|
214
|
-
return [];
|
|
215
|
-
const results = [];
|
|
216
|
-
try {
|
|
217
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
218
|
-
for (const entry of entries) {
|
|
219
|
-
const fullPath = path.join(dir, entry.name);
|
|
220
|
-
if (entry.isFile() && entry.name === "claude") {
|
|
221
|
-
results.push(fullPath);
|
|
222
|
-
} else if (entry.isDirectory() && !entry.name.startsWith(".")) {
|
|
223
|
-
results.push(...findClaudeBinaryInDirectory(fullPath, depth + 1));
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
} catch {
|
|
227
|
-
}
|
|
228
|
-
return results;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const execAsync = promisify(exec);
|
|
232
|
-
async function detectWrongClaudeCodePackage() {
|
|
233
|
-
try {
|
|
234
|
-
const { stdout } = await execAsync("npm list -g --depth=0 --json");
|
|
235
|
-
const packages = JSON.parse(stdout);
|
|
236
|
-
const dependencies = packages.dependencies || {};
|
|
237
|
-
if ("claude-code" in dependencies) {
|
|
238
|
-
return {
|
|
239
|
-
hasWrongPackage: true,
|
|
240
|
-
wrongPackageName: "claude-code",
|
|
241
|
-
correctPackageName: "@anthropic-ai/claude-code"
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
return {
|
|
245
|
-
hasWrongPackage: false,
|
|
246
|
-
wrongPackageName: null,
|
|
247
|
-
correctPackageName: "@anthropic-ai/claude-code"
|
|
248
|
-
};
|
|
249
|
-
} catch {
|
|
250
|
-
return {
|
|
251
|
-
hasWrongPackage: false,
|
|
252
|
-
wrongPackageName: null,
|
|
253
|
-
correctPackageName: "@anthropic-ai/claude-code"
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
async function getInstalledVersion(command, maxRetries = 3) {
|
|
258
|
-
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
259
|
-
try {
|
|
260
|
-
let stdout;
|
|
261
|
-
try {
|
|
262
|
-
const result = await execAsync(`${command} -v`);
|
|
263
|
-
stdout = result.stdout;
|
|
264
|
-
} catch {
|
|
265
|
-
const result = await execAsync(`${command} --version`);
|
|
266
|
-
stdout = result.stdout;
|
|
267
|
-
}
|
|
268
|
-
const versionMatch = stdout.match(/(\d+\.\d+\.\d+(?:-[\w.]+)?)/);
|
|
269
|
-
return versionMatch ? versionMatch[1] : null;
|
|
270
|
-
} catch {
|
|
271
|
-
if (attempt === maxRetries) {
|
|
272
|
-
return null;
|
|
273
|
-
}
|
|
274
|
-
await new Promise((resolve) => setTimeout(resolve, 100 * attempt));
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
return null;
|
|
278
|
-
}
|
|
279
|
-
async function getLatestVersion(packageName, maxRetries = 3) {
|
|
280
|
-
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
281
|
-
try {
|
|
282
|
-
const { stdout } = await execAsync(`npm view ${packageName} version`);
|
|
283
|
-
return stdout.trim();
|
|
284
|
-
} catch {
|
|
285
|
-
if (attempt === maxRetries) {
|
|
286
|
-
return null;
|
|
287
|
-
}
|
|
288
|
-
await new Promise((resolve) => setTimeout(resolve, 200 * attempt));
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
return null;
|
|
292
|
-
}
|
|
293
|
-
async function getClaudeCodeInstallationSource() {
|
|
294
|
-
const platform = getPlatform();
|
|
295
|
-
let commandPath = await findCommandPath("claude");
|
|
296
|
-
if (!commandPath) {
|
|
297
|
-
const commonPaths = getCommonPathsForPlatform(platform);
|
|
298
|
-
for (const path of commonPaths) {
|
|
299
|
-
if (fs.existsSync(path)) {
|
|
300
|
-
try {
|
|
301
|
-
const stats = fs.statSync(path);
|
|
302
|
-
if (stats.isFile()) {
|
|
303
|
-
commandPath = path;
|
|
304
|
-
break;
|
|
305
|
-
}
|
|
306
|
-
} catch {
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
if (!commandPath) {
|
|
311
|
-
const found = findInstallationByCommonPaths(platform);
|
|
312
|
-
if (found) {
|
|
313
|
-
commandPath = found.path;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
if (!commandPath) {
|
|
318
|
-
return { isHomebrew: false, commandPath: null, source: "not-found" };
|
|
319
|
-
}
|
|
320
|
-
let resolvedPath = commandPath;
|
|
321
|
-
try {
|
|
322
|
-
const { stdout } = await execAsync(
|
|
323
|
-
`readlink -f "${commandPath}" 2>/dev/null || realpath "${commandPath}" 2>/dev/null || echo "${commandPath}"`
|
|
324
|
-
);
|
|
325
|
-
resolvedPath = stdout.trim();
|
|
326
|
-
} catch {
|
|
327
|
-
}
|
|
328
|
-
const detectedSource = detectSourceFromPath(resolvedPath, platform) || detectSourceFromPath(commandPath, platform);
|
|
329
|
-
if (detectedSource) {
|
|
330
|
-
const sourceType = mapSourceType(detectedSource.type);
|
|
331
|
-
return {
|
|
332
|
-
isHomebrew: detectedSource.type === "homebrew-cask",
|
|
333
|
-
commandPath,
|
|
334
|
-
source: sourceType
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
return { isHomebrew: false, commandPath, source: "other" };
|
|
338
|
-
}
|
|
339
|
-
function mapSourceType(type) {
|
|
340
|
-
switch (type) {
|
|
341
|
-
case "homebrew-cask":
|
|
342
|
-
return "homebrew-cask";
|
|
343
|
-
case "npm":
|
|
344
|
-
case "npm-homebrew-node":
|
|
345
|
-
return "npm";
|
|
346
|
-
case "curl":
|
|
347
|
-
return "curl";
|
|
348
|
-
default:
|
|
349
|
-
return "other";
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
function isSymlinkBroken(symlinkPath) {
|
|
353
|
-
try {
|
|
354
|
-
const lstats = fs.lstatSync(symlinkPath);
|
|
355
|
-
if (!lstats.isSymbolicLink()) {
|
|
356
|
-
return false;
|
|
357
|
-
}
|
|
358
|
-
fs.statSync(symlinkPath);
|
|
359
|
-
return false;
|
|
360
|
-
} catch {
|
|
361
|
-
try {
|
|
362
|
-
fs.lstatSync(symlinkPath);
|
|
363
|
-
return true;
|
|
364
|
-
} catch {
|
|
365
|
-
return false;
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
async function fixBrokenNpmSymlink() {
|
|
370
|
-
const platform = getPlatform();
|
|
371
|
-
if (platform !== "macos" && platform !== "linux") {
|
|
372
|
-
return { fixed: false, message: "Symlink fix only supported on macOS and Linux" };
|
|
373
|
-
}
|
|
374
|
-
const symlinkPaths = [
|
|
375
|
-
"/opt/homebrew/bin/claude",
|
|
376
|
-
// macOS Apple Silicon
|
|
377
|
-
"/usr/local/bin/claude"
|
|
378
|
-
// macOS Intel / Linux
|
|
379
|
-
];
|
|
380
|
-
const npmPackagePaths = [
|
|
381
|
-
"/opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js",
|
|
382
|
-
"/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js",
|
|
383
|
-
`${process__default.env.HOME}/.npm-global/lib/node_modules/@anthropic-ai/claude-code/cli.js`
|
|
384
|
-
];
|
|
385
|
-
let packageCliPath = null;
|
|
386
|
-
for (const path of npmPackagePaths) {
|
|
387
|
-
if (fs.existsSync(path)) {
|
|
388
|
-
packageCliPath = path;
|
|
389
|
-
break;
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
if (!packageCliPath) {
|
|
393
|
-
return { fixed: false, message: "Claude Code npm package not found" };
|
|
394
|
-
}
|
|
395
|
-
for (const symlinkPath of symlinkPaths) {
|
|
396
|
-
if (isSymlinkBroken(symlinkPath)) {
|
|
397
|
-
try {
|
|
398
|
-
fs.unlinkSync(symlinkPath);
|
|
399
|
-
fs.symlinkSync(packageCliPath, symlinkPath);
|
|
400
|
-
return {
|
|
401
|
-
fixed: true,
|
|
402
|
-
message: `Fixed broken symlink: ${symlinkPath} -> ${packageCliPath}`
|
|
403
|
-
};
|
|
404
|
-
} catch (error) {
|
|
405
|
-
return {
|
|
406
|
-
fixed: false,
|
|
407
|
-
message: `Failed to fix symlink: ${error instanceof Error ? error.message : String(error)}`
|
|
408
|
-
};
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
const commandPath = await findCommandPath("claude");
|
|
413
|
-
if (!commandPath) {
|
|
414
|
-
const binDir = fs.existsSync("/opt/homebrew/bin") ? "/opt/homebrew/bin" : "/usr/local/bin";
|
|
415
|
-
const newSymlinkPath = path.join(binDir, "claude");
|
|
416
|
-
try {
|
|
417
|
-
if (!fs.existsSync(newSymlinkPath)) {
|
|
418
|
-
fs.symlinkSync(packageCliPath, newSymlinkPath);
|
|
419
|
-
return {
|
|
420
|
-
fixed: true,
|
|
421
|
-
message: `Created new symlink: ${newSymlinkPath} -> ${packageCliPath}`
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
} catch (error) {
|
|
425
|
-
return {
|
|
426
|
-
fixed: false,
|
|
427
|
-
message: `Failed to create symlink: ${error instanceof Error ? error.message : String(error)}`
|
|
428
|
-
};
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
return { fixed: false, message: "No broken symlinks found" };
|
|
432
|
-
}
|
|
433
|
-
async function detectAllClaudeCodeInstallations() {
|
|
434
|
-
const installations = [];
|
|
435
|
-
const checkedPaths = /* @__PURE__ */ new Set();
|
|
436
|
-
const activeCommandPath = await findCommandPath("claude");
|
|
437
|
-
let activeResolvedPath = null;
|
|
438
|
-
if (activeCommandPath) {
|
|
439
|
-
try {
|
|
440
|
-
const { stdout } = await execAsync(`readlink -f "${activeCommandPath}" 2>/dev/null || realpath "${activeCommandPath}" 2>/dev/null || echo "${activeCommandPath}"`);
|
|
441
|
-
activeResolvedPath = stdout.trim();
|
|
442
|
-
} catch {
|
|
443
|
-
activeResolvedPath = activeCommandPath;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
async function getVersionFromPath(path) {
|
|
447
|
-
try {
|
|
448
|
-
const { stdout } = await execAsync(`"${path}" -v 2>/dev/null || "${path}" --version 2>/dev/null`);
|
|
449
|
-
const versionMatch = stdout.match(/(\d+\.\d+\.\d+(?:-[\w.]+)?)/);
|
|
450
|
-
return versionMatch ? versionMatch[1] : null;
|
|
451
|
-
} catch {
|
|
452
|
-
return null;
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
function isActivePath(path) {
|
|
456
|
-
if (!activeResolvedPath)
|
|
457
|
-
return false;
|
|
458
|
-
return path === activeResolvedPath || path === activeCommandPath;
|
|
459
|
-
}
|
|
460
|
-
async function addInstallation(path, source) {
|
|
461
|
-
let resolvedPath = path;
|
|
462
|
-
try {
|
|
463
|
-
const { stdout } = await execAsync(`readlink -f "${path}" 2>/dev/null || realpath "${path}" 2>/dev/null || echo "${path}"`);
|
|
464
|
-
resolvedPath = stdout.trim();
|
|
465
|
-
} catch {
|
|
466
|
-
}
|
|
467
|
-
if (checkedPaths.has(resolvedPath))
|
|
468
|
-
return;
|
|
469
|
-
checkedPaths.add(resolvedPath);
|
|
470
|
-
if (!fs.existsSync(path))
|
|
471
|
-
return;
|
|
472
|
-
const version = await getVersionFromPath(path);
|
|
473
|
-
installations.push({
|
|
474
|
-
source,
|
|
475
|
-
path,
|
|
476
|
-
version,
|
|
477
|
-
isActive: isActivePath(path) || isActivePath(resolvedPath)
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
|
-
if (activeCommandPath && fs.existsSync(activeCommandPath)) {
|
|
481
|
-
let activeSource = "other";
|
|
482
|
-
if (activeResolvedPath?.includes("/Caskroom/claude-code/")) {
|
|
483
|
-
activeSource = "homebrew-cask";
|
|
484
|
-
} else if (activeResolvedPath?.includes("/node_modules/") || activeResolvedPath?.includes("/npm/") || activeResolvedPath?.includes("/fnm_multishells/") || activeResolvedPath?.includes("/.nvm/") || activeResolvedPath?.includes("/Cellar/node/") || activeCommandPath.includes("/fnm_multishells/") || activeCommandPath.includes("/.nvm/")) {
|
|
485
|
-
activeSource = "npm";
|
|
486
|
-
}
|
|
487
|
-
await addInstallation(activeCommandPath, activeSource);
|
|
488
|
-
}
|
|
489
|
-
if (getPlatform() === "macos") {
|
|
490
|
-
const homebrewPaths = await getHomebrewCommandPaths("claude");
|
|
491
|
-
for (const path of homebrewPaths) {
|
|
492
|
-
if (path.includes("/Caskroom/claude-code/")) {
|
|
493
|
-
await addInstallation(path, "homebrew-cask");
|
|
494
|
-
} else if (path.includes("/Cellar/node/")) {
|
|
495
|
-
await addInstallation(path, "npm-homebrew-node");
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
try {
|
|
499
|
-
await execAsync("brew list --cask claude-code");
|
|
500
|
-
const homebrewPrefixes = ["/opt/homebrew", "/usr/local"];
|
|
501
|
-
for (const prefix of homebrewPrefixes) {
|
|
502
|
-
const caskroomPath = `${prefix}/Caskroom/claude-code`;
|
|
503
|
-
if (fs.existsSync(caskroomPath)) {
|
|
504
|
-
const versions = fs.readdirSync(caskroomPath).filter((v) => !v.startsWith("."));
|
|
505
|
-
for (const version of versions) {
|
|
506
|
-
const claudePath = `${caskroomPath}/${version}/claude`;
|
|
507
|
-
await addInstallation(claudePath, "homebrew-cask");
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
} catch {
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
const npmGlobalPaths = [
|
|
515
|
-
"/usr/local/bin/claude",
|
|
516
|
-
"/usr/bin/claude",
|
|
517
|
-
"/opt/homebrew/bin/claude",
|
|
518
|
-
`${process__default.env.HOME}/.npm-global/bin/claude`,
|
|
519
|
-
`${process__default.env.HOME}/.local/bin/claude`
|
|
520
|
-
];
|
|
521
|
-
for (const path$1 of npmGlobalPaths) {
|
|
522
|
-
let exists = false;
|
|
523
|
-
let isBrokenSymlink = false;
|
|
524
|
-
try {
|
|
525
|
-
if (fs.existsSync(path$1)) {
|
|
526
|
-
exists = true;
|
|
527
|
-
} else {
|
|
528
|
-
const stats = fs.lstatSync(path$1);
|
|
529
|
-
if (stats.isSymbolicLink()) {
|
|
530
|
-
isBrokenSymlink = true;
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
} catch {
|
|
534
|
-
}
|
|
535
|
-
if (exists || isBrokenSymlink) {
|
|
536
|
-
let resolvedPath = path$1;
|
|
537
|
-
try {
|
|
538
|
-
const { stdout } = await execAsync(`readlink -f "${path$1}" 2>/dev/null || realpath "${path$1}" 2>/dev/null || echo "${path$1}"`);
|
|
539
|
-
resolvedPath = stdout.trim();
|
|
540
|
-
} catch {
|
|
541
|
-
}
|
|
542
|
-
if (resolvedPath.includes("/node_modules/") || resolvedPath.includes("/npm/")) {
|
|
543
|
-
await addInstallation(path$1, "npm");
|
|
544
|
-
} else if (resolvedPath.includes("/Caskroom/")) ; else if (isBrokenSymlink) {
|
|
545
|
-
const potentialLibPath = path$1.replace("/bin/claude", "/lib/node_modules/@anthropic-ai/claude-code");
|
|
546
|
-
if (fs.existsSync(potentialLibPath)) {
|
|
547
|
-
try {
|
|
548
|
-
const pkgJsonPath = path.join(potentialLibPath, "package.json");
|
|
549
|
-
if (fs.existsSync(pkgJsonPath)) {
|
|
550
|
-
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"));
|
|
551
|
-
installations.push({
|
|
552
|
-
source: "npm",
|
|
553
|
-
path: path$1,
|
|
554
|
-
version: pkg.version,
|
|
555
|
-
isActive: isActivePath(path$1)
|
|
556
|
-
});
|
|
557
|
-
checkedPaths.add(path$1);
|
|
558
|
-
}
|
|
559
|
-
} catch {
|
|
560
|
-
}
|
|
561
|
-
} else {
|
|
562
|
-
await addInstallation(path$1, "other");
|
|
563
|
-
}
|
|
564
|
-
} else {
|
|
565
|
-
await addInstallation(path$1, "other");
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
const globalModulesPaths = [
|
|
570
|
-
"/opt/homebrew/lib/node_modules/@anthropic-ai/claude-code",
|
|
571
|
-
"/usr/local/lib/node_modules/@anthropic-ai/claude-code",
|
|
572
|
-
`${process__default.env.HOME}/.npm-global/lib/node_modules/@anthropic-ai/claude-code`
|
|
573
|
-
];
|
|
574
|
-
for (const libPath of globalModulesPaths) {
|
|
575
|
-
if (fs.existsSync(libPath) && !checkedPaths.has(libPath)) {
|
|
576
|
-
try {
|
|
577
|
-
const pkgJsonPath = path.join(libPath, "package.json");
|
|
578
|
-
if (fs.existsSync(pkgJsonPath)) {
|
|
579
|
-
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"));
|
|
580
|
-
const binPath = libPath.replace("/lib/node_modules/@anthropic-ai/claude-code", "/bin/claude");
|
|
581
|
-
if (!checkedPaths.has(binPath)) {
|
|
582
|
-
installations.push({
|
|
583
|
-
source: "npm",
|
|
584
|
-
path: fs.existsSync(binPath) ? binPath : libPath,
|
|
585
|
-
// Use bin path if exists, else lib path
|
|
586
|
-
version: pkg.version,
|
|
587
|
-
isActive: false
|
|
588
|
-
});
|
|
589
|
-
checkedPaths.add(libPath);
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
} catch {
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
if (getPlatform() === "macos") {
|
|
597
|
-
const homebrewPrefixes = ["/opt/homebrew", "/usr/local"];
|
|
598
|
-
for (const prefix of homebrewPrefixes) {
|
|
599
|
-
const cellarNodePath = `${prefix}/Cellar/node`;
|
|
600
|
-
if (fs.existsSync(cellarNodePath)) {
|
|
601
|
-
try {
|
|
602
|
-
const versions = fs.readdirSync(cellarNodePath);
|
|
603
|
-
for (const version of versions) {
|
|
604
|
-
const claudePath = `${cellarNodePath}/${version}/bin/claude`;
|
|
605
|
-
await addInstallation(claudePath, "npm-homebrew-node");
|
|
606
|
-
}
|
|
607
|
-
} catch {
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
return installations;
|
|
613
|
-
}
|
|
614
|
-
async function checkDuplicateInstallations() {
|
|
615
|
-
const installations = await detectAllClaudeCodeInstallations();
|
|
616
|
-
const activeInstallation = installations.find((i) => i.isActive) || null;
|
|
617
|
-
const inactiveInstallations = installations.filter((i) => !i.isActive);
|
|
618
|
-
const homebrewInstallation = installations.find((i) => i.source === "homebrew-cask") || null;
|
|
619
|
-
const npmInstallation = installations.find((i) => i.source === "npm" || i.source === "npm-homebrew-node") || null;
|
|
620
|
-
const hasDuplicates = homebrewInstallation !== null && npmInstallation !== null;
|
|
621
|
-
const recommendation = hasDuplicates ? "remove-npm" : "none";
|
|
622
|
-
return {
|
|
623
|
-
hasDuplicates,
|
|
624
|
-
installations,
|
|
625
|
-
activeInstallation,
|
|
626
|
-
inactiveInstallations,
|
|
627
|
-
homebrewInstallation,
|
|
628
|
-
npmInstallation,
|
|
629
|
-
recommendation
|
|
630
|
-
};
|
|
631
|
-
}
|
|
632
|
-
function getSourceDisplayName(source, i18n) {
|
|
633
|
-
const sourceMap = {
|
|
634
|
-
"homebrew-cask": i18n.t("installation:sourceHomebrewCask"),
|
|
635
|
-
"npm": i18n.t("installation:sourceNpm"),
|
|
636
|
-
"npm-homebrew-node": i18n.t("installation:sourceNpmHomebrewNode"),
|
|
637
|
-
"curl": i18n.t("installation:sourceCurl"),
|
|
638
|
-
"other": i18n.t("installation:sourceOther")
|
|
639
|
-
};
|
|
640
|
-
return sourceMap[source] || source;
|
|
641
|
-
}
|
|
642
|
-
async function performNpmRemovalAndActivateHomebrew(_npmInstallation, homebrewInstallation, tinyExec, i18n, ansis) {
|
|
643
|
-
const ora = (await import('./index7.mjs')).default;
|
|
644
|
-
const spinner = ora(i18n.t("installation:removingDuplicateInstallation")).start();
|
|
645
|
-
try {
|
|
646
|
-
const { wrapCommandWithSudo } = await import('./platform.mjs').then(function (n) { return n.p; });
|
|
647
|
-
const { command, args, usedSudo } = wrapCommandWithSudo("npm", ["uninstall", "-g", "@anthropic-ai/claude-code"]);
|
|
648
|
-
if (usedSudo) {
|
|
649
|
-
spinner.info(i18n.t("installation:usingSudo"));
|
|
650
|
-
spinner.start();
|
|
651
|
-
}
|
|
652
|
-
await tinyExec(command, args);
|
|
653
|
-
spinner.succeed(i18n.t("installation:duplicateRemoved"));
|
|
654
|
-
if (homebrewInstallation && !homebrewInstallation.isActive) {
|
|
655
|
-
console.log("");
|
|
656
|
-
console.log(ansis.green(`\u{1F517} ${i18n.t("installation:activatingHomebrew")}`));
|
|
657
|
-
const { createHomebrewSymlink } = await import('./installer.mjs');
|
|
658
|
-
const symlinkResult = await createHomebrewSymlink("claude", homebrewInstallation.path);
|
|
659
|
-
if (symlinkResult.success) {
|
|
660
|
-
console.log(ansis.green(`\u2714 ${i18n.t("installation:symlinkCreated", { path: symlinkResult.symlinkPath || "/usr/local/bin/claude" })}`));
|
|
661
|
-
} else {
|
|
662
|
-
console.log(ansis.yellow(`\u26A0 ${i18n.t("installation:manualSymlinkHint")}`));
|
|
663
|
-
if (symlinkResult.error) {
|
|
664
|
-
console.log(ansis.gray(` ${symlinkResult.error}`));
|
|
665
|
-
} else {
|
|
666
|
-
const homebrewBin = fs.existsSync("/opt/homebrew/bin") ? "/opt/homebrew/bin" : "/usr/local/bin";
|
|
667
|
-
console.log(ansis.gray(` sudo ln -sf "${homebrewInstallation.path}" ${homebrewBin}/claude`));
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
return { hadDuplicates: true, resolved: true, action: "removed-npm" };
|
|
672
|
-
} catch (error) {
|
|
673
|
-
spinner.fail(i18n.t("installation:duplicateRemovalFailed"));
|
|
674
|
-
if (error instanceof Error) {
|
|
675
|
-
console.error(ansis.gray(error.message));
|
|
676
|
-
}
|
|
677
|
-
return { hadDuplicates: true, resolved: false, action: "kept-both" };
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
async function handleDuplicateInstallations(skipPrompt = false) {
|
|
681
|
-
const { ensureI18nInitialized, format, i18n } = await import('./index5.mjs');
|
|
682
|
-
const ansis = (await import('./index2.mjs')).default;
|
|
683
|
-
ensureI18nInitialized();
|
|
684
|
-
const duplicateInfo = await checkDuplicateInstallations();
|
|
685
|
-
if (!duplicateInfo.hasDuplicates) {
|
|
686
|
-
return { hadDuplicates: false, resolved: true, action: "no-duplicates" };
|
|
687
|
-
}
|
|
688
|
-
const { npmInstallation, homebrewInstallation } = duplicateInfo;
|
|
689
|
-
console.log("");
|
|
690
|
-
console.log(ansis.yellow.bold(i18n.t("installation:duplicateInstallationsDetected")));
|
|
691
|
-
console.log(ansis.gray(i18n.t("installation:duplicateInstallationsWarning")));
|
|
692
|
-
console.log("");
|
|
693
|
-
if (homebrewInstallation) {
|
|
694
|
-
const isActive = homebrewInstallation.isActive;
|
|
695
|
-
const statusIcon = isActive ? "\u2705" : "\u26A0\uFE0F";
|
|
696
|
-
const statusColor = isActive ? ansis.green : ansis.yellow;
|
|
697
|
-
console.log(ansis.green.bold(`\u{1F37A} Homebrew Cask ${i18n.t("installation:recommendedMethod")}:`));
|
|
698
|
-
console.log(ansis.white(` ${i18n.t("installation:installationSource")}: ${statusColor(getSourceDisplayName(homebrewInstallation.source, i18n))}`));
|
|
699
|
-
console.log(ansis.white(` ${i18n.t("installation:installationPath")}: ${ansis.gray(homebrewInstallation.path)}`));
|
|
700
|
-
if (homebrewInstallation.version) {
|
|
701
|
-
console.log(ansis.white(` ${i18n.t("installation:installationVersion")}: ${ansis.green(homebrewInstallation.version)}`));
|
|
702
|
-
}
|
|
703
|
-
console.log(ansis.white(` ${statusIcon} ${isActive ? i18n.t("installation:currentActiveInstallation") : i18n.t("installation:inactiveInstallations")}`));
|
|
704
|
-
console.log("");
|
|
705
|
-
}
|
|
706
|
-
if (npmInstallation) {
|
|
707
|
-
const isActive = npmInstallation.isActive;
|
|
708
|
-
console.log(ansis.yellow.bold(`\u{1F4E6} npm ${i18n.t("installation:notRecommended")}:`));
|
|
709
|
-
console.log(ansis.white(` ${i18n.t("installation:installationSource")}: ${ansis.yellow(getSourceDisplayName(npmInstallation.source, i18n))}`));
|
|
710
|
-
console.log(ansis.white(` ${i18n.t("installation:installationPath")}: ${ansis.gray(npmInstallation.path)}`));
|
|
711
|
-
if (npmInstallation.version) {
|
|
712
|
-
console.log(ansis.white(` ${i18n.t("installation:installationVersion")}: ${ansis.green(npmInstallation.version)}`));
|
|
713
|
-
if (homebrewInstallation?.version && npmInstallation.version !== homebrewInstallation.version) {
|
|
714
|
-
console.log(ansis.red(` ${format(i18n.t("installation:versionMismatchWarning"), {
|
|
715
|
-
npmVersion: npmInstallation.version,
|
|
716
|
-
homebrewVersion: homebrewInstallation.version
|
|
717
|
-
})}`));
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
if (isActive) {
|
|
721
|
-
console.log(ansis.white(` \u26A0\uFE0F ${i18n.t("installation:currentActiveInstallation")}`));
|
|
722
|
-
}
|
|
723
|
-
console.log("");
|
|
724
|
-
}
|
|
725
|
-
console.log(ansis.green(`\u{1F4A1} ${i18n.t("installation:recommendRemoveNpm")}`));
|
|
726
|
-
console.log("");
|
|
727
|
-
if (!npmInstallation) {
|
|
728
|
-
return { hadDuplicates: true, resolved: false, action: "kept-both" };
|
|
729
|
-
}
|
|
730
|
-
const { exec: tinyExec } = await import('./main.mjs');
|
|
731
|
-
if (skipPrompt) {
|
|
732
|
-
console.log(ansis.green(`\u{1F504} ${i18n.t("installation:autoRemovingNpm")}`));
|
|
733
|
-
return await performNpmRemovalAndActivateHomebrew(
|
|
734
|
-
npmInstallation,
|
|
735
|
-
homebrewInstallation,
|
|
736
|
-
tinyExec,
|
|
737
|
-
i18n,
|
|
738
|
-
ansis
|
|
739
|
-
);
|
|
740
|
-
}
|
|
741
|
-
const inquirer = (await import('./index3.mjs').then(function (n) { return n.c; })).default;
|
|
742
|
-
const sourceDisplayName = getSourceDisplayName(npmInstallation.source, i18n);
|
|
743
|
-
const confirmMessage = format(i18n.t("installation:confirmRemoveDuplicate"), { source: sourceDisplayName });
|
|
744
|
-
const { action } = await inquirer.prompt([
|
|
745
|
-
{
|
|
746
|
-
type: "list",
|
|
747
|
-
name: "action",
|
|
748
|
-
message: confirmMessage,
|
|
749
|
-
choices: [
|
|
750
|
-
{
|
|
751
|
-
name: `\u2705 ${i18n.t("common:yes")} - ${i18n.t("installation:removingDuplicateInstallation")}`,
|
|
752
|
-
value: "remove"
|
|
753
|
-
},
|
|
754
|
-
{
|
|
755
|
-
name: `\u274C ${i18n.t("installation:keepBothInstallations")}`,
|
|
756
|
-
value: "keep"
|
|
757
|
-
}
|
|
758
|
-
]
|
|
759
|
-
}
|
|
760
|
-
]);
|
|
761
|
-
if (action === "keep") {
|
|
762
|
-
console.log(ansis.gray(i18n.t("installation:duplicateWarningContinue")));
|
|
763
|
-
return { hadDuplicates: true, resolved: false, action: "kept-both" };
|
|
764
|
-
}
|
|
765
|
-
return await performNpmRemovalAndActivateHomebrew(
|
|
766
|
-
npmInstallation,
|
|
767
|
-
homebrewInstallation,
|
|
768
|
-
tinyExec,
|
|
769
|
-
i18n,
|
|
770
|
-
ansis
|
|
771
|
-
);
|
|
772
|
-
}
|
|
773
|
-
async function getHomebrewClaudeCodeVersion() {
|
|
774
|
-
try {
|
|
775
|
-
const { stdout } = await execAsync("brew info --cask claude-code --json=v2");
|
|
776
|
-
const info = JSON.parse(stdout);
|
|
777
|
-
if (info.casks && info.casks.length > 0) {
|
|
778
|
-
return info.casks[0].version;
|
|
779
|
-
}
|
|
780
|
-
return null;
|
|
781
|
-
} catch {
|
|
782
|
-
return null;
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
function compareVersions(current, latest) {
|
|
786
|
-
if (!semverExports.valid(current) || !semverExports.valid(latest)) {
|
|
787
|
-
return -1;
|
|
788
|
-
}
|
|
789
|
-
return semverExports.compare(current, latest);
|
|
790
|
-
}
|
|
791
|
-
function shouldUpdate(current, latest) {
|
|
792
|
-
return compareVersions(current, latest) < 0;
|
|
793
|
-
}
|
|
794
|
-
async function checkCcrVersion() {
|
|
795
|
-
const currentVersion = await getInstalledVersion("ccr");
|
|
796
|
-
const latestVersion = await getLatestVersion("@musistudio/claude-code-router");
|
|
797
|
-
return {
|
|
798
|
-
installed: currentVersion !== null,
|
|
799
|
-
currentVersion,
|
|
800
|
-
latestVersion,
|
|
801
|
-
needsUpdate: currentVersion && latestVersion ? shouldUpdate(currentVersion, latestVersion) : false
|
|
802
|
-
};
|
|
803
|
-
}
|
|
804
|
-
async function checkClaudeCodeVersion() {
|
|
805
|
-
const wrongPackageInfo = await detectWrongClaudeCodePackage();
|
|
806
|
-
let currentVersion = await getInstalledVersion("claude");
|
|
807
|
-
const initialGetVersionSuccess = currentVersion !== null;
|
|
808
|
-
let installationInfo = await getClaudeCodeInstallationSource();
|
|
809
|
-
if (!currentVersion) {
|
|
810
|
-
const installations = await detectAllClaudeCodeInstallations();
|
|
811
|
-
const bestInstall = installations.find((i) => i.source === "homebrew-cask") || installations.find((i) => i.source === "npm") || installations.find((i) => i.source === "curl") || installations[0];
|
|
812
|
-
if (bestInstall && bestInstall.version) {
|
|
813
|
-
currentVersion = bestInstall.version;
|
|
814
|
-
let mappedSource;
|
|
815
|
-
switch (bestInstall.source) {
|
|
816
|
-
case "homebrew-cask":
|
|
817
|
-
mappedSource = "homebrew-cask";
|
|
818
|
-
break;
|
|
819
|
-
case "npm":
|
|
820
|
-
case "npm-homebrew-node":
|
|
821
|
-
mappedSource = "npm";
|
|
822
|
-
break;
|
|
823
|
-
case "curl":
|
|
824
|
-
mappedSource = "curl";
|
|
825
|
-
break;
|
|
826
|
-
default:
|
|
827
|
-
mappedSource = "other";
|
|
828
|
-
}
|
|
829
|
-
installationInfo = {
|
|
830
|
-
isHomebrew: bestInstall.source === "homebrew-cask",
|
|
831
|
-
commandPath: bestInstall.path,
|
|
832
|
-
source: mappedSource
|
|
833
|
-
};
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
const { isHomebrew, commandPath, source: installationSource } = installationInfo;
|
|
837
|
-
let latestVersion;
|
|
838
|
-
if (isHomebrew) {
|
|
839
|
-
latestVersion = await getHomebrewClaudeCodeVersion();
|
|
840
|
-
} else {
|
|
841
|
-
latestVersion = await getLatestVersion("@anthropic-ai/claude-code");
|
|
842
|
-
}
|
|
843
|
-
const needsUpdate = (currentVersion && latestVersion ? shouldUpdate(currentVersion, latestVersion) : false) || !initialGetVersionSuccess && currentVersion !== null;
|
|
844
|
-
return {
|
|
845
|
-
installed: currentVersion !== null,
|
|
846
|
-
currentVersion,
|
|
847
|
-
latestVersion,
|
|
848
|
-
needsUpdate,
|
|
849
|
-
isHomebrew,
|
|
850
|
-
commandPath,
|
|
851
|
-
installationSource,
|
|
852
|
-
isBroken: !initialGetVersionSuccess && currentVersion !== null,
|
|
853
|
-
hasWrongPackage: wrongPackageInfo.hasWrongPackage,
|
|
854
|
-
wrongPackageName: wrongPackageInfo.wrongPackageName
|
|
855
|
-
};
|
|
856
|
-
}
|
|
857
|
-
async function checkCometixLineVersion() {
|
|
858
|
-
const currentVersion = await getInstalledVersion("ccline");
|
|
859
|
-
const latestVersion = await getLatestVersion("@cometix/ccline");
|
|
860
|
-
return {
|
|
861
|
-
installed: currentVersion !== null,
|
|
862
|
-
currentVersion,
|
|
863
|
-
latestVersion,
|
|
864
|
-
needsUpdate: currentVersion && latestVersion ? shouldUpdate(currentVersion, latestVersion) : false
|
|
865
|
-
};
|
|
866
|
-
}
|
|
867
|
-
async function checkClaudeCodeVersionAndPrompt(skipPrompt = false) {
|
|
868
|
-
try {
|
|
869
|
-
const versionInfo = await checkClaudeCodeVersion();
|
|
870
|
-
if (!versionInfo.needsUpdate) {
|
|
871
|
-
return;
|
|
872
|
-
}
|
|
873
|
-
const { updateClaudeCode } = await import('./auto-updater.mjs');
|
|
874
|
-
await updateClaudeCode(false, skipPrompt);
|
|
875
|
-
} catch (error) {
|
|
876
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
877
|
-
console.warn(`Claude Code version check failed: ${errorMessage}`);
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
export { checkCcrVersion, checkClaudeCodeVersion, checkClaudeCodeVersionAndPrompt, checkCometixLineVersion, checkDuplicateInstallations, compareVersions, detectAllClaudeCodeInstallations, detectWrongClaudeCodePackage, fixBrokenNpmSymlink, getClaudeCodeInstallationSource, getHomebrewClaudeCodeVersion, getInstalledVersion, getLatestVersion, getSourceDisplayName, handleDuplicateInstallations, shouldUpdate };
|