ccjk 2.2.4 → 2.2.5

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.
Files changed (65) hide show
  1. package/dist/chunks/auto-updater.mjs +15 -1
  2. package/dist/chunks/ccjk-config.mjs +77 -13
  3. package/dist/chunks/ccr.mjs +7 -10
  4. package/dist/chunks/ccu.mjs +4 -4
  5. package/dist/chunks/check-updates.mjs +4 -7
  6. package/dist/chunks/claude-code-config-manager.mjs +8 -11
  7. package/dist/chunks/claude-code-incremental-manager.mjs +4 -7
  8. package/dist/chunks/codex.mjs +496 -17
  9. package/dist/chunks/commands.mjs +392 -89
  10. package/dist/chunks/commands2.mjs +109 -0
  11. package/dist/chunks/config-consolidator.mjs +2 -2
  12. package/dist/chunks/config-switch.mjs +5 -8
  13. package/dist/chunks/doctor.mjs +6 -6
  14. package/dist/chunks/features.mjs +654 -35
  15. package/dist/chunks/help.mjs +339 -0
  16. package/dist/chunks/index.mjs +323 -10
  17. package/dist/chunks/index2.mjs +3 -3
  18. package/dist/chunks/index3.mjs +1171 -0
  19. package/dist/chunks/init.mjs +21 -24
  20. package/dist/chunks/installer.mjs +178 -0
  21. package/dist/chunks/interview.mjs +6 -6
  22. package/dist/chunks/mcp-performance.mjs +82 -2
  23. package/dist/chunks/mcp.mjs +500 -0
  24. package/dist/chunks/menu.mjs +10 -10
  25. package/dist/chunks/notification.mjs +5 -5
  26. package/dist/chunks/onboarding.mjs +6 -6
  27. package/dist/chunks/package.mjs +1 -1
  28. package/dist/chunks/platform.mjs +10 -10
  29. package/dist/chunks/prompts.mjs +7 -8
  30. package/dist/chunks/session.mjs +2 -2
  31. package/dist/chunks/skills-sync.mjs +2 -2
  32. package/dist/chunks/uninstall.mjs +4 -5
  33. package/dist/chunks/update.mjs +4 -7
  34. package/dist/chunks/upgrade-manager.mjs +2 -2
  35. package/dist/chunks/version-checker.mjs +88 -7
  36. package/dist/cli.mjs +293 -53
  37. package/dist/i18n/locales/en/agentBrowser.json +79 -0
  38. package/dist/i18n/locales/en/mcp.json +2 -4
  39. package/dist/i18n/locales/en/updater.json +3 -1
  40. package/dist/i18n/locales/zh/agentBrowser.json +79 -0
  41. package/dist/i18n/locales/zh-CN/common.json +1 -1
  42. package/dist/i18n/locales/zh-CN/mcp.json +2 -4
  43. package/dist/i18n/locales/zh-CN/updater.json +3 -1
  44. package/dist/index.d.mts +8 -584
  45. package/dist/index.d.ts +8 -584
  46. package/dist/index.mjs +9 -13
  47. package/dist/shared/{ccjk.DJM5aVQJ.mjs → ccjk.ByTIGCUC.mjs} +3 -3
  48. package/dist/shared/{ccjk.qYAnUMuy.mjs → ccjk.CGTmRqsu.mjs} +2 -3
  49. package/dist/shared/{ccjk.CUdzQluX.mjs → ccjk.CURU8gbR.mjs} +1 -1
  50. package/dist/{chunks/mcp-market.mjs → shared/ccjk.D-RZS4E2.mjs} +6 -65
  51. package/dist/shared/{ccjk.B7169qud.mjs → ccjk.tB4-Y4Qb.mjs} +3 -3
  52. package/package.json +4 -1
  53. package/templates/common/skills/en/agent-browser.md +258 -0
  54. package/templates/common/skills/zh-CN/agent-browser.md +260 -0
  55. package/dist/chunks/claude-config.mjs +0 -228
  56. package/dist/chunks/features2.mjs +0 -661
  57. package/dist/chunks/json-config.mjs +0 -59
  58. package/dist/chunks/mcp-doctor.mjs +0 -160
  59. package/dist/chunks/mcp-profile.mjs +0 -220
  60. package/dist/chunks/mcp-release.mjs +0 -138
  61. package/dist/chunks/shencha.mjs +0 -320
  62. package/dist/chunks/tools.mjs +0 -169
  63. package/dist/shared/ccjk.COdsoe-Y.mjs +0 -64
  64. package/dist/shared/ccjk.DwDtZ5cK.mjs +0 -266
  65. package/dist/shared/ccjk.n_AtlHzB.mjs +0 -186
