ccjk 2.3.2 → 2.4.2

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 (37) hide show
  1. package/README.md +270 -444
  2. package/README.zh-CN.md +273 -447
  3. package/dist/chunks/api-providers.mjs +5 -35
  4. package/dist/chunks/auto-bootstrap.mjs +1 -1
  5. package/dist/chunks/ccr.mjs +5 -2
  6. package/dist/chunks/claude-wrapper.mjs +442 -0
  7. package/dist/chunks/cloud-sync.mjs +29 -0
  8. package/dist/chunks/constants.mjs +1 -1
  9. package/dist/chunks/context-manager.mjs +641 -0
  10. package/dist/chunks/context.mjs +248 -0
  11. package/dist/chunks/index2.mjs +2 -0
  12. package/dist/chunks/index3.mjs +19 -19
  13. package/dist/chunks/init.mjs +18 -8
  14. package/dist/chunks/marketplace.mjs +6 -2
  15. package/dist/chunks/mcp.mjs +1 -1
  16. package/dist/chunks/menu.mjs +3 -3
  17. package/dist/chunks/notification.mjs +27 -27
  18. package/dist/chunks/package.mjs +1 -1
  19. package/dist/chunks/platform.mjs +70 -21
  20. package/dist/chunks/skills-sync.mjs +1 -1
  21. package/dist/chunks/version-checker.mjs +31 -31
  22. package/dist/cli.mjs +55 -5
  23. package/dist/i18n/locales/en/context.json +32 -0
  24. package/dist/i18n/locales/en/marketplace.json +1 -0
  25. package/dist/i18n/locales/en/mcp.json +12 -1
  26. package/dist/i18n/locales/en/superpowers.json +46 -0
  27. package/dist/i18n/locales/zh-CN/context.json +32 -0
  28. package/dist/i18n/locales/zh-CN/marketplace.json +1 -0
  29. package/dist/i18n/locales/zh-CN/mcp.json +12 -1
  30. package/dist/i18n/locales/zh-CN/superpowers.json +46 -0
  31. package/dist/index.d.mts +2 -2
  32. package/dist/index.d.ts +2 -2
  33. package/dist/shared/ccjk.QbS8EAOd.mjs +1019 -0
  34. package/dist/shared/ccjk.RR9TS76h.mjs +698 -0
  35. package/package.json +4 -1
  36. package/dist/shared/ccjk.Bi-m3LKY.mjs +0 -357
  37. package/dist/shared/ccjk.D-RZS4E2.mjs +0 -416
