chatccc 0.2.270 → 0.2.272

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.
@@ -270,6 +270,16 @@ function normalizePositiveInteger(raw, fallback) {
270
270
  const value = typeof raw === "string" ? Number(raw.trim()) : Number(raw);
271
271
  return Number.isInteger(value) && value > 0 ? value : fallback;
272
272
  }
273
+ function normalizeNullablePositiveInteger(raw, label) {
274
+ if (raw === undefined || raw === null || (typeof raw === "string" && raw.trim() === "")) {
275
+ return null;
276
+ }
277
+ const value = typeof raw === "string" ? Number(raw.trim()) : Number(raw);
278
+ if (Number.isInteger(value) && value > 0)
279
+ return value;
280
+ console.warn(`[CONFIG] ${label} 必须为正整数或留空,已按留空处理。`);
281
+ return null;
282
+ }
273
283
  function normalizeRawStreamAgentLogConfig(raw) {
274
284
  const obj = typeof raw === "object" && raw !== null
275
285
  ? raw
@@ -317,6 +327,7 @@ function loadConfig() {
317
327
  subModel: "",
318
328
  alternativeModel: "",
319
329
  effort: "",
330
+ maxOutputTokens: null,
320
331
  provider: "",
321
332
  gitCoAuthor: null,
322
333
  compactionTimeoutMs: DEFAULT_CCC_COMPACTION_TIMEOUT_MS,
@@ -527,6 +538,7 @@ function loadConfig() {
527
538
  subModel: normalizeOptionalConfigField(cccRaw.subModel, { label: "ccc.subModel" }),
528
539
  alternativeModel: normalizeOptionalConfigField(cccRaw.alternativeModel, { label: "ccc.alternativeModel" }),
529
540
  effort: normalizeOptionalConfigField(cccRaw.effort, { label: "ccc.effort" }),
541
+ maxOutputTokens: normalizeNullablePositiveInteger(cccRaw.maxOutputTokens, "ccc.maxOutputTokens"),
530
542
  provider: normalizeCccProviderOverride(cccRaw.provider),
531
543
  gitCoAuthor: typeof cccRaw.gitCoAuthor === "boolean" ? cccRaw.gitCoAuthor : null,
532
544
  compactionTimeoutMs: normalizePositiveInteger(cccRaw.compactionTimeoutMs, DEFAULT_CCC_COMPACTION_TIMEOUT_MS),
@@ -1,8 +1,11 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
3
3
  import { dirname, join } from "node:path";
4
+ import { tmpdir } from "node:os";
4
5
  import { USER_DATA_DIR } from "./config.js";
5
- export const SAFE_MAINTENANCE_FILE = join(USER_DATA_DIR, "state", "safe-maintenance.json");
6
+ export const SAFE_MAINTENANCE_FILE = process.env.VITEST
7
+ ? join(tmpdir(), `chatccc-vitest-safe-maintenance-${process.pid}-${randomUUID()}.json`)
8
+ : join(USER_DATA_DIR, "state", "safe-maintenance.json");
6
9
  export const SAFE_MAINTENANCE_STABLE_IDLE_MS = 1_000;
7
10
  const EMPTY_SNAPSHOT = {
8
11
  activeSessionIds: [],
@@ -508,11 +508,17 @@ export function setSessionFastModeOverride(sessionId, fastMode) {
508
508
  sessionFastModeOverrides.set(sessionId, fastMode);
509
509
  adapterCache.clear();
510
510
  }
511
+ function buildAdapterCacheKey(tool, model, effort, fastMode) {
512
+ const base = `${tool}:${model}:${effort}:${fastMode ? "fast" : "default"}`;
513
+ return tool === "ccc"
514
+ ? `${base}:${config.ccc.maxOutputTokens ?? "inherit"}`
515
+ : base;
516
+ }
511
517
  export function getAdapterForTool(tool, sessionId) {
512
518
  const effectiveModel = getEffectiveModelForTool(tool, sessionId);
513
519
  const effectiveEffort = getEffectiveEffortForTool(tool, sessionId);
514
520
  const effectiveFastMode = getEffectiveFastModeForTool(tool, sessionId);
515
- const cacheKey = `${tool}:${effectiveModel || ""}:${effectiveEffort || ""}:${effectiveFastMode ? "fast" : "default"}`;
521
+ const cacheKey = buildAdapterCacheKey(tool, effectiveModel || "", effectiveEffort || "", effectiveFastMode);
516
522
  const cached = adapterCache.get(cacheKey);
517
523
  if (cached)
518
524
  return cached;
@@ -535,6 +541,9 @@ export function getAdapterForTool(tool, sessionId) {
535
541
  compactionTimeoutMs: config.ccc.compactionTimeoutMs,
536
542
  contextWindow: config.ccc.contextWindow,
537
543
  ...(effectiveEffort ? { effort: effectiveEffort } : {}),
544
+ ...(config.ccc.maxOutputTokens !== null
545
+ ? { maxOutputTokens: config.ccc.maxOutputTokens }
546
+ : {}),
538
547
  // 留空("")不传 → ChatSession 跟随 DeepCCC 内核配置(~/.deepccc/config.json 或 DEEPCCC_PROVIDER)
539
548
  ...(config.ccc.provider ? { provider: config.ccc.provider } : {}),
540
549
  ...(config.ccc.subModel ? { subModel: config.ccc.subModel } : {}),
@@ -2192,7 +2201,7 @@ export function _setAdapterForToolForTest(tool, adapter) {
2192
2201
  const effective = getEffectiveModelForTool(tool);
2193
2202
  const effort = getEffectiveEffortForTool(tool);
2194
2203
  const fastMode = getEffectiveFastModeForTool(tool);
2195
- adapterCache.set(`${tool}:${effective || ""}:${effort || ""}:${fastMode ? "fast" : "default"}`, adapter);
2204
+ adapterCache.set(buildAdapterCacheKey(tool, effective || "", effort || "", fastMode), adapter);
2196
2205
  if (effective)
2197
2206
  adapterCache.set(`${tool}:${effective}`, adapter);
2198
2207
  }
@@ -496,6 +496,14 @@ export function unflattenConfig(flat) {
496
496
  result.ccc = result.ccc || {};
497
497
  result.ccc.effort = val;
498
498
  }
499
+ else if (key === "CHATCCC_CCC_MAX_OUTPUT_TOKENS") {
500
+ result.ccc = result.ccc || {};
501
+ const raw = String(val ?? "").trim();
502
+ const parsed = Number(raw);
503
+ result.ccc.maxOutputTokens = raw && Number.isInteger(parsed) && parsed > 0
504
+ ? parsed
505
+ : null;
506
+ }
499
507
  else if (key === "CHATCCC_CCC_PROVIDER") {
500
508
  result.ccc = result.ccc || {};
501
509
  result.ccc.provider = val;
@@ -934,7 +942,7 @@ header .badge{font-size:13px;padding:4px 12px;border-radius:12px;font-weight:500
934
942
  <div class="form-group">
935
943
  <label>Effort(推理强度,选填)</label>
936
944
  <select id="field-CHATCCC_CCC_EFFORT">
937
- <option value="">(留空/默认,服务端 medium)</option>
945
+ <option value="">跟随 DeepCCC 内核配置(默认)</option>
938
946
  <option value="none">none - 直接作答,最省 token</option>
939
947
  <option value="minimal">minimal</option>
940
948
  <option value="low">low</option>
@@ -943,6 +951,12 @@ header .badge{font-size:13px;padding:4px 12px;border-radius:12px;font-weight:500
943
951
  <option value="xhigh">xhigh</option>
944
952
  <option value="max">max - 最强推理</option>
945
953
  </select>
954
+ <div class="hint">留空时读取 ~/.deepccc/config.json 或 DEEPCCC_EFFORT;DeepCCC 也留空时使用模型服务端默认值。</div>
955
+ </div>
956
+ <div class="form-group">
957
+ <label>最大输出 Token(选填)</label>
958
+ <input type="number" id="field-CHATCCC_CCC_MAX_OUTPUT_TOKENS" min="1" step="1" placeholder="留空跟随 DeepCCC 内核配置">
959
+ <div class="hint">限制主对话单次输出长度。留空时读取 ~/.deepccc/config.json 或 DEEPCCC_MAX_OUTPUT_TOKENS;DeepCCC 也未配置时使用模型服务端默认值。</div>
946
960
  </div>
947
961
  <div class="form-group">
948
962
  <label>上下文窗口(模型最大上下文)</label>
@@ -1279,6 +1293,8 @@ header .badge{font-size:13px;padding:4px 12px;border-radius:12px;font-weight:500
1279
1293
  <div class="config-row"><span class="key">模型</span><span class="val" id="cfg-CCC_MODEL">-</span></div>
1280
1294
  <div class="config-row"><span class="key">子模型</span><span class="val" id="cfg-CCC_SUB_MODEL">-</span></div>
1281
1295
  <div class="config-row"><span class="key">备选模型</span><span class="val" id="cfg-CCC_ALTERNATIVE_MODEL">-</span></div>
1296
+ <div class="config-row"><span class="key">Effort</span><span class="val" id="cfg-CCC_EFFORT">-</span></div>
1297
+ <div class="config-row"><span class="key">最大输出 Token</span><span class="val" id="cfg-CCC_MAX_OUTPUT_TOKENS">-</span></div>
1282
1298
  <div class="config-row"><span class="key">Git 共同作者</span><span class="val" id="cfg-CCC_GIT_COAUTHOR">-</span></div>
1283
1299
  <label class="agent-default-row" style="margin-top:10px"><input type="checkbox" id="dash-default-ccc" onchange="setDashboardDefaultAgent('ccc', this.checked)"> 设为默认 Agent</label>
1284
1300
  <div class="hint" style="margin-top:6px;line-height:1.6">备选模型仅加入 /model 人工切换列表;保存后下一条消息或下个新会话生效。</div>
@@ -1330,7 +1346,7 @@ const AGENT_FIELDS = {
1330
1346
  claude: ['CHATCCC_ANTHROPIC_MODEL','CHATCCC_ANTHROPIC_SUBAGENT_MODEL','CHATCCC_ANTHROPIC_EFFORT','CHATCCC_ANTHROPIC_API_KEY','CHATCCC_ANTHROPIC_BASE_URL','CHATCCC_ANTHROPIC_MAX_TURN'],
1331
1347
  cursor: ['CHATCCC_CURSOR_PATH','CHATCCC_CURSOR_MODEL','CHATCCC_CURSOR_ALTERNATIVE_MODEL','CHATCCC_CURSOR_AVATAR_BATTERY_MODE','CHATCCC_CURSOR_ON_DEMAND_MONTHLY_BUDGET'],
1332
1348
  codex: ['CHATCCC_CODEX_PATH','CHATCCC_CODEX_MODEL','CHATCCC_CODEX_ALTERNATIVE_MODEL','CHATCCC_CODEX_EFFORT','CHATCCC_CODEX_FAST_MODE'],
1333
- ccc: ['CHATCCC_CCC_API_KEY','CHATCCC_CCC_BASE_URL','CHATCCC_CCC_MODEL','CHATCCC_CCC_SUB_MODEL','CHATCCC_CCC_ALTERNATIVE_MODEL','CHATCCC_CCC_EFFORT','CHATCCC_CCC_PROVIDER','CHATCCC_CCC_GIT_COAUTHOR','CHATCCC_CCC_CONTEXT_WINDOW'],
1349
+ ccc: ['CHATCCC_CCC_API_KEY','CHATCCC_CCC_BASE_URL','CHATCCC_CCC_MODEL','CHATCCC_CCC_SUB_MODEL','CHATCCC_CCC_ALTERNATIVE_MODEL','CHATCCC_CCC_EFFORT','CHATCCC_CCC_MAX_OUTPUT_TOKENS','CHATCCC_CCC_PROVIDER','CHATCCC_CCC_GIT_COAUTHOR','CHATCCC_CCC_CONTEXT_WINDOW'],
1334
1350
  dsh: ['CHATCCC_DSH_API_KEY','CHATCCC_DSH_BASE_URL','CHATCCC_DSH_MODEL','CHATCCC_DSH_SUB_MODEL','CHATCCC_DSH_ALTERNATIVE_MODEL','CHATCCC_DSH_PROVIDER','CHATCCC_DSH_MAX_TOKENS']
1335
1351
  };
1336
1352
  const FEISHU_FIELDS = ['CHATCCC_APP_ID','CHATCCC_APP_SECRET'];
@@ -1728,6 +1744,7 @@ function renderStep2() {
1728
1744
  prefillNested('field-CHATCCC_CCC_SUB_MODEL', c.ccc.subModel);
1729
1745
  prefillNested('field-CHATCCC_CCC_ALTERNATIVE_MODEL', c.ccc.alternativeModel);
1730
1746
  prefillNested('field-CHATCCC_CCC_EFFORT', c.ccc.effort);
1747
+ prefillNested('field-CHATCCC_CCC_MAX_OUTPUT_TOKENS', c.ccc.maxOutputTokens);
1731
1748
  prefillContextWindow('field-', c.ccc.contextWindow);
1732
1749
  }
1733
1750
  if (c.dsh) {
@@ -1936,6 +1953,7 @@ function renderStep3() {
1936
1953
  lines.push('<div class="config-row"><span class="key">子模型</span><span class="val">' + (vars.CHATCCC_CCC_SUB_MODEL || '(留空,跟随主模型)') + '</span></div>');
1937
1954
  lines.push('<div class="config-row"><span class="key">备选模型</span><span class="val">' + (vars.CHATCCC_CCC_ALTERNATIVE_MODEL || '(留空)') + '</span></div>');
1938
1955
  lines.push('<div class="config-row"><span class="key">Effort</span><span class="val">' + (vars.CHATCCC_CCC_EFFORT || '(留空)') + '</span></div>');
1956
+ lines.push('<div class="config-row"><span class="key">最大输出 Token</span><span class="val">' + (vars.CHATCCC_CCC_MAX_OUTPUT_TOKENS || '(跟随 DeepCCC)') + '</span></div>');
1939
1957
  lines.push('<div class="config-row"><span class="key">上下文窗口</span><span class="val">' + contextWindowTokensLabel(vars.CHATCCC_CCC_CONTEXT_WINDOW || 1048576) + '</span></div>');
1940
1958
  } else if (t === 'dsh') {
1941
1959
  lines.push('<h4 style="margin:10px 0 4px;color:#334155">DeepSeek Harness</h4>');
@@ -2167,6 +2185,10 @@ function updateDashboardUI() {
2167
2185
  document.getElementById('cfg-CCC_MODEL').textContent = (c.ccc && c.ccc.model) || '(留空)';
2168
2186
  document.getElementById('cfg-CCC_SUB_MODEL').textContent = (c.ccc && c.ccc.subModel) || '(留空,跟随主模型)';
2169
2187
  document.getElementById('cfg-CCC_ALTERNATIVE_MODEL').textContent = (c.ccc && c.ccc.alternativeModel) || '(留空)';
2188
+ document.getElementById('cfg-CCC_EFFORT').textContent = (c.ccc && c.ccc.effort) || '(跟随 DeepCCC 内核配置)';
2189
+ document.getElementById('cfg-CCC_MAX_OUTPUT_TOKENS').textContent = c.ccc && c.ccc.maxOutputTokens
2190
+ ? String(c.ccc.maxOutputTokens)
2191
+ : '(跟随 DeepCCC 内核配置)';
2170
2192
  document.getElementById('cfg-CCC_GIT_COAUTHOR').textContent = !c.ccc || c.ccc.gitCoAuthor == null
2171
2193
  ? '跟随 DeepCCC 全局设置(缺省开启)'
2172
2194
  : (c.ccc.gitCoAuthor ? '强制开启' : '强制关闭');
@@ -2255,7 +2277,7 @@ function editSection(section) {
2255
2277
  'CHATCCC_CCC_API_KEY': 'API Key', 'CHATCCC_CCC_BASE_URL': 'Base URL',
2256
2278
  'CHATCCC_CCC_PROVIDER': 'API 协议(选填)',
2257
2279
  'CHATCCC_CCC_GIT_COAUTHOR': 'Git 提交共同作者',
2258
- 'CHATCCC_CCC_MODEL': '模型', 'CHATCCC_CCC_SUB_MODEL': '子模型', 'CHATCCC_CCC_ALTERNATIVE_MODEL': '备选模型', 'CHATCCC_CCC_EFFORT': 'Effort', 'CHATCCC_CCC_CONTEXT_WINDOW': '上下文窗口',
2280
+ 'CHATCCC_CCC_MODEL': '模型', 'CHATCCC_CCC_SUB_MODEL': '子模型', 'CHATCCC_CCC_ALTERNATIVE_MODEL': '备选模型', 'CHATCCC_CCC_EFFORT': 'Effort', 'CHATCCC_CCC_MAX_OUTPUT_TOKENS': '最大输出 Token', 'CHATCCC_CCC_CONTEXT_WINDOW': '上下文窗口',
2259
2281
  'CHATCCC_DSH_API_KEY': 'API Key', 'CHATCCC_DSH_BASE_URL': 'Base URL', 'CHATCCC_DSH_MODEL': '模型', 'CHATCCC_DSH_SUB_MODEL': '子模型', 'CHATCCC_DSH_ALTERNATIVE_MODEL': '备选模型', 'CHATCCC_DSH_PROVIDER': 'Provider 路由', 'CHATCCC_DSH_MAX_TOKENS': '单次最大输出 Tokens'
2260
2282
  };
2261
2283
  var hintMap = {
@@ -2264,6 +2286,8 @@ function editSection(section) {
2264
2286
  'CHATCCC_CHROME_DEVTOOLS_PORT': '默认 15166,健康检查端点为 http://127.0.0.1:15166/json/version。',
2265
2287
  'CHATCCC_CHROME_DEVTOOLS_PATH': '选填。留空时自动探测 Google Chrome。',
2266
2288
  'CHATCCC_CCC_PROVIDER': '与 Base URL 强相关:OpenAI 兼容端点选 openai;Anthropic Messages 端点选 anthropic。留空 = 跟随 DeepCCC 内核配置(~/.deepccc/config.json 或 DEEPCCC_PROVIDER),改动需重启 ChatCCC 生效。',
2289
+ 'CHATCCC_CCC_EFFORT': '留空 = 跟随 DeepCCC 内核配置(~/.deepccc/config.json 或 DEEPCCC_EFFORT);内核也留空时使用模型服务端默认值。',
2290
+ 'CHATCCC_CCC_MAX_OUTPUT_TOKENS': '正整数;留空 = 跟随 DeepCCC 内核配置(~/.deepccc/config.json 或 DEEPCCC_MAX_OUTPUT_TOKENS);内核也未配置时使用模型服务端默认值。',
2267
2291
  'CHATCCC_CCC_GIT_COAUTHOR': '跟随全局时读取 ~/.deepccc/config.json 的 git.coAuthor.enabled(缺省为开启)。强制选项只影响 ChatCCC 内置 CCC Agent。',
2268
2292
  'CHATCCC_CCC_CONTEXT_WINDOW': '压缩阈值自动 = 窗口 × 80%(超出即把较早消息压缩为摘要)。⚠️ 超过模型/服务端实际上限时请求会被 API 直接拒绝(context length exceeded),实际窗口以模型与所用服务端为准(如 litellm 代理的 max_input_tokens);单位 k = 1024 tokens,1M = 1,048,576 tokens。',
2269
2293
  'CHATCCC_CCC_SUB_MODEL': '用于 DeepCCC 内部轻量环节(上下文压缩摘要生成、task 子代理任务)。留空 = 跟随主模型;改动需重启 ChatCCC 生效。'
@@ -2314,6 +2338,7 @@ function editSection(section) {
2314
2338
  else if (key === 'CHATCCC_CCC_SUB_MODEL') val = state.config.ccc.subModel || '';
2315
2339
  else if (key === 'CHATCCC_CCC_ALTERNATIVE_MODEL') val = state.config.ccc.alternativeModel || '';
2316
2340
  else if (key === 'CHATCCC_CCC_EFFORT') val = state.config.ccc.effort || '';
2341
+ else if (key === 'CHATCCC_CCC_MAX_OUTPUT_TOKENS') val = state.config.ccc.maxOutputTokens || '';
2317
2342
  else if (key === 'CHATCCC_CCC_CONTEXT_WINDOW') val = state.config.ccc.contextWindow || '1048576';
2318
2343
  } else if (section === 'dsh' && state.config.dsh) {
2319
2344
  if (key === 'CHATCCC_DSH_API_KEY') val = state.config.dsh.apiKey || '';
@@ -2378,12 +2403,14 @@ function editSection(section) {
2378
2403
  var rowId = key === 'CHATCCC_CURSOR_ON_DEMAND_MONTHLY_BUDGET'
2379
2404
  ? ' id="edit-cursor-on-demand-budget-row"'
2380
2405
  : (section === 'chromeDevtools' && key !== 'CHATCCC_CHROME_DEVTOOLS_ENABLED' ? ' id="edit-row-' + key + '"' : '');
2381
- var isNumber = key === 'CHATCCC_CURSOR_ON_DEMAND_MONTHLY_BUDGET' || key === 'CHATCCC_CHROME_DEVTOOLS_PORT';
2406
+ var isNumber = key === 'CHATCCC_CURSOR_ON_DEMAND_MONTHLY_BUDGET' || key === 'CHATCCC_CHROME_DEVTOOLS_PORT' || key === 'CHATCCC_CCC_MAX_OUTPUT_TOKENS';
2382
2407
  var inputType = isNumber ? 'number' : (isSecret ? 'password' : 'text');
2383
2408
  var attrs = key === 'CHATCCC_CURSOR_ON_DEMAND_MONTHLY_BUDGET'
2384
2409
  ? ' min="1" step="1"'
2385
2410
  : key === 'CHATCCC_CHROME_DEVTOOLS_PORT'
2386
2411
  ? ' min="1" max="65535" step="1" placeholder="15166"'
2412
+ : key === 'CHATCCC_CCC_MAX_OUTPUT_TOKENS'
2413
+ ? ' min="1" step="1" placeholder="留空跟随 DeepCCC 内核配置"'
2387
2414
  : '';
2388
2415
  html += '<div class="form-group"' + rowId + '><label>' + (labelMap[key] || key) + '</label>';
2389
2416
  html += '<input type="' + inputType + '" id="edit-' + key + '"' + attrs + ' value="' + String(val).replace(/"/g,'&quot;') + '">';
package/package.json CHANGED
@@ -1,76 +1,76 @@
1
- {
2
- "name": "chatccc",
3
- "version": "0.2.270",
4
- "description": "Feishu bot bridge for Claude Code",
5
- "license": "Apache-2.0",
6
- "type": "module",
7
- "main": "./dist/src/index.js",
8
- "bin": {
9
- "chatccc": "bin/chatccc.mjs",
10
- "cccagent": "bin/cccagent.mjs"
11
- },
12
- "files": [
13
- "dist/",
14
- "deepccc-agent/os-prompts/",
15
- "bin/",
16
- "scripts/postinstall-sharp-check.mjs",
17
- "demo/ilink_echo_probe.ts",
18
- "agent-prompts/",
19
- "im-skills/",
20
- ".agents/skills/create-chatccc-feishu-app/",
21
- ".claude/skills/create-chatccc-feishu-app/",
22
- ".cursor/skills/create-chatccc-feishu-app/",
23
- "images/img_readme_*.jpg",
24
- "images/img_readme_*.png",
25
- "images/avatars/status_*.png",
26
- "images/avatars/badges/",
27
- "images/avatars/combinations/",
28
- "package.json",
29
- "README.md",
30
- "config.sample.json"
31
- ],
32
- "scripts": {
33
- "build": "node scripts/build.mjs",
34
- "prepack": "npm run build",
35
- "dev": "tsx src/index.ts",
36
- "chatccc": "tsx src/index.ts",
37
- "start": "tsx src/index.ts",
38
- "demo:bot-test": "tsx demo/bot_test.ts",
39
- "demo:bot-test:local": "tsx demo/bot_test.ts --local",
40
- "demo:create-group": "tsx src/index.ts",
41
- "demo:create-group:local": "tsx src/index.ts --local",
42
- "demo:permission-check": "tsx demo/permission_check.ts",
43
- "demo:claude-hi": "tsx demo/claude_say_hi.ts",
44
- "demo:codex-hi": "tsx demo/codex_say_hi.ts",
45
- "demo:codex-app-server-approval": "tsx demo/codex-app-server-approval/approval_demo.ts",
46
- "demo:ilink-echo": "tsx demo/ilink_echo_probe.ts",
47
- "claude-proxy": "tsx src/litellm-proxy.ts",
48
- "test": "vitest run",
49
- "test:deepccc": "vitest run --root deepccc-agent",
50
- "test:watch": "vitest",
51
- "postinstall": "node scripts/postinstall-sharp-check.mjs"
52
- },
53
- "dependencies": {
54
- "@ai-sdk/anthropic": "^3.0.105",
55
- "@ai-sdk/openai-compatible": "^2.0.47",
56
- "@larksuiteoapi/node-sdk": "^1.59.0",
57
- "@openilink/openilink-sdk-node": "^0.6.0",
58
- "@vscode/ripgrep": "^1.18.0",
59
- "ai": "^6.0.184",
60
- "nodemailer": "^8.0.7",
61
- "qrcode-terminal": "^0.12.0",
62
- "sharp": "^0.34.5",
63
- "ws": "^8.18.0"
64
- },
65
- "devDependencies": {
66
- "@types/node": "^20.0.0",
67
- "@types/qrcode-terminal": "^0.12.2",
68
- "@types/ws": "^8.18.1",
69
- "tsx": "^4.0.0",
70
- "typescript": "^5.0.0",
71
- "vitest": "^3.2.4"
72
- },
73
- "engines": {
74
- "node": ">=20"
75
- }
76
- }
1
+ {
2
+ "name": "chatccc",
3
+ "version": "0.2.272",
4
+ "description": "Feishu bot bridge for Claude Code",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "main": "./dist/src/index.js",
8
+ "bin": {
9
+ "chatccc": "bin/chatccc.mjs",
10
+ "cccagent": "bin/cccagent.mjs"
11
+ },
12
+ "files": [
13
+ "dist/",
14
+ "deepccc-agent/os-prompts/",
15
+ "bin/",
16
+ "scripts/postinstall-sharp-check.mjs",
17
+ "demo/ilink_echo_probe.ts",
18
+ "agent-prompts/",
19
+ "im-skills/",
20
+ ".agents/skills/create-chatccc-feishu-app/",
21
+ ".claude/skills/create-chatccc-feishu-app/",
22
+ ".cursor/skills/create-chatccc-feishu-app/",
23
+ "images/img_readme_*.jpg",
24
+ "images/img_readme_*.png",
25
+ "images/avatars/status_*.png",
26
+ "images/avatars/badges/",
27
+ "images/avatars/combinations/",
28
+ "package.json",
29
+ "README.md",
30
+ "config.sample.json"
31
+ ],
32
+ "scripts": {
33
+ "build": "node scripts/build.mjs",
34
+ "prepack": "npm run build",
35
+ "dev": "tsx src/index.ts",
36
+ "chatccc": "tsx src/index.ts",
37
+ "start": "tsx src/index.ts",
38
+ "demo:bot-test": "tsx demo/bot_test.ts",
39
+ "demo:bot-test:local": "tsx demo/bot_test.ts --local",
40
+ "demo:create-group": "tsx src/index.ts",
41
+ "demo:create-group:local": "tsx src/index.ts --local",
42
+ "demo:permission-check": "tsx demo/permission_check.ts",
43
+ "demo:claude-hi": "tsx demo/claude_say_hi.ts",
44
+ "demo:codex-hi": "tsx demo/codex_say_hi.ts",
45
+ "demo:codex-app-server-approval": "tsx demo/codex-app-server-approval/approval_demo.ts",
46
+ "demo:ilink-echo": "tsx demo/ilink_echo_probe.ts",
47
+ "claude-proxy": "tsx src/litellm-proxy.ts",
48
+ "test": "vitest run",
49
+ "test:deepccc": "vitest run --root deepccc-agent",
50
+ "test:watch": "vitest",
51
+ "postinstall": "node scripts/postinstall-sharp-check.mjs"
52
+ },
53
+ "dependencies": {
54
+ "@ai-sdk/anthropic": "^3.0.105",
55
+ "@ai-sdk/openai-compatible": "^2.0.47",
56
+ "@larksuiteoapi/node-sdk": "^1.59.0",
57
+ "@openilink/openilink-sdk-node": "^0.6.0",
58
+ "@vscode/ripgrep": "^1.18.0",
59
+ "ai": "^6.0.184",
60
+ "nodemailer": "^8.0.7",
61
+ "qrcode-terminal": "^0.12.0",
62
+ "sharp": "^0.34.5",
63
+ "ws": "^8.18.0"
64
+ },
65
+ "devDependencies": {
66
+ "@types/node": "^20.0.0",
67
+ "@types/qrcode-terminal": "^0.12.2",
68
+ "@types/ws": "^8.18.1",
69
+ "tsx": "^4.0.0",
70
+ "typescript": "^5.0.0",
71
+ "vitest": "^3.2.4"
72
+ },
73
+ "engines": {
74
+ "node": ">=20"
75
+ }
76
+ }