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.
- package/README.md +270 -444
- package/README.zh-CN.md +273 -447
- package/dist/chunks/api-providers.mjs +5 -35
- package/dist/chunks/auto-bootstrap.mjs +1 -1
- package/dist/chunks/ccr.mjs +5 -2
- package/dist/chunks/claude-wrapper.mjs +442 -0
- package/dist/chunks/cloud-sync.mjs +29 -0
- package/dist/chunks/constants.mjs +1 -1
- package/dist/chunks/context-manager.mjs +641 -0
- package/dist/chunks/context.mjs +248 -0
- package/dist/chunks/index2.mjs +2 -0
- package/dist/chunks/index3.mjs +19 -19
- package/dist/chunks/init.mjs +18 -8
- package/dist/chunks/marketplace.mjs +6 -2
- package/dist/chunks/mcp.mjs +1 -1
- package/dist/chunks/menu.mjs +3 -3
- package/dist/chunks/notification.mjs +27 -27
- package/dist/chunks/package.mjs +1 -1
- package/dist/chunks/platform.mjs +70 -21
- package/dist/chunks/skills-sync.mjs +1 -1
- package/dist/chunks/version-checker.mjs +31 -31
- package/dist/cli.mjs +55 -5
- package/dist/i18n/locales/en/context.json +32 -0
- package/dist/i18n/locales/en/marketplace.json +1 -0
- package/dist/i18n/locales/en/mcp.json +12 -1
- package/dist/i18n/locales/en/superpowers.json +46 -0
- package/dist/i18n/locales/zh-CN/context.json +32 -0
- package/dist/i18n/locales/zh-CN/marketplace.json +1 -0
- package/dist/i18n/locales/zh-CN/mcp.json +12 -1
- package/dist/i18n/locales/zh-CN/superpowers.json +46 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/shared/ccjk.QbS8EAOd.mjs +1019 -0
- package/dist/shared/ccjk.RR9TS76h.mjs +698 -0
- package/package.json +4 -1
- package/dist/shared/ccjk.Bi-m3LKY.mjs +0 -357
- 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 };
|
package/dist/chunks/index2.mjs
CHANGED
package/dist/chunks/index3.mjs
CHANGED
|
@@ -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
|
|
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 (!
|
|
622
|
-
|
|
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
|
-
|
|
636
|
+
fs.writeFileSync(filepath, content, "utf-8");
|
|
637
637
|
const jsonPath = path.join(this.postmortemDir, `${report.id}.json`);
|
|
638
|
-
|
|
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 (!
|
|
646
|
+
if (!fs.existsSync(jsonPath)) {
|
|
647
647
|
return null;
|
|
648
648
|
}
|
|
649
649
|
try {
|
|
650
|
-
const content =
|
|
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 (!
|
|
782
|
+
if (!fs.existsSync(indexPath)) {
|
|
783
783
|
return null;
|
|
784
784
|
}
|
|
785
785
|
try {
|
|
786
|
-
const content =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 (
|
|
847
|
-
content =
|
|
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
|
-
|
|
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 (!
|
|
986
|
+
if (!fs.existsSync(fullPath))
|
|
987
987
|
continue;
|
|
988
|
-
const content =
|
|
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 =
|
|
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
|
-
|
|
1124
|
+
fs.writeFileSync(summaryPath, JSON.stringify(summary, null, 2), "utf-8");
|
|
1125
1125
|
if (this.config.autoSyncToClaudeMd) {
|
|
1126
1126
|
await this.syncToClaudeMd();
|
|
1127
1127
|
}
|
package/dist/chunks/init.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
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 (
|
|
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 =
|
|
1231
|
+
const stats = fs.lstatSync(symlinkPath);
|
|
1232
1232
|
if (stats.isSymbolicLink()) {
|
|
1233
|
-
const existingTarget =
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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 {
|
package/dist/chunks/mcp.mjs
CHANGED
|
@@ -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.
|
|
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';
|
package/dist/chunks/menu.mjs
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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
|
|
5
|
-
import
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
84
|
-
const cipher =
|
|
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 =
|
|
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 (
|
|
592
|
-
|
|
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 (!
|
|
747
|
+
if (!fs.existsSync(CONFIG_FILE)) {
|
|
748
748
|
return { ...DEFAULT_CONFIG };
|
|
749
749
|
}
|
|
750
|
-
const content =
|
|
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 (!
|
|
764
|
-
|
|
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 (!
|
|
940
|
-
|
|
939
|
+
if (!fs__default.existsSync(CCJK_CONFIG_DIR)) {
|
|
940
|
+
fs__default.mkdirSync(CCJK_CONFIG_DIR, { recursive: true });
|
|
941
941
|
}
|
|
942
|
-
if (!
|
|
942
|
+
if (!fs__default.existsSync(CONFIG_FILE_PATH)) {
|
|
943
943
|
return { ...DEFAULT_NOTIFICATION_CONFIG };
|
|
944
944
|
}
|
|
945
|
-
const configContent =
|
|
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 (!
|
|
981
|
+
if (!fs__default.existsSync(SECRETS_FILE_PATH)) {
|
|
982
982
|
return null;
|
|
983
983
|
}
|
|
984
|
-
const secretsContent =
|
|
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 (!
|
|
998
|
-
|
|
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 (
|
|
1002
|
-
const configContent =
|
|
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 (
|
|
1025
|
-
const secretsContent =
|
|
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;
|
package/dist/chunks/package.mjs
CHANGED