@@ -1,6 +1,6 @@
1
1
  import * as nodeFs from 'node:fs';
2
2
  import { homedir, platform } from 'node:os';
3
- import process from 'node:process';
3
+ import process__default from 'node:process';
4
4
  import { dirname } from 'pathe';
5
5
  import { exec } from 'tinyexec';
6
6
 
@@ -14,16 +14,16 @@ function getPlatform() {
14
14
  return "linux";
15
15
  }
16
16
  function isTermux() {
17
- return !!(process.env.PREFIX && process.env.PREFIX.includes("com.termux")) || !!process.env.TERMUX_VERSION || nodeFs.existsSync("/data/data/com.termux/files/usr");
17
+ return !!(process__default.env.PREFIX && process__default.env.PREFIX.includes("com.termux")) || !!process__default.env.TERMUX_VERSION || nodeFs.existsSync("/data/data/com.termux/files/usr");
18
18
  }
19
19
  function getTermuxPrefix() {
20
- return process.env.PREFIX || "/data/data/com.termux/files/usr";
20
+ return process__default.env.PREFIX || "/data/data/com.termux/files/usr";
21
21
  }
22
22
  function isWindows() {
23
23
  return getPlatform() === "windows";
24
24
  }
25
25
  function isWSL() {
26
- if (process.env.WSL_DISTRO_NAME) {
26
+ if (process__default.env.WSL_DISTRO_NAME) {
27
27
  return true;
28
28
  }
29
29
  if (nodeFs.existsSync("/proc/version")) {
@@ -41,8 +41,8 @@ function isWSL() {
41
41
  return false;
42
42
  }
43
43
  function getWSLDistro() {
44
- if (process.env.WSL_DISTRO_NAME) {
45
- return process.env.WSL_DISTRO_NAME;
44
+ if (process__default.env.WSL_DISTRO_NAME) {
45
+ return process__default.env.WSL_DISTRO_NAME;
46
46
  }
47
47
  if (nodeFs.existsSync("/etc/os-release")) {
48
48
  try {
@@ -85,7 +85,7 @@ function normalizeTomlPath(str) {
85
85
  function getSystemRoot() {
86
86
  if (!isWindows())
87
87
  return null;
88
- const env = process.env;
88
+ const env = process__default.env;
89
89
  let systemRoot = "C:\\Windows";
90
90
  if (Object.prototype.hasOwnProperty.call(env, "SYSTEMROOT") && env.SYSTEMROOT)
91
91
  systemRoot = env.SYSTEMROOT;
@@ -103,7 +103,7 @@ function shouldUseSudoForGlobalInstall() {
103
103
  if (isPathInsideHome(npmPrefix) || canWriteToPath(npmPrefix))
104
104
  return false;
105
105
  }
106
- const getuid = process.getuid;
106
+ const getuid = process__default.getuid;
107
107
  if (typeof getuid !== "function")
108
108
  return false;
109
109
  try {
@@ -147,11 +147,11 @@ function canWriteToPath(path) {
147
147
  }
148
148
  }
149
149
  function getGlobalNpmPrefix() {
150
- const env = process.env;
150
+ const env = process__default.env;
151
151
  const envPrefix = env.npm_config_prefix || env.NPM_CONFIG_PREFIX || env.PREFIX;
152
152
  if (envPrefix)
153
153
  return envPrefix;
154
- const execPath = process.execPath;
154
+ const execPath = process__default.execPath;
155
155
  if (execPath) {
156
156
  const binDir = dirname(execPath);
157
157
  return dirname(binDir);
@@ -1,10 +1,10 @@
1
- import process from 'node:process';
1
+ import process__default from 'node:process';
2
2
  import ansis from 'ansis';
3
3
  import inquirer from 'inquirer';
4
4
  import { version } from './package.mjs';
5
5
  import { LANG_LABELS, getAiOutputLanguageLabel, SUPPORTED_LANGS, AI_OUTPUT_LANGUAGES } from './constants.mjs';
6
6
  import { ensureI18nInitialized, i18n } from './index2.mjs';
7
- import { readZcfConfig, updateZcfConfig } from './ccjk-config.mjs';
7
+ import { a as readZcfConfig, u as updateZcfConfig } from './ccjk-config.mjs';
8
8
  import { a as addNumbersToChoices, p as promptBoolean } from '../shared/ccjk.DhBeLRzf.mjs';
9
9
  import 'node:os';
10
10
  import 'pathe';
@@ -16,7 +16,6 @@ import 'smol-toml';
16
16
  import './fs-operations.mjs';
17
17
  import 'node:crypto';
18
18
  import 'node:fs/promises';
19
- import './json-config.mjs';
20
19
  import 'dayjs';
21
20
  import 'inquirer-toggle';
22
21
 
@@ -42,7 +41,7 @@ async function selectAiOutputLanguage(defaultLang) {
42
41
  });
43
42
  if (!lang) {
44
43
  console.log(ansis.yellow(i18n.t("common:cancelled")));
45
- process.exit(0);
44
+ process__default.exit(0);
46
45
  }
47
46
  const aiOutputLang = lang;
48
47
  if (aiOutputLang === "custom") {
@@ -54,7 +53,7 @@ async function selectAiOutputLanguage(defaultLang) {
54
53
  });
55
54
  if (!customLang) {
56
55
  console.log(ansis.yellow(i18n.t("common:cancelled")));
57
- process.exit(0);
56
+ process__default.exit(0);
58
57
  }
59
58
  return customLang;
60
59
  }
@@ -83,7 +82,7 @@ async function selectScriptLanguage(currentLang) {
83
82
  });
84
83
  if (!lang) {
85
84
  console.log(ansis.yellow(LANGUAGE_SELECTION_MESSAGES.operationCancelled));
86
- process.exit(0);
85
+ process__default.exit(0);
87
86
  }
88
87
  const scriptLang = lang;
89
88
  updateZcfConfig({
@@ -137,7 +136,7 @@ async function selectTemplateLanguage() {
137
136
  });
138
137
  if (!lang) {
139
138
  console.log(ansis.yellow(i18n.t("common:cancelled")));
140
- process.exit(0);
139
+ process__default.exit(0);
141
140
  }
142
141
  return lang;
143
142
  }
@@ -220,7 +219,7 @@ async function resolveSystemPromptStyle(availablePrompts, commandLineOption, sav
220
219
  }]);
221
220
  if (!systemPrompt) {
222
221
  console.log(ansis.yellow(i18n.t("common:cancelled")));
223
- process.exit(0);
222
+ process__default.exit(0);
224
223
  }
225
224
  return systemPrompt;
226
225
  }
@@ -2,7 +2,7 @@ import { existsSync } from 'node:fs';
2
2
  import { mkdir, writeFile, readdir, readFile, rm, stat } from 'node:fs/promises';
3
3
  import { homedir } from 'node:os';
4
4
  import { join } from 'node:path';
5
- import process from 'node:process';
5
+ import process__default from 'node:process';
6
6
  import ansis from 'ansis';
7
7
  import inquirer from 'inquirer';
8
8
 
@@ -159,7 +159,7 @@ ${metadata.description ? `**Description:** ${metadata.description}
159
159
 
160
160
  Session data would be exported here.
161
161
  `;
162
- const outputFile = join(process.cwd(), `${sessionId}.md`);
162
+ const outputFile = join(process__default.cwd(), `${sessionId}.md`);
163
163
  await writeFile(outputFile, markdown);
164
164
  console.log(ansis.green(`\u2714 Session exported: ${outputFile}`));
165
165
  } catch (error) {
@@ -3,7 +3,7 @@ import inquirer from 'inquirer';
3
3
  import { getTranslation } from './index2.mjs';
4
4
  import { createHash } from 'node:crypto';
5
5
  import { existsSync, readdirSync, readFileSync, mkdirSync } from 'node:fs';
6
- import process from 'node:process';
6
+ import process__default from 'node:process';
7
7
  import { join } from 'pathe';
8
8
  import { CCJK_SKILLS_DIR, CCJK_CONFIG_DIR } from './constants.mjs';
9
9
  import { writeFileAtomic } from './fs-operations.mjs';
@@ -121,7 +121,7 @@ function extractMetadata(data, filePath) {
121
121
  return metadata;
122
122
  }
123
123
 
124
- const CLOUD_API_BASE_URL = process.env.CCJK_CLOUD_API_URL || "https://api.ccjk.dev/v1";
124
+ const CLOUD_API_BASE_URL = process__default.env.CCJK_CLOUD_API_URL || "https://api.ccjk.dev/v1";
125
125
  const SYNC_STATE_FILE = join(CCJK_CONFIG_DIR, "skills-sync-state.json");
126
126
  const DEFAULT_TIMEOUT = 3e4;
127
127
  function loadSyncState() {
@@ -2,15 +2,14 @@ import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
3
  import { ZCF_CONFIG_FILE, DEFAULT_CODE_TOOL_TYPE, isCodeToolType } from './constants.mjs';
4
4
  import { i18n, ensureI18nInitialized } from './index2.mjs';
5
- import { readZcfConfig } from './ccjk-config.mjs';
6
- import { r as resolveCodeType } from '../shared/ccjk.CUdzQluX.mjs';
7
- import { h as handleExitPromptError, a as handleGeneralError } from '../shared/ccjk.B7169qud.mjs';
5
+ import { r as readJsonConfig, w as writeJsonConfig, a as readZcfConfig } from './ccjk-config.mjs';
6
+ import { r as resolveCodeType } from '../shared/ccjk.CURU8gbR.mjs';
7
+ import { h as handleExitPromptError, a as handleGeneralError } from '../shared/ccjk.tB4-Y4Qb.mjs';
8
8
  import { p as promptBoolean, a as addNumbersToChoices } from '../shared/ccjk.DhBeLRzf.mjs';
9
9
  import { homedir } from 'node:os';
10
10
  import { pathExists } from 'fs-extra';
11
11
  import { join } from 'pathe';
12
12
  import { exec } from 'tinyexec';
13
- import { readJsonConfig, writeJsonConfig } from './json-config.mjs';
14
13
  import { m as moveToTrash } from '../shared/ccjk.DGjQxTq_.mjs';
15
14
  import 'node:fs';
16
15
  import 'node:process';
@@ -548,7 +547,7 @@ async function uninstall(options = {}) {
548
547
  }
549
548
  const uninstaller = new ZcfUninstaller(options.lang || "en");
550
549
  if (codeType === "codex") {
551
- const { runCodexUninstall } = await import('./codex.mjs').then(function (n) { return n.a2; });
550
+ const { runCodexUninstall } = await import('./codex.mjs').then(function (n) { return n.ai; });
552
551
  await runCodexUninstall();
553
552
  return;
554
553
  }
@@ -3,10 +3,10 @@ import { version } from './package.mjs';
3
3
  import { DEFAULT_CODE_TOOL_TYPE, resolveCodeToolType as resolveCodeToolType$1, isCodeToolType } from './constants.mjs';
4
4
  import { i18n } from './index2.mjs';
5
5
  import { d as displayBanner } from '../shared/ccjk.BhKlRJ0h.mjs';
6
- import { readZcfConfig, updateZcfConfig } from './ccjk-config.mjs';
7
- import { E as runCodexUpdate } from './codex.mjs';
8
- import { u as updatePromptOnly, s as selectAndInstallWorkflows } from '../shared/ccjk.qYAnUMuy.mjs';
9
- import { h as handleExitPromptError, a as handleGeneralError } from '../shared/ccjk.B7169qud.mjs';
6
+ import { a as readZcfConfig, u as updateZcfConfig } from './ccjk-config.mjs';
7
+ import { Q as runCodexUpdate } from './codex.mjs';
8
+ import { u as updatePromptOnly, s as selectAndInstallWorkflows } from '../shared/ccjk.CGTmRqsu.mjs';
9
+ import { h as handleExitPromptError, a as handleGeneralError } from '../shared/ccjk.tB4-Y4Qb.mjs';
10
10
  import { resolveAiOutputLanguage } from './prompts.mjs';
11
11
  import { checkClaudeCodeVersionAndPrompt } from './version-checker.mjs';
12
12
  import 'node:os';
@@ -20,17 +20,14 @@ import 'smol-toml';
20
20
  import './fs-operations.mjs';
21
21
  import 'node:crypto';
22
22
  import 'node:fs/promises';
23
- import './json-config.mjs';
24
23
  import 'dayjs';
25
24
  import 'inquirer';
26
25
  import 'ora';
27
26
  import 'semver';
28
27
  import 'tinyexec';
29
- import './claude-config.mjs';
30
28
  import './platform.mjs';
31
29
  import '../shared/ccjk.DhBeLRzf.mjs';
32
30
  import 'inquirer-toggle';
33
- import '../shared/ccjk.DwDtZ5cK.mjs';
34
31
  import 'node:child_process';
35
32
  import 'node:path';
36
33
  import 'node:util';
@@ -1,4 +1,4 @@
1
- import process from 'node:process';
1
+ import process__default from 'node:process';
2
2
  import ansis from 'ansis';
3
3
  import ora from 'ora';
4
4
  import semver from 'semver';
@@ -76,7 +76,7 @@ async function upgradeClaudeCode() {
76
76
  newVersion: versionInfo.latest
77
77
  };
78
78
  }
79
- if (process.platform !== "win32") {
79
+ if (process__default.platform !== "win32") {
80
80
  spinner.text = "Retrying with elevated permissions...";
81
81
  const sudoResult = await exec("sudo", ["npm", "install", "-g", "@anthropic-ai/claude-code@latest"], { throwOnError: false });
82
82
  if (sudoResult.exitCode === 0) {
@@ -1,16 +1,16 @@
1
1
  import { exec } from 'node:child_process';
2
2
  import * as nodeFs from 'node:fs';
3
3
  import * as path from 'node:path';
4
- import process from 'node:process';
4
+ import process__default from 'node:process';
5
5
  import { promisify } from 'node:util';
6
6
  import semver from 'semver';
7
- import { findCommandPath, getPlatform, getHomebrewCommandPaths } from './platform.mjs';
7
+ import { getPlatform, findCommandPath, getHomebrewCommandPaths } from './platform.mjs';
8
8
  import 'node:os';
9
9
  import 'pathe';
10
10
  import 'tinyexec';
11
11
 
12
12
  function getHome() {
13
- return process.env.HOME || process.env.USERPROFILE || "";
13
+ return process__default.env.HOME || process__default.env.USERPROFILE || "";
14
14
  }
15
15
  const INSTALLATION_SOURCES = [
16
16
  // ==================== macOS Sources ====================
@@ -320,6 +320,87 @@ function mapSourceType(type) {
320
320
  return "other";
321
321
  }
322
322
  }
323
+ function isSymlinkBroken(symlinkPath) {
324
+ try {
325
+ const lstats = nodeFs.lstatSync(symlinkPath);
326
+ if (!lstats.isSymbolicLink()) {
327
+ return false;
328
+ }
329
+ nodeFs.statSync(symlinkPath);
330
+ return false;
331
+ } catch {
332
+ try {
333
+ nodeFs.lstatSync(symlinkPath);
334
+ return true;
335
+ } catch {
336
+ return false;
337
+ }
338
+ }
339
+ }
340
+ async function fixBrokenNpmSymlink() {
341
+ const platform = getPlatform();
342
+ if (platform !== "macos" && platform !== "linux") {
343
+ return { fixed: false, message: "Symlink fix only supported on macOS and Linux" };
344
+ }
345
+ const symlinkPaths = [
346
+ "/opt/homebrew/bin/claude",
347
+ // macOS Apple Silicon
348
+ "/usr/local/bin/claude"
349
+ // macOS Intel / Linux
350
+ ];
351
+ const npmPackagePaths = [
352
+ "/opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js",
353
+ "/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js",
354
+ `${process__default.env.HOME}/.npm-global/lib/node_modules/@anthropic-ai/claude-code/cli.js`
355
+ ];
356
+ let packageCliPath = null;
357
+ for (const path of npmPackagePaths) {
358
+ if (nodeFs.existsSync(path)) {
359
+ packageCliPath = path;
360
+ break;
361
+ }
362
+ }
363
+ if (!packageCliPath) {
364
+ return { fixed: false, message: "Claude Code npm package not found" };
365
+ }
366
+ for (const symlinkPath of symlinkPaths) {
367
+ if (isSymlinkBroken(symlinkPath)) {
368
+ try {
369
+ nodeFs.unlinkSync(symlinkPath);
370
+ nodeFs.symlinkSync(packageCliPath, symlinkPath);
371
+ return {
372
+ fixed: true,
373
+ message: `Fixed broken symlink: ${symlinkPath} -> ${packageCliPath}`
374
+ };
375
+ } catch (error) {
376
+ return {
377
+ fixed: false,
378
+ message: `Failed to fix symlink: ${error instanceof Error ? error.message : String(error)}`
379
+ };
380
+ }
381
+ }
382
+ }
383
+ const commandPath = await findCommandPath("claude");
384
+ if (!commandPath) {
385
+ const binDir = nodeFs.existsSync("/opt/homebrew/bin") ? "/opt/homebrew/bin" : "/usr/local/bin";
386
+ const newSymlinkPath = path.join(binDir, "claude");
387
+ try {
388
+ if (!nodeFs.existsSync(newSymlinkPath)) {
389
+ nodeFs.symlinkSync(packageCliPath, newSymlinkPath);
390
+ return {
391
+ fixed: true,
392
+ message: `Created new symlink: ${newSymlinkPath} -> ${packageCliPath}`
393
+ };
394
+ }
395
+ } catch (error) {
396
+ return {
397
+ fixed: false,
398
+ message: `Failed to create symlink: ${error instanceof Error ? error.message : String(error)}`
399
+ };
400
+ }
401
+ }
402
+ return { fixed: false, message: "No broken symlinks found" };
403
+ }
323
404
  async function detectAllClaudeCodeInstallations() {
324
405
  const installations = [];
325
406
  const checkedPaths = /* @__PURE__ */ new Set();
@@ -405,8 +486,8 @@ async function detectAllClaudeCodeInstallations() {
405
486
  "/usr/local/bin/claude",
406
487
  "/usr/bin/claude",
407
488
  "/opt/homebrew/bin/claude",
408
- `${process.env.HOME}/.npm-global/bin/claude`,
409
- `${process.env.HOME}/.local/bin/claude`
489
+ `${process__default.env.HOME}/.npm-global/bin/claude`,
490
+ `${process__default.env.HOME}/.local/bin/claude`
410
491
  ];
411
492
  for (const path$1 of npmGlobalPaths) {
412
493
  let exists = false;
@@ -459,7 +540,7 @@ async function detectAllClaudeCodeInstallations() {
459
540
  const globalModulesPaths = [
460
541
  "/opt/homebrew/lib/node_modules/@anthropic-ai/claude-code",
461
542
  "/usr/local/lib/node_modules/@anthropic-ai/claude-code",
462
- `${process.env.HOME}/.npm-global/lib/node_modules/@anthropic-ai/claude-code`
543
+ `${process__default.env.HOME}/.npm-global/lib/node_modules/@anthropic-ai/claude-code`
463
544
  ];
464
545
  for (const libPath of globalModulesPaths) {
465
546
  if (nodeFs.existsSync(libPath) && !checkedPaths.has(libPath)) {
@@ -765,4 +846,4 @@ async function checkClaudeCodeVersionAndPrompt(skipPrompt = false) {
765
846
  }
766
847
  }
767
848
 
768
- export { checkCcrVersion, checkClaudeCodeVersion, checkClaudeCodeVersionAndPrompt, checkCometixLineVersion, checkDuplicateInstallations, compareVersions, detectAllClaudeCodeInstallations, getClaudeCodeInstallationSource, getHomebrewClaudeCodeVersion, getInstalledVersion, getLatestVersion, getSourceDisplayName, handleDuplicateInstallations, shouldUpdate };
849
+ export { checkCcrVersion, checkClaudeCodeVersion, checkClaudeCodeVersionAndPrompt, checkCometixLineVersion, checkDuplicateInstallations, compareVersions, detectAllClaudeCodeInstallations, fixBrokenNpmSymlink, getClaudeCodeInstallationSource, getHomebrewClaudeCodeVersion, getInstalledVersion, getLatestVersion, getSourceDisplayName, handleDuplicateInstallations, shouldUpdate };