codexmate 0.0.47 → 0.0.48

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/cli.js CHANGED
@@ -2319,6 +2319,42 @@ function buildConfigTemplateDiff(params = {}) {
2319
2319
  };
2320
2320
  }
2321
2321
 
2322
+ function buildClaudeSettingsDiff(params = {}) {
2323
+ const content = typeof params.content === 'string' ? params.content : '';
2324
+ if (!content.trim()) {
2325
+ return { error: 'JSON 内容不能为空' };
2326
+ }
2327
+ if (content.length > 1024 * 1024) {
2328
+ return { error: '内容过大(最大 1MB)' };
2329
+ }
2330
+ let parsed;
2331
+ try {
2332
+ parsed = JSON.parse(content);
2333
+ } catch (e) {
2334
+ return { error: `JSON 解析失败: ${e.message}` };
2335
+ }
2336
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
2337
+ return { error: 'JSON 内容必须是一个对象' };
2338
+ }
2339
+ let beforeText = '';
2340
+ if (fs.existsSync(CLAUDE_SETTINGS_FILE)) {
2341
+ try {
2342
+ beforeText = fs.readFileSync(CLAUDE_SETTINGS_FILE, 'utf-8');
2343
+ } catch (e) {
2344
+ return { error: `读取 settings.json 失败: ${e.message}` };
2345
+ }
2346
+ }
2347
+ const afterText = JSON.stringify(parsed, null, 2) + '\n';
2348
+ const diff = buildLineDiff(beforeText, afterText);
2349
+ const hasChanges = (diff.stats.added || 0) + (diff.stats.removed || 0) > 0;
2350
+ return {
2351
+ diff: {
2352
+ ...diff,
2353
+ hasChanges
2354
+ }
2355
+ };
2356
+ }
2357
+
2322
2358
  function addProviderToConfig(params = {}) {
2323
2359
  const name = typeof params.name === 'string' ? params.name.trim() : '';
2324
2360
  const url = typeof params.url === 'string' ? params.url.trim() : '';
@@ -9528,6 +9564,12 @@ async function applyToClaudeSettings(config = {}) {
9528
9564
  };
9529
9565
  delete nextEnv.ANTHROPIC_AUTH_TOKEN;
9530
9566
  delete nextEnv.CLAUDE_CODE_USE_KEY;
9567
+ const subModels = {
9568
+ ANTHROPIC_DEFAULT_HAIKU_MODEL: model,
9569
+ ANTHROPIC_DEFAULT_SONNET_MODEL: model,
9570
+ ANTHROPIC_DEFAULT_OPUS_MODEL: model
9571
+ };
9572
+ Object.assign(nextEnv, subModels);
9531
9573
 
9532
9574
  const nextSettings = {
9533
9575
  ...currentSettings,
@@ -9546,7 +9588,10 @@ async function applyToClaudeSettings(config = {}) {
9546
9588
  updatedKeys: [
9547
9589
  'env.ANTHROPIC_API_KEY',
9548
9590
  'env.ANTHROPIC_BASE_URL',
9549
- 'env.ANTHROPIC_MODEL'
9591
+ 'env.ANTHROPIC_MODEL',
9592
+ 'env.ANTHROPIC_DEFAULT_HAIKU_MODEL',
9593
+ 'env.ANTHROPIC_DEFAULT_SONNET_MODEL',
9594
+ 'env.ANTHROPIC_DEFAULT_OPUS_MODEL'
9550
9595
  ]
9551
9596
  };
9552
9597
  if (proxyResult) {
@@ -11910,6 +11955,9 @@ function createWebServer({ htmlPath, assetsDir, webDir, host, port, openBrowser
11910
11955
  case 'get-claude-settings-raw':
11911
11956
  result = readClaudeSettingsRaw();
11912
11957
  break;
11958
+ case 'preview-claude-settings-diff':
11959
+ result = buildClaudeSettingsDiff(params || {});
11960
+ break;
11913
11961
  case 'apply-claude-settings-raw':
11914
11962
  result = applyClaudeSettingsRaw(params || {});
11915
11963
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codexmate",
3
- "version": "0.0.47",
3
+ "version": "0.0.48",
4
4
  "description": "Codex/Claude Code/OpenClaw 配置、会话与任务编排 CLI + Web 工具",
5
5
  "main": "cli.js",
6
6
  "bin": {
@@ -750,9 +750,13 @@ export function createCodexConfigMethods(options = {}) {
750
750
  && this._configTemplateDiffPreviewRequestToken === requestToken
751
751
  && this.buildConfigTemplateDiffFingerprint() === requestFingerprint
752
752
  );
753
- const res = await api('preview-config-template-diff', {
754
- template: this.configTemplateContent
755
- });
753
+ const res = this.configTemplateContext === 'claude'
754
+ ? await api('preview-claude-settings-diff', {
755
+ content: this.configTemplateContent
756
+ })
757
+ : await api('preview-config-template-diff', {
758
+ template: this.configTemplateContent
759
+ });
756
760
  if (!shouldApply()) {
757
761
  return;
758
762
  }
@@ -145,9 +145,9 @@ export function createStartupClaudeMethods(options = {}) {
145
145
  this.maybeShowStarPrompt();
146
146
  return true;
147
147
  } catch (e) {
148
- this.initError = e && e.message === 'timeout'
149
- ? '读取配置超时'
150
- : '连接失败: ' + (e && e.message ? e.message : '');
148
+ if (e && e.message !== 'timeout') {
149
+ this.initError = '连接失败: ' + (e.message || '');
150
+ }
151
151
  return false;
152
152
  } finally {
153
153
  if (!preserveLoading) {
@@ -486,6 +486,7 @@ const en = Object.freeze({
486
486
  'modal.configTemplate.mode.twoStep': 'Two-step confirm: preview diff, then apply.',
487
487
  'modal.configTemplate.mode.oneStep': 'One-step apply: write immediately.',
488
488
  'diff.title.configTemplate': 'Diff preview (config.toml)',
489
+ 'diff.title.claudeSettings': 'Diff preview (settings.json)',
489
490
  'diff.generating': 'Generating...',
490
491
  'diff.failed': 'Failed',
491
492
  'diff.noChanges': 'No changes detected',
@@ -1210,6 +1211,10 @@ const en = Object.freeze({
1210
1211
  'claude.model': 'Model',
1211
1212
  'claude.model.placeholder': 'e.g. claude-3-7-sonnet',
1212
1213
  'claude.model.hint': 'Model changes are saved and applied to the current config automatically.',
1214
+ 'claude.model.haiku': 'Haiku Model',
1215
+ 'claude.model.sonnet': 'Sonnet Model',
1216
+ 'claude.model.opus': 'Opus Model',
1217
+ 'claude.model.sub.placeholder': 'Defaults to the main model if left empty',
1213
1218
  'claude.targetApi.label': 'Target API',
1214
1219
  'claude.targetApi.responses': 'Anthropic',
1215
1220
  'claude.targetApi.chatCompletions': 'OpenAI Chat Completions (/v1/chat/completions)',
@@ -488,6 +488,7 @@ const ja = Object.freeze({
488
488
  'modal.configTemplate.mode.twoStep': '二段階確認:先に差分をプレビューし、その後適用します。',
489
489
  'modal.configTemplate.mode.oneStep': '一段階適用:「適用」をクリックすると直接書き込みます。',
490
490
  'diff.title.configTemplate': '差分プレビュー(config.toml)',
491
+ 'diff.title.claudeSettings': '差分プレビュー(settings.json)',
491
492
  'diff.generating': '生成中...',
492
493
  'diff.failed': '生成失敗',
493
494
  'diff.noChanges': '変更が検出されませんでした',
@@ -1203,6 +1204,10 @@ const ja = Object.freeze({
1203
1204
  'claude.model': 'モデル',
1204
1205
  'claude.model.placeholder': '例: claude-3-7-sonnet',
1205
1206
  'claude.model.hint': 'モデル変更後は自動保存され、現在の設定に適用されます。',
1207
+ 'claude.model.haiku': 'Haiku モデル',
1208
+ 'claude.model.sonnet': 'Sonnet モデル',
1209
+ 'claude.model.opus': 'Opus モデル',
1210
+ 'claude.model.sub.placeholder': '空欄の場合、メインモデルに従います',
1206
1211
  'claude.targetApi.label': 'ターゲット API',
1207
1212
  'claude.targetApi.responses': 'Anthropic',
1208
1213
  'claude.targetApi.chatCompletions': 'OpenAI Chat Completions (/v1/chat/completions)',
@@ -362,6 +362,10 @@ const vi = Object.freeze({
362
362
  'validation.claude.baseUrlRequired': 'Base URL là bắt buộc',
363
363
  'validation.claude.baseUrlHttpOnly': 'Base URL chỉ hỗ trợ http/https',
364
364
  'validation.claude.modelRequired': 'Tên mô hình là bắt buộc',
365
+ 'claude.model.haiku': 'Mô hình Haiku',
366
+ 'claude.model.sonnet': 'Mô hình Sonnet',
367
+ 'claude.model.opus': 'Mô hình Opus',
368
+ 'claude.model.sub.placeholder': 'Để trống sẽ dùng mô hình chính',
365
369
  'modal.claudeDelete.title': 'Xóa cấu hình Claude',
366
370
  'modal.claudeDelete.message': 'Xóa cấu hình "{name}"?',
367
371
  'modal.claudeDelete.confirm': 'Xóa',
@@ -486,6 +486,7 @@ const zhTw = Object.freeze({
486
486
  'modal.configTemplate.mode.twoStep': '兩步確認:先預覽差異,再應用寫入。',
487
487
  'modal.configTemplate.mode.oneStep': '一步應用:點擊“應用”直接寫入。',
488
488
  'diff.title.configTemplate': '差異預覽(config.toml)',
489
+ 'diff.title.claudeSettings': '差異預覽(settings.json)',
489
490
  'diff.generating': '生成中...',
490
491
  'diff.failed': '生成失敗',
491
492
  'diff.noChanges': '未檢測到改動',
@@ -1213,6 +1214,10 @@ const zhTw = Object.freeze({
1213
1214
  'claude.model': '模型',
1214
1215
  'claude.model.placeholder': '例如: claude-3-7-sonnet',
1215
1216
  'claude.model.hint': '模型修改後會自動保存並應用到目前設定。',
1217
+ 'claude.model.haiku': 'Haiku 模型',
1218
+ 'claude.model.sonnet': 'Sonnet 模型',
1219
+ 'claude.model.opus': 'Opus 模型',
1220
+ 'claude.model.sub.placeholder': '留空則跟隨主模型',
1216
1221
  'claude.targetApi.label': '目標 API',
1217
1222
  'claude.targetApi.responses': 'Anthropic',
1218
1223
  'claude.targetApi.chatCompletions': 'OpenAI Chat Completions (/v1/chat/completions)',
@@ -486,6 +486,7 @@ const zh = Object.freeze({
486
486
  'modal.configTemplate.mode.twoStep': '两步确认:先预览差异,再应用写入。',
487
487
  'modal.configTemplate.mode.oneStep': '一步应用:点击“应用”直接写入。',
488
488
  'diff.title.configTemplate': '差异预览(config.toml)',
489
+ 'diff.title.claudeSettings': '差异预览(settings.json)',
489
490
  'diff.generating': '生成中...',
490
491
  'diff.failed': '生成失败',
491
492
  'diff.noChanges': '未检测到改动',
@@ -1213,6 +1214,10 @@ const zh = Object.freeze({
1213
1214
  'claude.model': '模型',
1214
1215
  'claude.model.placeholder': '例如: claude-3-7-sonnet',
1215
1216
  'claude.model.hint': '模型修改后会自动保存并应用到当前配置。',
1217
+ 'claude.model.haiku': 'Haiku 模型',
1218
+ 'claude.model.sonnet': 'Sonnet 模型',
1219
+ 'claude.model.opus': 'Opus 模型',
1220
+ 'claude.model.sub.placeholder': '留空则跟随主模型',
1216
1221
  'claude.targetApi.label': '目标 API',
1217
1222
  'claude.targetApi.responses': 'Anthropic',
1218
1223
  'claude.targetApi.chatCompletions': 'OpenAI Chat Completions (/v1/chat/completions)',
@@ -12,7 +12,7 @@
12
12
  <div v-if="configTemplateDiffVisible" class="agents-diff-container">
13
13
  <div class="agents-diff-header">
14
14
  <div class="agents-diff-title">
15
- {{ t('diff.title.configTemplate') }}
15
+ {{ configTemplateContext === 'claude' ? t('diff.title.claudeSettings') : t('diff.title.configTemplate') }}
16
16
  <span v-if="configTemplateDiffLoading" class="agents-diff-subtitle">{{ t('diff.generating') }}</span>
17
17
  <span v-else-if="configTemplateDiffError" class="agents-diff-subtitle">{{ t('diff.failed') }}</span>
18
18
  <span v-else-if="!configTemplateDiffHasChanges" class="agents-diff-subtitle">{{ t('diff.noChanges') }}</span>
@@ -7794,7 +7794,7 @@ return function render(_ctx, _cache) {
7794
7794
  }, [
7795
7795
  _createElementVNode("div", { class: "agents-diff-header" }, [
7796
7796
  _createElementVNode("div", { class: "agents-diff-title" }, [
7797
- _createTextVNode(_toDisplayString(_ctx.t('diff.title.configTemplate')) + " ", 1 /* TEXT */),
7797
+ _createTextVNode(_toDisplayString(_ctx.configTemplateContext === 'claude' ? _ctx.t('diff.title.claudeSettings') : _ctx.t('diff.title.configTemplate')) + " ", 1 /* TEXT */),
7798
7798
  (_ctx.configTemplateDiffLoading)
7799
7799
  ? (_openBlock(), _createElementBlock("span", {
7800
7800
  key: 0,