ccjk 9.0.3 → 9.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/ccjk-hooks.mjs +9 -1
- package/dist/chunks/fs-operations.mjs +13 -1
- package/dist/chunks/package.mjs +1 -1
- package/dist/chunks/quick-provider.mjs +899 -0
- package/dist/cli.mjs +30 -0
- package/package.json +1 -1
|
@@ -629,6 +629,8 @@ async function validateGitTrigger(pattern, condition, projectInfo) {
|
|
|
629
629
|
const validGitHooks = [
|
|
630
630
|
"pre-commit",
|
|
631
631
|
"post-commit",
|
|
632
|
+
"commit-msg",
|
|
633
|
+
"prepare-commit-msg",
|
|
632
634
|
"pre-push",
|
|
633
635
|
"post-push",
|
|
634
636
|
"pre-merge",
|
|
@@ -636,7 +638,13 @@ async function validateGitTrigger(pattern, condition, projectInfo) {
|
|
|
636
638
|
"pre-rebase",
|
|
637
639
|
"post-rebase",
|
|
638
640
|
"pre-checkout",
|
|
639
|
-
"post-checkout"
|
|
641
|
+
"post-checkout",
|
|
642
|
+
"pre-receive",
|
|
643
|
+
"post-receive",
|
|
644
|
+
"update",
|
|
645
|
+
"pre-applypatch",
|
|
646
|
+
"post-applypatch",
|
|
647
|
+
"applypatch-msg"
|
|
640
648
|
];
|
|
641
649
|
if (!validGitHooks.includes(pattern)) {
|
|
642
650
|
throw new Error(`Invalid git hook: ${pattern}`);
|
|
@@ -106,6 +106,18 @@ function readJsonFile(path) {
|
|
|
106
106
|
);
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
+
function writeJsonFile(path, data, pretty = true) {
|
|
110
|
+
try {
|
|
111
|
+
const content = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
|
|
112
|
+
writeFile(path, content, "utf-8");
|
|
113
|
+
} catch (error) {
|
|
114
|
+
throw new FileSystemError(
|
|
115
|
+
`Failed to write JSON file: ${path}`,
|
|
116
|
+
path,
|
|
117
|
+
error
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
109
121
|
function copyFile(src, dest) {
|
|
110
122
|
try {
|
|
111
123
|
ensureFileDir(dest);
|
|
@@ -177,4 +189,4 @@ function copyDir(src, dest, options = {}) {
|
|
|
177
189
|
}
|
|
178
190
|
}
|
|
179
191
|
|
|
180
|
-
export { FileSystemError, copyDir, copyFile, ensureDir, ensureFileDir, exists, getStatsSafe, readDir, readFile, readJsonFile, removeFile, writeFile, writeFileAtomic, writeFileAtomicAsync };
|
|
192
|
+
export { FileSystemError, copyDir, copyFile, ensureDir, ensureFileDir, exists, getStatsSafe, readDir, readFile, readJsonFile, removeFile, writeFile, writeFileAtomic, writeFileAtomicAsync, writeJsonFile };
|
package/dist/chunks/package.mjs
CHANGED
|
@@ -0,0 +1,899 @@
|
|
|
1
|
+
import ansis from 'ansis';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
|
|
5
|
+
function isValidApiUrl(url) {
|
|
6
|
+
try {
|
|
7
|
+
const parsed = new URL(url);
|
|
8
|
+
return parsed.protocol === "https:" || parsed.protocol === "http:";
|
|
9
|
+
} catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const DEFAULT_TIMEOUT = 3e4;
|
|
15
|
+
const DEFAULT_RETRY_ATTEMPTS = 3;
|
|
16
|
+
const DEFAULT_RETRY_DELAY = 1e3;
|
|
17
|
+
class CloudApiClient {
|
|
18
|
+
baseUrl;
|
|
19
|
+
timeout;
|
|
20
|
+
authToken;
|
|
21
|
+
userAgent;
|
|
22
|
+
retry;
|
|
23
|
+
/**
|
|
24
|
+
* Create a new CloudApiClient instance
|
|
25
|
+
*
|
|
26
|
+
* @param config - Client configuration
|
|
27
|
+
*/
|
|
28
|
+
constructor(config) {
|
|
29
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
30
|
+
this.timeout = config.timeout || DEFAULT_TIMEOUT;
|
|
31
|
+
this.authToken = config.authToken;
|
|
32
|
+
this.userAgent = config.userAgent || "CCJK-Client/1.0";
|
|
33
|
+
this.retry = config.retry || {
|
|
34
|
+
maxAttempts: DEFAULT_RETRY_ATTEMPTS,
|
|
35
|
+
delay: DEFAULT_RETRY_DELAY
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
// ==========================================================================
|
|
39
|
+
// Configuration Methods
|
|
40
|
+
// ==========================================================================
|
|
41
|
+
/**
|
|
42
|
+
* Set authentication token
|
|
43
|
+
*
|
|
44
|
+
* @param token - Authentication token
|
|
45
|
+
*/
|
|
46
|
+
setAuthToken(token) {
|
|
47
|
+
this.authToken = token;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Clear authentication token
|
|
51
|
+
*/
|
|
52
|
+
clearAuthToken() {
|
|
53
|
+
this.authToken = void 0;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get current base URL
|
|
57
|
+
*/
|
|
58
|
+
getBaseUrl() {
|
|
59
|
+
return this.baseUrl;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Update base URL
|
|
63
|
+
*
|
|
64
|
+
* @param url - New base URL
|
|
65
|
+
*/
|
|
66
|
+
setBaseUrl(url) {
|
|
67
|
+
this.baseUrl = url.replace(/\/$/, "");
|
|
68
|
+
}
|
|
69
|
+
// ==========================================================================
|
|
70
|
+
// Request Methods
|
|
71
|
+
// ==========================================================================
|
|
72
|
+
/**
|
|
73
|
+
* Make an HTTP request to the cloud service
|
|
74
|
+
*
|
|
75
|
+
* @param path - API endpoint path (e.g., '/plugins/recommend')
|
|
76
|
+
* @param options - Request options
|
|
77
|
+
* @returns API response
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* const response = await client.request<{ data: string }>('/api/endpoint', {
|
|
82
|
+
* method: 'POST',
|
|
83
|
+
* body: { key: 'value' },
|
|
84
|
+
* timeout: 5000
|
|
85
|
+
* })
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
async request(path, options) {
|
|
89
|
+
const maxAttempts = options.retry?.maxAttempts || this.retry.maxAttempts;
|
|
90
|
+
const retryDelay = options.retry?.delay || this.retry.delay;
|
|
91
|
+
let lastError = null;
|
|
92
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
93
|
+
try {
|
|
94
|
+
return await this.executeRequest(path, options);
|
|
95
|
+
} catch (error) {
|
|
96
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
97
|
+
if (attempt === maxAttempts || this.isClientError(lastError)) {
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
await this.sleep(retryDelay * attempt);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
success: false,
|
|
105
|
+
error: lastError?.message || "Request failed",
|
|
106
|
+
code: "REQUEST_FAILED"
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Execute a single HTTP request
|
|
111
|
+
*
|
|
112
|
+
* @private
|
|
113
|
+
*/
|
|
114
|
+
async executeRequest(path, options) {
|
|
115
|
+
const url = this.buildUrl(path, options.query);
|
|
116
|
+
const timeout = options.timeout || this.timeout;
|
|
117
|
+
const controller = new AbortController();
|
|
118
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
119
|
+
try {
|
|
120
|
+
const headers = this.buildHeaders(options);
|
|
121
|
+
const response = await fetch(url, {
|
|
122
|
+
method: options.method,
|
|
123
|
+
headers,
|
|
124
|
+
body: options.body ? JSON.stringify(options.body) : void 0,
|
|
125
|
+
signal: controller.signal
|
|
126
|
+
});
|
|
127
|
+
clearTimeout(timeoutId);
|
|
128
|
+
const data = await response.json();
|
|
129
|
+
if (!response.ok) {
|
|
130
|
+
return {
|
|
131
|
+
success: false,
|
|
132
|
+
error: data.error || `HTTP ${response.status}: ${response.statusText}`,
|
|
133
|
+
code: data.code || `HTTP_${response.status}`
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
...data,
|
|
138
|
+
success: true
|
|
139
|
+
};
|
|
140
|
+
} catch (error) {
|
|
141
|
+
clearTimeout(timeoutId);
|
|
142
|
+
if (error instanceof Error) {
|
|
143
|
+
if (error.name === "AbortError") {
|
|
144
|
+
return {
|
|
145
|
+
success: false,
|
|
146
|
+
error: "Request timeout",
|
|
147
|
+
code: "TIMEOUT"
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
success: false,
|
|
152
|
+
error: error.message,
|
|
153
|
+
code: "NETWORK_ERROR"
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
success: false,
|
|
158
|
+
error: String(error),
|
|
159
|
+
code: "UNKNOWN_ERROR"
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// ==========================================================================
|
|
164
|
+
// Convenience Methods
|
|
165
|
+
// ==========================================================================
|
|
166
|
+
/**
|
|
167
|
+
* Make a GET request
|
|
168
|
+
*
|
|
169
|
+
* @param path - API endpoint path
|
|
170
|
+
* @param query - Query parameters
|
|
171
|
+
* @param options - Additional request options
|
|
172
|
+
* @returns API response
|
|
173
|
+
*/
|
|
174
|
+
async get(path, query, options) {
|
|
175
|
+
return this.request(path, {
|
|
176
|
+
method: "GET",
|
|
177
|
+
query,
|
|
178
|
+
...options
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Make a POST request
|
|
183
|
+
*
|
|
184
|
+
* @param path - API endpoint path
|
|
185
|
+
* @param body - Request body
|
|
186
|
+
* @param options - Additional request options
|
|
187
|
+
* @returns API response
|
|
188
|
+
*/
|
|
189
|
+
async post(path, body, options) {
|
|
190
|
+
return this.request(path, {
|
|
191
|
+
method: "POST",
|
|
192
|
+
body,
|
|
193
|
+
...options
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Make a PUT request
|
|
198
|
+
*
|
|
199
|
+
* @param path - API endpoint path
|
|
200
|
+
* @param body - Request body
|
|
201
|
+
* @param options - Additional request options
|
|
202
|
+
* @returns API response
|
|
203
|
+
*/
|
|
204
|
+
async put(path, body, options) {
|
|
205
|
+
return this.request(path, {
|
|
206
|
+
method: "PUT",
|
|
207
|
+
body,
|
|
208
|
+
...options
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Make a DELETE request
|
|
213
|
+
*
|
|
214
|
+
* @param path - API endpoint path
|
|
215
|
+
* @param options - Additional request options
|
|
216
|
+
* @returns API response
|
|
217
|
+
*/
|
|
218
|
+
async delete(path, options) {
|
|
219
|
+
return this.request(path, {
|
|
220
|
+
method: "DELETE",
|
|
221
|
+
...options
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
// ==========================================================================
|
|
225
|
+
// Helper Methods
|
|
226
|
+
// ==========================================================================
|
|
227
|
+
/**
|
|
228
|
+
* Build full URL with query parameters
|
|
229
|
+
*
|
|
230
|
+
* @private
|
|
231
|
+
*/
|
|
232
|
+
buildUrl(path, query) {
|
|
233
|
+
const url = `${this.baseUrl}${path}`;
|
|
234
|
+
if (!query || Object.keys(query).length === 0) {
|
|
235
|
+
return url;
|
|
236
|
+
}
|
|
237
|
+
const params = new URLSearchParams();
|
|
238
|
+
for (const [key, value] of Object.entries(query)) {
|
|
239
|
+
params.append(key, String(value));
|
|
240
|
+
}
|
|
241
|
+
return `${url}?${params.toString()}`;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Build request headers
|
|
245
|
+
*
|
|
246
|
+
* @private
|
|
247
|
+
*/
|
|
248
|
+
buildHeaders(options) {
|
|
249
|
+
const headers = {
|
|
250
|
+
"Content-Type": "application/json",
|
|
251
|
+
"User-Agent": this.userAgent,
|
|
252
|
+
...options.headers
|
|
253
|
+
};
|
|
254
|
+
const token = options.authToken || this.authToken;
|
|
255
|
+
if (token) {
|
|
256
|
+
headers.Authorization = `Bearer ${token}`;
|
|
257
|
+
}
|
|
258
|
+
return headers;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Check if error is a client error (4xx)
|
|
262
|
+
*
|
|
263
|
+
* @private
|
|
264
|
+
*/
|
|
265
|
+
isClientError(error) {
|
|
266
|
+
return error.message.includes("HTTP 4");
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Sleep for specified milliseconds
|
|
270
|
+
*
|
|
271
|
+
* @private
|
|
272
|
+
*/
|
|
273
|
+
sleep(ms) {
|
|
274
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function createApiClient(config) {
|
|
278
|
+
return new CloudApiClient(config);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const CLOUD_API_BASE_URL = "https://api.claudehome.cn/v1";
|
|
282
|
+
const REQUEST_TIMEOUT = 1e4;
|
|
283
|
+
const BUILTIN_PROVIDERS = {
|
|
284
|
+
"302": {
|
|
285
|
+
shortcode: "302",
|
|
286
|
+
name: "302.AI",
|
|
287
|
+
apiUrl: "https://api.302.ai",
|
|
288
|
+
description: "302.AI \u4E2D\u8F6C\u670D\u52A1 - \u652F\u6301\u591A\u79CD\u6A21\u578B",
|
|
289
|
+
models: ["gpt-4", "gpt-4-turbo", "gpt-3.5-turbo", "claude-3-opus", "claude-3-sonnet"],
|
|
290
|
+
verified: true,
|
|
291
|
+
category: "relay",
|
|
292
|
+
status: "active",
|
|
293
|
+
createdAt: "2024-01-01T00:00:00Z"
|
|
294
|
+
},
|
|
295
|
+
"glm": {
|
|
296
|
+
shortcode: "glm",
|
|
297
|
+
name: "\u667A\u8C31AI",
|
|
298
|
+
apiUrl: "https://open.bigmodel.cn/api/paas/v4",
|
|
299
|
+
description: "\u667A\u8C31 GLM \u5927\u6A21\u578B",
|
|
300
|
+
models: ["glm-4", "glm-4-plus", "glm-3-turbo"],
|
|
301
|
+
verified: true,
|
|
302
|
+
category: "domestic",
|
|
303
|
+
status: "active",
|
|
304
|
+
createdAt: "2024-01-01T00:00:00Z"
|
|
305
|
+
},
|
|
306
|
+
"kimi": {
|
|
307
|
+
shortcode: "kimi",
|
|
308
|
+
name: "\u6708\u4E4B\u6697\u9762 Kimi",
|
|
309
|
+
apiUrl: "https://api.moonshot.cn/v1",
|
|
310
|
+
description: "Moonshot Kimi \u5927\u6A21\u578B",
|
|
311
|
+
models: ["moonshot-v1-8k", "moonshot-v1-32k", "moonshot-v1-128k"],
|
|
312
|
+
verified: true,
|
|
313
|
+
category: "domestic",
|
|
314
|
+
status: "active",
|
|
315
|
+
createdAt: "2024-01-01T00:00:00Z"
|
|
316
|
+
},
|
|
317
|
+
"minimax": {
|
|
318
|
+
shortcode: "minimax",
|
|
319
|
+
name: "MiniMax",
|
|
320
|
+
apiUrl: "https://api.minimax.chat/v1",
|
|
321
|
+
description: "MiniMax \u5927\u6A21\u578B",
|
|
322
|
+
models: ["abab5.5-chat", "abab6-chat", "abab6.5-chat"],
|
|
323
|
+
verified: true,
|
|
324
|
+
category: "domestic",
|
|
325
|
+
status: "active",
|
|
326
|
+
createdAt: "2024-01-01T00:00:00Z"
|
|
327
|
+
},
|
|
328
|
+
"deepseek": {
|
|
329
|
+
shortcode: "deepseek",
|
|
330
|
+
name: "DeepSeek",
|
|
331
|
+
apiUrl: "https://api.deepseek.com/v1",
|
|
332
|
+
description: "DeepSeek \u5927\u6A21\u578B",
|
|
333
|
+
models: ["deepseek-chat", "deepseek-coder"],
|
|
334
|
+
verified: true,
|
|
335
|
+
category: "domestic",
|
|
336
|
+
status: "active",
|
|
337
|
+
createdAt: "2024-01-01T00:00:00Z"
|
|
338
|
+
},
|
|
339
|
+
"qwen": {
|
|
340
|
+
shortcode: "qwen",
|
|
341
|
+
name: "\u901A\u4E49\u5343\u95EE",
|
|
342
|
+
apiUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
343
|
+
description: "\u963F\u91CC\u901A\u4E49\u5343\u95EE\u5927\u6A21\u578B",
|
|
344
|
+
models: ["qwen-turbo", "qwen-plus", "qwen-max"],
|
|
345
|
+
verified: true,
|
|
346
|
+
category: "domestic",
|
|
347
|
+
status: "active",
|
|
348
|
+
createdAt: "2024-01-01T00:00:00Z"
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
class ProviderRegistryService {
|
|
352
|
+
client;
|
|
353
|
+
useCloud = true;
|
|
354
|
+
constructor(options) {
|
|
355
|
+
this.client = createApiClient({
|
|
356
|
+
baseUrl: options?.baseUrl || CLOUD_API_BASE_URL,
|
|
357
|
+
timeout: REQUEST_TIMEOUT,
|
|
358
|
+
userAgent: "CCJK-QuickLaunch/1.0"
|
|
359
|
+
});
|
|
360
|
+
this.useCloud = options?.useCloud ?? true;
|
|
361
|
+
}
|
|
362
|
+
// ==========================================================================
|
|
363
|
+
// Query Methods
|
|
364
|
+
// ==========================================================================
|
|
365
|
+
/**
|
|
366
|
+
* Get provider by shortcode
|
|
367
|
+
*
|
|
368
|
+
* First tries cloud registry, falls back to built-in providers.
|
|
369
|
+
*
|
|
370
|
+
* @param shortcode - Provider shortcode (e.g., "302", "glm")
|
|
371
|
+
* @returns Provider info or null if not found
|
|
372
|
+
*/
|
|
373
|
+
async getProvider(shortcode) {
|
|
374
|
+
const normalizedCode = shortcode.toLowerCase().trim();
|
|
375
|
+
if (this.useCloud) {
|
|
376
|
+
try {
|
|
377
|
+
const response = await this.client.get(
|
|
378
|
+
`/providers/${encodeURIComponent(normalizedCode)}`
|
|
379
|
+
);
|
|
380
|
+
if (response.success && response.data?.data) {
|
|
381
|
+
return response.data.data;
|
|
382
|
+
}
|
|
383
|
+
} catch {
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return BUILTIN_PROVIDERS[normalizedCode] || null;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Check if shortcode exists
|
|
390
|
+
*
|
|
391
|
+
* @param shortcode - Provider shortcode to check
|
|
392
|
+
* @returns true if exists, false otherwise
|
|
393
|
+
*/
|
|
394
|
+
async exists(shortcode) {
|
|
395
|
+
const provider = await this.getProvider(shortcode);
|
|
396
|
+
return provider !== null;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Check if shortcode is available for registration
|
|
400
|
+
*
|
|
401
|
+
* @param shortcode - Provider shortcode to check
|
|
402
|
+
* @returns true if available, false if taken
|
|
403
|
+
*/
|
|
404
|
+
async isAvailable(shortcode) {
|
|
405
|
+
return !await this.exists(shortcode);
|
|
406
|
+
}
|
|
407
|
+
// ==========================================================================
|
|
408
|
+
// Registration Methods
|
|
409
|
+
// ==========================================================================
|
|
410
|
+
/**
|
|
411
|
+
* Create a new provider in the cloud registry
|
|
412
|
+
*
|
|
413
|
+
* @param input - Provider creation data
|
|
414
|
+
* @returns Created provider or error
|
|
415
|
+
*/
|
|
416
|
+
async createProvider(input) {
|
|
417
|
+
if (!this.useCloud) {
|
|
418
|
+
return {
|
|
419
|
+
success: false,
|
|
420
|
+
error: {
|
|
421
|
+
code: "CLOUD_DISABLED",
|
|
422
|
+
message: "Cloud service is disabled"
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
try {
|
|
427
|
+
const response = await this.client.post(
|
|
428
|
+
"/providers",
|
|
429
|
+
input
|
|
430
|
+
);
|
|
431
|
+
if (response.success && response.data) {
|
|
432
|
+
return response.data;
|
|
433
|
+
}
|
|
434
|
+
return {
|
|
435
|
+
success: false,
|
|
436
|
+
error: {
|
|
437
|
+
code: response.code || "CREATE_FAILED",
|
|
438
|
+
message: response.error || "Failed to create provider"
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
} catch (error) {
|
|
442
|
+
return {
|
|
443
|
+
success: false,
|
|
444
|
+
error: {
|
|
445
|
+
code: "NETWORK_ERROR",
|
|
446
|
+
message: error instanceof Error ? error.message : "Network error"
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
// ==========================================================================
|
|
452
|
+
// List Methods
|
|
453
|
+
// ==========================================================================
|
|
454
|
+
/**
|
|
455
|
+
* List all available providers
|
|
456
|
+
*
|
|
457
|
+
* @param options - List options
|
|
458
|
+
* @returns List of providers
|
|
459
|
+
*/
|
|
460
|
+
async listProviders(options) {
|
|
461
|
+
if (this.useCloud) {
|
|
462
|
+
try {
|
|
463
|
+
const query = {};
|
|
464
|
+
if (options?.category) query.category = options.category;
|
|
465
|
+
if (options?.verified !== void 0) query.verified = options.verified;
|
|
466
|
+
if (options?.limit) query.limit = options.limit;
|
|
467
|
+
const response = await this.client.get(
|
|
468
|
+
"/providers",
|
|
469
|
+
query
|
|
470
|
+
);
|
|
471
|
+
if (response.success && response.data?.data?.providers) {
|
|
472
|
+
return response.data.data.providers;
|
|
473
|
+
}
|
|
474
|
+
} catch {
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
let providers = Object.values(BUILTIN_PROVIDERS);
|
|
478
|
+
if (options?.category) {
|
|
479
|
+
providers = providers.filter((p) => p.category === options.category);
|
|
480
|
+
}
|
|
481
|
+
if (options?.verified !== void 0) {
|
|
482
|
+
providers = providers.filter((p) => p.verified === options.verified);
|
|
483
|
+
}
|
|
484
|
+
if (options?.limit) {
|
|
485
|
+
providers = providers.slice(0, options.limit);
|
|
486
|
+
}
|
|
487
|
+
return providers;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Get built-in provider (always available, no network)
|
|
491
|
+
*
|
|
492
|
+
* @param shortcode - Provider shortcode
|
|
493
|
+
* @returns Built-in provider or null
|
|
494
|
+
*/
|
|
495
|
+
getBuiltinProvider(shortcode) {
|
|
496
|
+
return BUILTIN_PROVIDERS[shortcode.toLowerCase()] || null;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* List all built-in providers
|
|
500
|
+
*
|
|
501
|
+
* @returns Array of built-in providers
|
|
502
|
+
*/
|
|
503
|
+
listBuiltinProviders() {
|
|
504
|
+
return Object.values(BUILTIN_PROVIDERS);
|
|
505
|
+
}
|
|
506
|
+
// ==========================================================================
|
|
507
|
+
// Configuration
|
|
508
|
+
// ==========================================================================
|
|
509
|
+
/**
|
|
510
|
+
* Enable or disable cloud service
|
|
511
|
+
*/
|
|
512
|
+
setUseCloud(enabled) {
|
|
513
|
+
this.useCloud = enabled;
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Check if cloud service is enabled
|
|
517
|
+
*/
|
|
518
|
+
isCloudEnabled() {
|
|
519
|
+
return this.useCloud;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
let _instance = null;
|
|
523
|
+
function getProviderRegistry() {
|
|
524
|
+
if (!_instance) {
|
|
525
|
+
_instance = new ProviderRegistryService();
|
|
526
|
+
}
|
|
527
|
+
return _instance;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
const KNOWN_COMMANDS = /* @__PURE__ */ new Set([
|
|
531
|
+
// Core commands
|
|
532
|
+
"",
|
|
533
|
+
"init",
|
|
534
|
+
"update",
|
|
535
|
+
"doctor",
|
|
536
|
+
"help",
|
|
537
|
+
// Extended commands
|
|
538
|
+
"serve",
|
|
539
|
+
"mcp",
|
|
540
|
+
"browser",
|
|
541
|
+
"interview",
|
|
542
|
+
"commit",
|
|
543
|
+
"config",
|
|
544
|
+
"daemon",
|
|
545
|
+
"providers",
|
|
546
|
+
"task",
|
|
547
|
+
"tasks",
|
|
548
|
+
"keybinding",
|
|
549
|
+
"kb",
|
|
550
|
+
"history",
|
|
551
|
+
"hist",
|
|
552
|
+
"ccr",
|
|
553
|
+
"vim",
|
|
554
|
+
"permissions",
|
|
555
|
+
"perm",
|
|
556
|
+
"skills",
|
|
557
|
+
"sk",
|
|
558
|
+
"skill",
|
|
559
|
+
"agent",
|
|
560
|
+
"ag",
|
|
561
|
+
"ccu",
|
|
562
|
+
"stats",
|
|
563
|
+
"uninstall",
|
|
564
|
+
"check-updates",
|
|
565
|
+
"check",
|
|
566
|
+
"config-switch",
|
|
567
|
+
"cs",
|
|
568
|
+
"workflows",
|
|
569
|
+
"wf",
|
|
570
|
+
"notification",
|
|
571
|
+
"notify",
|
|
572
|
+
"session",
|
|
573
|
+
"context",
|
|
574
|
+
"ctx",
|
|
575
|
+
"api",
|
|
576
|
+
"team",
|
|
577
|
+
"thinking",
|
|
578
|
+
"think",
|
|
579
|
+
"postmortem",
|
|
580
|
+
"pm",
|
|
581
|
+
"claude",
|
|
582
|
+
"monitor",
|
|
583
|
+
// CCJK v8 commands
|
|
584
|
+
"ccjk:mcp",
|
|
585
|
+
"ccjk-mcp",
|
|
586
|
+
"ccjk:skills",
|
|
587
|
+
"ccjk-skills",
|
|
588
|
+
"ccjk:agents",
|
|
589
|
+
"ccjk-agents",
|
|
590
|
+
"ccjk:hooks",
|
|
591
|
+
"ccjk-hooks",
|
|
592
|
+
"ccjk:all",
|
|
593
|
+
"ccjk-all",
|
|
594
|
+
"ccjk:setup",
|
|
595
|
+
"ccjk-setup",
|
|
596
|
+
// Special commands
|
|
597
|
+
"cloud",
|
|
598
|
+
"system",
|
|
599
|
+
"sys",
|
|
600
|
+
"plugin",
|
|
601
|
+
"completion",
|
|
602
|
+
// Deprecated but still recognized
|
|
603
|
+
"skills-sync",
|
|
604
|
+
"agents-sync",
|
|
605
|
+
"marketplace",
|
|
606
|
+
"quick",
|
|
607
|
+
"deep",
|
|
608
|
+
"setup",
|
|
609
|
+
"sync",
|
|
610
|
+
"versions",
|
|
611
|
+
"upgrade",
|
|
612
|
+
"config-scan",
|
|
613
|
+
"workspace"
|
|
614
|
+
]);
|
|
615
|
+
function isKnownCommand(arg) {
|
|
616
|
+
if (!arg) return true;
|
|
617
|
+
if (arg.startsWith("-")) return true;
|
|
618
|
+
return KNOWN_COMMANDS.has(arg.toLowerCase());
|
|
619
|
+
}
|
|
620
|
+
function couldBeShortcode(arg) {
|
|
621
|
+
if (!arg) return false;
|
|
622
|
+
if (arg.startsWith("-")) return false;
|
|
623
|
+
if (isKnownCommand(arg)) return false;
|
|
624
|
+
return /^[a-z0-9][a-z0-9-]{0,18}[a-z0-9]?$/i.test(arg);
|
|
625
|
+
}
|
|
626
|
+
async function quickProviderLaunch(shortcode, options = {}) {
|
|
627
|
+
const registry = getProviderRegistry();
|
|
628
|
+
const normalizedCode = shortcode.toLowerCase().trim();
|
|
629
|
+
console.log();
|
|
630
|
+
const spinner = ora({
|
|
631
|
+
text: ansis.gray(`\u6B63\u5728\u67E5\u8BE2\u4F9B\u5E94\u5546 "${normalizedCode}"...`),
|
|
632
|
+
color: "cyan"
|
|
633
|
+
}).start();
|
|
634
|
+
try {
|
|
635
|
+
const provider = await registry.getProvider(normalizedCode);
|
|
636
|
+
spinner.stop();
|
|
637
|
+
if (provider) {
|
|
638
|
+
return await handleExistingProvider(provider, options);
|
|
639
|
+
} else {
|
|
640
|
+
return await handleNewProvider(normalizedCode, options);
|
|
641
|
+
}
|
|
642
|
+
} catch (error) {
|
|
643
|
+
spinner.fail(ansis.red("\u67E5\u8BE2\u5931\u8D25"));
|
|
644
|
+
console.error(ansis.gray(error instanceof Error ? error.message : "\u7F51\u7EDC\u9519\u8BEF"));
|
|
645
|
+
return false;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
async function handleExistingProvider(provider, options) {
|
|
649
|
+
console.log(ansis.cyan.bold(`
|
|
650
|
+
\u{1F680} \u5FEB\u901F\u914D\u7F6E: ${provider.name}`));
|
|
651
|
+
console.log(ansis.gray("\u2500".repeat(40)));
|
|
652
|
+
console.log(` ${ansis.yellow("\u77ED\u7801:")} ${provider.shortcode}`);
|
|
653
|
+
console.log(` ${ansis.yellow("API URL:")} ${provider.apiUrl}`);
|
|
654
|
+
if (provider.description) {
|
|
655
|
+
console.log(` ${ansis.yellow("\u63CF\u8FF0:")} ${provider.description}`);
|
|
656
|
+
}
|
|
657
|
+
if (provider.verified) {
|
|
658
|
+
console.log(` ${ansis.green("\u2713")} \u5B98\u65B9\u9A8C\u8BC1`);
|
|
659
|
+
}
|
|
660
|
+
console.log();
|
|
661
|
+
const { confirmed } = await inquirer.prompt([
|
|
662
|
+
{
|
|
663
|
+
type: "confirm",
|
|
664
|
+
name: "confirmed",
|
|
665
|
+
message: `\u662F\u5426\u4F7F\u7528 ${ansis.cyan(provider.name)} \u4F5C\u4E3A API \u4F9B\u5E94\u5546?`,
|
|
666
|
+
default: true
|
|
667
|
+
}
|
|
668
|
+
]);
|
|
669
|
+
if (!confirmed) {
|
|
670
|
+
console.log(ansis.gray("\n\u5DF2\u53D6\u6D88\uFF0C\u8FDB\u5165\u4E3B\u83DC\u5355...\n"));
|
|
671
|
+
return false;
|
|
672
|
+
}
|
|
673
|
+
const config = await configureProvider(provider);
|
|
674
|
+
if (config) {
|
|
675
|
+
await saveProviderConfig(config);
|
|
676
|
+
showSuccessMessage(config);
|
|
677
|
+
return true;
|
|
678
|
+
}
|
|
679
|
+
return false;
|
|
680
|
+
}
|
|
681
|
+
async function handleNewProvider(shortcode, options) {
|
|
682
|
+
console.log(ansis.yellow(`
|
|
683
|
+
\u26A0\uFE0F \u4F9B\u5E94\u5546 "${shortcode}" \u5C1A\u672A\u6CE8\u518C`));
|
|
684
|
+
console.log(ansis.gray("\u8BE5\u77ED\u7801\u5728\u4E91\u7AEF\u6CE8\u518C\u8868\u4E2D\u4E0D\u5B58\u5728\n"));
|
|
685
|
+
const { createNew } = await inquirer.prompt([
|
|
686
|
+
{
|
|
687
|
+
type: "confirm",
|
|
688
|
+
name: "createNew",
|
|
689
|
+
message: "\u662F\u5426\u521B\u5EFA\u8BE5\u4F9B\u5E94\u5546?",
|
|
690
|
+
default: false
|
|
691
|
+
}
|
|
692
|
+
]);
|
|
693
|
+
if (!createNew) {
|
|
694
|
+
console.log(ansis.gray("\n\u5DF2\u53D6\u6D88\uFF0C\u8FDB\u5165\u4E3B\u83DC\u5355...\n"));
|
|
695
|
+
return false;
|
|
696
|
+
}
|
|
697
|
+
const { name, apiUrl } = await inquirer.prompt([
|
|
698
|
+
{
|
|
699
|
+
type: "input",
|
|
700
|
+
name: "name",
|
|
701
|
+
message: "\u4F9B\u5E94\u5546\u540D\u79F0:",
|
|
702
|
+
default: shortcode.toUpperCase(),
|
|
703
|
+
validate: (value) => {
|
|
704
|
+
if (!value.trim()) return "\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A";
|
|
705
|
+
if (value.length > 50) return "\u540D\u79F0\u8FC7\u957F\uFF08\u6700\u591A50\u5B57\u7B26\uFF09";
|
|
706
|
+
return true;
|
|
707
|
+
}
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
type: "input",
|
|
711
|
+
name: "apiUrl",
|
|
712
|
+
message: "API URL (\u5982 https://api.example.com/v1):",
|
|
713
|
+
validate: (value) => {
|
|
714
|
+
if (!value.trim()) return "URL \u4E0D\u80FD\u4E3A\u7A7A";
|
|
715
|
+
if (!isValidApiUrl(value)) return "\u8BF7\u8F93\u5165\u6709\u6548\u7684 URL\uFF08http:// \u6216 https://\uFF09";
|
|
716
|
+
return true;
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
]);
|
|
720
|
+
const spinner = ora("\u6B63\u5728\u6CE8\u518C\u4F9B\u5E94\u5546...").start();
|
|
721
|
+
try {
|
|
722
|
+
const registry = getProviderRegistry();
|
|
723
|
+
const result = await registry.createProvider({
|
|
724
|
+
shortcode,
|
|
725
|
+
name: name.trim(),
|
|
726
|
+
apiUrl: apiUrl.trim()
|
|
727
|
+
});
|
|
728
|
+
if (result.success && result.data) {
|
|
729
|
+
spinner.succeed(ansis.green("\u4F9B\u5E94\u5546\u6CE8\u518C\u6210\u529F!"));
|
|
730
|
+
const config = await configureProvider(result.data, options);
|
|
731
|
+
if (config) {
|
|
732
|
+
await saveProviderConfig(config);
|
|
733
|
+
showSuccessMessage(config);
|
|
734
|
+
return true;
|
|
735
|
+
}
|
|
736
|
+
} else {
|
|
737
|
+
spinner.fail(ansis.red("\u6CE8\u518C\u5931\u8D25"));
|
|
738
|
+
console.error(ansis.gray(result.error?.message || "\u672A\u77E5\u9519\u8BEF"));
|
|
739
|
+
const { continueLocal } = await inquirer.prompt([
|
|
740
|
+
{
|
|
741
|
+
type: "confirm",
|
|
742
|
+
name: "continueLocal",
|
|
743
|
+
message: "\u662F\u5426\u4ECD\u7136\u4F7F\u7528\u6B64\u914D\u7F6E\uFF08\u4EC5\u672C\u5730\uFF09?",
|
|
744
|
+
default: true
|
|
745
|
+
}
|
|
746
|
+
]);
|
|
747
|
+
if (continueLocal) {
|
|
748
|
+
const localProvider = {
|
|
749
|
+
shortcode,
|
|
750
|
+
name: name.trim(),
|
|
751
|
+
apiUrl: apiUrl.trim(),
|
|
752
|
+
verified: false,
|
|
753
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
754
|
+
};
|
|
755
|
+
const config = await configureProvider(localProvider, options);
|
|
756
|
+
if (config) {
|
|
757
|
+
await saveProviderConfig(config);
|
|
758
|
+
showSuccessMessage(config);
|
|
759
|
+
return true;
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
} catch (error) {
|
|
764
|
+
spinner.fail(ansis.red("\u6CE8\u518C\u5931\u8D25"));
|
|
765
|
+
console.error(ansis.gray(error instanceof Error ? error.message : "\u7F51\u7EDC\u9519\u8BEF"));
|
|
766
|
+
}
|
|
767
|
+
return false;
|
|
768
|
+
}
|
|
769
|
+
async function configureProvider(provider, _options) {
|
|
770
|
+
console.log(ansis.cyan("\n\u{1F4DD} \u914D\u7F6E API \u51ED\u8BC1"));
|
|
771
|
+
console.log(ansis.gray("\u2500".repeat(40)));
|
|
772
|
+
const { apiKey } = await inquirer.prompt([
|
|
773
|
+
{
|
|
774
|
+
type: "password",
|
|
775
|
+
name: "apiKey",
|
|
776
|
+
message: "API Key:",
|
|
777
|
+
mask: "*",
|
|
778
|
+
validate: (value) => {
|
|
779
|
+
if (!value.trim()) return "API Key \u4E0D\u80FD\u4E3A\u7A7A";
|
|
780
|
+
if (value.length < 10) return "API Key \u683C\u5F0F\u4E0D\u6B63\u786E";
|
|
781
|
+
return true;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
]);
|
|
785
|
+
let model;
|
|
786
|
+
if (provider.models && provider.models.length > 0) {
|
|
787
|
+
const { modelChoice } = await inquirer.prompt([
|
|
788
|
+
{
|
|
789
|
+
type: "list",
|
|
790
|
+
name: "modelChoice",
|
|
791
|
+
message: "\u9009\u62E9\u6A21\u578B:",
|
|
792
|
+
choices: [
|
|
793
|
+
...provider.models.map((m) => ({
|
|
794
|
+
name: m,
|
|
795
|
+
value: m
|
|
796
|
+
})),
|
|
797
|
+
{
|
|
798
|
+
name: ansis.gray("\u81EA\u5B9A\u4E49..."),
|
|
799
|
+
value: "__custom__"
|
|
800
|
+
}
|
|
801
|
+
]
|
|
802
|
+
}
|
|
803
|
+
]);
|
|
804
|
+
if (modelChoice === "__custom__") {
|
|
805
|
+
const { customModel } = await inquirer.prompt([
|
|
806
|
+
{
|
|
807
|
+
type: "input",
|
|
808
|
+
name: "customModel",
|
|
809
|
+
message: "\u8F93\u5165\u6A21\u578B\u540D\u79F0:",
|
|
810
|
+
validate: (value) => {
|
|
811
|
+
if (!value.trim()) return "\u6A21\u578B\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A";
|
|
812
|
+
return true;
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
]);
|
|
816
|
+
model = customModel;
|
|
817
|
+
} else {
|
|
818
|
+
model = modelChoice;
|
|
819
|
+
}
|
|
820
|
+
} else {
|
|
821
|
+
const { inputModel } = await inquirer.prompt([
|
|
822
|
+
{
|
|
823
|
+
type: "input",
|
|
824
|
+
name: "inputModel",
|
|
825
|
+
message: "\u6A21\u578B\u540D\u79F0 (\u5982 gpt-4, claude-3-opus):",
|
|
826
|
+
default: "gpt-4",
|
|
827
|
+
validate: (value) => {
|
|
828
|
+
if (!value.trim()) return "\u6A21\u578B\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A";
|
|
829
|
+
return true;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
]);
|
|
833
|
+
model = inputModel;
|
|
834
|
+
}
|
|
835
|
+
return {
|
|
836
|
+
shortcode: provider.shortcode,
|
|
837
|
+
provider,
|
|
838
|
+
apiKey: apiKey.trim(),
|
|
839
|
+
model: model.trim()
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
async function saveProviderConfig(config) {
|
|
843
|
+
const spinner = ora("\u6B63\u5728\u4FDD\u5B58\u914D\u7F6E...").start();
|
|
844
|
+
try {
|
|
845
|
+
const { readJsonFile, writeJsonFile } = await import('./fs-operations.mjs');
|
|
846
|
+
const { join } = await import('pathe');
|
|
847
|
+
const { homedir } = await import('node:os');
|
|
848
|
+
const { existsSync, mkdirSync } = await import('node:fs');
|
|
849
|
+
const claudeDir = join(homedir(), ".claude");
|
|
850
|
+
const settingsPath = join(claudeDir, "settings.json");
|
|
851
|
+
if (!existsSync(claudeDir)) {
|
|
852
|
+
mkdirSync(claudeDir, { recursive: true });
|
|
853
|
+
}
|
|
854
|
+
let settings = {};
|
|
855
|
+
try {
|
|
856
|
+
if (existsSync(settingsPath)) {
|
|
857
|
+
settings = readJsonFile(settingsPath) || {};
|
|
858
|
+
}
|
|
859
|
+
} catch {
|
|
860
|
+
}
|
|
861
|
+
settings.apiProvider = "custom";
|
|
862
|
+
settings.apiUrl = config.provider.apiUrl;
|
|
863
|
+
settings.apiKey = config.apiKey;
|
|
864
|
+
settings.model = config.model;
|
|
865
|
+
const envConfig = {
|
|
866
|
+
ANTHROPIC_BASE_URL: config.provider.apiUrl,
|
|
867
|
+
ANTHROPIC_API_KEY: config.apiKey,
|
|
868
|
+
ANTHROPIC_MODEL: config.model
|
|
869
|
+
};
|
|
870
|
+
settings.env = {
|
|
871
|
+
...settings.env || {},
|
|
872
|
+
...envConfig
|
|
873
|
+
};
|
|
874
|
+
writeJsonFile(settingsPath, settings);
|
|
875
|
+
spinner.succeed(ansis.green("\u914D\u7F6E\u5DF2\u4FDD\u5B58"));
|
|
876
|
+
} catch (error) {
|
|
877
|
+
spinner.fail(ansis.red("\u4FDD\u5B58\u5931\u8D25"));
|
|
878
|
+
console.log(ansis.yellow("\n\u8BF7\u624B\u52A8\u914D\u7F6E:"));
|
|
879
|
+
console.log(ansis.gray("\u2500".repeat(40)));
|
|
880
|
+
console.log(`${ansis.cyan("API URL:")} ${config.provider.apiUrl}`);
|
|
881
|
+
console.log(`${ansis.cyan("Model:")} ${config.model}`);
|
|
882
|
+
console.log(ansis.gray('\n\u8FD0\u884C "ccjk api" \u8FDB\u884C\u624B\u52A8\u914D\u7F6E'));
|
|
883
|
+
throw error;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
function showSuccessMessage(config) {
|
|
887
|
+
console.log();
|
|
888
|
+
console.log(ansis.green.bold("\u2705 \u914D\u7F6E\u5B8C\u6210!"));
|
|
889
|
+
console.log(ansis.gray("\u2500".repeat(40)));
|
|
890
|
+
console.log(` ${ansis.yellow("\u4F9B\u5E94\u5546:")} ${config.provider.name}`);
|
|
891
|
+
console.log(` ${ansis.yellow("API URL:")} ${config.provider.apiUrl}`);
|
|
892
|
+
console.log(` ${ansis.yellow("\u6A21\u578B:")} ${config.model}`);
|
|
893
|
+
console.log();
|
|
894
|
+
console.log(ansis.gray("\u73B0\u5728\u53EF\u4EE5\u5F00\u59CB\u4F7F\u7528 Claude Code \u4E86"));
|
|
895
|
+
console.log(ansis.gray('\u8FD0\u884C "claude" \u542F\u52A8\u5BF9\u8BDD'));
|
|
896
|
+
console.log();
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
export { configureProvider, couldBeShortcode, handleExistingProvider, handleNewProvider, isKnownCommand, quickProviderLaunch, saveProviderConfig };
|
package/dist/cli.mjs
CHANGED
|
@@ -1635,11 +1635,41 @@ function customizeHelpLazy(_sections, version) {
|
|
|
1635
1635
|
}
|
|
1636
1636
|
async function runLazyCli() {
|
|
1637
1637
|
bootstrapCloudServices();
|
|
1638
|
+
const handled = await tryQuickProviderLaunch();
|
|
1639
|
+
if (handled) {
|
|
1640
|
+
return;
|
|
1641
|
+
}
|
|
1638
1642
|
const cac = (await import('cac')).default;
|
|
1639
1643
|
const cli = cac("ccjk");
|
|
1640
1644
|
await setupCommandsLazy(cli);
|
|
1641
1645
|
cli.parse();
|
|
1642
1646
|
}
|
|
1647
|
+
async function tryQuickProviderLaunch() {
|
|
1648
|
+
const args = process__default.argv.slice(2);
|
|
1649
|
+
if (args.length === 0 || args[0].startsWith("-")) {
|
|
1650
|
+
return false;
|
|
1651
|
+
}
|
|
1652
|
+
const firstArg = args[0].toLowerCase();
|
|
1653
|
+
const { couldBeShortcode, isKnownCommand } = await import('./chunks/quick-provider.mjs');
|
|
1654
|
+
if (isKnownCommand(firstArg)) {
|
|
1655
|
+
return false;
|
|
1656
|
+
}
|
|
1657
|
+
if (!couldBeShortcode(firstArg)) {
|
|
1658
|
+
return false;
|
|
1659
|
+
}
|
|
1660
|
+
const { quickProviderLaunch } = await import('./chunks/quick-provider.mjs');
|
|
1661
|
+
try {
|
|
1662
|
+
const handled = await quickProviderLaunch(firstArg, {
|
|
1663
|
+
lang: process__default.env.CCJK_LANG
|
|
1664
|
+
});
|
|
1665
|
+
if (handled) {
|
|
1666
|
+
return true;
|
|
1667
|
+
}
|
|
1668
|
+
return false;
|
|
1669
|
+
} catch {
|
|
1670
|
+
return false;
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1643
1673
|
function bootstrapCloudServices() {
|
|
1644
1674
|
setImmediate(async () => {
|
|
1645
1675
|
try {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccjk",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "9.0
|
|
4
|
+
"version": "9.1.0",
|
|
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": {
|