ccjk 9.3.25 → 9.3.27
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/dist/chunks/ccjk-all.mjs +300 -10
- package/dist/chunks/ccjk-setup.mjs +1 -1
- package/dist/chunks/ccjk-skills.mjs +41 -311
- package/dist/chunks/menu.mjs +1 -1
- package/dist/chunks/package.mjs +1 -1
- package/dist/cli.mjs +2 -2
- package/package.json +1 -1
package/dist/chunks/ccjk-all.mjs
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import ansis from 'ansis';
|
|
2
2
|
import consola from 'consola';
|
|
3
3
|
import { i18n, ensureI18nInitialized } from './index.mjs';
|
|
4
|
-
import fs__default, {
|
|
5
|
-
import path__default, {
|
|
4
|
+
import fs__default, { readFileSync, promises } from 'node:fs';
|
|
5
|
+
import path__default, { dirname, join } from 'node:path';
|
|
6
6
|
import { randomUUID, createHash } from 'node:crypto';
|
|
7
|
-
import {
|
|
7
|
+
import { ccjkSkills } from './ccjk-skills.mjs';
|
|
8
8
|
import { ccjkMcp } from './ccjk-mcp.mjs';
|
|
9
9
|
import { ccjkAgents } from './ccjk-agents.mjs';
|
|
10
10
|
import { ccjkHooks } from './ccjk-hooks.mjs';
|
|
11
11
|
import { fileURLToPath } from 'node:url';
|
|
12
12
|
import { a as analyzeProject } from '../shared/ccjk.CcFAyU1D.mjs';
|
|
13
|
+
import { ofetch } from 'ofetch';
|
|
13
14
|
import { hash } from 'ohash';
|
|
14
15
|
import { a as extractString } from '../shared/ccjk.AqnXPAzw.mjs';
|
|
15
16
|
import 'node:process';
|
|
@@ -18,8 +19,13 @@ import 'i18next-fs-backend';
|
|
|
18
19
|
import 'pathe';
|
|
19
20
|
import 'node:os';
|
|
20
21
|
import 'inquirer';
|
|
21
|
-
import 'ofetch';
|
|
22
22
|
import '../shared/ccjk.Bdhyg3X-.mjs';
|
|
23
|
+
import 'fs-extra';
|
|
24
|
+
import 'fs';
|
|
25
|
+
import 'path';
|
|
26
|
+
import 'url';
|
|
27
|
+
import 'module';
|
|
28
|
+
import 'smol-toml';
|
|
23
29
|
import './claude-config.mjs';
|
|
24
30
|
import './constants.mjs';
|
|
25
31
|
import './json-config.mjs';
|
|
@@ -28,16 +34,300 @@ import './fs-operations.mjs';
|
|
|
28
34
|
import 'node:fs/promises';
|
|
29
35
|
import './platform.mjs';
|
|
30
36
|
import 'tinyexec';
|
|
31
|
-
import 'fs-extra';
|
|
32
|
-
import 'fs';
|
|
33
|
-
import 'path';
|
|
34
|
-
import 'url';
|
|
35
|
-
import 'module';
|
|
36
|
-
import 'smol-toml';
|
|
37
37
|
import 'node:child_process';
|
|
38
38
|
import 'node:util';
|
|
39
39
|
import 'node:perf_hooks';
|
|
40
40
|
|
|
41
|
+
class CloudClientError extends Error {
|
|
42
|
+
/** Error type */
|
|
43
|
+
type;
|
|
44
|
+
/** HTTP status code if applicable */
|
|
45
|
+
statusCode;
|
|
46
|
+
/** Original error */
|
|
47
|
+
originalError;
|
|
48
|
+
constructor(type, message, statusCode, originalError) {
|
|
49
|
+
super(message);
|
|
50
|
+
this.name = "CloudClientError";
|
|
51
|
+
this.type = type;
|
|
52
|
+
this.statusCode = statusCode;
|
|
53
|
+
this.originalError = originalError;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create error from HTTP response
|
|
57
|
+
*/
|
|
58
|
+
static fromResponse(statusCode, message) {
|
|
59
|
+
let type;
|
|
60
|
+
if (statusCode === 401) type = "AUTH_ERROR";
|
|
61
|
+
else if (statusCode === 429) type = "RATE_LIMIT_ERROR";
|
|
62
|
+
else if (statusCode >= 500) type = "SERVER_ERROR";
|
|
63
|
+
else if (statusCode >= 400) type = "API_ERROR";
|
|
64
|
+
else type = "UNKNOWN_ERROR";
|
|
65
|
+
return new CloudClientError(type, message, statusCode);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Create network error
|
|
69
|
+
*/
|
|
70
|
+
static network(error) {
|
|
71
|
+
return new CloudClientError(
|
|
72
|
+
"NETWORK_ERROR",
|
|
73
|
+
error instanceof Error ? error.message : "Network connection failed",
|
|
74
|
+
void 0,
|
|
75
|
+
error
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Create timeout error
|
|
80
|
+
*/
|
|
81
|
+
static timeout(timeout) {
|
|
82
|
+
return new CloudClientError(
|
|
83
|
+
"TIMEOUT_ERROR",
|
|
84
|
+
`Request timeout after ${timeout}ms`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Create validation error
|
|
89
|
+
*/
|
|
90
|
+
static validation(message) {
|
|
91
|
+
return new CloudClientError("VALIDATION_ERROR", message);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const __dirname$1 = dirname(fileURLToPath(import.meta.url));
|
|
96
|
+
let CCJK_VERSION$1 = "9.0.0";
|
|
97
|
+
try {
|
|
98
|
+
const packageJson = JSON.parse(readFileSync(join(__dirname$1, "../../package.json"), "utf-8"));
|
|
99
|
+
CCJK_VERSION$1 = packageJson.version;
|
|
100
|
+
} catch {
|
|
101
|
+
}
|
|
102
|
+
const API_PREFIX = "/api/v1";
|
|
103
|
+
class CloudClient {
|
|
104
|
+
fetch;
|
|
105
|
+
config;
|
|
106
|
+
constructor(config) {
|
|
107
|
+
this.config = {
|
|
108
|
+
timeout: 1e4,
|
|
109
|
+
enableRetry: true,
|
|
110
|
+
maxRetries: 3,
|
|
111
|
+
enableTelemetry: true,
|
|
112
|
+
...config
|
|
113
|
+
};
|
|
114
|
+
this.fetch = ofetch.create({
|
|
115
|
+
baseURL: this.config.baseURL,
|
|
116
|
+
timeout: this.config.timeout,
|
|
117
|
+
headers: {
|
|
118
|
+
"User-Agent": `CCJK/${this.config.version || CCJK_VERSION$1}`,
|
|
119
|
+
...this.config.apiKey && { Authorization: `Bearer ${this.config.apiKey}` }
|
|
120
|
+
},
|
|
121
|
+
retry: this.config.enableRetry ? this.config.maxRetries : 0,
|
|
122
|
+
retryDelay: (context) => this.calculateRetryDelay(context.options.retry || 0)
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Calculate retry delay with exponential backoff
|
|
127
|
+
*/
|
|
128
|
+
calculateRetryDelay(attempt) {
|
|
129
|
+
const delays = [100, 200, 400, 800];
|
|
130
|
+
return delays[Math.min(attempt, delays.length - 1)];
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Handle fetch errors and convert to CloudClientError
|
|
134
|
+
*/
|
|
135
|
+
handleError(error, context) {
|
|
136
|
+
if (error instanceof CloudClientError) {
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
139
|
+
if (error instanceof Error) {
|
|
140
|
+
const errorMessage = error.message || "";
|
|
141
|
+
if (errorMessage.includes("timeout") || errorMessage.includes("timed out")) {
|
|
142
|
+
throw CloudClientError.timeout(this.config.timeout || 1e4);
|
|
143
|
+
}
|
|
144
|
+
if (errorMessage.includes("ECONNREFUSED") || errorMessage.includes("ENOTFOUND")) {
|
|
145
|
+
throw CloudClientError.network(error);
|
|
146
|
+
}
|
|
147
|
+
const statusMatch = errorMessage.match(/(\d{3})\s+/);
|
|
148
|
+
const statusCode = statusMatch ? parseInt(statusMatch[1]) : void 0;
|
|
149
|
+
let responseDetails = errorMessage;
|
|
150
|
+
try {
|
|
151
|
+
if (errorMessage.includes(":")) {
|
|
152
|
+
const parts = errorMessage.split(":");
|
|
153
|
+
if (parts.length > 1) {
|
|
154
|
+
responseDetails = parts.slice(1).join(":").trim();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
} catch {
|
|
158
|
+
}
|
|
159
|
+
consola.warn(`Cloud API error in ${context}:`, {
|
|
160
|
+
statusCode,
|
|
161
|
+
message: responseDetails,
|
|
162
|
+
originalError: error
|
|
163
|
+
});
|
|
164
|
+
if (statusCode) {
|
|
165
|
+
throw CloudClientError.fromResponse(statusCode, responseDetails);
|
|
166
|
+
}
|
|
167
|
+
throw new CloudClientError(
|
|
168
|
+
"UNKNOWN_ERROR",
|
|
169
|
+
`Unexpected error during ${context}: ${responseDetails}`,
|
|
170
|
+
void 0,
|
|
171
|
+
error
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
consola.warn(`Cloud API error in ${context}:`, error);
|
|
175
|
+
throw new CloudClientError(
|
|
176
|
+
"UNKNOWN_ERROR",
|
|
177
|
+
`Unexpected error during ${context}`,
|
|
178
|
+
void 0,
|
|
179
|
+
error
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Analyze project and get recommendations
|
|
184
|
+
*
|
|
185
|
+
* POST /api/v1/analysis/projects
|
|
186
|
+
*
|
|
187
|
+
* @param request - Project analysis request
|
|
188
|
+
* @returns Project analysis response with recommendations
|
|
189
|
+
*/
|
|
190
|
+
async analyzeProject(request) {
|
|
191
|
+
try {
|
|
192
|
+
consola.debug("Analyzing project:", request.projectRoot);
|
|
193
|
+
const response = await this.fetch(`${API_PREFIX}/analysis/projects`, {
|
|
194
|
+
method: "POST",
|
|
195
|
+
body: request
|
|
196
|
+
});
|
|
197
|
+
consola.debug(`Received ${response.recommendations.length} recommendations`);
|
|
198
|
+
return response;
|
|
199
|
+
} catch (error) {
|
|
200
|
+
this.handleError(error, "project analysis");
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Get a single template by ID
|
|
205
|
+
*
|
|
206
|
+
* GET /api/v1/templates/:id
|
|
207
|
+
*
|
|
208
|
+
* @param id - Template identifier
|
|
209
|
+
* @param language - Language for translations (optional)
|
|
210
|
+
* @returns Template response
|
|
211
|
+
*/
|
|
212
|
+
async getTemplate(id, language) {
|
|
213
|
+
try {
|
|
214
|
+
consola.debug("Fetching template:", id);
|
|
215
|
+
const response = await this.fetch(`${API_PREFIX}/templates/${encodeURIComponent(id)}`, {
|
|
216
|
+
method: "GET",
|
|
217
|
+
params: language ? { language } : void 0
|
|
218
|
+
});
|
|
219
|
+
consola.debug(`Template ${id} fetched successfully`);
|
|
220
|
+
return response;
|
|
221
|
+
} catch (error) {
|
|
222
|
+
this.handleError(error, `template fetch: ${id}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get multiple templates in batch
|
|
227
|
+
*
|
|
228
|
+
* POST /api/v1/templates/batch
|
|
229
|
+
*
|
|
230
|
+
* @param request - Batch template request
|
|
231
|
+
* @returns Batch template response
|
|
232
|
+
*/
|
|
233
|
+
async getBatchTemplates(request) {
|
|
234
|
+
try {
|
|
235
|
+
consola.debug("Fetching batch templates:", request.ids.length);
|
|
236
|
+
const response = await this.fetch(`${API_PREFIX}/templates/batch`, {
|
|
237
|
+
method: "POST",
|
|
238
|
+
body: request
|
|
239
|
+
});
|
|
240
|
+
consola.debug(`Fetched ${Object.keys(response.templates).length} templates`);
|
|
241
|
+
return response;
|
|
242
|
+
} catch (error) {
|
|
243
|
+
this.handleError(error, "batch template fetch");
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Report usage metrics
|
|
248
|
+
*
|
|
249
|
+
* POST /api/v1/telemetry/installation
|
|
250
|
+
*
|
|
251
|
+
* @param report - Usage report payload
|
|
252
|
+
* @returns Usage report response
|
|
253
|
+
*/
|
|
254
|
+
async reportUsage(report) {
|
|
255
|
+
try {
|
|
256
|
+
consola.debug("Reporting usage:", report.metricType);
|
|
257
|
+
const response = await this.fetch(`${API_PREFIX}/telemetry/installation`, {
|
|
258
|
+
method: "POST",
|
|
259
|
+
body: report
|
|
260
|
+
});
|
|
261
|
+
consola.debug("Usage report accepted");
|
|
262
|
+
return response;
|
|
263
|
+
} catch (error) {
|
|
264
|
+
consola.warn("Failed to report usage:", error);
|
|
265
|
+
return {
|
|
266
|
+
success: false,
|
|
267
|
+
requestId: "",
|
|
268
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Check API health status
|
|
274
|
+
*
|
|
275
|
+
* GET /api/v1/health
|
|
276
|
+
*
|
|
277
|
+
* @returns Health check response
|
|
278
|
+
*/
|
|
279
|
+
async healthCheck() {
|
|
280
|
+
try {
|
|
281
|
+
consola.debug("Checking API health");
|
|
282
|
+
const response = await this.fetch(`${API_PREFIX}/health`, {
|
|
283
|
+
method: "GET"
|
|
284
|
+
});
|
|
285
|
+
consola.debug(`API health: ${response.status}`);
|
|
286
|
+
return response;
|
|
287
|
+
} catch (error) {
|
|
288
|
+
this.handleError(error, "health check");
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Update client configuration
|
|
293
|
+
*
|
|
294
|
+
* @param config - Partial configuration to update
|
|
295
|
+
*/
|
|
296
|
+
updateConfig(config) {
|
|
297
|
+
this.config = { ...this.config, ...config };
|
|
298
|
+
if (config.baseURL || config.timeout || config.apiKey) {
|
|
299
|
+
this.fetch = ofetch.create({
|
|
300
|
+
baseURL: this.config.baseURL,
|
|
301
|
+
timeout: this.config.timeout,
|
|
302
|
+
headers: {
|
|
303
|
+
"User-Agent": `CCJK/${this.config.version || CCJK_VERSION$1}`,
|
|
304
|
+
...this.config.apiKey && { Authorization: `Bearer ${this.config.apiKey}` }
|
|
305
|
+
},
|
|
306
|
+
retry: this.config.enableRetry ? this.config.maxRetries : 0,
|
|
307
|
+
retryDelay: (context) => this.calculateRetryDelay(context.options.retry || 0)
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Get current configuration
|
|
313
|
+
*/
|
|
314
|
+
getConfig() {
|
|
315
|
+
return { ...this.config };
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function createCloudClient(config) {
|
|
319
|
+
return new CloudClient({
|
|
320
|
+
baseURL: "https://api.claudehome.cn",
|
|
321
|
+
timeout: 1e4,
|
|
322
|
+
version: CCJK_VERSION$1,
|
|
323
|
+
enableCache: true,
|
|
324
|
+
enableRetry: true,
|
|
325
|
+
maxRetries: 3,
|
|
326
|
+
enableTelemetry: true,
|
|
327
|
+
...config
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
|
|
41
331
|
class CloudCache {
|
|
42
332
|
memoryCache;
|
|
43
333
|
cacheDir;
|
|
@@ -7,7 +7,7 @@ import { performance } from 'node:perf_hooks';
|
|
|
7
7
|
import { promises } from 'node:fs';
|
|
8
8
|
import { join } from 'pathe';
|
|
9
9
|
import dayjs from 'dayjs';
|
|
10
|
-
import {
|
|
10
|
+
import { ccjkSkills } from './ccjk-skills.mjs';
|
|
11
11
|
import { ccjkMcp } from './ccjk-mcp.mjs';
|
|
12
12
|
import { ccjkAgents } from './ccjk-agents.mjs';
|
|
13
13
|
import { ccjkHooks } from './ccjk-hooks.mjs';
|
|
@@ -1,304 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { promises } from 'node:fs';
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
|
-
import {
|
|
3
|
+
import { join } from 'node:path';
|
|
4
4
|
import ansis from 'ansis';
|
|
5
5
|
import consola from 'consola';
|
|
6
6
|
import inquirer from 'inquirer';
|
|
7
7
|
import { i18n } from './index.mjs';
|
|
8
8
|
import { a as analyzeProject, g as getTemplatesClient } from '../shared/ccjk.CcFAyU1D.mjs';
|
|
9
|
-
import { ofetch } from 'ofetch';
|
|
10
|
-
import { fileURLToPath } from 'node:url';
|
|
11
9
|
import { g as getSkillParser } from '../shared/ccjk.Bdhyg3X-.mjs';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
this.statusCode = statusCode;
|
|
25
|
-
this.originalError = originalError;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Create error from HTTP response
|
|
29
|
-
*/
|
|
30
|
-
static fromResponse(statusCode, message) {
|
|
31
|
-
let type;
|
|
32
|
-
if (statusCode === 401) type = "AUTH_ERROR";
|
|
33
|
-
else if (statusCode === 429) type = "RATE_LIMIT_ERROR";
|
|
34
|
-
else if (statusCode >= 500) type = "SERVER_ERROR";
|
|
35
|
-
else if (statusCode >= 400) type = "API_ERROR";
|
|
36
|
-
else type = "UNKNOWN_ERROR";
|
|
37
|
-
return new CloudClientError(type, message, statusCode);
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Create network error
|
|
41
|
-
*/
|
|
42
|
-
static network(error) {
|
|
43
|
-
return new CloudClientError(
|
|
44
|
-
"NETWORK_ERROR",
|
|
45
|
-
error instanceof Error ? error.message : "Network connection failed",
|
|
46
|
-
void 0,
|
|
47
|
-
error
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Create timeout error
|
|
52
|
-
*/
|
|
53
|
-
static timeout(timeout) {
|
|
54
|
-
return new CloudClientError(
|
|
55
|
-
"TIMEOUT_ERROR",
|
|
56
|
-
`Request timeout after ${timeout}ms`
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Create validation error
|
|
61
|
-
*/
|
|
62
|
-
static validation(message) {
|
|
63
|
-
return new CloudClientError("VALIDATION_ERROR", message);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const __dirname$1 = dirname(fileURLToPath(import.meta.url));
|
|
68
|
-
let CCJK_VERSION = "9.0.0";
|
|
69
|
-
try {
|
|
70
|
-
const packageJson = JSON.parse(readFileSync(join(__dirname$1, "../../package.json"), "utf-8"));
|
|
71
|
-
CCJK_VERSION = packageJson.version;
|
|
72
|
-
} catch {
|
|
73
|
-
}
|
|
74
|
-
const API_PREFIX = "/api/v1";
|
|
75
|
-
class CloudClient {
|
|
76
|
-
fetch;
|
|
77
|
-
config;
|
|
78
|
-
constructor(config) {
|
|
79
|
-
this.config = {
|
|
80
|
-
timeout: 1e4,
|
|
81
|
-
enableRetry: true,
|
|
82
|
-
maxRetries: 3,
|
|
83
|
-
enableTelemetry: true,
|
|
84
|
-
...config
|
|
85
|
-
};
|
|
86
|
-
this.fetch = ofetch.create({
|
|
87
|
-
baseURL: this.config.baseURL,
|
|
88
|
-
timeout: this.config.timeout,
|
|
89
|
-
headers: {
|
|
90
|
-
"User-Agent": `CCJK/${this.config.version || CCJK_VERSION}`,
|
|
91
|
-
...this.config.apiKey && { Authorization: `Bearer ${this.config.apiKey}` }
|
|
92
|
-
},
|
|
93
|
-
retry: this.config.enableRetry ? this.config.maxRetries : 0,
|
|
94
|
-
retryDelay: (context) => this.calculateRetryDelay(context.options.retry || 0)
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Calculate retry delay with exponential backoff
|
|
99
|
-
*/
|
|
100
|
-
calculateRetryDelay(attempt) {
|
|
101
|
-
const delays = [100, 200, 400, 800];
|
|
102
|
-
return delays[Math.min(attempt, delays.length - 1)];
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Handle fetch errors and convert to CloudClientError
|
|
106
|
-
*/
|
|
107
|
-
handleError(error, context) {
|
|
108
|
-
if (error instanceof CloudClientError) {
|
|
109
|
-
throw error;
|
|
110
|
-
}
|
|
111
|
-
if (error instanceof Error) {
|
|
112
|
-
const errorMessage = error.message || "";
|
|
113
|
-
if (errorMessage.includes("timeout") || errorMessage.includes("timed out")) {
|
|
114
|
-
throw CloudClientError.timeout(this.config.timeout || 1e4);
|
|
115
|
-
}
|
|
116
|
-
if (errorMessage.includes("ECONNREFUSED") || errorMessage.includes("ENOTFOUND")) {
|
|
117
|
-
throw CloudClientError.network(error);
|
|
118
|
-
}
|
|
119
|
-
const statusMatch = errorMessage.match(/(\d{3})\s+/);
|
|
120
|
-
const statusCode = statusMatch ? parseInt(statusMatch[1]) : void 0;
|
|
121
|
-
let responseDetails = errorMessage;
|
|
122
|
-
try {
|
|
123
|
-
if (errorMessage.includes(":")) {
|
|
124
|
-
const parts = errorMessage.split(":");
|
|
125
|
-
if (parts.length > 1) {
|
|
126
|
-
responseDetails = parts.slice(1).join(":").trim();
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
} catch {
|
|
130
|
-
}
|
|
131
|
-
consola.warn(`Cloud API error in ${context}:`, {
|
|
132
|
-
statusCode,
|
|
133
|
-
message: responseDetails,
|
|
134
|
-
originalError: error
|
|
135
|
-
});
|
|
136
|
-
if (statusCode) {
|
|
137
|
-
throw CloudClientError.fromResponse(statusCode, responseDetails);
|
|
138
|
-
}
|
|
139
|
-
throw new CloudClientError(
|
|
140
|
-
"UNKNOWN_ERROR",
|
|
141
|
-
`Unexpected error during ${context}: ${responseDetails}`,
|
|
142
|
-
void 0,
|
|
143
|
-
error
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
consola.warn(`Cloud API error in ${context}:`, error);
|
|
147
|
-
throw new CloudClientError(
|
|
148
|
-
"UNKNOWN_ERROR",
|
|
149
|
-
`Unexpected error during ${context}`,
|
|
150
|
-
void 0,
|
|
151
|
-
error
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Analyze project and get recommendations
|
|
156
|
-
*
|
|
157
|
-
* POST /api/v1/analysis/projects
|
|
158
|
-
*
|
|
159
|
-
* @param request - Project analysis request
|
|
160
|
-
* @returns Project analysis response with recommendations
|
|
161
|
-
*/
|
|
162
|
-
async analyzeProject(request) {
|
|
163
|
-
try {
|
|
164
|
-
consola.debug("Analyzing project:", request.projectRoot);
|
|
165
|
-
const response = await this.fetch(`${API_PREFIX}/analysis/projects`, {
|
|
166
|
-
method: "POST",
|
|
167
|
-
body: request
|
|
168
|
-
});
|
|
169
|
-
consola.debug(`Received ${response.recommendations.length} recommendations`);
|
|
170
|
-
return response;
|
|
171
|
-
} catch (error) {
|
|
172
|
-
this.handleError(error, "project analysis");
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Get a single template by ID
|
|
177
|
-
*
|
|
178
|
-
* GET /api/v1/templates/:id
|
|
179
|
-
*
|
|
180
|
-
* @param id - Template identifier
|
|
181
|
-
* @param language - Language for translations (optional)
|
|
182
|
-
* @returns Template response
|
|
183
|
-
*/
|
|
184
|
-
async getTemplate(id, language) {
|
|
185
|
-
try {
|
|
186
|
-
consola.debug("Fetching template:", id);
|
|
187
|
-
const response = await this.fetch(`${API_PREFIX}/templates/${encodeURIComponent(id)}`, {
|
|
188
|
-
method: "GET",
|
|
189
|
-
params: language ? { language } : void 0
|
|
190
|
-
});
|
|
191
|
-
consola.debug(`Template ${id} fetched successfully`);
|
|
192
|
-
return response;
|
|
193
|
-
} catch (error) {
|
|
194
|
-
this.handleError(error, `template fetch: ${id}`);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Get multiple templates in batch
|
|
199
|
-
*
|
|
200
|
-
* POST /api/v1/templates/batch
|
|
201
|
-
*
|
|
202
|
-
* @param request - Batch template request
|
|
203
|
-
* @returns Batch template response
|
|
204
|
-
*/
|
|
205
|
-
async getBatchTemplates(request) {
|
|
206
|
-
try {
|
|
207
|
-
consola.debug("Fetching batch templates:", request.ids.length);
|
|
208
|
-
const response = await this.fetch(`${API_PREFIX}/templates/batch`, {
|
|
209
|
-
method: "POST",
|
|
210
|
-
body: request
|
|
211
|
-
});
|
|
212
|
-
consola.debug(`Fetched ${Object.keys(response.templates).length} templates`);
|
|
213
|
-
return response;
|
|
214
|
-
} catch (error) {
|
|
215
|
-
this.handleError(error, "batch template fetch");
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Report usage metrics
|
|
220
|
-
*
|
|
221
|
-
* POST /api/v1/telemetry/installation
|
|
222
|
-
*
|
|
223
|
-
* @param report - Usage report payload
|
|
224
|
-
* @returns Usage report response
|
|
225
|
-
*/
|
|
226
|
-
async reportUsage(report) {
|
|
227
|
-
try {
|
|
228
|
-
consola.debug("Reporting usage:", report.metricType);
|
|
229
|
-
const response = await this.fetch(`${API_PREFIX}/telemetry/installation`, {
|
|
230
|
-
method: "POST",
|
|
231
|
-
body: report
|
|
232
|
-
});
|
|
233
|
-
consola.debug("Usage report accepted");
|
|
234
|
-
return response;
|
|
235
|
-
} catch (error) {
|
|
236
|
-
consola.warn("Failed to report usage:", error);
|
|
237
|
-
return {
|
|
238
|
-
success: false,
|
|
239
|
-
requestId: "",
|
|
240
|
-
message: error instanceof Error ? error.message : "Unknown error"
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Check API health status
|
|
246
|
-
*
|
|
247
|
-
* GET /api/v1/health
|
|
248
|
-
*
|
|
249
|
-
* @returns Health check response
|
|
250
|
-
*/
|
|
251
|
-
async healthCheck() {
|
|
252
|
-
try {
|
|
253
|
-
consola.debug("Checking API health");
|
|
254
|
-
const response = await this.fetch(`${API_PREFIX}/health`, {
|
|
255
|
-
method: "GET"
|
|
256
|
-
});
|
|
257
|
-
consola.debug(`API health: ${response.status}`);
|
|
258
|
-
return response;
|
|
259
|
-
} catch (error) {
|
|
260
|
-
this.handleError(error, "health check");
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* Update client configuration
|
|
265
|
-
*
|
|
266
|
-
* @param config - Partial configuration to update
|
|
267
|
-
*/
|
|
268
|
-
updateConfig(config) {
|
|
269
|
-
this.config = { ...this.config, ...config };
|
|
270
|
-
if (config.baseURL || config.timeout || config.apiKey) {
|
|
271
|
-
this.fetch = ofetch.create({
|
|
272
|
-
baseURL: this.config.baseURL,
|
|
273
|
-
timeout: this.config.timeout,
|
|
274
|
-
headers: {
|
|
275
|
-
"User-Agent": `CCJK/${this.config.version || CCJK_VERSION}`,
|
|
276
|
-
...this.config.apiKey && { Authorization: `Bearer ${this.config.apiKey}` }
|
|
277
|
-
},
|
|
278
|
-
retry: this.config.enableRetry ? this.config.maxRetries : 0,
|
|
279
|
-
retryDelay: (context) => this.calculateRetryDelay(context.options.retry || 0)
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* Get current configuration
|
|
285
|
-
*/
|
|
286
|
-
getConfig() {
|
|
287
|
-
return { ...this.config };
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
function createCloudClient(config) {
|
|
291
|
-
return new CloudClient({
|
|
292
|
-
baseURL: "https://api.claudehome.cn",
|
|
293
|
-
timeout: 1e4,
|
|
294
|
-
version: CCJK_VERSION,
|
|
295
|
-
enableCache: true,
|
|
296
|
-
enableRetry: true,
|
|
297
|
-
maxRetries: 3,
|
|
298
|
-
enableTelemetry: true,
|
|
299
|
-
...config
|
|
300
|
-
});
|
|
301
|
-
}
|
|
10
|
+
import 'node:process';
|
|
11
|
+
import 'node:url';
|
|
12
|
+
import 'i18next';
|
|
13
|
+
import 'i18next-fs-backend';
|
|
14
|
+
import 'pathe';
|
|
15
|
+
import 'fs-extra';
|
|
16
|
+
import 'fs';
|
|
17
|
+
import 'path';
|
|
18
|
+
import 'url';
|
|
19
|
+
import 'module';
|
|
20
|
+
import 'smol-toml';
|
|
21
|
+
import 'ofetch';
|
|
302
22
|
|
|
303
23
|
async function ccjkSkills(options = {}) {
|
|
304
24
|
const logger = consola.withTag("ccjk:skills");
|
|
@@ -307,7 +27,7 @@ async function ccjkSkills(options = {}) {
|
|
|
307
27
|
const opts = {
|
|
308
28
|
lang: options.lang || "en",
|
|
309
29
|
interactive: options.interactive ?? true,
|
|
310
|
-
category: options.category,
|
|
30
|
+
category: options.category || "custom",
|
|
311
31
|
tags: options.tags || [],
|
|
312
32
|
exclude: options.exclude || [],
|
|
313
33
|
dryRun: options.dryRun ?? false,
|
|
@@ -460,7 +180,9 @@ async function getRecommendedSkills(analysis, options) {
|
|
|
460
180
|
priority: skill.rating_average ? skill.rating_average * 2 : 7,
|
|
461
181
|
source: "cloud",
|
|
462
182
|
tags: skill.tags || [],
|
|
463
|
-
templatePath: skill.id || skill.name_en.toLowerCase().replace(/\s+/g, "-")
|
|
183
|
+
templatePath: skill.id || skill.name_en.toLowerCase().replace(/\s+/g, "-"),
|
|
184
|
+
// Store template content from V8 API response
|
|
185
|
+
templateContent: skill.template_content || skill.content
|
|
464
186
|
});
|
|
465
187
|
}
|
|
466
188
|
}
|
|
@@ -643,7 +365,7 @@ async function installSkills(skills, options) {
|
|
|
643
365
|
});
|
|
644
366
|
continue;
|
|
645
367
|
}
|
|
646
|
-
const templateContent = await loadSkillTemplate(skill
|
|
368
|
+
const templateContent = await loadSkillTemplate(skill);
|
|
647
369
|
if (!templateContent) {
|
|
648
370
|
throw new Error(`Template not found: ${skill.templatePath}`);
|
|
649
371
|
}
|
|
@@ -686,15 +408,27 @@ async function installSkills(skills, options) {
|
|
|
686
408
|
}
|
|
687
409
|
return results;
|
|
688
410
|
}
|
|
689
|
-
async function loadSkillTemplate(
|
|
411
|
+
async function loadSkillTemplate(skill) {
|
|
412
|
+
const templatePath = skill.templatePath;
|
|
690
413
|
try {
|
|
691
|
-
|
|
692
|
-
|
|
414
|
+
if (skill.templateContent) {
|
|
415
|
+
return skill.templateContent;
|
|
416
|
+
}
|
|
417
|
+
const isSkillRecord = templatePath.startsWith("skill_");
|
|
418
|
+
if (isSkillRecord) {
|
|
419
|
+
consola.warn(`Cloud skill ${templatePath} has no template content. The cloud API may not have returned the content.`);
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
const isTemplateId = templatePath.startsWith("tpl_");
|
|
423
|
+
if (isTemplateId) {
|
|
693
424
|
try {
|
|
694
|
-
const
|
|
695
|
-
const template = await
|
|
696
|
-
if (template
|
|
697
|
-
|
|
425
|
+
const templatesClient = getTemplatesClient();
|
|
426
|
+
const template = await templatesClient.getTemplate(templatePath);
|
|
427
|
+
if (template) {
|
|
428
|
+
const content = template.template_content || template.content;
|
|
429
|
+
if (content) {
|
|
430
|
+
return content;
|
|
431
|
+
}
|
|
698
432
|
}
|
|
699
433
|
} catch (error) {
|
|
700
434
|
consola.warn(`Failed to fetch cloud template ${templatePath}:`, error);
|
|
@@ -753,14 +487,10 @@ function getCategoryIcon(category) {
|
|
|
753
487
|
review: "\u{1F440}",
|
|
754
488
|
seo: "\u{1F50D}",
|
|
755
489
|
devops: "\u{1F680}",
|
|
756
|
-
custom: "\u2699\uFE0F"
|
|
490
|
+
custom: "\u2699\uFE0F",
|
|
491
|
+
debug: "\u{1F41B}"
|
|
757
492
|
};
|
|
758
493
|
return icons[category] || "\u{1F4E6}";
|
|
759
494
|
}
|
|
760
495
|
|
|
761
|
-
|
|
762
|
-
__proto__: null,
|
|
763
|
-
ccjkSkills: ccjkSkills
|
|
764
|
-
};
|
|
765
|
-
|
|
766
|
-
export { CloudClientError as C, createCloudClient as a, ccjkSkills$1 as b, ccjkSkills as c };
|
|
496
|
+
export { ccjkSkills };
|
package/dist/chunks/menu.mjs
CHANGED
|
@@ -15,7 +15,7 @@ import { ClaudeCodeConfigManager } from './claude-code-config-manager.mjs';
|
|
|
15
15
|
import { configSwitchCommand } from './config-switch.mjs';
|
|
16
16
|
import { ccjkAgents } from './ccjk-agents.mjs';
|
|
17
17
|
import { ccjkMcp } from './ccjk-mcp.mjs';
|
|
18
|
-
import {
|
|
18
|
+
import { ccjkSkills } from './ccjk-skills.mjs';
|
|
19
19
|
import { checkUpdates } from './check-updates.mjs';
|
|
20
20
|
import { doctor } from './doctor.mjs';
|
|
21
21
|
import { simplifiedInit } from './init.mjs';
|
package/dist/chunks/package.mjs
CHANGED
package/dist/cli.mjs
CHANGED
|
@@ -1144,7 +1144,7 @@ ${ansis.yellow("By Status:")}`);
|
|
|
1144
1144
|
],
|
|
1145
1145
|
loader: async () => {
|
|
1146
1146
|
return async (options) => {
|
|
1147
|
-
const { ccjkSkills } = await import('./chunks/ccjk-skills.mjs')
|
|
1147
|
+
const { ccjkSkills } = await import('./chunks/ccjk-skills.mjs');
|
|
1148
1148
|
await ccjkSkills({
|
|
1149
1149
|
category: options.category,
|
|
1150
1150
|
tags: options.tags ? options.tags.split(",") : void 0,
|
|
@@ -1231,7 +1231,7 @@ ${ansis.yellow("By Status:")}`);
|
|
|
1231
1231
|
],
|
|
1232
1232
|
loader: async () => {
|
|
1233
1233
|
return async (options) => {
|
|
1234
|
-
const { ccjkSkills } = await import('./chunks/ccjk-skills.mjs')
|
|
1234
|
+
const { ccjkSkills } = await import('./chunks/ccjk-skills.mjs');
|
|
1235
1235
|
await ccjkSkills({
|
|
1236
1236
|
interactive: options.interactive !== false,
|
|
1237
1237
|
category: options.category,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccjk",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "9.3.
|
|
4
|
+
"version": "9.3.27",
|
|
5
5
|
"packageManager": "pnpm@10.17.1",
|
|
6
6
|
"description": "CCJK v9.0.0 - Revolutionary AI Development Platform with Enterprise Security, Streaming Cloud Sync, CRDT Conflict Resolution, and Unified V3 Architecture",
|
|
7
7
|
"author": {
|