@@ -0,0 +1,248 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+
4
+ const { green, yellow, cyan, gray, red, blue } = chalk;
5
+ async function contextCommand(action, id, options) {
6
+ switch (action) {
7
+ case "status":
8
+ case "s":
9
+ await showStatus(options);
10
+ break;
11
+ case "compress":
12
+ case "c":
13
+ await triggerCompress(id, options);
14
+ break;
15
+ case "history":
16
+ case "h":
17
+ await showHistory(options);
18
+ break;
19
+ case "restore":
20
+ case "r":
21
+ await restoreContext(id, options);
22
+ break;
23
+ case "config":
24
+ case "cfg":
25
+ await configureContext(options);
26
+ break;
27
+ case "clear":
28
+ await clearContext(options);
29
+ break;
30
+ case "hook":
31
+ await handleHookCommand(id, options);
32
+ break;
33
+ case "help":
34
+ default:
35
+ showHelp();
36
+ }
37
+ }
38
+ async function handleHookCommand(subAction, options) {
39
+ const { contextCommand: hookContextCommand } = await import('./claude-wrapper.mjs');
40
+ await hookContextCommand(subAction || "status", [], {
41
+ lang: options.lang,
42
+ verbose: options.verbose
43
+ });
44
+ }
45
+ async function showStatus(options) {
46
+ const spinner = ora("Loading context status...").start();
47
+ try {
48
+ const { getContextManager } = await import('./context-manager.mjs');
49
+ const manager = getContextManager();
50
+ const status = await manager.getStatus();
51
+ spinner.stop();
52
+ console.log(`
53
+ ${cyan("\u{1F9E0} Context Compression Status")}
54
+ `);
55
+ console.log(`${yellow("Current Session:")}`);
56
+ console.log(` ${gray("ID:")} ${status.sessionId || "None"}`);
57
+ console.log(` ${gray("Started:")} ${status.startTime ? new Date(status.startTime).toLocaleString() : "N/A"}`);
58
+ console.log(` ${gray("Duration:")} ${status.duration || "N/A"}`);
59
+ console.log(`
60
+ ${yellow("Context Statistics:")}`);
61
+ console.log(` ${gray("Total Tokens:")} ${status.totalTokens?.toLocaleString() || 0}`);
62
+ console.log(` ${gray("Compressed Tokens:")} ${status.compressedTokens?.toLocaleString() || 0}`);
63
+ console.log(` ${gray("Compression Ratio:")} ${status.compressionRatio ? `${(status.compressionRatio * 100).toFixed(1)}%` : "N/A"}`);
64
+ console.log(` ${gray("Savings:")} ${status.tokensSaved?.toLocaleString() || 0} tokens`);
65
+ console.log(`
66
+ ${yellow("Compression Status:")}`);
67
+ console.log(` ${gray("Auto-compress:")} ${status.autoCompress ? green("Enabled") : gray("Disabled")}`);
68
+ console.log(` ${gray("Threshold:")} ${status.threshold?.toLocaleString() || "N/A"} tokens`);
69
+ console.log(` ${gray("Last Compressed:")} ${status.lastCompressed ? new Date(status.lastCompressed).toLocaleString() : "Never"}`);
70
+ console.log(` ${gray("Compressions Today:")} ${status.compressionsToday || 0}`);
71
+ if (options.verbose) {
72
+ console.log(`
73
+ ${yellow("Detailed Info:")}`);
74
+ console.log(` ${gray("Storage Path:")} ${status.storagePath || "N/A"}`);
75
+ console.log(` ${gray("Cache Size:")} ${status.cacheSize || "N/A"}`);
76
+ console.log(` ${gray("Model:")} ${status.model || "haiku"}`);
77
+ }
78
+ console.log();
79
+ } catch (error) {
80
+ spinner.fail(red("Failed to get context status"));
81
+ if (options.verbose) {
82
+ console.error(error);
83
+ } else {
84
+ console.log(gray("Run with --verbose for details"));
85
+ }
86
+ }
87
+ }
88
+ async function triggerCompress(sessionId, options) {
89
+ const spinner = ora("Compressing context...").start();
90
+ try {
91
+ const { getContextManager } = await import('./context-manager.mjs');
92
+ const manager = getContextManager();
93
+ const targetSession = sessionId || options.session;
94
+ const result = await manager.compress(targetSession);
95
+ spinner.succeed(green("Context compressed successfully"));
96
+ console.log(`
97
+ ${cyan("Compression Result:")}`);
98
+ console.log(` ${gray("Original Tokens:")} ${result.originalTokens.toLocaleString()}`);
99
+ console.log(` ${gray("Compressed Tokens:")} ${result.compressedTokens.toLocaleString()}`);
100
+ console.log(` ${gray("Reduction:")} ${((1 - result.compressedTokens / result.originalTokens) * 100).toFixed(1)}%`);
101
+ console.log(` ${gray("Time:")} ${result.duration}ms`);
102
+ console.log();
103
+ } catch (error) {
104
+ spinner.fail(red("Compression failed"));
105
+ if (options.verbose) {
106
+ console.error(error);
107
+ }
108
+ }
109
+ }
110
+ async function showHistory(options) {
111
+ const spinner = ora("Loading compression history...").start();
112
+ try {
113
+ const { getContextManager } = await import('./context-manager.mjs');
114
+ const manager = getContextManager();
115
+ const history = await manager.getHistory();
116
+ spinner.stop();
117
+ if (history.length === 0) {
118
+ console.log(yellow("\nNo compression history found.\n"));
119
+ return;
120
+ }
121
+ console.log(`
122
+ ${cyan("\u{1F4DC} Compression History")}
123
+ `);
124
+ if (options.format === "json") {
125
+ console.log(JSON.stringify(history, null, 2));
126
+ return;
127
+ }
128
+ console.log(`${gray("ID".padEnd(12))} ${gray("Date".padEnd(20))} ${gray("Original".padEnd(12))} ${gray("Compressed".padEnd(12))} ${gray("Ratio")}`);
129
+ console.log(gray("\u2500".repeat(70)));
130
+ for (const entry of history.slice(0, 20)) {
131
+ const date = new Date(entry.timestamp).toLocaleString();
132
+ const ratio = ((1 - entry.compressedTokens / entry.originalTokens) * 100).toFixed(1);
133
+ console.log(
134
+ `${entry.id.slice(0, 10).padEnd(12)} ${date.padEnd(20)} ${entry.originalTokens.toString().padEnd(12)} ${entry.compressedTokens.toString().padEnd(12)} ${green(`-${ratio}%`)}`
135
+ );
136
+ }
137
+ if (history.length > 20) {
138
+ console.log(gray(`
139
+ ... and ${history.length - 20} more entries`));
140
+ }
141
+ console.log();
142
+ } catch (error) {
143
+ spinner.fail(red("Failed to load history"));
144
+ if (options.verbose) {
145
+ console.error(error);
146
+ }
147
+ }
148
+ }
149
+ async function restoreContext(id, options) {
150
+ if (!id) {
151
+ console.log(red("\nError: Please provide a context ID to restore."));
152
+ console.log(gray("Usage: ccjk context restore <id>\n"));
153
+ return;
154
+ }
155
+ const spinner = ora(`Restoring context ${id}...`).start();
156
+ try {
157
+ const { getContextManager } = await import('./context-manager.mjs');
158
+ const manager = getContextManager();
159
+ await manager.restore(id);
160
+ spinner.succeed(green(`Context ${id} restored successfully`));
161
+ console.log();
162
+ } catch (error) {
163
+ spinner.fail(red("Failed to restore context"));
164
+ if (options.verbose) {
165
+ console.error(error);
166
+ }
167
+ }
168
+ }
169
+ async function configureContext(options) {
170
+ try {
171
+ const { getContextManager } = await import('./context-manager.mjs');
172
+ const manager = getContextManager();
173
+ const config = await manager.getConfig();
174
+ console.log(`
175
+ ${cyan("\u2699\uFE0F Context Compression Configuration")}
176
+ `);
177
+ console.log(`${yellow("Current Settings:")}`);
178
+ console.log(` ${gray("Auto-compress:")} ${config.autoCompress ? green("Enabled") : gray("Disabled")}`);
179
+ console.log(` ${gray("Threshold:")} ${config.threshold.toLocaleString()} tokens`);
180
+ console.log(` ${gray("Model:")} ${config.model}`);
181
+ console.log(` ${gray("Max History:")} ${config.maxHistory} entries`);
182
+ console.log(` ${gray("Retention Days:")} ${config.retentionDays} days`);
183
+ console.log(`
184
+ ${yellow("To modify settings:")}`);
185
+ console.log(` ${gray("Edit:")} ~/.ccjk/context-compression/config.json`);
186
+ console.log(` ${gray("Or use:")} ccjk config context.<setting> <value>`);
187
+ console.log();
188
+ } catch (error) {
189
+ console.error(red("Failed to load configuration"));
190
+ if (options.verbose) {
191
+ console.error(error);
192
+ }
193
+ }
194
+ }
195
+ async function clearContext(options) {
196
+ const spinner = ora("Clearing context cache...").start();
197
+ try {
198
+ const { getContextManager } = await import('./context-manager.mjs');
199
+ const manager = getContextManager();
200
+ await manager.clear();
201
+ spinner.succeed(green("Context cache cleared"));
202
+ console.log();
203
+ } catch (error) {
204
+ spinner.fail(red("Failed to clear cache"));
205
+ if (options.verbose) {
206
+ console.error(error);
207
+ }
208
+ }
209
+ }
210
+ function showHelp() {
211
+ console.log(`
212
+ ${cyan("\u{1F9E0} Context Compression Commands")}
213
+
214
+ ${yellow("Usage:")} ccjk context <action> [id] [options]
215
+
216
+ ${yellow("Actions:")}
217
+ ${green("status")} ${gray("s")} Show current context status
218
+ ${green("compress")} ${gray("c")} Manually trigger compression
219
+ ${green("history")} ${gray("h")} View compression history
220
+ ${green("restore")} ${gray("r")} Restore a previous context
221
+ ${green("config")} ${gray("cfg")} View/edit configuration
222
+ ${green("clear")} Clear context cache
223
+ ${green("hook")} Shell hook management
224
+ ${green("help")} Show this help
225
+
226
+ ${yellow("Hook Subcommands:")}
227
+ ${green("hook install")} Install shell hook for transparent wrapping
228
+ ${green("hook uninstall")} Remove shell hook
229
+ ${green("hook status")} Show hook installation status
230
+
231
+ ${yellow("Options:")}
232
+ ${blue("--session, -s")} <id> Session ID to operate on
233
+ ${blue("--format, -f")} <fmt> Output format (json, text)
234
+ ${blue("--verbose, -v")} Show detailed output
235
+
236
+ ${yellow("Examples:")}
237
+ ${gray("ccjk context status")} Show current status
238
+ ${gray("ccjk ctx s -v")} Status with details
239
+ ${gray("ccjk context compress")} Compress current session
240
+ ${gray("ccjk context history -f json")} History in JSON format
241
+ ${gray("ccjk context restore abc123")} Restore specific context
242
+ ${gray("ccjk context hook install")} Install shell hook
243
+
244
+ ${yellow("Aliases:")} ctx
245
+ `);
246
+ }
247
+
248
+ export { contextCommand };
@@ -18,6 +18,8 @@ const NAMESPACES = [
18
18
  "cometix",
19
19
  "codex",
20
20
  "configuration",
21
+ "context",
22
+ // Context compression system
21
23
  "errors",
22
24
  "installation",
23
25
  "interview",
@@ -1,7 +1,7 @@
1
1
  import { execSync } from 'node:child_process';
2
2
  import * as path from 'node:path';
3
3
  import * as process from 'node:process';
4
- import * as nodeFs from 'node:fs';
4
+ import * as fs from 'node:fs';
5
5
 
6
6
  function getFixCommits(options) {
7
7
  const { since, until, limit = 100, cwd = process.cwd() } = options;
@@ -618,8 +618,8 @@ class PostmortemManager {
618
618
  path.join(this.postmortemDir, "summaries")
619
619
  ];
620
620
  for (const dir of dirs) {
621
- if (!nodeFs.existsSync(dir)) {
622
- nodeFs.mkdirSync(dir, { recursive: true });
621
+ if (!fs.existsSync(dir)) {
622
+ fs.mkdirSync(dir, { recursive: true });
623
623
  }
624
624
  }
625
625
  }
@@ -633,9 +633,9 @@ class PostmortemManager {
633
633
  const filename = `${report.id}-${this.slugify(report.title)}.md`;
634
634
  const filepath = path.join(this.postmortemDir, filename);
635
635
  const content = this.renderReportToMarkdown(report);
636
- nodeFs.writeFileSync(filepath, content, "utf-8");
636
+ fs.writeFileSync(filepath, content, "utf-8");
637
637
  const jsonPath = path.join(this.postmortemDir, `${report.id}.json`);
638
- nodeFs.writeFileSync(jsonPath, JSON.stringify(report, null, 2), "utf-8");
638
+ fs.writeFileSync(jsonPath, JSON.stringify(report, null, 2), "utf-8");
639
639
  return filepath;
640
640
  }
641
641
  /**
@@ -643,11 +643,11 @@ class PostmortemManager {
643
643
  */
644
644
  getReport(id) {
645
645
  const jsonPath = path.join(this.postmortemDir, `${id}.json`);
646
- if (!nodeFs.existsSync(jsonPath)) {
646
+ if (!fs.existsSync(jsonPath)) {
647
647
  return null;
648
648
  }
649
649
  try {
650
- const content = nodeFs.readFileSync(jsonPath, "utf-8");
650
+ const content = fs.readFileSync(jsonPath, "utf-8");
651
651
  return JSON.parse(content);
652
652
  } catch {
653
653
  return null;
@@ -779,11 +779,11 @@ ${report.tags.map((t) => `\`${t}\``).join(" ")}
779
779
  */
780
780
  loadIndex() {
781
781
  const indexPath = path.join(this.postmortemDir, INDEX_FILE);
782
- if (!nodeFs.existsSync(indexPath)) {
782
+ if (!fs.existsSync(indexPath)) {
783
783
  return null;
784
784
  }
785
785
  try {
786
- const content = nodeFs.readFileSync(indexPath, "utf-8");
786
+ const content = fs.readFileSync(indexPath, "utf-8");
787
787
  return JSON.parse(content);
788
788
  } catch {
789
789
  return null;
@@ -794,17 +794,17 @@ ${report.tags.map((t) => `\`${t}\``).join(" ")}
794
794
  */
795
795
  saveIndex(index) {
796
796
  const indexPath = path.join(this.postmortemDir, INDEX_FILE);
797
- nodeFs.writeFileSync(indexPath, JSON.stringify(index, null, 2), "utf-8");
797
+ fs.writeFileSync(indexPath, JSON.stringify(index, null, 2), "utf-8");
798
798
  }
799
799
  /**
800
800
  * 更新索引
801
801
  */
802
802
  updateIndex() {
803
803
  const index = this.createEmptyIndex();
804
- const files = nodeFs.readdirSync(this.postmortemDir).filter((f) => f.startsWith("PM-") && f.endsWith(".json"));
804
+ const files = fs.readdirSync(this.postmortemDir).filter((f) => f.startsWith("PM-") && f.endsWith(".json"));
805
805
  for (const file of files) {
806
806
  try {
807
- const content = nodeFs.readFileSync(path.join(this.postmortemDir, file), "utf-8");
807
+ const content = fs.readFileSync(path.join(this.postmortemDir, file), "utf-8");
808
808
  const report = JSON.parse(content);
809
809
  index.stats.total++;
810
810
  index.stats.bySeverity[report.severity]++;
@@ -843,8 +843,8 @@ ${report.tags.map((t) => `\`${t}\``).join(" ")}
843
843
  const claudeMdPath = path.join(this.projectRoot, "CLAUDE.md");
844
844
  const injection = this.generateClaudeMdInjection();
845
845
  let content = "";
846
- if (nodeFs.existsSync(claudeMdPath)) {
847
- content = nodeFs.readFileSync(claudeMdPath, "utf-8");
846
+ if (fs.existsSync(claudeMdPath)) {
847
+ content = fs.readFileSync(claudeMdPath, "utf-8");
848
848
  }
849
849
  const startIndex = content.indexOf(CLAUDE_MD_SECTION_START);
850
850
  const endIndex = content.indexOf(CLAUDE_MD_SECTION_END);
@@ -860,7 +860,7 @@ ${CLAUDE_MD_SECTION_END}
860
860
 
861
861
  ${injectionContent.trim()}
862
862
  `;
863
- nodeFs.writeFileSync(claudeMdPath, content, "utf-8");
863
+ fs.writeFileSync(claudeMdPath, content, "utf-8");
864
864
  return {
865
865
  synced: injection.sourcePostmortems.length,
866
866
  claudeMdPath
@@ -983,9 +983,9 @@ ${injectionContent.trim()}
983
983
  }
984
984
  for (const file of filesToCheck) {
985
985
  const fullPath = path.isAbsolute(file) ? file : path.join(this.projectRoot, file);
986
- if (!nodeFs.existsSync(fullPath))
986
+ if (!fs.existsSync(fullPath))
987
987
  continue;
988
- const content = nodeFs.readFileSync(fullPath, "utf-8");
988
+ const content = fs.readFileSync(fullPath, "utf-8");
989
989
  const lines = content.split("\n");
990
990
  for (const { pattern, postmortemId } of patterns) {
991
991
  if (!pattern.fileTypes.some((ft) => file.endsWith(ft))) {
@@ -1048,7 +1048,7 @@ ${injectionContent.trim()}
1048
1048
  getAllSourceFiles() {
1049
1049
  const files = [];
1050
1050
  const walk = (dir) => {
1051
- const entries = nodeFs.readdirSync(dir, { withFileTypes: true });
1051
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
1052
1052
  for (const entry of entries) {
1053
1053
  const fullPath = path.join(dir, entry.name);
1054
1054
  const relativePath = path.relative(this.projectRoot, fullPath);
@@ -1121,7 +1121,7 @@ ${injectionContent.trim()}
1121
1121
  keyLessons: this.extractKeyLessons(newReports)
1122
1122
  };
1123
1123
  const summaryPath = path.join(this.postmortemDir, "summaries", `${version}.json`);
1124
- nodeFs.writeFileSync(summaryPath, JSON.stringify(summary, null, 2), "utf-8");
1124
+ fs.writeFileSync(summaryPath, JSON.stringify(summary, null, 2), "utf-8");
1125
1125
  if (this.config.autoSyncToClaudeMd) {
1126
1126
  await this.syncToClaudeMd();
1127
1127
  }
@@ -1,4 +1,4 @@
1
- import * as nodeFs from 'node:fs';
1
+ import * as fs from 'node:fs';
2
2
  import { existsSync, copyFileSync, mkdirSync } from 'node:fs';
3
3
  import process__default from 'node:process';
4
4
  import ansis from 'ansis';
@@ -1214,7 +1214,7 @@ async function createHomebrewSymlink(command, sourcePath) {
1214
1214
  ];
1215
1215
  let targetDir = null;
1216
1216
  for (const binPath of homebrewBinPaths) {
1217
- if (nodeFs.existsSync(binPath)) {
1217
+ if (fs.existsSync(binPath)) {
1218
1218
  targetDir = binPath;
1219
1219
  break;
1220
1220
  }
@@ -1228,16 +1228,16 @@ async function createHomebrewSymlink(command, sourcePath) {
1228
1228
  }
1229
1229
  const symlinkPath = join(targetDir, command);
1230
1230
  try {
1231
- const stats = nodeFs.lstatSync(symlinkPath);
1231
+ const stats = fs.lstatSync(symlinkPath);
1232
1232
  if (stats.isSymbolicLink()) {
1233
- const existingTarget = nodeFs.readlinkSync(symlinkPath);
1233
+ const existingTarget = fs.readlinkSync(symlinkPath);
1234
1234
  if (existingTarget === sourcePath) {
1235
1235
  return {
1236
1236
  success: true,
1237
1237
  symlinkPath
1238
1238
  };
1239
1239
  }
1240
- nodeFs.unlinkSync(symlinkPath);
1240
+ fs.unlinkSync(symlinkPath);
1241
1241
  } else {
1242
1242
  return {
1243
1243
  success: false,
@@ -1255,7 +1255,7 @@ async function createHomebrewSymlink(command, sourcePath) {
1255
1255
  }
1256
1256
  }
1257
1257
  try {
1258
- nodeFs.symlinkSync(sourcePath, symlinkPath);
1258
+ fs.symlinkSync(sourcePath, symlinkPath);
1259
1259
  return {
1260
1260
  success: true,
1261
1261
  symlinkPath
@@ -1366,7 +1366,7 @@ async function checkSuperpowersInstalled() {
1366
1366
  return { installed: true, path: superpowersPath };
1367
1367
  }
1368
1368
  }
1369
- async function installSuperpowers(_options) {
1369
+ async function installSuperpowers(options) {
1370
1370
  try {
1371
1371
  const status = await checkSuperpowersInstalled();
1372
1372
  if (status.installed) {
@@ -1375,7 +1375,17 @@ async function installSuperpowers(_options) {
1375
1375
  message: i18n.t("superpowers:alreadyInstalled")
1376
1376
  };
1377
1377
  }
1378
- return installSuperpowersViaGit();
1378
+ const result = await installSuperpowersViaGit();
1379
+ if (result.success && options.enableCloudSync && options.cloudProvider && options.cloudCredentials) {
1380
+ try {
1381
+ const { configureCloudSync } = await import('./cloud-sync.mjs');
1382
+ await configureCloudSync(options.cloudProvider, options.cloudCredentials);
1383
+ console.log(i18n.t("superpowers:cloudSync.configured"));
1384
+ } catch (error) {
1385
+ console.warn(i18n.t("superpowers:cloudSync.configFailed"), error);
1386
+ }
1387
+ }
1388
+ return result;
1379
1389
  } catch (error) {
1380
1390
  const errorMessage = error instanceof Error ? error.message : String(error);
1381
1391
  return {
@@ -1,16 +1,20 @@
1
1
  import ansis from 'ansis';
2
2
  import { i18n } from './index2.mjs';
3
- import { a as getPackage, i as isPackageInstalled, g as getInstalledPackages, u as updatePackage, c as checkForUpdates, b as uninstallPackage, d as installPackage, s as searchPackages } from '../shared/ccjk.Bi-m3LKY.mjs';
3
+ import { a as getPackage, i as isPackageInstalled, g as getInstalledPackages, u as updatePackage, c as checkForUpdates, b as uninstallPackage, d as installPackage, s as searchPackages } from '../shared/ccjk.RR9TS76h.mjs';
4
4
  import 'node:fs';
5
5
  import 'node:process';
6
6
  import 'node:url';
7
7
  import 'i18next';
8
8
  import 'i18next-fs-backend';
9
9
  import 'pathe';
10
+ import 'node:crypto';
10
11
  import 'node:fs/promises';
11
12
  import 'node:os';
13
+ import 'node:stream';
14
+ import 'node:stream/promises';
15
+ import 'tar';
16
+ import 'tinyexec';
12
17
  import './fs-operations.mjs';
13
- import 'node:crypto';
14
18
 
15
19
  async function searchCommand(query, _options) {
16
20
  try {
@@ -4,7 +4,7 @@ import 'node:child_process';
4
4
  import 'node:process';
5
5
  import { M as MCP_SERVICE_TIERS, i as isCoreService, g as getServicesByTier, c as checkMcpPerformance, f as formatPerformanceWarning, a as calculateResourceUsage, b as getOptimizationSuggestions, d as getMcpTierConfig } from './mcp-performance.mjs';
6
6
  import { e as readMcpConfig, h as backupMcpConfig, f as writeMcpConfig, ab as MCP_SERVICE_CONFIGS } from './codex.mjs';
7
- export { m as mcpInstall, a as mcpList, b as mcpSearch, c as mcpUninstall } from '../shared/ccjk.D-RZS4E2.mjs';
7
+ export { m as mcpInstall, a as mcpList, b as mcpSearch, c as mcpUninstall } from '../shared/ccjk.QbS8EAOd.mjs';
8
8
  import 'node:fs';
9
9
  import 'node:url';
10
10
  import 'i18next';
@@ -11,7 +11,7 @@ import { Q as runCodexUpdate, P as runCodexUninstall, Y as configureCodexMcp, z
11
11
  import { r as resolveCodeType } from '../shared/ccjk.CURU8gbR.mjs';
12
12
  import { h as handleExitPromptError, a as handleGeneralError } from '../shared/ccjk.tB4-Y4Qb.mjs';
13
13
  import { changeScriptLanguageFeature, configureCodexAiMemoryFeature, configureCodexDefaultModelFeature, configureEnvPermissionFeature, configureAiMemoryFeature, configureDefaultModelFeature, configureMcpFeature, configureApiFeature } from './features.mjs';
14
- import { c as checkForUpdates, g as getInstalledPackages, s as searchPackages } from '../shared/ccjk.Bi-m3LKY.mjs';
14
+ import { c as checkForUpdates, g as getInstalledPackages, s as searchPackages } from '../shared/ccjk.RR9TS76h.mjs';
15
15
  import { p as promptBoolean, a as addNumbersToChoices } from '../shared/ccjk.DhBeLRzf.mjs';
16
16
  import { isSmartGuideInstalled, generateSkillReferenceCard, removeSmartGuide, injectSmartGuide, generateQuickActionsPanel, QUICK_ACTIONS } from './smart-guide.mjs';
17
17
  import { executeCcusage } from './ccu.mjs';
@@ -25,7 +25,7 @@ import { configSwitchCommand } from './config-switch.mjs';
25
25
  import { d as detectProjectContext, h as getProjectTypeLabel, b as getApplicableRules, c as getContextFiles, j as getContextFileTypeLabel, r as readContextFile, m as mergeContextContent, e as generateContextContent, w as writeContextFile, f as getRecommendedRules, k as formatFileSize } from '../shared/ccjk.ByTIGCUC.mjs';
26
26
  import { doctor, workspaceDiagnostics } from './doctor.mjs';
27
27
  import { ensureDir, writeFileAtomic, exists, readJsonFile } from './fs-operations.mjs';
28
- import { a as mcpList, c as mcpUninstall, m as mcpInstall, d as mcpTrending, b as mcpSearch } from '../shared/ccjk.D-RZS4E2.mjs';
28
+ import { a as mcpList, c as mcpUninstall, m as mcpInstall, d as mcpTrending, b as mcpSearch } from '../shared/ccjk.QbS8EAOd.mjs';
29
29
  import { notificationCommand } from './notification.mjs';
30
30
  import { uninstall } from './uninstall.mjs';
31
31
  import { update } from './update.mjs';
@@ -1471,7 +1471,7 @@ class CloudHooksSyncClient {
1471
1471
  timeout;
1472
1472
  enableLogging;
1473
1473
  constructor(options = {}) {
1474
- this.baseUrl = options.baseUrl || "https://api.ccjk.dev/v1/hooks";
1474
+ this.baseUrl = options.baseUrl || "https://api.api.claudehome.cn/v1/hooks";
1475
1475
  this.apiKey = options.apiKey;
1476
1476
  this.timeout = options.timeout || 3e4;
1477
1477
  this.enableLogging = options.enableLogging || false;
@@ -1,14 +1,14 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
3
  import { i18n } from './index2.mjs';
4
- import * as nodeFs from 'node:fs';
5
- import nodeFs__default, { existsSync, readFileSync, mkdirSync, unlinkSync } from 'node:fs';
4
+ import * as fs from 'node:fs';
5
+ import fs__default, { existsSync, readFileSync, mkdirSync, unlinkSync } from 'node:fs';
6
6
  import * as os from 'node:os';
7
7
  import os__default, { homedir } from 'node:os';
8
8
  import { join } from 'pathe';
9
9
  import { writeFileAtomic } from './fs-operations.mjs';
10
10
  import { Buffer } from 'node:buffer';
11
- import crypto from 'node:crypto';
11
+ import crypto__default from 'node:crypto';
12
12
  import { exec } from 'node:child_process';
13
13
  import * as path from 'node:path';
14
14
  import path__default from 'node:path';
@@ -24,7 +24,7 @@ const TOKEN_PREFIX = "ccjk_";
24
24
  const TOKEN_LENGTH = 64;
25
25
  const TOKEN_VERSION = 1;
26
26
  function generateDeviceToken() {
27
- const randomBytes = crypto.randomBytes(TOKEN_LENGTH / 2);
27
+ const randomBytes = crypto__default.randomBytes(TOKEN_LENGTH / 2);
28
28
  const randomHex = randomBytes.toString("hex");
29
29
  return `${TOKEN_PREFIX}${TOKEN_VERSION}${randomHex}`;
30
30
  }
@@ -71,17 +71,17 @@ function generateMachineId() {
71
71
  // Limit to first 3 MACs
72
72
  ];
73
73
  const combined = components.join("|");
74
- return crypto.createHash("sha256").update(combined).digest("hex").slice(0, 32);
74
+ return crypto__default.createHash("sha256").update(combined).digest("hex").slice(0, 32);
75
75
  }
76
76
  function deriveEncryptionKey() {
77
77
  const machineId = generateMachineId();
78
78
  const salt = "ccjk-notification-token-v1";
79
- return crypto.pbkdf2Sync(machineId, salt, 1e5, 32, "sha256");
79
+ return crypto__default.pbkdf2Sync(machineId, salt, 1e5, 32, "sha256");
80
80
  }
81
81
  function encryptToken(token) {
82
82
  const key = deriveEncryptionKey();
83
- const iv = crypto.randomBytes(16);
84
- const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
83
+ const iv = crypto__default.randomBytes(16);
84
+ const cipher = crypto__default.createCipheriv("aes-256-gcm", key, iv);
85
85
  let encrypted = cipher.update(token, "utf8", "hex");
86
86
  encrypted += cipher.final("hex");
87
87
  const authTag = cipher.getAuthTag();
@@ -97,7 +97,7 @@ function decryptToken(encryptedToken) {
97
97
  const key = deriveEncryptionKey();
98
98
  const iv = Buffer.from(ivHex, "hex");
99
99
  const authTag = Buffer.from(authTagHex, "hex");
100
- const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
100
+ const decipher = crypto__default.createDecipheriv("aes-256-gcm", key, iv);
101
101
  decipher.setAuthTag(authTag);
102
102
  let decrypted = decipher.update(encrypted, "hex", "utf8");
103
103
  decrypted += decipher.final("utf8");
@@ -588,8 +588,8 @@ else:
588
588
  });
589
589
  } finally {
590
590
  try {
591
- if (nodeFs.existsSync(TEMP_NOTIFICATION_FILE)) {
592
- nodeFs.unlinkSync(TEMP_NOTIFICATION_FILE);
591
+ if (fs.existsSync(TEMP_NOTIFICATION_FILE)) {
592
+ fs.unlinkSync(TEMP_NOTIFICATION_FILE);
593
593
  }
594
594
  } catch {
595
595
  }
@@ -744,10 +744,10 @@ else:
744
744
  }
745
745
  async function loadLocalNotificationConfig() {
746
746
  try {
747
- if (!nodeFs.existsSync(CONFIG_FILE)) {
747
+ if (!fs.existsSync(CONFIG_FILE)) {
748
748
  return { ...DEFAULT_CONFIG };
749
749
  }
750
- const content = nodeFs.readFileSync(CONFIG_FILE, "utf-8");
750
+ const content = fs.readFileSync(CONFIG_FILE, "utf-8");
751
751
  const config = JSON.parse(content);
752
752
  return {
753
753
  ...DEFAULT_CONFIG,
@@ -760,8 +760,8 @@ async function loadLocalNotificationConfig() {
760
760
  }
761
761
  async function saveLocalNotificationConfig(config) {
762
762
  try {
763
- if (!nodeFs.existsSync(CONFIG_DIR)) {
764
- nodeFs.mkdirSync(CONFIG_DIR, { recursive: true });
763
+ if (!fs.existsSync(CONFIG_DIR)) {
764
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
765
765
  }
766
766
  const existingConfig = await loadLocalNotificationConfig();
767
767
  const newConfig = { ...existingConfig, ...config };
@@ -936,13 +936,13 @@ const CONFIG_FILE_PATH = path__default.join(CCJK_CONFIG_DIR, "config.toml");
936
936
  const SECRETS_FILE_PATH = path__default.join(CCJK_CONFIG_DIR, ".notification-secrets");
937
937
  async function loadNotificationConfig() {
938
938
  try {
939
- if (!nodeFs__default.existsSync(CCJK_CONFIG_DIR)) {
940
- nodeFs__default.mkdirSync(CCJK_CONFIG_DIR, { recursive: true });
939
+ if (!fs__default.existsSync(CCJK_CONFIG_DIR)) {
940
+ fs__default.mkdirSync(CCJK_CONFIG_DIR, { recursive: true });
941
941
  }
942
- if (!nodeFs__default.existsSync(CONFIG_FILE_PATH)) {
942
+ if (!fs__default.existsSync(CONFIG_FILE_PATH)) {
943
943
  return { ...DEFAULT_NOTIFICATION_CONFIG };
944
944
  }
945
- const configContent = nodeFs__default.readFileSync(CONFIG_FILE_PATH, "utf-8");
945
+ const configContent = fs__default.readFileSync(CONFIG_FILE_PATH, "utf-8");
946
946
  const config = parse(configContent);
947
947
  const notificationConfig = config.notification;
948
948
  if (!notificationConfig) {
@@ -978,10 +978,10 @@ async function loadNotificationConfig() {
978
978
  }
979
979
  async function loadDeviceToken() {
980
980
  try {
981
- if (!nodeFs__default.existsSync(SECRETS_FILE_PATH)) {
981
+ if (!fs__default.existsSync(SECRETS_FILE_PATH)) {
982
982
  return null;
983
983
  }
984
- const secretsContent = nodeFs__default.readFileSync(SECRETS_FILE_PATH, "utf-8");
984
+ const secretsContent = fs__default.readFileSync(SECRETS_FILE_PATH, "utf-8");
985
985
  const secrets = JSON.parse(secretsContent);
986
986
  if (!secrets.deviceToken) {
987
987
  return null;
@@ -994,12 +994,12 @@ async function loadDeviceToken() {
994
994
  }
995
995
  async function saveNotificationConfig(config) {
996
996
  try {
997
- if (!nodeFs__default.existsSync(CCJK_CONFIG_DIR)) {
998
- nodeFs__default.mkdirSync(CCJK_CONFIG_DIR, { recursive: true });
997
+ if (!fs__default.existsSync(CCJK_CONFIG_DIR)) {
998
+ fs__default.mkdirSync(CCJK_CONFIG_DIR, { recursive: true });
999
999
  }
1000
1000
  let existingConfig = {};
1001
- if (nodeFs__default.existsSync(CONFIG_FILE_PATH)) {
1002
- const configContent = nodeFs__default.readFileSync(CONFIG_FILE_PATH, "utf-8");
1001
+ if (fs__default.existsSync(CONFIG_FILE_PATH)) {
1002
+ const configContent = fs__default.readFileSync(CONFIG_FILE_PATH, "utf-8");
1003
1003
  existingConfig = parse(configContent);
1004
1004
  }
1005
1005
  const notificationConfig = { ...config };
@@ -1021,8 +1021,8 @@ async function saveDeviceToken(token) {
1021
1021
  try {
1022
1022
  const encryptedToken = encryptToken(token);
1023
1023
  let secrets = {};
1024
- if (nodeFs__default.existsSync(SECRETS_FILE_PATH)) {
1025
- const secretsContent = nodeFs__default.readFileSync(SECRETS_FILE_PATH, "utf-8");
1024
+ if (fs__default.existsSync(SECRETS_FILE_PATH)) {
1025
+ const secretsContent = fs__default.readFileSync(SECRETS_FILE_PATH, "utf-8");
1026
1026
  secrets = JSON.parse(secretsContent);
1027
1027
  }
1028
1028
  secrets.deviceToken = encryptedToken;
@@ -1,4 +1,4 @@
1
- const version = "2.3.2";
1
+ const version = "2.4.2";
2
2
  const homepage = "https://github.com/miounet11/ccjk";
3
3
 
4
4
  export { homepage, version };