ccjk 14.1.8 → 14.1.10

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.
@@ -70,7 +70,9 @@ async function configureIncrementalManagement() {
70
70
  const config = ClaudeCodeConfigManager.readConfig();
71
71
  if (!config || !config.profiles || Object.keys(config.profiles).length === 0) {
72
72
  await handleAddProfile();
73
- await syncMyclaudeProfilesIfNeeded();
73
+ if (!isClavueRuntime()) {
74
+ await syncMyclaudeProfilesIfNeeded();
75
+ }
74
76
  return;
75
77
  }
76
78
  const profiles = Object.values(config.profiles);
@@ -122,13 +124,130 @@ async function promptContinueAdding() {
122
124
  async function addProfileDirect() {
123
125
  ensureI18nInitialized();
124
126
  await handleAddProfile();
125
- await syncMyclaudeProfilesIfNeeded();
127
+ if (!isClavueRuntime()) {
128
+ await syncMyclaudeProfilesIfNeeded();
129
+ }
126
130
  }
127
131
  function getProviderDefaultModels(provider) {
128
132
  return resolveClaudeFamilyModelSlots({
129
133
  defaultModels: provider?.claudeCode?.defaultModels
130
134
  });
131
135
  }
136
+ function isClavueRuntime() {
137
+ return readZcfConfig()?.codeToolType === "clavue";
138
+ }
139
+ function getDefaultModelsForRouteMode(mode, provider) {
140
+ if (mode === "official") {
141
+ return {
142
+ primaryModel: "claude-sonnet-4-6",
143
+ haikuModel: "claude-haiku-4-5-20251001",
144
+ sonnetModel: "claude-sonnet-4-6",
145
+ opusModel: "claude-opus-4-6"
146
+ };
147
+ }
148
+ if (mode === "openai-native") {
149
+ if (provider?.claudeCode?.defaultModels?.length) {
150
+ const defaults = getProviderDefaultModels(provider);
151
+ return {
152
+ primaryModel: defaults.primaryModel || "gpt-5-codex",
153
+ haikuModel: defaults.haikuModel || defaults.primaryModel || "gpt-5-codex",
154
+ sonnetModel: defaults.sonnetModel || defaults.primaryModel || "gpt-5-codex",
155
+ opusModel: defaults.opusModel || defaults.primaryModel || "gpt-5-codex"
156
+ };
157
+ }
158
+ return resolveClaudeFamilyModelSlots({ selectedModel: "gpt-5-codex" });
159
+ }
160
+ return {
161
+ primaryModel: "gpt-5-codex",
162
+ haikuModel: "claude-haiku-4-5-20251001",
163
+ sonnetModel: "gpt-5-codex",
164
+ opusModel: "claude-opus-4-6"
165
+ };
166
+ }
167
+ function toLegacyProviderMode(mode) {
168
+ return mode === "openai-native" ? "openai-native" : mode === "ccr-proxy" ? "ccr-proxy" : "official";
169
+ }
170
+ async function promptModelRouteSelection(provider) {
171
+ const isZh = i18n.language === "zh-CN";
172
+ const { mode } = await inquirer.prompt([{
173
+ type: "list",
174
+ name: "mode",
175
+ message: isZh ? "\u8BF7\u9009\u62E9\u6A21\u578B\u8DEF\u7531\u6A21\u5F0F:" : "Select model routing mode:",
176
+ choices: addNumbersToChoices([
177
+ {
178
+ name: isZh ? "OpenAI / GPT \u6A21\u578B\uFF08GPT-5.x\u3001Codex\uFF09" : "OpenAI / GPT models (GPT-5.x, Codex)",
179
+ value: "openai-native"
180
+ },
181
+ {
182
+ name: isZh ? "Claude \u6A21\u578B\uFF08Anthropic / Claude \u517C\u5BB9\uFF09" : "Claude models (Anthropic / Claude compatible)",
183
+ value: "official"
184
+ },
185
+ {
186
+ name: isZh ? "\u6DF7\u5408\u6A21\u578B\uFF08OpenAI + Claude \u5206\u69FD\uFF09" : "Hybrid models (OpenAI + Claude slots)",
187
+ value: "ccr-proxy"
188
+ }
189
+ ]),
190
+ default: "openai-native"
191
+ }]);
192
+ const defaults = getDefaultModelsForRouteMode(mode, provider);
193
+ const { promptCustomModels } = await import('./features.mjs');
194
+ const models = await promptCustomModels(
195
+ defaults.primaryModel,
196
+ defaults.haikuModel,
197
+ defaults.sonnetModel,
198
+ defaults.opusModel
199
+ );
200
+ return { mode: toLegacyProviderMode(mode), models };
201
+ }
202
+ function toMyclaudeProviderProfile(profile, routeSelection) {
203
+ return {
204
+ id: profile.id || ClaudeCodeConfigManager.generateProfileId(profile.name),
205
+ name: profile.name,
206
+ provider: profile.provider || "custom",
207
+ apiKey: profile.apiKey,
208
+ baseUrl: profile.baseUrl,
209
+ model: profile.primaryModel,
210
+ fastModel: profile.defaultHaikuModel,
211
+ authType: profile.authType,
212
+ primaryModel: profile.primaryModel,
213
+ defaultHaikuModel: profile.defaultHaikuModel,
214
+ defaultSonnetModel: profile.defaultSonnetModel,
215
+ defaultOpusModel: profile.defaultOpusModel,
216
+ mode: routeSelection.mode
217
+ };
218
+ }
219
+ function fromClavueProviderProfile(profile) {
220
+ const routing = profile.modelRouting;
221
+ return {
222
+ id: profile.provenance?.kind === "imported" && profile.provenance.sourceId === "ccjk" && typeof profile.provenance.externalProfileId === "string" ? profile.provenance.externalProfileId : profile.id,
223
+ name: profile.name,
224
+ provider: profile.providerId || "custom",
225
+ baseUrl: profile.baseUrl,
226
+ authType: profile.authType,
227
+ model: routing?.primaryModel,
228
+ fastModel: routing?.smallFastModel,
229
+ primaryModel: routing?.primaryModel,
230
+ defaultHaikuModel: routing?.smallFastModel,
231
+ defaultSonnetModel: routing?.generalModel || routing?.subagentModel,
232
+ defaultOpusModel: routing?.planModel,
233
+ mode: profile.modelMode === "openai_native" ? "openai-native" : profile.modelMode === "hybrid_compatible" ? "ccr-proxy" : "official"
234
+ };
235
+ }
236
+ async function saveClavueNativeProfile(profile, routeSelection, setAsDefault) {
237
+ const { readClavueConfig, setMyclaudeProviderProfiles } = await import('./config.mjs').then(function (n) { return n.P; });
238
+ const config = readClavueConfig();
239
+ const activeClavueProfileId = config?.clavueActiveProviderProfileId;
240
+ const existingManagedProfiles = (config?.clavueProviderProfiles || []).filter((existing) => existing.provenance?.kind === "imported" && existing.provenance.sourceId === "ccjk").map(fromClavueProviderProfile);
241
+ const activeManagedProfileId = existingManagedProfiles.find((existing) => {
242
+ return existing.id === activeClavueProfileId || `ccjk-${existing.id}` === activeClavueProfileId;
243
+ })?.id;
244
+ const nextProfile = toMyclaudeProviderProfile(profile, routeSelection);
245
+ const profiles = [
246
+ ...existingManagedProfiles.filter((existing) => existing.id !== nextProfile.id),
247
+ nextProfile
248
+ ];
249
+ setMyclaudeProviderProfiles(profiles, setAsDefault ? nextProfile.id : activeManagedProfileId || activeClavueProfileId);
250
+ }
132
251
  async function handleAddProfile() {
133
252
  console.log(a.green(`
134
253
  ${i18n.t("multi-config:addingNewProfile")}`));
@@ -218,17 +337,8 @@ ${i18n.t("multi-config:addingNewProfile")}`));
218
337
  }
219
338
  }
220
339
  ]);
221
- let modelConfig = null;
222
- {
223
- const { promptCustomModels } = await import('./features.mjs');
224
- const defaults = getProviderDefaultModels(selectedProviderPreset);
225
- modelConfig = await promptCustomModels(
226
- defaults.primaryModel,
227
- defaults.haikuModel,
228
- defaults.sonnetModel,
229
- defaults.opusModel
230
- );
231
- }
340
+ const routeSelection = await promptModelRouteSelection(selectedProviderPreset);
341
+ const modelConfig = routeSelection.models;
232
342
  const setAsDefault = await promptBoolean({
233
343
  message: i18n.t("multi-config:setAsDefaultPrompt"),
234
344
  defaultValue: true
@@ -256,66 +366,71 @@ ${i18n.t("multi-config:addingNewProfile")}`));
256
366
  if (modelConfig.opusModel.trim())
257
367
  profile.defaultOpusModel = modelConfig.opusModel.trim();
258
368
  }
