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.
@@ -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, { promises, readFileSync } from 'node:fs';
5
- import path__default, { join, dirname } from 'node:path';
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 { C as CloudClientError, a as createCloudClient, c as ccjkSkills } from './ccjk-skills.mjs';
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 { c as ccjkSkills } from './ccjk-skills.mjs';
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 { readFileSync, promises } from 'node:fs';
1
+ import { promises } from 'node:fs';
2
2
  import { homedir } from 'node:os';
3
- import { dirname, join } from 'node:path';
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
- class CloudClientError extends Error {
14
- /** Error type */
15
- type;
16
- /** HTTP status code if applicable */
17
- statusCode;
18
- /** Original error */
19
- originalError;
20
- constructor(type, message, statusCode, originalError) {
21
- super(message);
22
- this.name = "CloudClientError";
23
- this.type = type;
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.templatePath);
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(templatePath) {
411
+ async function loadSkillTemplate(skill) {
412
+ const templatePath = skill.templatePath;
690
413
  try {
691
- const isCloudTemplate = templatePath.startsWith("skill_") || templatePath.startsWith("tpl_");
692
- if (isCloudTemplate) {
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 cloudClient = createCloudClient();
695
- const template = await cloudClient.getTemplate(templatePath);
696
- if (template && template.content) {
697
- return template.content;
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
- const ccjkSkills$1 = {
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 };
@@ -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 { c as ccjkSkills } from './ccjk-skills.mjs';
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';
@@ -1,4 +1,4 @@
1
- const version = "9.3.25";
1
+ const version = "9.3.27";
2
2
  const homepage = "https://github.com/miounet11/ccjk";
3
3
 
4
4
  export { homepage, version };
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').then(function (n) { return n.b; });
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').then(function (n) { return n.b; });
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.25",
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": {