ccjk 9.6.1 → 9.8.0

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 (56) hide show
  1. package/dist/chunks/boost.mjs +246 -7
  2. package/dist/chunks/ccjk-mcp.mjs +1 -1
  3. package/dist/chunks/ccr.mjs +25 -28
  4. package/dist/chunks/check-updates.mjs +4 -3
  5. package/dist/chunks/claude-code-config-manager.mjs +1 -1
  6. package/dist/chunks/claude-code-incremental-manager.mjs +1 -1
  7. package/dist/chunks/claude-config.mjs +1 -1
  8. package/dist/chunks/codex-config-switch.mjs +3 -4
  9. package/dist/chunks/codex-provider-manager.mjs +1 -2
  10. package/dist/chunks/codex.mjs +204 -3
  11. package/dist/chunks/config-switch.mjs +2 -3
  12. package/dist/chunks/config.mjs +1 -1
  13. package/dist/chunks/doctor.mjs +1 -1
  14. package/dist/chunks/features.mjs +24 -15
  15. package/dist/chunks/hook-installer.mjs +44 -0
  16. package/dist/chunks/index3.mjs +32 -32
  17. package/dist/chunks/init.mjs +129 -87
  18. package/dist/chunks/installer2.mjs +1 -1
  19. package/dist/chunks/interview.mjs +1 -1
  20. package/dist/chunks/mcp.mjs +1058 -17
  21. package/dist/chunks/menu.mjs +140 -56
  22. package/dist/chunks/package.mjs +2 -210
  23. package/dist/chunks/platform.mjs +1 -1
  24. package/dist/chunks/quick-setup.mjs +35 -18
  25. package/dist/chunks/simple-config.mjs +1 -1
  26. package/dist/{shared/ccjk.q1koQxEE.mjs → chunks/smart-defaults.mjs} +77 -79
  27. package/dist/chunks/status.mjs +208 -101
  28. package/dist/chunks/thinking.mjs +1 -1
  29. package/dist/chunks/uninstall.mjs +6 -4
  30. package/dist/chunks/update.mjs +4 -7
  31. package/dist/chunks/version-checker.mjs +1 -1
  32. package/dist/cli.mjs +4 -80
  33. package/dist/index.d.mts +17 -1482
  34. package/dist/index.d.ts +17 -1482
  35. package/dist/index.mjs +12 -4191
  36. package/dist/shared/{ccjk.CSkyCZIM.mjs → ccjk.Bndhan7G.mjs} +4 -242
  37. package/dist/shared/ccjk.CeE8RLG2.mjs +62 -0
  38. package/dist/shared/ccjk.DKojSRzw.mjs +266 -0
  39. package/dist/shared/{ccjk.CItD1fpl.mjs → ccjk.DvIrK0wz.mjs} +1 -1
  40. package/dist/shared/ccjk.LsPZ2PYo.mjs +1048 -0
  41. package/package.json +1 -1
  42. package/dist/chunks/api-adapter.mjs +0 -180
  43. package/dist/chunks/cli.mjs +0 -2227
  44. package/dist/chunks/context-menu.mjs +0 -913
  45. package/dist/chunks/hooks-sync.mjs +0 -1627
  46. package/dist/chunks/mcp-market.mjs +0 -1077
  47. package/dist/chunks/mcp-server.mjs +0 -776
  48. package/dist/chunks/project-detector.mjs +0 -131
  49. package/dist/chunks/provider-registry.mjs +0 -92
  50. package/dist/chunks/setup-wizard.mjs +0 -362
  51. package/dist/chunks/tools.mjs +0 -143
  52. package/dist/chunks/workflows2.mjs +0 -232
  53. package/dist/shared/ccjk.C0pb50xH.mjs +0 -347
  54. package/dist/shared/ccjk.ChMkBmdL.mjs +0 -490
  55. package/dist/shared/ccjk.CtSfXUSh.mjs +0 -209
  56. package/dist/shared/ccjk.xfAjmbJp.mjs +0 -75