259
- const existingProfile = ClaudeCodeConfigManager.getProfileByName(profile.name);
260
- if (existingProfile) {
261
- const overwrite = await promptBoolean({
262
- message: i18n.t("multi-config:profileDuplicatePrompt", {
263
- name: profile.name,
264
- source: i18n.t("multi-config:existingConfig")
265
- }),
266
- defaultValue: false
267
- });
268
- if (!overwrite) {
269
- console.log(a.yellow(i18n.t("multi-config:profileDuplicateSkipped", { name: profile.name })));
270
- const shouldContinue2 = await promptContinueAdding();
271
- if (shouldContinue2) {
272
- await handleAddProfile();
273
- }
274
- return;
275
- }
276
- const updateResult = await ClaudeCodeConfigManager.updateProfile(existingProfile.id, {
277
- name: profile.name,
278
- authType: profile.authType,
279
- provider: profile.provider,
280
- apiKey: profile.apiKey,
281
- baseUrl: profile.baseUrl,
282
- primaryModel: profile.primaryModel,
283
- defaultHaikuModel: profile.defaultHaikuModel,
284
- defaultSonnetModel: profile.defaultSonnetModel,
285
- defaultOpusModel: profile.defaultOpusModel
286
- });
287
- if (updateResult.success) {
288
- console.log(a.green(i18n.t("multi-config:profileUpdated", { name: profile.name })));
289
- if (updateResult.backupPath) {
290
- console.log(a.gray(i18n.t("common:backupCreated", { path: updateResult.backupPath })));
369
+ if (isClavueRuntime()) {
370
+ await saveClavueNativeProfile(profile, routeSelection, setAsDefault);
371
+ console.log(a.green(i18n.t("multi-config:profileAdded", { name: profile.name })));
372
+ } else {
373
+ const existingProfile = ClaudeCodeConfigManager.getProfileByName(profile.name);
374
+ if (existingProfile) {
375
+ const overwrite = await promptBoolean({
376
+ message: i18n.t("multi-config:profileDuplicatePrompt", {
377
+ name: profile.name,
378
+ source: i18n.t("multi-config:existingConfig")
379
+ }),
380
+ defaultValue: false
381
+ });
382
+ if (!overwrite) {
383
+ console.log(a.yellow(i18n.t("multi-config:profileDuplicateSkipped", { name: profile.name })));
384
+ const shouldContinue2 = await promptContinueAdding();
385
+ if (shouldContinue2) {
386
+ await handleAddProfile();
387
+ }
388
+ return;
291
389
  }
292
- if (setAsDefault) {
293
- const switchResult = await ClaudeCodeConfigManager.switchProfile(existingProfile.id);
294
- if (switchResult.success) {
295
- console.log(a.green(i18n.t("multi-config:profileSetAsDefault", { name: profile.name })));
296
- await ClaudeCodeConfigManager.applyProfileSettings({ ...profile, id: existingProfile.id });
390
+ const updateResult = await ClaudeCodeConfigManager.updateProfile(existingProfile.id, {
391
+ name: profile.name,
392
+ authType: profile.authType,
393
+ provider: profile.provider,
394
+ apiKey: profile.apiKey,
395
+ baseUrl: profile.baseUrl,
396
+ primaryModel: profile.primaryModel,
397
+ defaultHaikuModel: profile.defaultHaikuModel,
398
+ defaultSonnetModel: profile.defaultSonnetModel,
399
+ defaultOpusModel: profile.defaultOpusModel
400
+ });
401
+ if (updateResult.success) {
402
+ console.log(a.green(i18n.t("multi-config:profileUpdated", { name: profile.name })));
403
+ if (updateResult.backupPath) {
404
+ console.log(a.gray(i18n.t("common:backupCreated", { path: updateResult.backupPath })));
297
405
  }
406
+ if (setAsDefault) {
407
+ const switchResult = await ClaudeCodeConfigManager.switchProfile(existingProfile.id);
408
+ if (switchResult.success) {
409
+ console.log(a.green(i18n.t("multi-config:profileSetAsDefault", { name: profile.name })));
410
+ await ClaudeCodeConfigManager.applyProfileSettings({ ...profile, id: existingProfile.id });
411
+ }
412
+ }
413
+ } else {
414
+ console.log(a.red(i18n.t("multi-config:profileUpdateFailed", { error: updateResult.error || "" })));
298
415
  }
299
416
  } else {
300
- console.log(a.red(i18n.t("multi-config:profileUpdateFailed", { error: updateResult.error || "" })));
301
- }
302
- } else {
303
- const result = await ClaudeCodeConfigManager.addProfile(profile);
304
- if (result.success) {
305
- const runtimeProfile = result.addedProfile || { ...profile, id: profileId };
306
- console.log(a.green(i18n.t("multi-config:profileAdded", { name: runtimeProfile.name })));
307
- if (result.backupPath) {
308
- console.log(a.gray(i18n.t("common:backupCreated", { path: result.backupPath })));
309
- }
310
- if (setAsDefault) {
311
- const switchResult = await ClaudeCodeConfigManager.switchProfile(runtimeProfile.id);
312
- if (switchResult.success) {
313
- console.log(a.green(i18n.t("multi-config:profileSetAsDefault", { name: runtimeProfile.name })));
314
- await ClaudeCodeConfigManager.applyProfileSettings(runtimeProfile);
417
+ const result = await ClaudeCodeConfigManager.addProfile(profile);
418
+ if (result.success) {
419
+ const runtimeProfile = result.addedProfile || { ...profile, id: profileId };
420
+ console.log(a.green(i18n.t("multi-config:profileAdded", { name: runtimeProfile.name })));
421
+ if (result.backupPath) {
422
+ console.log(a.gray(i18n.t("common:backupCreated", { path: result.backupPath })));
315
423
  }
424
+ if (setAsDefault) {
425
+ const switchResult = await ClaudeCodeConfigManager.switchProfile(runtimeProfile.id);
426
+ if (switchResult.success) {
427
+ console.log(a.green(i18n.t("multi-config:profileSetAsDefault", { name: runtimeProfile.name })));
428
+ await ClaudeCodeConfigManager.applyProfileSettings(runtimeProfile);
429
+ }
430
+ }
431
+ } else {
432
+ console.log(a.red(i18n.t("multi-config:profileAddFailed", { error: result.error })));
316
433
  }
317
- } else {
318
- console.log(a.red(i18n.t("multi-config:profileAddFailed", { error: result.error })));
319
434
  }
320
435
  }
321
436
  const shouldContinue = await promptContinueAdding();
@@ -432,7 +432,8 @@ class SmartDefaultsDetector {
432
432
  const platform = getPlatform();
433
433
  const apiKey = this.detectApiKey();
434
434
  const apiProvider = this.detectApiProvider(apiKey);
435
- const ccVersion = await this.detectClaudeCodeVersion();
435
+ const codeToolType = this.detectCodeToolType();
436
+ const ccVersion = await this.detectClaudeCodeVersion(codeToolType);
436
437
  const projectContext = scanProject(cwd);
437
438
  return {
438
439
  // Environment detection
@@ -457,7 +458,7 @@ class SmartDefaultsDetector {
457
458
  "ccjk-testing-specialist"
458
459
  ],
459
460
  // Code tool detection
460
- codeToolType: this.detectCodeToolType(),
461
+ codeToolType,
461
462
  // Workflow preferences
462
463
  workflows: {
463
464
  outputStyle: "engineer-professional",
@@ -485,11 +486,13 @@ class SmartDefaultsDetector {
485
486
  /**
486
487
  * Detect installed Claude Code version
487
488
  */
488
- async detectClaudeCodeVersion() {
489
+ async detectClaudeCodeVersion(preferredCodeTool) {
490
+ const preferredCommand = preferredCodeTool && preferredCodeTool in CODE_TOOL_INFO ? CODE_TOOL_INFO[preferredCodeTool].runtimeCommand : void 0;
489
491
  const candidateCommands = [
492
+ preferredCommand,
490
493
  CODE_TOOL_INFO["claude-code"].runtimeCommand,
491
494
  CODE_TOOL_INFO.clavue.runtimeCommand
492
- ];
495
+ ].filter((command, index, commands) => Boolean(command) && commands.indexOf(command) === index);
493
496
  for (const command of candidateCommands) {
494
497
  try {
495
498
  if (!await commandExists(command)) {
@@ -1,3 +1,3 @@
1
- const version = "14.1.8";
1
+ const version = "14.1.10";
2
2
 
3
3
  export { version };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ccjk",
3
3
  "type": "module",
4
- "version": "14.1.8",
4
+ "version": "14.1.10",
5
5
  "packageManager": "pnpm@10.17.1",
6
6
  "description": "Production-ready AI dev environment for Claude Code, Codex, and modern coding workflows with 30-second onboarding, persistent memory, Agent Teams, remote control, and capability discovery.",
7
7
  "author": {