ccjk 9.5.6 → 9.7.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 (103) hide show
  1. package/dist/chunks/agent.mjs +1 -1
  2. package/dist/chunks/api-providers.mjs +1 -1
  3. package/dist/chunks/api.mjs +3 -3
  4. package/dist/chunks/auto-bootstrap.mjs +1 -1
  5. package/dist/chunks/auto-updater.mjs +1 -1
  6. package/dist/chunks/boost.mjs +160 -0
  7. package/dist/chunks/ccjk-agents.mjs +1 -1
  8. package/dist/chunks/ccjk-all.mjs +1 -1
  9. package/dist/chunks/ccjk-config.mjs +1 -1
  10. package/dist/chunks/ccjk-hooks.mjs +1 -1
  11. package/dist/chunks/ccjk-mcp.mjs +2 -2
  12. package/dist/chunks/ccjk-setup.mjs +1 -1
  13. package/dist/chunks/ccjk-skills.mjs +1 -1
  14. package/dist/chunks/ccr.mjs +25 -30
  15. package/dist/chunks/ccu.mjs +1 -1
  16. package/dist/chunks/check-updates.mjs +3 -4
  17. package/dist/chunks/claude-code-config-manager.mjs +7 -7
  18. package/dist/chunks/claude-code-incremental-manager.mjs +2 -2
  19. package/dist/chunks/claude-config.mjs +4 -4
  20. package/dist/chunks/claude-wrapper.mjs +2 -2
  21. package/dist/chunks/codex-config-switch.mjs +4 -5
  22. package/dist/chunks/codex-provider-manager.mjs +2 -3
  23. package/dist/chunks/codex-uninstaller.mjs +2 -2
  24. package/dist/chunks/codex.mjs +207 -6
  25. package/dist/chunks/commands.mjs +391 -88
  26. package/dist/chunks/commands2.mjs +88 -391
  27. package/dist/chunks/completion.mjs +1 -1
  28. package/dist/chunks/config-consolidator.mjs +2 -2
  29. package/dist/chunks/config-switch.mjs +3 -4
  30. package/dist/chunks/config.mjs +78 -7
  31. package/dist/chunks/config2.mjs +400 -410
  32. package/dist/chunks/config3.mjs +410 -400
  33. package/dist/chunks/constants.mjs +1 -1
  34. package/dist/chunks/doctor.mjs +4 -4
  35. package/dist/chunks/features.mjs +24 -17
  36. package/dist/chunks/index.mjs +178 -7
  37. package/dist/chunks/index2.mjs +1162 -169
  38. package/dist/chunks/index3.mjs +910 -1076
  39. package/dist/chunks/index4.mjs +137 -947
  40. package/dist/chunks/index5.mjs +635 -167
  41. package/dist/chunks/init.mjs +141 -99
  42. package/dist/chunks/installer.mjs +147 -649
  43. package/dist/chunks/installer2.mjs +649 -147
  44. package/dist/chunks/interview.mjs +2 -2
  45. package/dist/chunks/marketplace.mjs +1 -1
  46. package/dist/chunks/mcp.mjs +1058 -17
  47. package/dist/chunks/menu.mjs +147 -56
  48. package/dist/chunks/monitor.mjs +2 -2
  49. package/dist/chunks/notification.mjs +1 -1
  50. package/dist/chunks/onboarding.mjs +2 -2
  51. package/dist/chunks/package.mjs +2 -210
  52. package/dist/chunks/permission-manager.mjs +2 -2
  53. package/dist/chunks/permissions.mjs +1 -1
  54. package/dist/chunks/platform.mjs +1 -1
  55. package/dist/chunks/plugin.mjs +1 -1
  56. package/dist/chunks/prompts.mjs +1 -1
  57. package/dist/chunks/providers.mjs +1 -1
  58. package/dist/chunks/quick-setup.mjs +16 -20
  59. package/dist/chunks/silent-updater.mjs +1 -1
  60. package/dist/chunks/simple-config.mjs +2 -2
  61. package/dist/chunks/skill.mjs +1 -1
  62. package/dist/chunks/skills-sync.mjs +1 -1
  63. package/dist/chunks/skills.mjs +1 -1
  64. package/dist/chunks/startup.mjs +1 -1
  65. package/dist/chunks/stats.mjs +1 -1
  66. package/dist/chunks/status.mjs +159 -0
  67. package/dist/chunks/team.mjs +1 -1
  68. package/dist/chunks/thinking.mjs +2 -2
  69. package/dist/chunks/uninstall.mjs +6 -6
  70. package/dist/chunks/update.mjs +6 -9
  71. package/dist/chunks/upgrade-manager.mjs +2 -2
  72. package/dist/chunks/version-checker.mjs +3 -3
  73. package/dist/chunks/vim.mjs +1 -1
  74. package/dist/chunks/workflows.mjs +616 -215
  75. package/dist/cli.mjs +70 -121
  76. package/dist/index.d.mts +17 -1482
  77. package/dist/index.d.ts +17 -1482
  78. package/dist/index.mjs +950 -4740
  79. package/dist/shared/{ccjk.zCqdxT2Y.mjs → ccjk.Br91zBIG.mjs} +2 -2
  80. package/dist/shared/ccjk.CSkyCZIM.mjs +638 -0
  81. package/dist/shared/{ccjk.BKoi8-Hy.mjs → ccjk.DE91nClQ.mjs} +1 -1
  82. package/dist/shared/{ccjk.f40us0yY.mjs → ccjk.DvIrK0wz.mjs} +2 -2
  83. package/dist/shared/ccjk.LsPZ2PYo.mjs +1048 -0
  84. package/dist/shared/{ccjk.DRweXU5F.mjs → ccjk.q1koQxEE.mjs} +2 -2
  85. package/package.json +1 -1
  86. package/templates/claude-code/common/settings.json +15 -111
  87. package/dist/chunks/api-adapter.mjs +0 -180
  88. package/dist/chunks/cli.mjs +0 -2227
  89. package/dist/chunks/context-menu.mjs +0 -913
  90. package/dist/chunks/hooks-sync.mjs +0 -1627
  91. package/dist/chunks/index6.mjs +0 -663
  92. package/dist/chunks/mcp-market.mjs +0 -1077
  93. package/dist/chunks/mcp-server.mjs +0 -776
  94. package/dist/chunks/project-detector.mjs +0 -131
  95. package/dist/chunks/provider-registry.mjs +0 -92
  96. package/dist/chunks/setup-wizard.mjs +0 -362
  97. package/dist/chunks/tools.mjs +0 -143
  98. package/dist/chunks/workflows2.mjs +0 -633
  99. package/dist/shared/ccjk.BM_HZogn.mjs +0 -347
  100. package/dist/shared/ccjk.BaEp4UHQ.mjs +0 -75
  101. package/dist/shared/ccjk.CS0ybJCf.mjs +0 -490
  102. package/dist/shared/ccjk.CZgIwikC.mjs +0 -209
  103. package/dist/shared/ccjk.tO8zeFh1.mjs +0 -397
