chatccc 0.2.213 → 0.2.215
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/.agents/skills/create-chatccc-feishu-app/SKILL.md +85 -0
- package/.agents/skills/create-chatccc-feishu-app/agents/openai.yaml +4 -0
- package/.claude/skills/create-chatccc-feishu-app/SKILL.md +85 -0
- package/.claude/skills/create-chatccc-feishu-app/agents/openai.yaml +4 -0
- package/.cursor/skills/create-chatccc-feishu-app/SKILL.md +85 -0
- package/.cursor/skills/create-chatccc-feishu-app/agents/openai.yaml +4 -0
- package/README.md +12 -7
- package/config.sample.json +2 -1
- package/package.json +4 -1
- package/src/__tests__/cards.test.ts +37 -1
- package/src/__tests__/codex-adapter.test.ts +18 -3
- package/src/__tests__/config-reload.test.ts +6 -5
- package/src/__tests__/config-sample.test.ts +8 -7
- package/src/__tests__/orchestrator.test.ts +60 -1
- package/src/__tests__/package-files.test.ts +24 -0
- package/src/__tests__/session.test.ts +24 -2
- package/src/__tests__/web-ui.test.ts +17 -2
- package/src/adapters/codex-adapter.ts +40 -6
- package/src/cards.ts +43 -2
- package/src/config.ts +10 -6
- package/src/orchestrator.ts +116 -21
- package/src/session.ts +26 -5
- package/src/web-ui.ts +54 -37
package/src/web-ui.ts
CHANGED
|
@@ -53,7 +53,7 @@ interface AppConfig {
|
|
|
53
53
|
avatarBatteryMode?: string;
|
|
54
54
|
onDemandMonthlyBudget?: number;
|
|
55
55
|
};
|
|
56
|
-
codex?: { enabled?: boolean; defaultAgent?: boolean; path?: string; command?: string; model?: string; alternativeModel?: string; effort?: string };
|
|
56
|
+
codex?: { enabled?: boolean; defaultAgent?: boolean; path?: string; command?: string; model?: string; alternativeModel?: string; effort?: string; fastMode?: boolean };
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
// ---------------------------------------------------------------------------
|
|
@@ -488,10 +488,13 @@ export function unflattenConfig(flat: Record<string, unknown>): Record<string, u
|
|
|
488
488
|
} else if (key === "CHATCCC_CODEX_ALTERNATIVE_MODEL") {
|
|
489
489
|
result.codex = result.codex || {};
|
|
490
490
|
(result.codex as Record<string, unknown>).alternativeModel = val;
|
|
491
|
-
} else if (key === "CHATCCC_CODEX_EFFORT") {
|
|
492
|
-
result.codex = result.codex || {};
|
|
493
|
-
(result.codex as Record<string, unknown>).effort = val;
|
|
494
|
-
} else if (key === "
|
|
491
|
+
} else if (key === "CHATCCC_CODEX_EFFORT") {
|
|
492
|
+
result.codex = result.codex || {};
|
|
493
|
+
(result.codex as Record<string, unknown>).effort = val;
|
|
494
|
+
} else if (key === "CHATCCC_CODEX_FAST_MODE") {
|
|
495
|
+
result.codex = result.codex || {};
|
|
496
|
+
(result.codex as Record<string, unknown>).fastMode = val === true || val === "true";
|
|
497
|
+
} else if (key === "CHATCCC_CODEX_ENABLED") {
|
|
495
498
|
result.codex = result.codex || {};
|
|
496
499
|
(result.codex as Record<string, unknown>).enabled = val === true || val === "true";
|
|
497
500
|
} else if (key === "CHATCCC_CODEX_DEFAULT_AGENT") {
|
|
@@ -928,11 +931,16 @@ header .badge{font-size:13px;padding:4px 12px;border-radius:12px;font-weight:500
|
|
|
928
931
|
<label>备选模型(选填)</label>
|
|
929
932
|
<input type="text" id="field-CHATCCC_CODEX_ALTERNATIVE_MODEL" placeholder="加入 /model 列表,便于会话内切换">
|
|
930
933
|
</div>
|
|
931
|
-
<div class="form-group">
|
|
932
|
-
<label>努力程度 (Effort)</label>
|
|
933
|
-
<input type="text" id="field-CHATCCC_CODEX_EFFORT" placeholder="留空由 codex config.toml 决定">
|
|
934
|
-
</div>
|
|
935
|
-
<
|
|
934
|
+
<div class="form-group">
|
|
935
|
+
<label>努力程度 (Effort)</label>
|
|
936
|
+
<input type="text" id="field-CHATCCC_CODEX_EFFORT" placeholder="留空由 codex config.toml 决定">
|
|
937
|
+
</div>
|
|
938
|
+
<div class="form-group">
|
|
939
|
+
<label style="display:flex;align-items:center;gap:8px">
|
|
940
|
+
<input type="checkbox" id="field-CHATCCC_CODEX_FAST_MODE"> Fast 模式
|
|
941
|
+
</label>
|
|
942
|
+
</div>
|
|
943
|
+
<button class="btn btn-outline" onclick="validateCli('codex')" style="margin-bottom:12px">检测 Codex CLI</button>
|
|
936
944
|
<div id="codex-validate-result"></div>
|
|
937
945
|
</fieldset>
|
|
938
946
|
</div>
|
|
@@ -1060,8 +1068,9 @@ header .badge{font-size:13px;padding:4px 12px;border-radius:12px;font-weight:500
|
|
|
1060
1068
|
<div class="section-detail">
|
|
1061
1069
|
<div class="config-row"><span class="key">CLI 路径</span><span class="val" id="cfg-CODEX_PATH">-</span></div>
|
|
1062
1070
|
<div class="config-row"><span class="key">模型</span><span class="val" id="cfg-CODEX_MODEL">-</span></div>
|
|
1063
|
-
<div class="config-row"><span class="key">备选模型</span><span class="val" id="cfg-CODEX_ALTERNATIVE_MODEL">-</span></div>
|
|
1071
|
+
<div class="config-row"><span class="key">备选模型</span><span class="val" id="cfg-CODEX_ALTERNATIVE_MODEL">-</span></div>
|
|
1064
1072
|
<div class="config-row"><span class="key">Effort</span><span class="val" id="cfg-CODEX_EFFORT">-</span></div>
|
|
1073
|
+
<div class="config-row"><span class="key">Fast 模式</span><span class="val" id="cfg-CODEX_FAST_MODE">-</span></div>
|
|
1065
1074
|
<label class="agent-default-row" style="margin-top:10px"><input type="checkbox" id="dash-default-codex" onchange="setDashboardDefaultAgent('codex', this.checked)"> 设为默认 Agent</label>
|
|
1066
1075
|
<div class="hint" style="margin-top:6px;line-height:1.6">生效范围:保存后下一条消息或下个新会话生效,当前生成不中断。</div>
|
|
1067
1076
|
<button class="btn btn-outline" style="margin-top:8px" onclick="editSection('codex')">编辑</button>
|
|
@@ -1111,7 +1120,7 @@ var step2InputBound = false;
|
|
|
1111
1120
|
const AGENT_FIELDS = {
|
|
1112
1121
|
claude: ['CHATCCC_ANTHROPIC_MODEL','CHATCCC_ANTHROPIC_SUBAGENT_MODEL','CHATCCC_ANTHROPIC_EFFORT','CHATCCC_ANTHROPIC_API_KEY','CHATCCC_ANTHROPIC_BASE_URL','CHATCCC_ANTHROPIC_MAX_TURN'],
|
|
1113
1122
|
cursor: ['CHATCCC_CURSOR_PATH','CHATCCC_CURSOR_MODEL','CHATCCC_CURSOR_ALTERNATIVE_MODEL','CHATCCC_CURSOR_AVATAR_BATTERY_MODE','CHATCCC_CURSOR_ON_DEMAND_MONTHLY_BUDGET'],
|
|
1114
|
-
codex: ['CHATCCC_CODEX_PATH','CHATCCC_CODEX_MODEL','CHATCCC_CODEX_ALTERNATIVE_MODEL','CHATCCC_CODEX_EFFORT']
|
|
1123
|
+
codex: ['CHATCCC_CODEX_PATH','CHATCCC_CODEX_MODEL','CHATCCC_CODEX_ALTERNATIVE_MODEL','CHATCCC_CODEX_EFFORT','CHATCCC_CODEX_FAST_MODE']
|
|
1115
1124
|
};
|
|
1116
1125
|
const FEISHU_FIELDS = ['CHATCCC_APP_ID','CHATCCC_APP_SECRET'];
|
|
1117
1126
|
const WEB_UI_FIELDS = ['CHATCCC_WEB_UI_OPEN_ON_START'];
|
|
@@ -1402,7 +1411,7 @@ function isAgentEnabled(node, keys) {
|
|
|
1402
1411
|
|
|
1403
1412
|
var CLAUDE_FALLBACK_KEYS = ['model','subagentModel','effort','maxTurn'];
|
|
1404
1413
|
var CURSOR_FALLBACK_KEYS = ['path','command','model','alternativeModel'];
|
|
1405
|
-
var CODEX_FALLBACK_KEYS = ['path','command','model','alternativeModel','effort'];
|
|
1414
|
+
var CODEX_FALLBACK_KEYS = ['path','command','model','alternativeModel','effort','fastMode'];
|
|
1406
1415
|
|
|
1407
1416
|
function renderStep2() {
|
|
1408
1417
|
var c = state.config || {};
|
|
@@ -1427,12 +1436,14 @@ function renderStep2() {
|
|
|
1427
1436
|
var cursorBatteryModeEl = document.getElementById('field-CHATCCC_CURSOR_AVATAR_BATTERY_MODE');
|
|
1428
1437
|
if (cursorBatteryModeEl && !cursorBatteryModeEl.value) cursorBatteryModeEl.value = 'apiPercent';
|
|
1429
1438
|
onCursorBatteryModeChange('field-', cursorBatteryModeEl ? cursorBatteryModeEl.value : 'apiPercent');
|
|
1430
|
-
if (c.codex) {
|
|
1431
|
-
prefillNested('field-CHATCCC_CODEX_PATH', c.codex.path || c.codex.command);
|
|
1432
|
-
prefillNested('field-CHATCCC_CODEX_MODEL', c.codex.model);
|
|
1433
|
-
prefillNested('field-CHATCCC_CODEX_ALTERNATIVE_MODEL', c.codex.alternativeModel);
|
|
1434
|
-
prefillNested('field-CHATCCC_CODEX_EFFORT', c.codex.effort);
|
|
1435
|
-
}
|
|
1439
|
+
if (c.codex) {
|
|
1440
|
+
prefillNested('field-CHATCCC_CODEX_PATH', c.codex.path || c.codex.command);
|
|
1441
|
+
prefillNested('field-CHATCCC_CODEX_MODEL', c.codex.model);
|
|
1442
|
+
prefillNested('field-CHATCCC_CODEX_ALTERNATIVE_MODEL', c.codex.alternativeModel);
|
|
1443
|
+
prefillNested('field-CHATCCC_CODEX_EFFORT', c.codex.effort);
|
|
1444
|
+
}
|
|
1445
|
+
var codexFastModeEl = document.getElementById('field-CHATCCC_CODEX_FAST_MODE');
|
|
1446
|
+
if (codexFastModeEl) codexFastModeEl.checked = !!(c.codex && c.codex.fastMode === true);
|
|
1436
1447
|
|
|
1437
1448
|
// 按已有 config 决定每个 Agent 默认是否开启:优先 enabled 字段,缺省时按"任一字段非空"
|
|
1438
1449
|
var claudeOn = isAgentEnabled(c.claude, CLAUDE_FALLBACK_KEYS);
|
|
@@ -1512,11 +1523,13 @@ function collectAllFields() {
|
|
|
1512
1523
|
if (el && el.value.trim()) vars[key] = el.value.trim();
|
|
1513
1524
|
});
|
|
1514
1525
|
}
|
|
1515
|
-
if (state.agentsEnabled.codex) {
|
|
1516
|
-
AGENT_FIELDS.codex.forEach(function(key){
|
|
1517
|
-
var el = document.getElementById('field-' + key);
|
|
1518
|
-
if (el
|
|
1519
|
-
|
|
1526
|
+
if (state.agentsEnabled.codex) {
|
|
1527
|
+
AGENT_FIELDS.codex.forEach(function(key){
|
|
1528
|
+
var el = document.getElementById('field-' + key);
|
|
1529
|
+
if (!el) return;
|
|
1530
|
+
if (key === 'CHATCCC_CODEX_FAST_MODE') vars[key] = !!el.checked;
|
|
1531
|
+
else if (el.value.trim()) vars[key] = el.value.trim();
|
|
1532
|
+
});
|
|
1520
1533
|
}
|
|
1521
1534
|
return vars;
|
|
1522
1535
|
}
|
|
@@ -1585,8 +1598,9 @@ function renderStep3() {
|
|
|
1585
1598
|
lines.push('<h4 style="margin:10px 0 4px;color:#334155">Codex</h4>');
|
|
1586
1599
|
if (vars.CHATCCC_CODEX_PATH) lines.push('<div class="config-row"><span class="key">CLI 路径</span><span class="val">' + vars.CHATCCC_CODEX_PATH + '</span></div>');
|
|
1587
1600
|
lines.push('<div class="config-row"><span class="key">模型</span><span class="val">' + (vars.CHATCCC_CODEX_MODEL || '(留空)') + '</span></div>');
|
|
1588
|
-
lines.push('<div class="config-row"><span class="key">备选模型</span><span class="val">' + (vars.CHATCCC_CODEX_ALTERNATIVE_MODEL || '(留空)') + '</span></div>');
|
|
1589
|
-
lines.push('<div class="config-row"><span class="key">Effort</span><span class="val">' + (vars.CHATCCC_CODEX_EFFORT || '(留空)') + '</span></div>');
|
|
1601
|
+
lines.push('<div class="config-row"><span class="key">备选模型</span><span class="val">' + (vars.CHATCCC_CODEX_ALTERNATIVE_MODEL || '(留空)') + '</span></div>');
|
|
1602
|
+
lines.push('<div class="config-row"><span class="key">Effort</span><span class="val">' + (vars.CHATCCC_CODEX_EFFORT || '(留空)') + '</span></div>');
|
|
1603
|
+
lines.push('<div class="config-row"><span class="key">Fast 模式</span><span class="val">' + (vars.CHATCCC_CODEX_FAST_MODE ? '已启用' : '已禁用') + '</span></div>');
|
|
1590
1604
|
}
|
|
1591
1605
|
});
|
|
1592
1606
|
document.getElementById('review-content').innerHTML = lines.join('');
|
|
@@ -1793,8 +1807,9 @@ function updateDashboardUI() {
|
|
|
1793
1807
|
document.getElementById('cfg-CURSOR_ON_DEMAND_MONTHLY_BUDGET').textContent = String((c.cursor && c.cursor.onDemandMonthlyBudget) || 1000);
|
|
1794
1808
|
document.getElementById('cfg-CODEX_PATH').textContent = (c.codex && (c.codex.path || c.codex.command)) || 'codex';
|
|
1795
1809
|
document.getElementById('cfg-CODEX_MODEL').textContent = (c.codex && c.codex.model) || '(留空)';
|
|
1796
|
-
document.getElementById('cfg-CODEX_ALTERNATIVE_MODEL').textContent = (c.codex && c.codex.alternativeModel) || '(留空)';
|
|
1797
|
-
document.getElementById('cfg-CODEX_EFFORT').textContent = (c.codex && c.codex.effort) || '(留空)';
|
|
1810
|
+
document.getElementById('cfg-CODEX_ALTERNATIVE_MODEL').textContent = (c.codex && c.codex.alternativeModel) || '(留空)';
|
|
1811
|
+
document.getElementById('cfg-CODEX_EFFORT').textContent = (c.codex && c.codex.effort) || '(留空)';
|
|
1812
|
+
document.getElementById('cfg-CODEX_FAST_MODE').textContent = c.codex && c.codex.fastMode === true ? '已启用' : '已禁用';
|
|
1798
1813
|
}
|
|
1799
1814
|
|
|
1800
1815
|
function pollStatus() {
|
|
@@ -1867,7 +1882,8 @@ function editSection(section) {
|
|
|
1867
1882
|
'CHATCCC_CURSOR_PATH': 'CLI 路径', 'CHATCCC_CURSOR_MODEL': '模型', 'CHATCCC_CURSOR_ALTERNATIVE_MODEL': '备选模型',
|
|
1868
1883
|
'CHATCCC_CURSOR_AVATAR_BATTERY_MODE': '头像电池电量',
|
|
1869
1884
|
'CHATCCC_CURSOR_ON_DEMAND_MONTHLY_BUDGET': '每月On demand use预算',
|
|
1870
|
-
'CHATCCC_CODEX_PATH': 'CLI 路径', 'CHATCCC_CODEX_MODEL': '模型', 'CHATCCC_CODEX_ALTERNATIVE_MODEL': '备选模型', 'CHATCCC_CODEX_EFFORT': 'Effort'
|
|
1885
|
+
'CHATCCC_CODEX_PATH': 'CLI 路径', 'CHATCCC_CODEX_MODEL': '模型', 'CHATCCC_CODEX_ALTERNATIVE_MODEL': '备选模型', 'CHATCCC_CODEX_EFFORT': 'Effort',
|
|
1886
|
+
'CHATCCC_CODEX_FAST_MODE': 'Fast 模式'
|
|
1871
1887
|
};
|
|
1872
1888
|
var hintMap = {
|
|
1873
1889
|
'CHATCCC_WEB_UI_OPEN_ON_START': '关闭后可继续手动访问 http://localhost:<端口>/;/restart、/update 和 Web UI 重启无论此项为何值都不会自动打开。',
|
|
@@ -1908,13 +1924,14 @@ function editSection(section) {
|
|
|
1908
1924
|
else if (key === 'CHATCCC_CURSOR_ON_DEMAND_MONTHLY_BUDGET') val = (state.config.cursor.onDemandMonthlyBudget != null) ? String(state.config.cursor.onDemandMonthlyBudget) : '1000';
|
|
1909
1925
|
} else if (section === 'codex' && state.config.codex) {
|
|
1910
1926
|
if (key === 'CHATCCC_CODEX_PATH') val = state.config.codex.path || state.config.codex.command || '';
|
|
1911
|
-
else if (key === 'CHATCCC_CODEX_MODEL') val = state.config.codex.model || '';
|
|
1912
|
-
else if (key === 'CHATCCC_CODEX_ALTERNATIVE_MODEL') val = state.config.codex.alternativeModel || '';
|
|
1913
|
-
else if (key === 'CHATCCC_CODEX_EFFORT') val = state.config.codex.effort || '';
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1927
|
+
else if (key === 'CHATCCC_CODEX_MODEL') val = state.config.codex.model || '';
|
|
1928
|
+
else if (key === 'CHATCCC_CODEX_ALTERNATIVE_MODEL') val = state.config.codex.alternativeModel || '';
|
|
1929
|
+
else if (key === 'CHATCCC_CODEX_EFFORT') val = state.config.codex.effort || '';
|
|
1930
|
+
else if (key === 'CHATCCC_CODEX_FAST_MODE') val = state.config.codex.fastMode === true ? 'true' : 'false';
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
var isSecret = key.includes('SECRET') || key.includes('API_KEY');
|
|
1934
|
+
if (key === 'CHATCCC_WEB_UI_OPEN_ON_START' || key === 'CHATCCC_CHROME_DEVTOOLS_ENABLED' || key === 'CHATCCC_CODEX_FAST_MODE') {
|
|
1918
1935
|
var checked = val === true || val === 'true';
|
|
1919
1936
|
var changeHandler = key === 'CHATCCC_CHROME_DEVTOOLS_ENABLED' ? ' onchange="toggleEditChromeDevtoolsFields(this.checked)"' : '';
|
|
1920
1937
|
html += '<div class="form-group"><label style="display:flex;align-items:center;gap:8px"><input type="checkbox" id="edit-' + key + '"' + (checked ? ' checked' : '') + changeHandler + '> ' + (labelMap[key] || key) + '</label>';
|
|
@@ -1982,7 +1999,7 @@ async function saveEdit() {
|
|
|
1982
1999
|
fields.forEach(function(key){
|
|
1983
2000
|
var el = document.getElementById('edit-' + key);
|
|
1984
2001
|
if (!el) return;
|
|
1985
|
-
if (key === 'CHATCCC_WEB_UI_OPEN_ON_START' || key === 'CHATCCC_CHROME_DEVTOOLS_ENABLED') vars[key] = !!el.checked;
|
|
2002
|
+
if (key === 'CHATCCC_WEB_UI_OPEN_ON_START' || key === 'CHATCCC_CHROME_DEVTOOLS_ENABLED' || key === 'CHATCCC_CODEX_FAST_MODE') vars[key] = !!el.checked;
|
|
1986
2003
|
else vars[key] = el.value.trim();
|
|
1987
2004
|
});
|
|
1988
2005
|
if (editSectionType === 'chromeDevtools' && !vars.CHATCCC_CHROME_DEVTOOLS_PORT) {
|