@@ -14,11 +14,212 @@ import { updateZcfConfig, readZcfConfig, readDefaultTomlConfig, updateTomlConfig
14
14
  import { d as applyAiLanguageDirective } from './config.mjs';
15
15
  import { exists, readFile, ensureDir, writeFileAtomic, writeFile, copyFile, copyDir } from './fs-operations.mjs';
16
16
  import { readJsonConfig, writeJsonConfig } from './json-config.mjs';
17
- import { i as isWindows, a as getMcpCommand, g as getSystemRoot, w as wrapCommandWithSudo, n as normalizeTomlPath } from './platform.mjs';
17
+ import { i as isWindows, b as getMcpCommand, g as getSystemRoot, w as wrapCommandWithSudo, n as normalizeTomlPath } from './platform.mjs';
18
18
  import { a as addNumbersToChoices } from '../shared/ccjk.BFQ7yr5S.mjs';
19
19
  import { resolveAiOutputLanguage } from './prompts.mjs';
20
20
  import { p as promptBoolean } from '../shared/ccjk.DHbrGcgg.mjs';
21
- import { M as MCP_SERVICE_CONFIGS, s as selectMcpServices, a as getMcpServices } from '../shared/ccjk.CtSfXUSh.mjs';
21
+ import 'node:child_process';
22
+ import { homedir } from 'node:os';
23
+
24
+ const PLAYWRIGHT_PROFILES_DIR = join(homedir(), ".ccjk", "playwright");
25
+ function createPlaywrightMcpConfig(options = {}) {
26
+ const {
27
+ profile = "default",
28
+ headless = false,
29
+ browser = "chromium",
30
+ userDataDir
31
+ } = options;
32
+ const resolvedUserDataDir = userDataDir || join(PLAYWRIGHT_PROFILES_DIR, profile);
33
+ const args = ["-y", "@playwright/mcp@latest"];
34
+ args.push("--browser", browser);
35
+ args.push("--user-data-dir", resolvedUserDataDir);
36
+ if (headless) {
37
+ args.push("--headless");
38
+ }
39
+ return {
40
+ type: "stdio",
41
+ command: "npx",
42
+ args,
43
+ env: {}
44
+ };
45
+ }
46
+ const MCP_SERVICE_CONFIGS = [
47
+ // Documentation and Search Services - Universal (no GUI required)
48
+ {
49
+ id: "context7",
50
+ requiresApiKey: false,
51
+ config: {
52
+ type: "stdio",
53
+ command: "npx",
54
+ args: ["-y", "@upstash/context7-mcp@latest"],
55
+ env: {}
56
+ }
57
+ // Works on all platforms - no special requirements
58
+ },
59
+ {
60
+ id: "open-websearch",
61
+ requiresApiKey: false,
62
+ config: {
63
+ type: "stdio",
64
+ command: "npx",
65
+ args: ["-y", "open-websearch@latest"],
66
+ env: {
67
+ MODE: "stdio",
68
+ DEFAULT_SEARCH_ENGINE: "duckduckgo",
69
+ ALLOWED_SEARCH_ENGINES: "duckduckgo,bing,brave"
70
+ }
71
+ }
72
+ // Works on all platforms - no special requirements
73
+ },
74
+ {
75
+ id: "mcp-deepwiki",
76
+ requiresApiKey: false,
77
+ config: {
78
+ type: "stdio",
79
+ command: "npx",
80
+ args: ["-y", "mcp-deepwiki@latest"],
81
+ env: {}
82
+ }
83
+ // Works on all platforms - no special requirements
84
+ },
85
+ // Development Workflow Services
86
+ {
87
+ id: "spec-workflow",
88
+ requiresApiKey: false,
89
+ config: {
90
+ type: "stdio",
91
+ command: "npx",
92
+ args: ["-y", "@pimzino/spec-workflow-mcp@latest"],
93
+ env: {}
94
+ }
95
+ // Works on all platforms - no special requirements
96
+ },
97
+ {
98
+ id: "serena",
99
+ requiresApiKey: false,
100
+ config: {
101
+ type: "stdio",
102
+ command: "uvx",
103
+ args: ["--from", "git+https://github.com/oraios/serena", "serena", "start-mcp-server", "--context", "ide-assistant", "--enable-web-dashboard", "false"],
104
+ env: {}
105
+ },
106
+ platformRequirements: {
107
+ requiredCommands: ["uvx"]
108
+ // Requires uv/uvx to be installed
109
+ }
110
+ },
111
+ // Browser and Automation Services - Require GUI environment
112
+ {
113
+ id: "Playwright",
114
+ requiresApiKey: false,
115
+ config: createPlaywrightMcpConfig(),
116
+ // Uses default profile with chromium browser
117
+ platformRequirements: {
118
+ platforms: ["macos", "windows"],
119
+ // GUI required - exclude headless Linux/WSL/Termux
120
+ requiresGui: true
121
+ }
122
+ },
123
+ // Anthropic Official MCP Services - Universal
124
+ // Note: Removed low-value services: filesystem (buggy), puppeteer (duplicate of Playwright),
125
+ // memory (Claude has built-in memory), fetch (Claude has WebFetch), sequential-thinking (limited value)
126
+ {
127
+ id: "sqlite",
128
+ requiresApiKey: false,
129
+ config: {
130
+ type: "stdio",
131
+ command: "npx",
132
+ args: ["-y", "@anthropic-ai/mcp-server-sqlite@latest"],
133
+ env: {}
134
+ }
135
+ // Works on all platforms - no special requirements
136
+ }
137
+ ];
138
+ async function getMcpServices() {
139
+ ensureI18nInitialized();
140
+ const mcpServiceList = [
141
+ // Documentation and Search Services
142
+ {
143
+ id: "context7",
144
+ name: i18n.t("mcp:services.context7.name"),
145
+ description: i18n.t("mcp:services.context7.description")
146
+ },
147
+ {
148
+ id: "open-websearch",
149
+ name: i18n.t("mcp:services.open-websearch.name"),
150
+ description: i18n.t("mcp:services.open-websearch.description")
151
+ },
152
+ {
153
+ id: "mcp-deepwiki",
154
+ name: i18n.t("mcp:services.mcp-deepwiki.name"),
155
+ description: i18n.t("mcp:services.mcp-deepwiki.description")
156
+ },
157
+ // Development Workflow Services
158
+ {
159
+ id: "spec-workflow",
160
+ name: i18n.t("mcp:services.spec-workflow.name"),
161
+ description: i18n.t("mcp:services.spec-workflow.description")
162
+ },
163
+ {
164
+ id: "serena",
165
+ name: i18n.t("mcp:services.serena.name"),
166
+ description: i18n.t("mcp:services.serena.description")
167
+ },
168
+ // Browser and Automation Services
169
+ {
170
+ id: "Playwright",
171
+ name: i18n.t("mcp:services.playwright.name"),
172
+ description: i18n.t("mcp:services.playwright.description")
173
+ },
174
+ // Anthropic Official MCP Services
175
+ // Note: Removed low-value services: filesystem (buggy), puppeteer (duplicate),
176
+ // memory (Claude built-in), fetch (Claude WebFetch), sequential-thinking (limited value)
177
+ {
178
+ id: "sqlite",
179
+ name: i18n.t("mcp:services.sqlite.name"),
180
+ description: i18n.t("mcp:services.sqlite.description")
181
+ }
182
+ ];
183
+ return MCP_SERVICE_CONFIGS.map((config) => {
184
+ const serviceInfo = mcpServiceList.find((s) => s.id === config.id);
185
+ const service = {
186
+ id: config.id,
187
+ name: serviceInfo?.name || config.id,
188
+ description: serviceInfo?.description || "",
189
+ requiresApiKey: config.requiresApiKey,
190
+ config: config.config
191
+ };
192
+ if (config.apiKeyEnvVar) {
193
+ service.apiKeyEnvVar = config.apiKeyEnvVar;
194
+ }
195
+ return service;
196
+ });
197
+ }
198
+ async function getMcpService(id) {
199
+ const services = await getMcpServices();
200
+ return services.find((service) => service.id === id);
201
+ }
202
+
203
+ async function selectMcpServices() {
204
+ ensureI18nInitialized();
205
+ const mcpServices = await getMcpServices();
206
+ const choices = mcpServices.map((service) => ({
207
+ name: `${service.name} - ${ansis.gray(service.description)}`,
208
+ value: service.id,
209
+ selected: false
210
+ }));
211
+ const { services } = await inquirer.prompt({
212
+ type: "checkbox",
213
+ name: "services",
214
+ message: `${i18n.t("mcp:selectMcpServices")}${i18n.t("common:multiSelectHint")}`,
215
+ choices
216
+ });
217
+ if (services === void 0) {
218
+ console.log(ansis.yellow(i18n.t("common:cancelled")));
219
+ return void 0;
220
+ }
221
+ return services;
222
+ }
22
223
 
23
224
  function detectConfigManagementMode() {
24
225
  try {
@@ -1746,4 +1947,4 @@ const codex = {
1746
1947
  writeCodexConfig: writeCodexConfig
1747
1948
  };
1748
1949
 
1749
- export { switchToOfficialLogin as a, switchToProvider as b, applyCodexPlatformCommand as c, runCodexFullInit as d, runCodexUpdate as e, detectConfigManagementMode as f, backupCodexComplete as g, writeAuthFile as h, codex as i, listCodexProviders as l, readCodexConfig as r, switchCodexProvider as s, writeCodexConfig as w };
1950
+ export { MCP_SERVICE_CONFIGS as M, applyCodexPlatformCommand as a, runCodexFullInit as b, getMcpServices as c, runCodexUpdate as d, switchCodexProvider as e, switchToOfficialLogin as f, getMcpService as g, switchToProvider as h, backupCodexComplete as i, writeAuthFile as j, detectConfigManagementMode as k, listCodexProviders as l, codex as m, readCodexConfig as r, selectMcpServices as s, writeCodexConfig as w };
@@ -5,8 +5,8 @@ import { resolveCodeToolType, isCodeToolType, DEFAULT_CODE_TOOL_TYPE } from './c
5
5
  import { ensureI18nInitialized, i18n } from './index.mjs';
6
6
  import { readZcfConfig } from './ccjk-config.mjs';
7
7
  import { ClaudeCodeConfigManager } from './claude-code-config-manager.mjs';
8
- import { s as switchCodexProvider, l as listCodexProviders, r as readCodexConfig, a as switchToOfficialLogin, b as switchToProvider } from './codex.mjs';
9
- import { h as handleGeneralError } from '../shared/ccjk.CItD1fpl.mjs';
8
+ import { e as switchCodexProvider, l as listCodexProviders, r as readCodexConfig, f as switchToOfficialLogin, h as switchToProvider } from './codex.mjs';
9
+ import { a as handleGeneralError } from '../shared/ccjk.DvIrK0wz.mjs';
10
10
  import { a as addNumbersToChoices } from '../shared/ccjk.BFQ7yr5S.mjs';
11
11
  import 'node:os';
12
12
  import 'pathe';
@@ -30,7 +30,6 @@ import './prompts.mjs';
30
30
  import './package.mjs';
31
31
  import '../shared/ccjk.DHbrGcgg.mjs';
32
32
  import 'inquirer-toggle';
33
- import '../shared/ccjk.CtSfXUSh.mjs';
34
33
  import 'node:child_process';
35
34
 
36
35
  async function configSwitchCommand(options) {
@@ -452,4 +452,4 @@ const config = {
452
452
  updateDefaultModel: updateDefaultModel
453
453
  };
454
454
 
455
- export { clearModelEnv as a, backupExistingConfig as b, config as c, applyAiLanguageDirective as d, ensureClaudeDir as e, copyConfigFiles as f, getExistingApiConfig as g, configureApi as h, getExistingModelConfig as i, updateDefaultModel as j, mergeAndCleanPermissions as m, promptApiConfigurationAction as p, switchToOfficialLogin as s, updateCustomModel as u };
455
+ export { copyConfigFiles as a, backupExistingConfig as b, config as c, applyAiLanguageDirective as d, ensureClaudeDir as e, configureApi as f, getExistingApiConfig as g, getExistingModelConfig as h, updateDefaultModel as i, clearModelEnv as j, mergeAndCleanPermissions as m, promptApiConfigurationAction as p, switchToOfficialLogin as s, updateCustomModel as u };
@@ -7,7 +7,7 @@ import { getApiProviderPresets } from './api-providers.mjs';
7
7
  import { SETTINGS_FILE, CLAUDE_DIR } from './constants.mjs';
8
8
  import { i18n } from './index.mjs';
9
9
  import { g as getPermissionManager } from '../shared/ccjk.h7_W-wTs.mjs';
10
- import { k as commandExists } from './platform.mjs';
10
+ import { c as commandExists } from './platform.mjs';
11
11
  import { P as ProviderHealthMonitor } from '../shared/ccjk.J8YiPsOw.mjs';
12
12
  import { platform, userInfo, homedir } from 'node:os';
13
13
  import ora from 'ora';
@@ -1,40 +1,49 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
- import { s as selectMcpServices, a as getMcpServices } from '../shared/ccjk.CtSfXUSh.mjs';
3
+ import { s as selectMcpServices, c as getMcpServices } from './codex.mjs';
4
4
  import { SUPPORTED_LANGS, LANG_LABELS } from './constants.mjs';
5
5
  import { ensureI18nInitialized, i18n, changeLanguage } from './index.mjs';
6
6
  import { updateZcfConfig, readZcfConfig } from './ccjk-config.mjs';
7
7
  import { setupCcrConfiguration } from './config3.mjs';
8
- import { i as isCcrInstalled, a as installCcr } from '../shared/ccjk.xfAjmbJp.mjs';
8
+ import { a as isCcrInstalled, b as installCcr } from './init.mjs';
9
9
  import { r as readMcpConfig, f as fixWindowsMcpConfig, w as writeMcpConfig, b as backupMcpConfig, a as buildMcpServerConfig, m as mergeMcpServers } from './claude-config.mjs';
10
- import { d as applyAiLanguageDirective, i as getExistingModelConfig, u as updateCustomModel, j as updateDefaultModel, g as getExistingApiConfig, p as promptApiConfigurationAction, h as configureApi, s as switchToOfficialLogin } from './config.mjs';
11
- import { a as configureOutputStyle, m as modifyApiConfigPartially, v as validateApiKey, f as formatApiKeyDisplay } from '../shared/ccjk.ChMkBmdL.mjs';
10
+ import { d as applyAiLanguageDirective, h as getExistingModelConfig, u as updateCustomModel, i as updateDefaultModel, g as getExistingApiConfig, p as promptApiConfigurationAction, f as configureApi, s as switchToOfficialLogin } from './config.mjs';
11
+ import { b as configureOutputStyle, m as modifyApiConfigPartially, v as validateApiKey, f as formatApiKeyDisplay } from '../shared/ccjk.LsPZ2PYo.mjs';
12
12
  import { i as isWindows } from './platform.mjs';
13
13
  import { a as addNumbersToChoices } from '../shared/ccjk.BFQ7yr5S.mjs';
14
14
  import { openSettingsJson, importRecommendedPermissions, importRecommendedEnv } from './simple-config.mjs';
15
15
  import { p as promptBoolean } from '../shared/ccjk.DHbrGcgg.mjs';
16
- import 'node:child_process';
17
- import 'node:os';
18
16
  import 'node:process';
19
- import 'pathe';
20
- import 'node:fs';
21
17
  import 'node:url';
22
- import 'i18next';
23
- import 'i18next-fs-backend';
18
+ import 'dayjs';
19
+ import 'ora';
20
+ import 'pathe';
21
+ import 'semver';
24
22
  import 'smol-toml';
23
+ import 'tinyexec';
25
24
  import './fs-operations.mjs';
26
25
  import 'node:crypto';
26
+ import 'node:fs';
27
27
  import 'node:fs/promises';
28
28
  import './json-config.mjs';
29
- import 'dayjs';
29
+ import './prompts.mjs';
30
+ import './package.mjs';
31
+ import 'node:child_process';
32
+ import 'node:os';
33
+ import 'i18next';
34
+ import 'i18next-fs-backend';
30
35
  import 'node:util';
31
- import 'tinyexec';
32
- import 'inquirer-toggle';
36
+ import '../shared/ccjk.Br91zBIG.mjs';
33
37
  import './auto-updater.mjs';
34
- import 'ora';
35
38
  import './version-checker.mjs';
36
39
  import 'node:path';
37
- import 'semver';
40
+ import '../shared/ccjk.CeE8RLG2.mjs';
41
+ import './smart-defaults.mjs';
42
+ import '../shared/ccjk.DKojSRzw.mjs';
43
+ import '../shared/ccjk.DvIrK0wz.mjs';
44
+ import './installer2.mjs';
45
+ import '../shared/ccjk.DE91nClQ.mjs';
46
+ import 'inquirer-toggle';
38
47
 
39
48
  async function handleCancellation() {
40
49
  ensureI18nInitialized();
@@ -0,0 +1,44 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { resolve } from 'pathe';
3
+ import { readJsonConfig, writeJsonConfig } from './json-config.mjs';
4
+ import 'dayjs';
5
+ import './fs-operations.mjs';
6
+ import 'node:crypto';
7
+ import 'node:fs';
8
+
9
+ async function installRecommendedHooks(hookIds) {
10
+ if (!hookIds.length) return 0;
11
+ const templatesPath = resolve(
12
+ import.meta.dirname ?? new URL(".", import.meta.url).pathname,
13
+ "../data/hook-templates.json"
14
+ );
15
+ const raw = await readFile(templatesPath, "utf-8");
16
+ const allTemplates = JSON.parse(raw);
17
+ const selected = allTemplates.filter((t) => hookIds.includes(t.id));
18
+ if (!selected.length) return 0;
19
+ const settings = readJsonConfig("settings") ?? {};
20
+ const hooks = settings.hooks ?? {};
21
+ let added = 0;
22
+ for (const tpl of selected) {
23
+ const event = tpl.event;
24
+ const existing = hooks[event] ?? [];
25
+ const alreadyExists = existing.some((h) => h.command === tpl.command);
26
+ if (alreadyExists) continue;
27
+ const entry = {
28
+ type: "command",
29
+ command: tpl.command
30
+ };
31
+ if (tpl.timeout) {
32
+ entry.timeout = tpl.timeout;
33
+ }
34
+ hooks[event] = [...existing, entry];
35
+ added++;
36
+ }
37
+ if (added > 0) {
38
+ settings.hooks = hooks;
39
+ writeJsonConfig("settings", settings);
40
+ }
41
+ return added;
42
+ }
43
+
44
+ export { installRecommendedHooks };
@@ -1,6 +1,6 @@
1
1
  import ansis from 'ansis';
2
2
  import ora from 'ora';
3
- import fs__default from 'node:fs/promises';
3
+ import fs from 'node:fs/promises';
4
4
  import os__default from 'node:os';
5
5
  import path__default from 'node:path';
6
6
  import { exec } from 'node:child_process';
@@ -23,15 +23,15 @@ function getInstallPath(pluginType, name) {
23
23
  return path__default.join(configDir, typeDir, name);
24
24
  }
25
25
  async function copyDirectory(src, dest) {
26
- await fs__default.mkdir(dest, { recursive: true });
27
- const entries = await fs__default.readdir(src, { withFileTypes: true });
26
+ await fs.mkdir(dest, { recursive: true });
27
+ const entries = await fs.readdir(src, { withFileTypes: true });
28
28
  for (const entry of entries) {
29
29
  const srcPath = path__default.join(src, entry.name);
30
30
  const destPath = path__default.join(dest, entry.name);
31
31
  if (entry.isDirectory()) {
32
32
  await copyDirectory(srcPath, destPath);
33
33
  } else {
34
- await fs__default.copyFile(srcPath, destPath);
34
+ await fs.copyFile(srcPath, destPath);
35
35
  }
36
36
  }
37
37
  }
@@ -46,7 +46,7 @@ async function downloadFile(url, destPath) {
46
46
  throw new Error(`Failed to download: ${response.statusText}`);
47
47
  }
48
48
  const buffer = Buffer.from(await response.arrayBuffer());
49
- await fs__default.writeFile(destPath, buffer);
49
+ await fs.writeFile(destPath, buffer);
50
50
  }
51
51
 
52
52
  async function installFromGitHub(sourceInfo, pluginType, options = {}) {
@@ -59,7 +59,7 @@ async function installFromGitHub(sourceInfo, pluginType, options = {}) {
59
59
  const installPath = getInstallPath(pluginType, repo);
60
60
  if (!force) {
61
61
  try {
62
- await fs__default.access(installPath);
62
+ await fs.access(installPath);
63
63
  return {
64
64
  success: false,
65
65
  source: sourceInfo.originalUrl,
@@ -88,9 +88,9 @@ async function installFromGitHub(sourceInfo, pluginType, options = {}) {
88
88
  }
89
89
  const tempDir = await downloadRepo(owner, repo, actualRef);
90
90
  const sourcePath = subpath ? path__default.join(tempDir, subpath) : tempDir;
91
- await fs__default.mkdir(path__default.dirname(installPath), { recursive: true });
91
+ await fs.mkdir(path__default.dirname(installPath), { recursive: true });
92
92
  await copyDirectory(sourcePath, installPath);
93
- await fs__default.rm(tempDir, { recursive: true, force: true });
93
+ await fs.rm(tempDir, { recursive: true, force: true });
94
94
  const installedFiles = await listInstalledFiles$1(installPath);
95
95
  return {
96
96
  success: true,
@@ -151,10 +151,10 @@ async function downloadRepo(owner, repo, ref) {
151
151
  const zipUrl = `https://github.com/${owner}/${repo}/archive/${ref}.zip`;
152
152
  const tempDir = path__default.join(os__default.tmpdir(), `ccjk-${repo}-${Date.now()}`);
153
153
  const zipPath = path__default.join(tempDir, "repo.zip");
154
- await fs__default.mkdir(tempDir, { recursive: true });
154
+ await fs.mkdir(tempDir, { recursive: true });
155
155
  await downloadFile(zipUrl, zipPath);
156
156
  const extractedDir = await extractZip(zipPath, tempDir);
157
- await fs__default.unlink(zipPath);
157
+ await fs.unlink(zipPath);
158
158
  return extractedDir;
159
159
  }
160
160
  async function extractZip(zipPath, destDir) {
@@ -170,7 +170,7 @@ async function extractZip(zipPath, destDir) {
170
170
  throw new Error("Failed to extract archive. Please ensure unzip or tar is installed.");
171
171
  }
172
172
  }
173
- const entries = await fs__default.readdir(destDir);
173
+ const entries = await fs.readdir(destDir);
174
174
  const extractedDir = entries.find((entry) => !entry.endsWith(".zip"));
175
175
  if (!extractedDir) {
176
176
  throw new Error("Failed to find extracted directory");
@@ -180,7 +180,7 @@ async function extractZip(zipPath, destDir) {
180
180
  async function listInstalledFiles$1(dir) {
181
181
  const files = [];
182
182
  async function walk(currentDir, prefix = "") {
183
- const entries = await fs__default.readdir(currentDir, { withFileTypes: true });
183
+ const entries = await fs.readdir(currentDir, { withFileTypes: true });
184
184
  for (const entry of entries) {
185
185
  const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
186
186
  if (entry.isDirectory()) {
@@ -198,7 +198,7 @@ async function installFromLocal(sourceInfo, pluginType, options = {}) {
198
198
  const { force = false, dryRun = false } = options;
199
199
  const { absolutePath, originalPath } = sourceInfo;
200
200
  try {
201
- const stat = await fs__default.stat(absolutePath);
201
+ const stat = await fs.stat(absolutePath);
202
202
  const isFile = stat.isFile();
203
203
  const isDirectory = stat.isDirectory();
204
204
  if (!isFile && !isDirectory) {
@@ -214,7 +214,7 @@ async function installFromLocal(sourceInfo, pluginType, options = {}) {
214
214
  const installPath = getInstallPath(pluginType, pluginName);
215
215
  if (!force) {
216
216
  try {
217
- await fs__default.access(installPath);
217
+ await fs.access(installPath);
218
218
  return {
219
219
  success: false,
220
220
  source: originalPath,
@@ -243,18 +243,18 @@ async function installFromLocal(sourceInfo, pluginType, options = {}) {
243
243
  };
244
244
  }
245
245
  if (isFile) {
246
- await fs__default.mkdir(path__default.dirname(installPath), { recursive: true });
246
+ await fs.mkdir(path__default.dirname(installPath), { recursive: true });
247
247
  if (absolutePath.endsWith(".md")) {
248
- await fs__default.copyFile(absolutePath, installPath);
248
+ await fs.copyFile(absolutePath, installPath);
249
249
  } else {
250
- await fs__default.mkdir(installPath, { recursive: true });
251
- await fs__default.copyFile(
250
+ await fs.mkdir(installPath, { recursive: true });
251
+ await fs.copyFile(
252
252
  absolutePath,
253
253
  path__default.join(installPath, path__default.basename(absolutePath))
254
254
  );
255
255
  }
256
256
  } else {
257
- await fs__default.mkdir(path__default.dirname(installPath), { recursive: true });
257
+ await fs.mkdir(path__default.dirname(installPath), { recursive: true });
258
258
  await copyDirectory(absolutePath, installPath);
259
259
  }
260
260
  const installedFiles = isFile ? [path__default.basename(absolutePath)] : await listFiles(installPath);
@@ -284,7 +284,7 @@ async function installFromLocal(sourceInfo, pluginType, options = {}) {
284
284
  async function listFiles(dir) {
285
285
  const files = [];
286
286
  async function walk(currentDir, prefix = "") {
287
- const entries = await fs__default.readdir(currentDir, { withFileTypes: true });
287
+ const entries = await fs.readdir(currentDir, { withFileTypes: true });
288
288
  for (const entry of entries) {
289
289
  if (entry.name.startsWith(".") || entry.name === "node_modules") {
290
290
  continue;
@@ -307,7 +307,7 @@ async function readPluginInfo(sourcePath, isFile) {
307
307
  }
308
308
  try {
309
309
  const packageJsonPath = path__default.join(sourcePath, "package.json");
310
- const content = await fs__default.readFile(packageJsonPath, "utf-8");
310
+ const content = await fs.readFile(packageJsonPath, "utf-8");
311
311
  const packageJson = JSON.parse(content);
312
312
  return {
313
313
  name: packageJson.name,
@@ -320,7 +320,7 @@ async function readPluginInfo(sourcePath, isFile) {
320
320
  for (const metaFile of metaFiles) {
321
321
  try {
322
322
  const metaPath = path__default.join(sourcePath, metaFile);
323
- const content = await fs__default.readFile(metaPath, "utf-8");
323
+ const content = await fs.readFile(metaPath, "utf-8");
324
324
  const titleMatch = content.match(/^#\s+(.+)$/m);
325
325
  if (titleMatch) {
326
326
  return { name: titleMatch[1].trim() };
@@ -342,7 +342,7 @@ async function installFromNpm(sourceInfo, pluginType, options = {}) {
342
342
  const installPath = getInstallPath(pluginType, shortName);
343
343
  if (!force) {
344
344
  try {
345
- await fs__default.access(installPath);
345
+ await fs.access(installPath);
346
346
  return {
347
347
  success: false,
348
348
  source: packageName,
@@ -422,7 +422,7 @@ function getShortName(packageName) {
422
422
  return packageName;
423
423
  }
424
424
  async function installMcpPackage(packageName, version, installPath) {
425
- await fs__default.mkdir(installPath, { recursive: true });
425
+ await fs.mkdir(installPath, { recursive: true });
426
426
  const packageJson = {
427
427
  name: `ccjk-mcp-${getShortName(packageName)}`,
428
428
  version: "1.0.0",
@@ -431,7 +431,7 @@ async function installMcpPackage(packageName, version, installPath) {
431
431
  [packageName]: version
432
432
  }
433
433
  };
434
- await fs__default.writeFile(
434
+ await fs.writeFile(
435
435
  path__default.join(installPath, "package.json"),
436
436
  JSON.stringify(packageJson, null, 2)
437
437
  );
@@ -462,14 +462,14 @@ async function installGenericPackage(packageName, version, installPath) {
462
462
  if (!tarballResponse.ok) {
463
463
  throw new Error(`Failed to download tarball: ${tarballResponse.statusText}`);
464
464
  }
465
- await fs__default.mkdir(installPath, { recursive: true });
465
+ await fs.mkdir(installPath, { recursive: true });
466
466
  const tarballBuffer = Buffer.from(await tarballResponse.arrayBuffer());
467
467
  const tarballPath = path__default.join(installPath, "package.tgz");
468
- await fs__default.writeFile(tarballPath, tarballBuffer);
468
+ await fs.writeFile(tarballPath, tarballBuffer);
469
469
  try {
470
470
  await execAsync(`tar -xzf package.tgz --strip-components=1`, { cwd: installPath });
471
471
  } finally {
472
- await fs__default.unlink(tarballPath).catch(() => {
472
+ await fs.unlink(tarballPath).catch(() => {
473
473
  });
474
474
  }
475
475
  }
@@ -477,7 +477,7 @@ async function listInstalledFiles(dir) {
477
477
  const files = [];
478
478
  async function walk(currentDir, prefix = "") {
479
479
  try {
480
- const entries = await fs__default.readdir(currentDir, { withFileTypes: true });
480
+ const entries = await fs.readdir(currentDir, { withFileTypes: true });
481
481
  for (const entry of entries) {
482
482
  if (entry.name === "node_modules")
483
483
  continue;
@@ -687,7 +687,7 @@ async function detectFromLocal(info) {
687
687
  }
688
688
  try {
689
689
  const packageJsonPath = path__default.join(absolutePath, "package.json");
690
- const content = await fs__default.readFile(packageJsonPath, "utf-8");
690
+ const content = await fs.readFile(packageJsonPath, "utf-8");
691
691
  const packageJson = JSON.parse(content);
692
692
  const pkgResult = detectFromPackageJson(packageJson);
693
693
  if (pkgResult.confidence !== "low") {
@@ -706,7 +706,7 @@ async function detectFromLocal(info) {
706
706
  for (const pattern of filePatterns) {
707
707
  try {
708
708
  const filePath = path__default.join(absolutePath, pattern.file);
709
- await fs__default.access(filePath);
709
+ await fs.access(filePath);
710
710
  return {
711
711
  type: pattern.type,
712
712
  confidence: "high",
@@ -716,7 +716,7 @@ async function detectFromLocal(info) {
716
716
  }
717
717
  }
718
718
  try {
719
- const stat = await fs__default.stat(absolutePath);
719
+ const stat = await fs.stat(absolutePath);
720
720
  if (stat.isFile() && absolutePath.endsWith(".md")) {
721
721
  return {
722
722
  type: "skill",