@@ -1,1005 +1,195 @@
1
- import ansis from 'ansis';
2
- import ora from 'ora';
3
- import fs__default from 'node:fs/promises';
4
- import os__default from 'node:os';
5
- import path__default from 'node:path';
6
- import { exec } from 'node:child_process';
7
- import { promisify } from 'node:util';
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import process__default from 'node:process';
4
+ import { join } from 'pathe';
5
+ import { i as installSuperpowers } from '../shared/ccjk.DE91nClQ.mjs';
6
+ import 'node:child_process';
7
+ import 'node:fs/promises';
8
+ import 'node:util';
9
+ import './index.mjs';
10
+ import 'node:url';
11
+ import 'i18next';
12
+ import 'i18next-fs-backend';
8
13
 
9
- function getCcjkConfigDir() {
10
- if (process.env.CCJK_CONFIG_DIR) {
11
- return process.env.CCJK_CONFIG_DIR;
12
- }
13
- return path__default.join(os__default.homedir(), ".ccjk");
14
+ const CORE_SKILLS = [
15
+ "agent-browser",
16
+ "tdd",
17
+ "debugging",
18
+ "code-review",
19
+ "git-worktrees"
20
+ ];
21
+
22
+ function getSuperpowersDir$1() {
23
+ return join(homedir(), ".claude", "plugins", "superpowers");
14
24
  }
15
- function getInstallPath(pluginType, name) {
16
- const configDir = getCcjkConfigDir();
17
- const typeDir = {
18
- skill: "skills",
19
- mcp: "mcp-servers",
20
- agent: "agents",
21
- hook: "hooks"
22
- }[pluginType];
23
- return path__default.join(configDir, typeDir, name);
25
+ function isSuperpowersInstalled() {
26
+ const superpowersDir = getSuperpowersDir$1();
27
+ return existsSync(superpowersDir) && existsSync(join(superpowersDir, "skills"));
24
28
  }
25
- async function copyDirectory(src, dest) {
26
- await fs__default.mkdir(dest, { recursive: true });
27
- const entries = await fs__default.readdir(src, { withFileTypes: true });
28
- for (const entry of entries) {
29
- const srcPath = path__default.join(src, entry.name);
30
- const destPath = path__default.join(dest, entry.name);
31
- if (entry.isDirectory()) {
32
- await copyDirectory(srcPath, destPath);
33
- } else {
34
- await fs__default.copyFile(srcPath, destPath);
35
- }
29
+ function areCoreSkillsInstalled() {
30
+ const skillsDir = join(getSuperpowersDir$1(), "skills");
31
+ if (!existsSync(skillsDir)) {
32
+ return false;
36
33
  }
37
- }
38
- async function downloadFile(url, destPath) {
39
- const response = await fetch(url, {
40
- headers: {
41
- "User-Agent": "ccjk-cli"
42
- },
43
- redirect: "follow"
44
- });
45
- if (!response.ok) {
46
- throw new Error(`Failed to download: ${response.statusText}`);
34
+ for (const skill of CORE_SKILLS) {
35
+ const skillPath = join(skillsDir, skill);
36
+ if (!existsSync(skillPath) || !existsSync(join(skillPath, "skill.json"))) {
37
+ return false;
38
+ }
47
39
  }
48
- const buffer = Buffer.from(await response.arrayBuffer());
49
- await fs__default.writeFile(destPath, buffer);
40
+ return true;
50
41
  }
51
-
52
- async function installFromGitHub(sourceInfo, pluginType, options = {}) {
53
- const { force = false, dryRun = false } = options;
54
- const { owner, repo, ref = "main", subpath } = sourceInfo;
42
+ async function autoInstallSuperpowers(lang = "zh-CN") {
55
43
  try {
56
- const repoInfo = await fetchRepoInfo(owner, repo);
57
- const defaultBranch = repoInfo.default_branch || "main";
58
- const actualRef = ref || defaultBranch;
59
- const installPath = getInstallPath(pluginType, repo);
60
- if (!force) {
61
- try {
62
- await fs__default.access(installPath);
63
- return {
64
- success: false,
65
- source: sourceInfo.originalUrl,
66
- sourceType: "github",
67
- pluginType,
68
- error: `Plugin already exists at ${installPath}. Use --force to overwrite.`
69
- };
70
- } catch {
71
- }
72
- }
73
- if (dryRun) {
74
- const files = await listRepoFiles(owner, repo, actualRef, subpath);
75
- return {
76
- success: true,
77
- source: sourceInfo.originalUrl,
78
- sourceType: "github",
79
- pluginType,
80
- installedPath: installPath,
81
- details: {
82
- name: repo,
83
- version: actualRef,
84
- description: repoInfo.description || void 0,
85
- files: files.slice(0, 20)
86
- }
87
- };
44
+ if (isSuperpowersInstalled() && areCoreSkillsInstalled()) {
45
+ return true;
88
46
  }
89
- const tempDir = await downloadRepo(owner, repo, actualRef);
90
- const sourcePath = subpath ? path__default.join(tempDir, subpath) : tempDir;
91
- await fs__default.mkdir(path__default.dirname(installPath), { recursive: true });
92
- await copyDirectory(sourcePath, installPath);
93
- await fs__default.rm(tempDir, { recursive: true, force: true });
94
- const installedFiles = await listInstalledFiles$1(installPath);
95
- return {
96
- success: true,
97
- source: sourceInfo.originalUrl,
98
- sourceType: "github",
99
- pluginType,
100
- installedPath: installPath,
101
- details: {
102
- name: repo,
103
- version: actualRef,
104
- description: repoInfo.description || void 0,
105
- files: installedFiles
47
+ const result = await installSuperpowers({
48
+ lang,
49
+ skipPrompt: true
50
+ // Skip user prompts for silent installation
51
+ });
52
+ if (!result.success) {
53
+ if (process__default.env.DEBUG) {
54
+ console.error("[CCJK Zero-Config] Installation failed:", result.error || result.message);
106
55
  }
107
- };
108
- } catch (error) {
109
- return {
110
- success: false,
111
- source: sourceInfo.originalUrl,
112
- sourceType: "github",
113
- pluginType,
114
- error: error instanceof Error ? error.message : String(error)
115
- };
116
- }
117
- }
118
- async function fetchRepoInfo(owner, repo) {
119
- const url = `https://api.github.com/repos/${owner}/${repo}`;
120
- const response = await fetch(url, {
121
- headers: {
122
- "Accept": "application/vnd.github.v3+json",
123
- "User-Agent": "ccjk-cli"
124
- }
125
- });
126
- if (!response.ok) {
127
- if (response.status === 404) {
128
- throw new Error(`Repository not found: ${owner}/${repo}`);
56
+ return false;
129
57
  }
130
- throw new Error(`Failed to fetch repository info: ${response.statusText}`);
131
- }
132
- return response.json();
133
- }
134
- async function listRepoFiles(owner, repo, ref, subpath) {
135
- const treePath = subpath || "";
136
- const url = `https://api.github.com/repos/${owner}/${repo}/git/trees/${ref}?recursive=1`;
137
- const response = await fetch(url, {
138
- headers: {
139
- "Accept": "application/vnd.github.v3+json",
140
- "User-Agent": "ccjk-cli"
58
+ return isSuperpowersInstalled() && areCoreSkillsInstalled();
59
+ } catch (error) {
60
+ if (process__default.env.DEBUG) {
61
+ console.error("[CCJK Zero-Config] Auto-install failed:", error);
141
62
  }
142
- });
143
- if (!response.ok) {
144
- return [];
63
+ return false;
145
64
  }
146
- const data = await response.json();
147
- const files = (data.tree || []).filter((item) => item.type === "blob").map((item) => item.path).filter((filePath) => !treePath || filePath.startsWith(treePath));
148
- return files;
149
- }
150
- async function downloadRepo(owner, repo, ref) {
151
- const zipUrl = `https://github.com/${owner}/${repo}/archive/${ref}.zip`;
152
- const tempDir = path__default.join(os__default.tmpdir(), `ccjk-${repo}-${Date.now()}`);
153
- const zipPath = path__default.join(tempDir, "repo.zip");
154
- await fs__default.mkdir(tempDir, { recursive: true });
155
- await downloadFile(zipUrl, zipPath);
156
- const extractedDir = await extractZip(zipPath, tempDir);
157
- await fs__default.unlink(zipPath);
158
- return extractedDir;
159
65
  }
160
- async function extractZip(zipPath, destDir) {
161
- const { exec } = await import('node:child_process');
162
- const { promisify } = await import('node:util');
163
- const execAsync = promisify(exec);
164
- try {
165
- await execAsync(`unzip -q "${zipPath}" -d "${destDir}"`);
166
- } catch {
167
- try {
168
- await execAsync(`tar -xf "${zipPath}" -C "${destDir}"`);
169
- } catch {
170
- throw new Error("Failed to extract archive. Please ensure unzip or tar is installed.");
171
- }
172
- }
173
- const entries = await fs__default.readdir(destDir);
174
- const extractedDir = entries.find((entry) => !entry.endsWith(".zip"));
175
- if (!extractedDir) {
176
- throw new Error("Failed to find extracted directory");
177
- }
178
- return path__default.join(destDir, extractedDir);
66
+
67
+ function getSkillsDir() {
68
+ return join(homedir(), ".claude", "plugins", "superpowers", "skills");
179
69
  }
180
- async function listInstalledFiles$1(dir) {
181
- const files = [];
182
- async function walk(currentDir, prefix = "") {
183
- const entries = await fs__default.readdir(currentDir, { withFileTypes: true });
184
- for (const entry of entries) {
185
- const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
186
- if (entry.isDirectory()) {
187
- await walk(path__default.join(currentDir, entry.name), relativePath);
188
- } else {
189
- files.push(relativePath);
190
- }
191
- }
192
- }
193
- await walk(dir);
194
- return files;
70
+ function isSkillInstalled(skillName) {
71
+ const skillPath = join(getSkillsDir(), skillName);
72
+ return existsSync(skillPath) && existsSync(join(skillPath, "skill.json"));
195
73
  }
196
-
197
- async function installFromLocal(sourceInfo, pluginType, options = {}) {
198
- const { force = false, dryRun = false } = options;
199
- const { absolutePath, originalPath } = sourceInfo;
74
+ async function loadSkill(skillName) {
200
75
  try {
201
- const stat = await fs__default.stat(absolutePath);
202
- const isFile = stat.isFile();
203
- const isDirectory = stat.isDirectory();
204
- if (!isFile && !isDirectory) {
76
+ if (!isSkillInstalled(skillName)) {
205
77
  return {
78
+ skill: skillName,
206
79
  success: false,
207
- source: originalPath,
208
- sourceType: "local",
209
- pluginType,
210
- error: `Source path is neither a file nor a directory: ${absolutePath}`
80
+ error: "Skill not installed"
211
81
  };
212
82
  }
213
- const pluginName = path__default.basename(absolutePath, path__default.extname(absolutePath));
214
- const installPath = getInstallPath(pluginType, pluginName);
215
- if (!force) {
216
- try {
217
- await fs__default.access(installPath);
218
- return {
219
- success: false,
220
- source: originalPath,
221
- sourceType: "local",
222
- pluginType,
223
- error: `Plugin already exists at ${installPath}. Use --force to overwrite.`
224
- };
225
- } catch {
226
- }
227
- }
228
- const files = isFile ? [path__default.basename(absolutePath)] : await listFiles(absolutePath);
229
- const pluginInfo = await readPluginInfo(absolutePath, isFile);
230
- if (dryRun) {
83
+ const skillJsonPath = join(getSkillsDir(), skillName, "skill.json");
84
+ const skillJson = JSON.parse(readFileSync(skillJsonPath, "utf-8"));
85
+ if (!skillJson.name || !skillJson.version) {
231
86
  return {
232
- success: true,
233
- source: originalPath,
234
- sourceType: "local",
235
- pluginType,
236
- installedPath: installPath,
237
- details: {
238
- name: pluginInfo.name || pluginName,
239
- version: pluginInfo.version,
240
- description: pluginInfo.description,
241
- files
242
- }
87
+ skill: skillName,
88
+ success: false,
89
+ error: "Invalid skill.json format"
243
90
  };
244
91
  }
245
- if (isFile) {
246
- await fs__default.mkdir(path__default.dirname(installPath), { recursive: true });
247
- if (absolutePath.endsWith(".md")) {
248
- await fs__default.copyFile(absolutePath, installPath);
249
- } else {
250
- await fs__default.mkdir(installPath, { recursive: true });
251
- await fs__default.copyFile(
252
- absolutePath,
253
- path__default.join(installPath, path__default.basename(absolutePath))
254
- );
255
- }
256
- } else {
257
- await fs__default.mkdir(path__default.dirname(installPath), { recursive: true });
258
- await copyDirectory(absolutePath, installPath);
259
- }
260
- const installedFiles = isFile ? [path__default.basename(absolutePath)] : await listFiles(installPath);
261
92
  return {
262
- success: true,
263
- source: originalPath,
264
- sourceType: "local",
265
- pluginType,
266
- installedPath: installPath,
267
- details: {
268
- name: pluginInfo.name || pluginName,
269
- version: pluginInfo.version,
270
- description: pluginInfo.description,
271
- files: installedFiles
272
- }
93
+ skill: skillName,
94
+ success: true
273
95
  };
274
96
  } catch (error) {
275
97
  return {
98
+ skill: skillName,
276
99
  success: false,
277
- source: originalPath,
278
- sourceType: "local",
279
- pluginType,
280
- error: error instanceof Error ? error.message : String(error)
100
+ error: error instanceof Error ? error.message : "Unknown error"
281
101
  };
282
102
  }
283
103
  }
284
- async function listFiles(dir) {
285
- const files = [];
286
- async function walk(currentDir, prefix = "") {
287
- const entries = await fs__default.readdir(currentDir, { withFileTypes: true });
288
- for (const entry of entries) {
289
- if (entry.name.startsWith(".") || entry.name === "node_modules") {
290
- continue;
291
- }
292
- const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
293
- if (entry.isDirectory()) {
294
- await walk(path__default.join(currentDir, entry.name), relativePath);
295
- } else {
296
- files.push(relativePath);
297
- }
298
- }
299
- }
300
- await walk(dir);
301
- return files;
302
- }
303
- async function readPluginInfo(sourcePath, isFile) {
304
- if (isFile) {
305
- const name = path__default.basename(sourcePath, path__default.extname(sourcePath));
306
- return { name };
307
- }
308
- try {
309
- const packageJsonPath = path__default.join(sourcePath, "package.json");
310
- const content = await fs__default.readFile(packageJsonPath, "utf-8");
311
- const packageJson = JSON.parse(content);
312
- return {
313
- name: packageJson.name,
314
- version: packageJson.version,
315
- description: packageJson.description
316
- };
317
- } catch {
318
- }
319
- const metaFiles = ["SKILL.md", "skill.md", "README.md", "readme.md"];
320
- for (const metaFile of metaFiles) {
321
- try {
322
- const metaPath = path__default.join(sourcePath, metaFile);
323
- const content = await fs__default.readFile(metaPath, "utf-8");
324
- const titleMatch = content.match(/^#\s+(.+)$/m);
325
- if (titleMatch) {
326
- return { name: titleMatch[1].trim() };
327
- }
328
- } catch {
104
+ async function loadCoreSkills(_lang = "zh-CN") {
105
+ const results = await Promise.all(
106
+ CORE_SKILLS.map((skill) => loadSkill(skill))
107
+ );
108
+ if (process__default.env.DEBUG) {
109
+ const successful = results.filter((r) => r.success);
110
+ const failed = results.filter((r) => !r.success);
111
+ console.log(`[Zero-Config] Loaded ${successful.length}/${CORE_SKILLS.length} core skills`);
112
+ if (failed.length > 0) {
113
+ console.log(`[Zero-Config] Failed skills: ${failed.map((r) => r.skill).join(", ")}`);
329
114
  }
330
115
  }
331
- return {};
116
+ return results;
332
117
  }
333
118
 
334
- const execAsync = promisify(exec);
335
- async function installFromNpm(sourceInfo, pluginType, options = {}) {
336
- const { force = false, dryRun = false } = options;
337
- const { packageName, version } = sourceInfo;
338
- try {
339
- const packageInfo = await fetchPackageInfo(packageName, version);
340
- const packageVersion = version || packageInfo.version;
341
- const shortName = getShortName(packageName);
342
- const installPath = getInstallPath(pluginType, shortName);
343
- if (!force) {
344
- try {
345
- await fs__default.access(installPath);
346
- return {
347
- success: false,
348
- source: packageName,
349
- sourceType: "npm",
350
- pluginType,
351
- error: `Plugin already exists at ${installPath}. Use --force to overwrite.`
352
- };
353
- } catch {
354
- }
355
- }
356
- if (dryRun) {
357
- const files = packageInfo.files || ["(package files)"];
358
- return {
359
- success: true,
360
- source: packageName,
361
- sourceType: "npm",
362
- pluginType,
363
- installedPath: installPath,
364
- details: {
365
- name: packageName,
366
- version: packageVersion,
367
- description: packageInfo.description,
368
- files
369
- }
370
- };
371
- }
372
- if (pluginType === "mcp") {
373
- await installMcpPackage(packageName, packageVersion, installPath);
374
- } else {
375
- await installGenericPackage(packageName, packageVersion, installPath);
376
- }
377
- const installedFiles = await listInstalledFiles(installPath);
378
- return {
379
- success: true,
380
- source: packageName,
381
- sourceType: "npm",
382
- pluginType,
383
- installedPath: installPath,
384
- details: {
385
- name: packageName,
386
- version: packageVersion,
387
- description: packageInfo.description,
388
- files: installedFiles
389
- }
390
- };
391
- } catch (error) {
392
- return {
393
- success: false,
394
- source: packageName,
395
- sourceType: "npm",
396
- pluginType,
397
- error: error instanceof Error ? error.message : String(error)
398
- };
399
- }
119
+ function getActivationStatePath() {
120
+ return join(homedir(), ".claude", "plugins", "superpowers", ".activation-state.json");
400
121
  }
401
- async function fetchPackageInfo(packageName, version) {
402
- const url = version ? `https://registry.npmjs.org/${packageName}/${version}` : `https://registry.npmjs.org/${packageName}/latest`;
403
- const response = await fetch(url);
404
- if (!response.ok) {
405
- if (response.status === 404) {
406
- throw new Error(`Package not found: ${packageName}`);
407
- }
408
- throw new Error(`Failed to fetch package info: ${response.statusText}`);
409
- }
410
- const data = await response.json();
411
- return {
412
- version: data.version,
413
- description: data.description,
414
- files: data.files
415
- };
416
- }
417
- function getShortName(packageName) {
418
- if (packageName.startsWith("@")) {
419
- const parts = packageName.split("/");
420
- return parts[1] || packageName;
421
- }
422
- return packageName;
122
+ function getSuperpowersDir() {
123
+ return join(homedir(), ".claude", "plugins", "superpowers");
423
124
  }
424
- async function installMcpPackage(packageName, version, installPath) {
425
- await fs__default.mkdir(installPath, { recursive: true });
426
- const packageJson = {
427
- name: `ccjk-mcp-${getShortName(packageName)}`,
428
- version: "1.0.0",
429
- private: true,
430
- dependencies: {
431
- [packageName]: version
432
- }
433
- };
434
- await fs__default.writeFile(
435
- path__default.join(installPath, "package.json"),
436
- JSON.stringify(packageJson, null, 2)
437
- );
125
+ function loadActivationState() {
438
126
  try {
439
- await execAsync("npm install", { cwd: installPath });
127
+ const statePath = getActivationStatePath();
128
+ if (!existsSync(statePath)) {
129
+ return null;
130
+ }
131
+ const stateJson = readFileSync(statePath, "utf-8");
132
+ return JSON.parse(stateJson);
440
133
  } catch (error) {
441
- try {
442
- await execAsync("pnpm install", { cwd: installPath });
443
- } catch {
444
- throw new Error(
445
- `Failed to install package. Original error: ${error instanceof Error ? error.message : String(error)}`
446
- );
134
+ if (process__default.env.DEBUG) {
135
+ console.error("[Zero-Config] Failed to load activation state:", error);
447
136
  }
137
+ return null;
448
138
  }
449
139
  }
450
- async function installGenericPackage(packageName, version, installPath) {
451
- const registryUrl = `https://registry.npmjs.org/${packageName}/${version}`;
452
- const response = await fetch(registryUrl);
453
- if (!response.ok) {
454
- throw new Error(`Failed to fetch package info: ${response.statusText}`);
455
- }
456
- const data = await response.json();
457
- const tarballUrl = data.dist?.tarball;
458
- if (!tarballUrl) {
459
- throw new Error("Failed to get tarball URL");
460
- }
461
- const tarballResponse = await fetch(tarballUrl);
462
- if (!tarballResponse.ok) {
463
- throw new Error(`Failed to download tarball: ${tarballResponse.statusText}`);
464
- }
465
- await fs__default.mkdir(installPath, { recursive: true });
466
- const tarballBuffer = Buffer.from(await tarballResponse.arrayBuffer());
467
- const tarballPath = path__default.join(installPath, "package.tgz");
468
- await fs__default.writeFile(tarballPath, tarballBuffer);
140
+ function saveActivationState(status) {
469
141
  try {
470
- await execAsync(`tar -xzf package.tgz --strip-components=1`, { cwd: installPath });
471
- } finally {
472
- await fs__default.unlink(tarballPath).catch(() => {
473
- });
474
- }
475
- }
476
- async function listInstalledFiles(dir) {
477
- const files = [];
478
- async function walk(currentDir, prefix = "") {
479
- try {
480
- const entries = await fs__default.readdir(currentDir, { withFileTypes: true });
481
- for (const entry of entries) {
482
- if (entry.name === "node_modules")
483
- continue;
484
- const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
485
- if (entry.isDirectory()) {
486
- await walk(path__default.join(currentDir, entry.name), relativePath);
487
- } else {
488
- files.push(relativePath);
489
- }
490
- }
491
- } catch {
492
- }
493
- }
494
- await walk(dir);
495
- return files;
496
- }
497
-
498
- function parseSource(source) {
499
- const trimmed = source.trim();
500
- const githubInfo = parseGitHubSource(trimmed);
501
- if (githubInfo) {
502
- return githubInfo;
503
- }
504
- const localInfo = parseLocalSource(trimmed);
505
- if (localInfo) {
506
- return localInfo;
507
- }
508
- return parseNpmSource(trimmed);
509
- }
510
- function parseGitHubSource(source) {
511
- const prefixMatch = source.match(/^(?:github|gh):([^/]+)\/([^#@/]+)(?:#(.+))?$/);
512
- if (prefixMatch) {
513
- return {
514
- type: "github",
515
- owner: prefixMatch[1],
516
- repo: prefixMatch[2],
517
- ref: prefixMatch[3],
518
- originalUrl: source
519
- };
520
- }
521
- const urlMatch = source.match(
522
- /^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/tree\/([^/]+))?(?:\/(.+))?$/
523
- );
524
- if (urlMatch) {
525
- return {
526
- type: "github",
527
- owner: urlMatch[1],
528
- repo: urlMatch[2],
529
- ref: urlMatch[3],
530
- subpath: urlMatch[4],
531
- originalUrl: source
532
- };
533
- }
534
- const shortMatch = source.match(/^([\w-]+)\/([\w.-]+)(?:#(.+))?$/);
535
- if (shortMatch && !source.startsWith(".") && !source.startsWith("/") && !source.startsWith("~")) {
536
- return {
537
- type: "github",
538
- owner: shortMatch[1],
539
- repo: shortMatch[2],
540
- ref: shortMatch[3],
541
- originalUrl: source
542
- };
543
- }
544
- return null;
545
- }
546
- function parseLocalSource(source) {
547
- if (source.startsWith("./") || source.startsWith("../") || source.startsWith("/") || source.startsWith("~/")) {
548
- let absolutePath;
549
- if (source.startsWith("~/")) {
550
- absolutePath = path__default.join(os__default.homedir(), source.slice(2));
551
- } else if (path__default.isAbsolute(source)) {
552
- absolutePath = source;
553
- } else {
554
- absolutePath = path__default.resolve(process.cwd(), source);
142
+ const statePath = getActivationStatePath();
143
+ writeFileSync(statePath, JSON.stringify(status, null, 2), "utf-8");
144
+ } catch (error) {
145
+ if (process__default.env.DEBUG) {
146
+ console.error("[Zero-Config] Failed to save activation state:", error);
555
147
  }
556
- return {
557
- type: "local",
558
- absolutePath,
559
- originalPath: source
560
- };
561
- }
562
- if (/^[a-z]:[\\/]/i.test(source)) {
563
- return {
564
- type: "local",
565
- absolutePath: path__default.resolve(source),
566
- originalPath: source
567
- };
568
148
  }
569
- return null;
570
149
  }
571
- function parseNpmSource(source) {
572
- const npmPrefixMatch = source.match(/^npm:(.+)$/);
573
- const packageStr = npmPrefixMatch ? npmPrefixMatch[1] : source;
574
- const scopedMatch = packageStr.match(/^(@[^/]+)\/([^@]+)(?:@(.+))?$/);
575
- if (scopedMatch) {
576
- return {
577
- type: "npm",
578
- scope: scopedMatch[1],
579
- packageName: `${scopedMatch[1]}/${scopedMatch[2]}`,
580
- version: scopedMatch[3]
581
- };
582
- }
583
- const versionMatch = packageStr.match(/^([^@]+)@(.+)$/);
584
- if (versionMatch) {
585
- return {
586
- type: "npm",
587
- packageName: versionMatch[1],
588
- version: versionMatch[2]
589
- };
150
+ function checkActivationStatus() {
151
+ const superpowersInstalled = existsSync(getSuperpowersDir());
152
+ const savedState = loadActivationState();
153
+ if (savedState) {
154
+ return savedState;
590
155
  }
591
156
  return {
592
- type: "npm",
593
- packageName: packageStr
157
+ isInstalled: superpowersInstalled,
158
+ coreSkillsLoaded: false,
159
+ loadedSkills: [],
160
+ needsActivation: true,
161
+ lastActivation: void 0
594
162
  };
595
163
  }
596
- function buildGitHubRawUrl(info, filePath) {
597
- const ref = info.ref || "main";
598
- return `https://raw.githubusercontent.com/${info.owner}/${info.repo}/${ref}/${filePath}`;
599
- }
600
-
601
- async function detectPluginType(sourceInfo) {
602
- const result = await detectPluginTypeWithConfidence(sourceInfo);
603
- return result.type;
604
- }
605
- async function detectPluginTypeWithConfidence(sourceInfo) {
606
- switch (sourceInfo.type) {
607
- case "github":
608
- return detectFromGitHub(sourceInfo);
609
- case "npm":
610
- return detectFromNpm(sourceInfo);
611
- case "local":
612
- return detectFromLocal(sourceInfo);
613
- default:
614
- return { type: "skill", confidence: "low", reason: "Unknown source type" };
615
- }
616
- }
617
- async function detectFromGitHub(info) {
618
- const repoNameResult = detectFromRepoName(info.repo);
619
- if (repoNameResult.confidence === "high") {
620
- return repoNameResult;
164
+ async function activateSuperpowers(lang = "zh-CN") {
165
+ const currentStatus = checkActivationStatus();
166
+ if (!currentStatus.needsActivation) {
167
+ return currentStatus;
621
168
  }
622
- try {
623
- const packageJsonUrl = buildGitHubRawUrl(info, "package.json");
624
- const response = await fetch(packageJsonUrl);
625
- if (response.ok) {
626
- const packageJson = await response.json();
627
- const pkgResult = detectFromPackageJson(packageJson);
628
- if (pkgResult.confidence !== "low") {
629
- return pkgResult;
630
- }
631
- }
632
- } catch {
633
- }
634
- const filePatterns = [
635
- { file: "SKILL.md", type: "skill" },
636
- { file: "skill.md", type: "skill" },
637
- { file: "AGENT.md", type: "agent" },
638
- { file: "agent.md", type: "agent" },
639
- { file: "mcp.json", type: "mcp" },
640
- { file: "hook.json", type: "hook" }
641
- ];
642
- for (const pattern of filePatterns) {
643
- try {
644
- const fileUrl = buildGitHubRawUrl(info, pattern.file);
645
- const response = await fetch(fileUrl, { method: "HEAD" });
646
- if (response.ok) {
647
- return {
648
- type: pattern.type,
649
- confidence: "high",
650
- reason: `Found ${pattern.file}`
651
- };
652
- }
653
- } catch {
654
- }
655
- }
656
- return repoNameResult.confidence !== "low" ? repoNameResult : { type: "skill", confidence: "low", reason: "Default type" };
657
- }
658
- async function detectFromNpm(info) {
659
- const nameResult = detectFromPackageName(info.packageName);
660
- if (nameResult.confidence === "high") {
661
- return nameResult;
662
- }
663
- try {
664
- const registryUrl = `https://registry.npmjs.org/${info.packageName}`;
665
- const response = await fetch(registryUrl);
666
- if (response.ok) {
667
- const data = await response.json();
668
- const latestVersion = data["dist-tags"]?.latest;
669
- if (latestVersion && data.versions?.[latestVersion]) {
670
- const packageJson = data.versions[latestVersion];
671
- const pkgResult = detectFromPackageJson(packageJson);
672
- if (pkgResult.confidence !== "low") {
673
- return pkgResult;
674
- }
675
- }
676
- }
677
- } catch {
678
- }
679
- return nameResult.confidence !== "low" ? nameResult : { type: "skill", confidence: "low", reason: "Default type" };
680
- }
681
- async function detectFromLocal(info) {
682
- const { absolutePath } = info;
683
- const dirName = path__default.basename(absolutePath);
684
- const dirResult = detectFromRepoName(dirName);
685
- if (dirResult.confidence === "high") {
686
- return dirResult;
687
- }
688
- try {
689
- const packageJsonPath = path__default.join(absolutePath, "package.json");
690
- const content = await fs__default.readFile(packageJsonPath, "utf-8");
691
- const packageJson = JSON.parse(content);
692
- const pkgResult = detectFromPackageJson(packageJson);
693
- if (pkgResult.confidence !== "low") {
694
- return pkgResult;
695
- }
696
- } catch {
697
- }
698
- const filePatterns = [
699
- { file: "SKILL.md", type: "skill" },
700
- { file: "skill.md", type: "skill" },
701
- { file: "AGENT.md", type: "agent" },
702
- { file: "agent.md", type: "agent" },
703
- { file: "mcp.json", type: "mcp" },
704
- { file: "hook.json", type: "hook" }
705
- ];
706
- for (const pattern of filePatterns) {
707
- try {
708
- const filePath = path__default.join(absolutePath, pattern.file);
709
- await fs__default.access(filePath);
169
+ if (!currentStatus.isInstalled) {
170
+ const installSuccess = await autoInstallSuperpowers(lang);
171
+ if (!installSuccess) {
710
172
  return {
711
- type: pattern.type,
712
- confidence: "high",
713
- reason: `Found ${pattern.file}`
173
+ isInstalled: false,
174
+ coreSkillsLoaded: false,
175
+ loadedSkills: [],
176
+ needsActivation: true,
177
+ lastActivation: void 0
714
178
  };
715
- } catch {
716
- }
717
- }
718
- try {
719
- const stat = await fs__default.stat(absolutePath);
720
- if (stat.isFile() && absolutePath.endsWith(".md")) {
721
- return {
722
- type: "skill",
723
- confidence: "high",
724
- reason: "Single markdown file"
725
- };
726
- }
727
- } catch {
728
- }
729
- return dirResult.confidence !== "low" ? dirResult : { type: "skill", confidence: "low", reason: "Default type" };
730
- }
731
- function detectFromRepoName(name) {
732
- const lowerName = name.toLowerCase();
733
- if (lowerName.includes("mcp-server") || lowerName.includes("mcp_server") || lowerName.startsWith("mcp-") || lowerName.endsWith("-mcp")) {
734
- return { type: "mcp", confidence: "high", reason: `Name contains MCP pattern: ${name}` };
735
- }
736
- if (lowerName.includes("agent") || lowerName.includes("-agent") || lowerName.endsWith("-agent")) {
737
- return { type: "agent", confidence: "medium", reason: `Name contains agent pattern: ${name}` };
738
- }
739
- if (lowerName.includes("hook") || lowerName.includes("-hook") || lowerName.endsWith("-hook")) {
740
- return { type: "hook", confidence: "medium", reason: `Name contains hook pattern: ${name}` };
741
- }
742
- if (lowerName.includes("skill") || lowerName.includes("-skill") || lowerName.endsWith("-skill")) {
743
- return { type: "skill", confidence: "medium", reason: `Name contains skill pattern: ${name}` };
744
- }
745
- return { type: "skill", confidence: "low", reason: "No pattern matched" };
746
- }
747
- function detectFromPackageName(packageName) {
748
- const lowerName = packageName.toLowerCase();
749
- if (lowerName.startsWith("@modelcontextprotocol/")) {
750
- return { type: "mcp", confidence: "high", reason: "MCP official scope" };
751
- }
752
- if (lowerName.includes("mcp-server") || lowerName.includes("mcp_server")) {
753
- return { type: "mcp", confidence: "high", reason: "MCP server pattern in name" };
754
- }
755
- return detectFromRepoName(packageName);
756
- }
757
- function detectFromPackageJson(packageJson) {
758
- if (packageJson.ccjk && typeof packageJson.ccjk === "object") {
759
- const ccjk = packageJson.ccjk;
760
- if (ccjk.type && typeof ccjk.type === "string") {
761
- const type = ccjk.type;
762
- if (["skill", "mcp", "agent", "hook"].includes(type)) {
763
- return { type, confidence: "high", reason: "Explicit ccjk.type field" };
764
- }
765
- }
766
- }
767
- if (Array.isArray(packageJson.keywords)) {
768
- const keywords = packageJson.keywords;
769
- const keywordMap = {
770
- "mcp-server": "mcp",
771
- "mcp": "mcp",
772
- "model-context-protocol": "mcp",
773
- "ccjk-skill": "skill",
774
- "claude-skill": "skill",
775
- "ccjk-agent": "agent",
776
- "ccjk-hook": "hook"
777
- };
778
- for (const keyword of keywords) {
779
- const type = keywordMap[keyword.toLowerCase()];
780
- if (type) {
781
- return { type, confidence: "high", reason: `Keyword: ${keyword}` };
782
- }
783
- }
784
- }
785
- if (packageJson.bin) {
786
- const binKeys = Object.keys(packageJson.bin);
787
- for (const key of binKeys) {
788
- if (key.includes("mcp") || key.includes("server")) {
789
- return { type: "mcp", confidence: "medium", reason: `Binary name: ${key}` };
790
- }
791
- }
792
- }
793
- if (typeof packageJson.main === "string") {
794
- const main = packageJson.main.toLowerCase();
795
- if (main.includes("server") || main.includes("mcp")) {
796
- return { type: "mcp", confidence: "low", reason: `Main file: ${packageJson.main}` };
797
179
  }
798
180
  }
799
- return { type: "skill", confidence: "low", reason: "No specific indicators" };
800
- }
801
-
802
- async function addCommand(source, options = {}) {
803
- const { force = false, dryRun = false, json = false, lang = "en" } = options;
804
- const i18n = getI18n(lang);
805
- const spinner = json ? null : ora(i18n.parsing).start();
806
- let sourceInfo;
807
- try {
808
- sourceInfo = parseSource(source);
809
- spinner?.succeed(i18n.parsed(sourceInfo.type));
810
- } catch (error) {
811
- spinner?.fail(i18n.parseFailed);
812
- const result = {
813
- success: false,
814
- source,
815
- sourceType: "local",
816
- pluginType: "skill",
817
- error: error instanceof Error ? error.message : String(error)
818
- };
819
- if (json) {
820
- console.log(JSON.stringify(result, null, 2));
821
- } else {
822
- console.error(ansis.red(`
823
- ${i18n.error}: ${result.error}
824
- `));
825
- }
826
- return result;
827
- }
828
- let pluginType = options.type;
829
- if (!pluginType) {
830
- spinner?.start(i18n.detectingType);
831
- try {
832
- pluginType = await detectPluginType(sourceInfo);
833
- spinner?.succeed(i18n.detectedType(pluginType));
834
- } catch {
835
- spinner?.info(i18n.defaultType);
836
- pluginType = "skill";
837
- }
838
- }
839
- spinner?.start(dryRun ? i18n.previewInstall : i18n.installing);
840
- try {
841
- let result;
842
- switch (sourceInfo.type) {
843
- case "github":
844
- result = await installFromGitHub(sourceInfo, pluginType, { force, dryRun });
845
- break;
846
- case "npm":
847
- result = await installFromNpm(sourceInfo, pluginType, { force, dryRun });
848
- break;
849
- case "local":
850
- result = await installFromLocal(sourceInfo, pluginType, { force, dryRun });
851
- break;
852
- default:
853
- throw new Error(`Unsupported source type: ${sourceInfo.type}`);
854
- }
855
- if (result.success) {
856
- spinner?.succeed(dryRun ? i18n.previewSuccess : i18n.installSuccess);
857
- } else {
858
- spinner?.fail(i18n.installFailed);
859
- }
860
- if (json) {
861
- console.log(JSON.stringify(result, null, 2));
862
- } else if (result.success && !dryRun) {
863
- printSuccessMessage(result, i18n);
864
- } else if (result.success && dryRun) {
865
- printPreviewMessage(result, i18n);
866
- } else {
867
- console.error(ansis.red(`
868
- ${i18n.error}: ${result.error}
869
- `));
870
- }
871
- return result;
872
- } catch (error) {
873
- spinner?.fail(i18n.installFailed);
874
- const result = {
875
- success: false,
876
- source,
877
- sourceType: sourceInfo.type,
878
- pluginType,
879
- error: error instanceof Error ? error.message : String(error)
880
- };
881
- if (json) {
882
- console.log(JSON.stringify(result, null, 2));
883
- } else {
884
- console.error(ansis.red(`
885
- ${i18n.error}: ${result.error}
886
- `));
887
- }
888
- return result;
889
- }
890
- }
891
- function printSuccessMessage(result, i18n) {
892
- console.log();
893
- console.log(ansis.green.bold(`\u2713 ${i18n.installed}`));
894
- console.log();
895
- console.log(` ${ansis.gray(i18n.name)}: ${result.details?.name || result.source}`);
896
- if (result.details?.version) {
897
- console.log(` ${ansis.gray(i18n.version)}: ${result.details.version}`);
898
- }
899
- console.log(` ${ansis.gray(i18n.type)}: ${result.pluginType}`);
900
- console.log(` ${ansis.gray(i18n.path)}: ${result.installedPath}`);
901
- console.log();
902
- console.log(ansis.cyan(i18n.nextSteps));
903
- switch (result.pluginType) {
904
- case "skill":
905
- console.log(` ${ansis.gray("\u2022")} ${i18n.skillHint}`);
906
- break;
907
- case "mcp":
908
- console.log(` ${ansis.gray("\u2022")} ${i18n.mcpHint}`);
909
- break;
910
- case "agent":
911
- console.log(` ${ansis.gray("\u2022")} ${i18n.agentHint}`);
912
- break;
913
- case "hook":
914
- console.log(` ${ansis.gray("\u2022")} ${i18n.hookHint}`);
915
- break;
916
- }
917
- console.log();
918
- }
919
- function printPreviewMessage(result, i18n) {
920
- console.log();
921
- console.log(ansis.yellow.bold(`\u26A1 ${i18n.preview}`));
922
- console.log();
923
- console.log(` ${ansis.gray(i18n.source)}: ${result.source}`);
924
- console.log(` ${ansis.gray(i18n.type)}: ${result.pluginType}`);
925
- console.log(` ${ansis.gray(i18n.target)}: ${result.installedPath}`);
926
- if (result.details?.files?.length) {
927
- console.log(` ${ansis.gray(i18n.files)}:`);
928
- for (const file of result.details.files.slice(0, 5)) {
929
- console.log(` ${ansis.gray("\u2022")} ${file}`);
930
- }
931
- if (result.details.files.length > 5) {
932
- console.log(` ${ansis.gray("...")} ${i18n.andMore(result.details.files.length - 5)}`);
933
- }
934
- }
935
- console.log();
936
- console.log(ansis.gray(i18n.dryRunNote));
937
- console.log();
938
- }
939
- function getI18n(lang) {
940
- const texts = {
941
- "zh-CN": {
942
- parsing: "\u89E3\u6790\u6765\u6E90...",
943
- parsed: (type) => `\u6765\u6E90\u7C7B\u578B: ${type}`,
944
- parseFailed: "\u89E3\u6790\u6765\u6E90\u5931\u8D25",
945
- detectingType: "\u68C0\u6D4B\u63D2\u4EF6\u7C7B\u578B...",
946
- detectedType: (type) => `\u68C0\u6D4B\u5230\u7C7B\u578B: ${type}`,
947
- defaultType: "\u4F7F\u7528\u9ED8\u8BA4\u7C7B\u578B: skill",
948
- installing: "\u5B89\u88C5\u4E2D...",
949
- previewInstall: "\u9884\u89C8\u5B89\u88C5...",
950
- installSuccess: "\u5B89\u88C5\u6210\u529F",
951
- previewSuccess: "\u9884\u89C8\u5B8C\u6210",
952
- installFailed: "\u5B89\u88C5\u5931\u8D25",
953
- error: "\u9519\u8BEF",
954
- installed: "\u63D2\u4EF6\u5DF2\u5B89\u88C5",
955
- preview: "\u5B89\u88C5\u9884\u89C8 (dry-run)",
956
- name: "\u540D\u79F0",
957
- version: "\u7248\u672C",
958
- type: "\u7C7B\u578B",
959
- path: "\u8DEF\u5F84",
960
- source: "\u6765\u6E90",
961
- target: "\u76EE\u6807",
962
- files: "\u6587\u4EF6",
963
- nextSteps: "\u4E0B\u4E00\u6B65:",
964
- skillHint: "\u4F7F\u7528 /skill-name \u5728 Claude Code \u4E2D\u8C03\u7528",
965
- mcpHint: "\u8FD0\u884C ccjk mcp status \u67E5\u770B\u72B6\u6001",
966
- agentHint: "\u4F7F\u7528 ccjk agent list \u67E5\u770B\u5DF2\u5B89\u88C5\u7684 agent",
967
- hookHint: "\u8FD0\u884C ccjk hooks list \u67E5\u770B\u5DF2\u5B89\u88C5\u7684 hook",
968
- dryRunNote: "\u8FD9\u662F\u9884\u89C8\u6A21\u5F0F\uFF0C\u672A\u5B9E\u9645\u5B89\u88C5\u3002\u79FB\u9664 --dry-run \u6267\u884C\u5B89\u88C5\u3002",
969
- andMore: (n) => `\u8FD8\u6709 ${n} \u4E2A\u6587\u4EF6`
970
- },
971
- "en": {
972
- parsing: "Parsing source...",
973
- parsed: (type) => `Source type: ${type}`,
974
- parseFailed: "Failed to parse source",
975
- detectingType: "Detecting plugin type...",
976
- detectedType: (type) => `Detected type: ${type}`,
977
- defaultType: "Using default type: skill",
978
- installing: "Installing...",
979
- previewInstall: "Previewing installation...",
980
- installSuccess: "Installation successful",
981
- previewSuccess: "Preview complete",
982
- installFailed: "Installation failed",
983
- error: "Error",
984
- installed: "Plugin installed",
985
- preview: "Installation preview (dry-run)",
986
- name: "Name",
987
- version: "Version",
988
- type: "Type",
989
- path: "Path",
990
- source: "Source",
991
- target: "Target",
992
- files: "Files",
993
- nextSteps: "Next steps:",
994
- skillHint: "Use /skill-name in Claude Code to invoke",
995
- mcpHint: "Run ccjk mcp status to check status",
996
- agentHint: "Use ccjk agent list to see installed agents",
997
- hookHint: "Run ccjk hooks list to see installed hooks",
998
- dryRunNote: "This is preview mode, nothing was installed. Remove --dry-run to install.",
999
- andMore: (n) => `and ${n} more files`
1000
- }
181
+ const loadResults = await loadCoreSkills(lang);
182
+ const successfulLoads = loadResults.filter((r) => r.success);
183
+ const allCoreSkillsLoaded = successfulLoads.length === loadResults.length;
184
+ const newStatus = {
185
+ isInstalled: true,
186
+ coreSkillsLoaded: allCoreSkillsLoaded,
187
+ loadedSkills: successfulLoads.map((r) => r.skill),
188
+ needsActivation: false,
189
+ lastActivation: (/* @__PURE__ */ new Date()).toISOString()
1001
190
  };
1002
- return texts[lang];
191
+ saveActivationState(newStatus);
192
+ return newStatus;
1003
193
  }
1004
194
 
1005
- export { addCommand, parseSource };
195
+ export { activateSuperpowers, autoInstallSuperpowers, checkActivationStatus, loadCoreSkills, loadSkill };