chatccc 0.2.246 → 0.2.248
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/README.md +2 -0
- package/config.sample.json +2 -1
- package/deepccc-agent/README.md +34 -34
- package/deepccc-agent/os-prompts/darwin.md +8 -8
- package/deepccc-agent/os-prompts/linux.md +8 -8
- package/deepccc-agent/os-prompts/win32.md +9 -9
- package/deepccc-agent/package-lock.json +2027 -2027
- package/deepccc-agent/package.json +65 -65
- package/deepccc-agent/src/__tests__/chat-session.test.ts +816 -741
- package/deepccc-agent/src/__tests__/config.test.ts +34 -34
- package/deepccc-agent/src/__tests__/permissions.test.ts +199 -199
- package/deepccc-agent/src/__tests__/privacy.test.ts +15 -15
- package/deepccc-agent/src/cli.ts +25 -25
- package/deepccc-agent/src/config.ts +101 -101
- package/deepccc-agent/src/index.ts +18 -5
- package/package.json +74 -74
- package/src/__tests__/builtin-chat-session.test.ts +532 -532
- package/src/__tests__/builtin-permissions.test.ts +219 -219
- package/src/__tests__/ccc-adapter.test.ts +194 -194
- package/src/__tests__/config-reload.test.ts +1 -1
- package/src/__tests__/config-utils.test.ts +40 -0
- package/src/__tests__/session-ccc-config.test.ts +21 -0
- package/src/__tests__/session.test.ts +369 -369
- package/src/__tests__/web-ui.test.ts +2 -0
- package/src/adapters/adapter-interface.ts +42 -42
- package/src/adapters/ccc-adapter.ts +150 -150
- package/src/config-utils.ts +37 -13
- package/src/config.ts +23 -13
- package/src/session.ts +2 -0
- package/src/web-ui.ts +33 -2
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
4
|
-
|
|
5
|
-
export type DeepCccProvider = "openai" | "anthropic";
|
|
6
|
-
|
|
7
|
-
export interface DeepCccConfig {
|
|
8
|
-
/** API protocol/provider. Defaults to OpenAI-compatible. */
|
|
9
|
-
provider: DeepCccProvider;
|
|
10
|
-
apiKey: string;
|
|
11
|
-
baseURL: string;
|
|
12
|
-
model: string;
|
|
13
|
-
/** Reasoning effort(none/minimal/low/medium/high/xhigh/max),留空不传 reasoning_effort */
|
|
14
|
-
effort: string;
|
|
15
|
-
/** 主对话是否使用流式请求;默认开启 */
|
|
16
|
-
streaming: boolean;
|
|
17
|
-
rawStreamLogs: {
|
|
18
|
-
enabled: boolean;
|
|
19
|
-
maxBytesPerTurn: number;
|
|
20
|
-
retentionDays: number;
|
|
21
|
-
keepCompleted: boolean;
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const DEEPCCC_HOME = join(homedir(), ".deepccc");
|
|
26
|
-
export const RAW_STREAM_LOGS_DIR = join(DEEPCCC_HOME, "raw-stream-logs");
|
|
27
|
-
const CONFIG_PATH = join(DEEPCCC_HOME, "config.json");
|
|
28
|
-
|
|
29
|
-
const DEFAULT_CONFIG: DeepCccConfig = {
|
|
30
|
-
provider: "openai",
|
|
31
|
-
apiKey: "",
|
|
32
|
-
baseURL: "https://api.deepseek.com/v1",
|
|
33
|
-
model: "deepseek-v4-pro",
|
|
34
|
-
effort: "",
|
|
35
|
-
streaming: true,
|
|
36
|
-
rawStreamLogs: {
|
|
37
|
-
enabled: false,
|
|
38
|
-
maxBytesPerTurn: 1024 * 1024,
|
|
39
|
-
retentionDays: 7,
|
|
40
|
-
keepCompleted: false,
|
|
41
|
-
},
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
function readConfigFile(): Partial<DeepCccConfig> {
|
|
45
|
-
if (!existsSync(CONFIG_PATH)) return {};
|
|
46
|
-
const raw = JSON.parse(readFileSync(CONFIG_PATH, "utf8")) as Partial<DeepCccConfig>;
|
|
47
|
-
return raw && typeof raw === "object" ? raw : {};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function env(name: string): string | undefined {
|
|
51
|
-
const value = process.env[name]?.trim();
|
|
52
|
-
return value ? value : undefined;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function boolEnv(name: string): boolean | undefined {
|
|
56
|
-
const value = env(name)?.toLowerCase();
|
|
57
|
-
if (value === undefined) return undefined;
|
|
58
|
-
if (["1", "true", "yes", "on"].includes(value)) return true;
|
|
59
|
-
if (["0", "false", "no", "off"].includes(value)) return false;
|
|
60
|
-
return undefined;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function numberEnv(name: string): number | undefined {
|
|
64
|
-
const value = Number(env(name));
|
|
65
|
-
return Number.isFinite(value) && value >= 0 ? value : undefined;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export function normalizeDeepCccProvider(value: unknown): DeepCccProvider {
|
|
69
|
-
if (value === undefined || value === null || String(value).trim() === "") return "openai";
|
|
70
|
-
const normalized = String(value).trim().toLowerCase();
|
|
71
|
-
if (normalized === "openai" || normalized === "anthropic") return normalized;
|
|
72
|
-
throw new Error(`DEEPCCC_PROVIDER/provider must be "openai" or "anthropic", received: ${String(value)}`);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function loadConfig(): DeepCccConfig {
|
|
76
|
-
const file = readConfigFile();
|
|
77
|
-
const rawLogs: Partial<DeepCccConfig["rawStreamLogs"]> = file.rawStreamLogs && typeof file.rawStreamLogs === "object"
|
|
78
|
-
? file.rawStreamLogs
|
|
79
|
-
: {};
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
provider: normalizeDeepCccProvider(env("DEEPCCC_PROVIDER") ?? file.provider ?? DEFAULT_CONFIG.provider),
|
|
83
|
-
apiKey: env("DEEPCCC_API_KEY") ?? env("DEEPSEEK_API_KEY") ?? file.apiKey ?? DEFAULT_CONFIG.apiKey,
|
|
84
|
-
baseURL: env("DEEPCCC_BASE_URL") ?? env("DEEPSEEK_BASE_URL") ?? file.baseURL ?? DEFAULT_CONFIG.baseURL,
|
|
85
|
-
model: env("DEEPCCC_MODEL") ?? env("DEEPSEEK_MODEL") ?? file.model ?? DEFAULT_CONFIG.model,
|
|
86
|
-
effort: env("DEEPCCC_EFFORT") ?? env("DEEPSEEK_EFFORT") ?? file.effort ?? DEFAULT_CONFIG.effort,
|
|
87
|
-
streaming: boolEnv("DEEPCCC_STREAMING") ?? file.streaming ?? DEFAULT_CONFIG.streaming,
|
|
88
|
-
rawStreamLogs: {
|
|
89
|
-
enabled: boolEnv("DEEPCCC_RAW_STREAM_LOGS") ?? rawLogs.enabled ?? DEFAULT_CONFIG.rawStreamLogs.enabled,
|
|
90
|
-
maxBytesPerTurn: numberEnv("DEEPCCC_RAW_STREAM_MAX_BYTES") ?? rawLogs.maxBytesPerTurn ?? DEFAULT_CONFIG.rawStreamLogs.maxBytesPerTurn,
|
|
91
|
-
retentionDays: numberEnv("DEEPCCC_RAW_STREAM_RETENTION_DAYS") ?? rawLogs.retentionDays ?? DEFAULT_CONFIG.rawStreamLogs.retentionDays,
|
|
92
|
-
keepCompleted: boolEnv("DEEPCCC_RAW_STREAM_KEEP_COMPLETED") ?? rawLogs.keepCompleted ?? DEFAULT_CONFIG.rawStreamLogs.keepCompleted,
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function ensureConfigDir(): void {
|
|
98
|
-
mkdirSync(dirname(CONFIG_PATH), { recursive: true });
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export const config = loadConfig();
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
|
|
5
|
+
export type DeepCccProvider = "openai" | "anthropic";
|
|
6
|
+
|
|
7
|
+
export interface DeepCccConfig {
|
|
8
|
+
/** API protocol/provider. Defaults to OpenAI-compatible. */
|
|
9
|
+
provider: DeepCccProvider;
|
|
10
|
+
apiKey: string;
|
|
11
|
+
baseURL: string;
|
|
12
|
+
model: string;
|
|
13
|
+
/** Reasoning effort(none/minimal/low/medium/high/xhigh/max),留空不传 reasoning_effort */
|
|
14
|
+
effort: string;
|
|
15
|
+
/** 主对话是否使用流式请求;默认开启 */
|
|
16
|
+
streaming: boolean;
|
|
17
|
+
rawStreamLogs: {
|
|
18
|
+
enabled: boolean;
|
|
19
|
+
maxBytesPerTurn: number;
|
|
20
|
+
retentionDays: number;
|
|
21
|
+
keepCompleted: boolean;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const DEEPCCC_HOME = join(homedir(), ".deepccc");
|
|
26
|
+
export const RAW_STREAM_LOGS_DIR = join(DEEPCCC_HOME, "raw-stream-logs");
|
|
27
|
+
const CONFIG_PATH = join(DEEPCCC_HOME, "config.json");
|
|
28
|
+
|
|
29
|
+
const DEFAULT_CONFIG: DeepCccConfig = {
|
|
30
|
+
provider: "openai",
|
|
31
|
+
apiKey: "",
|
|
32
|
+
baseURL: "https://api.deepseek.com/v1",
|
|
33
|
+
model: "deepseek-v4-pro",
|
|
34
|
+
effort: "",
|
|
35
|
+
streaming: true,
|
|
36
|
+
rawStreamLogs: {
|
|
37
|
+
enabled: false,
|
|
38
|
+
maxBytesPerTurn: 1024 * 1024,
|
|
39
|
+
retentionDays: 7,
|
|
40
|
+
keepCompleted: false,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
function readConfigFile(): Partial<DeepCccConfig> {
|
|
45
|
+
if (!existsSync(CONFIG_PATH)) return {};
|
|
46
|
+
const raw = JSON.parse(readFileSync(CONFIG_PATH, "utf8")) as Partial<DeepCccConfig>;
|
|
47
|
+
return raw && typeof raw === "object" ? raw : {};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function env(name: string): string | undefined {
|
|
51
|
+
const value = process.env[name]?.trim();
|
|
52
|
+
return value ? value : undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function boolEnv(name: string): boolean | undefined {
|
|
56
|
+
const value = env(name)?.toLowerCase();
|
|
57
|
+
if (value === undefined) return undefined;
|
|
58
|
+
if (["1", "true", "yes", "on"].includes(value)) return true;
|
|
59
|
+
if (["0", "false", "no", "off"].includes(value)) return false;
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function numberEnv(name: string): number | undefined {
|
|
64
|
+
const value = Number(env(name));
|
|
65
|
+
return Number.isFinite(value) && value >= 0 ? value : undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function normalizeDeepCccProvider(value: unknown): DeepCccProvider {
|
|
69
|
+
if (value === undefined || value === null || String(value).trim() === "") return "openai";
|
|
70
|
+
const normalized = String(value).trim().toLowerCase();
|
|
71
|
+
if (normalized === "openai" || normalized === "anthropic") return normalized;
|
|
72
|
+
throw new Error(`DEEPCCC_PROVIDER/provider must be "openai" or "anthropic", received: ${String(value)}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function loadConfig(): DeepCccConfig {
|
|
76
|
+
const file = readConfigFile();
|
|
77
|
+
const rawLogs: Partial<DeepCccConfig["rawStreamLogs"]> = file.rawStreamLogs && typeof file.rawStreamLogs === "object"
|
|
78
|
+
? file.rawStreamLogs
|
|
79
|
+
: {};
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
provider: normalizeDeepCccProvider(env("DEEPCCC_PROVIDER") ?? file.provider ?? DEFAULT_CONFIG.provider),
|
|
83
|
+
apiKey: env("DEEPCCC_API_KEY") ?? env("DEEPSEEK_API_KEY") ?? file.apiKey ?? DEFAULT_CONFIG.apiKey,
|
|
84
|
+
baseURL: env("DEEPCCC_BASE_URL") ?? env("DEEPSEEK_BASE_URL") ?? file.baseURL ?? DEFAULT_CONFIG.baseURL,
|
|
85
|
+
model: env("DEEPCCC_MODEL") ?? env("DEEPSEEK_MODEL") ?? file.model ?? DEFAULT_CONFIG.model,
|
|
86
|
+
effort: env("DEEPCCC_EFFORT") ?? env("DEEPSEEK_EFFORT") ?? file.effort ?? DEFAULT_CONFIG.effort,
|
|
87
|
+
streaming: boolEnv("DEEPCCC_STREAMING") ?? file.streaming ?? DEFAULT_CONFIG.streaming,
|
|
88
|
+
rawStreamLogs: {
|
|
89
|
+
enabled: boolEnv("DEEPCCC_RAW_STREAM_LOGS") ?? rawLogs.enabled ?? DEFAULT_CONFIG.rawStreamLogs.enabled,
|
|
90
|
+
maxBytesPerTurn: numberEnv("DEEPCCC_RAW_STREAM_MAX_BYTES") ?? rawLogs.maxBytesPerTurn ?? DEFAULT_CONFIG.rawStreamLogs.maxBytesPerTurn,
|
|
91
|
+
retentionDays: numberEnv("DEEPCCC_RAW_STREAM_RETENTION_DAYS") ?? rawLogs.retentionDays ?? DEFAULT_CONFIG.rawStreamLogs.retentionDays,
|
|
92
|
+
keepCompleted: boolEnv("DEEPCCC_RAW_STREAM_KEEP_COMPLETED") ?? rawLogs.keepCompleted ?? DEFAULT_CONFIG.rawStreamLogs.keepCompleted,
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function ensureConfigDir(): void {
|
|
98
|
+
mkdirSync(dirname(CONFIG_PATH), { recursive: true });
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const config = loadConfig();
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
|
|
8
8
|
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
9
|
+
import type { JSONObject } from "@ai-sdk/provider";
|
|
9
10
|
import { generateText, isLoopFinished, stepCountIs, streamText, type TextStreamPart } from "ai";
|
|
10
11
|
import { existsSync, readFileSync } from "node:fs";
|
|
11
12
|
import { homedir } from "node:os";
|
|
@@ -407,6 +408,17 @@ export class ChatSession {
|
|
|
407
408
|
const skills = await scanSkillsDirs(this.skillDirs);
|
|
408
409
|
const system = this.buildSystemPrompt(skills);
|
|
409
410
|
this.systemPrompt = system;
|
|
411
|
+
// effort 按协议映射:
|
|
412
|
+
// - OpenAI 兼容:providerOptions.deepseek.reasoningEffort 由 @ai-sdk/openai-compatible
|
|
413
|
+
// 自动映射为请求体 reasoning_effort 字段(DeepSeek 原生支持);
|
|
414
|
+
// - Anthropic:providerOptions.anthropic.effort 由 @ai-sdk/anthropic 组装为请求体
|
|
415
|
+
// output_config.effort(官方 Effort API,见 platform.claude.com/docs/en/build-with-claude/effort)
|
|
416
|
+
let effortProviderOptions: Record<string, JSONObject> | undefined;
|
|
417
|
+
if (this.effort) {
|
|
418
|
+
effortProviderOptions = this.provider === "openai"
|
|
419
|
+
? { deepseek: { reasoningEffort: this.effort } }
|
|
420
|
+
: { anthropic: { effort: this.effort } };
|
|
421
|
+
}
|
|
410
422
|
const generationOptions = {
|
|
411
423
|
model: this.model,
|
|
412
424
|
system,
|
|
@@ -414,11 +426,7 @@ export class ChatSession {
|
|
|
414
426
|
tools: createBuiltinFileTools(this.cwd, { permissionGate: this.permissionGate }),
|
|
415
427
|
stopWhen: maxSteps !== undefined ? stepCountIs(maxSteps) : isLoopFinished(),
|
|
416
428
|
abortSignal: signal,
|
|
417
|
-
|
|
418
|
-
// 由 @ai-sdk/openai-compatible 自动映射为请求体 reasoning_effort 字段
|
|
419
|
-
...(this.provider === "openai" && this.effort
|
|
420
|
-
? { providerOptions: { deepseek: { reasoningEffort: this.effort } } }
|
|
421
|
-
: {}),
|
|
429
|
+
...(effortProviderOptions ? { providerOptions: effortProviderOptions } : {}),
|
|
422
430
|
};
|
|
423
431
|
let stream: AsyncIterable<TextStreamPart<any>>;
|
|
424
432
|
if (appConfig.streaming) {
|
|
@@ -562,6 +570,11 @@ export class ChatSession {
|
|
|
562
570
|
messages: [{ role: "user", content: buildSummaryPrompt(plan) }],
|
|
563
571
|
abortSignal: compactionSignal,
|
|
564
572
|
temperature: 0,
|
|
573
|
+
// 压缩是摘要类任务:显式锁低 effort(OpenAI reasoning_effort=none / Anthropic
|
|
574
|
+
// output_config.effort=low),避免继承主对话的高 effort 拖慢"压缩上下文中"阶段
|
|
575
|
+
providerOptions: this.provider === "openai"
|
|
576
|
+
? { deepseek: { reasoningEffort: "none" } }
|
|
577
|
+
: { anthropic: { effort: "low" } },
|
|
565
578
|
});
|
|
566
579
|
|
|
567
580
|
if (!result.text.trim()) {
|
package/package.json
CHANGED
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "chatccc",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Feishu bot bridge for Claude Code",
|
|
5
|
-
"license": "Apache-2.0",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"main": "./src/index.ts",
|
|
8
|
-
"bin": {
|
|
9
|
-
"chatccc": "bin/chatccc.mjs",
|
|
10
|
-
"cccagent": "bin/cccagent.mjs"
|
|
11
|
-
},
|
|
12
|
-
"files": [
|
|
13
|
-
"src/",
|
|
14
|
-
"deepccc-agent/",
|
|
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
|
-
"dev": "tsx src/index.ts",
|
|
34
|
-
"chatccc": "tsx src/index.ts",
|
|
35
|
-
"start": "tsx src/index.ts",
|
|
36
|
-
"demo:bot-test": "tsx demo/bot_test.ts",
|
|
37
|
-
"demo:bot-test:local": "tsx demo/bot_test.ts --local",
|
|
38
|
-
"demo:create-group": "tsx src/index.ts",
|
|
39
|
-
"demo:create-group:local": "tsx src/index.ts --local",
|
|
40
|
-
"demo:permission-check": "tsx demo/permission_check.ts",
|
|
41
|
-
"demo:claude-hi": "tsx demo/claude_say_hi.ts",
|
|
42
|
-
"demo:codex-hi": "tsx demo/codex_say_hi.ts",
|
|
43
|
-
"demo:codex-app-server-approval": "tsx demo/codex-app-server-approval/approval_demo.ts",
|
|
44
|
-
"demo:ilink-echo": "tsx demo/ilink_echo_probe.ts",
|
|
45
|
-
"claude-proxy": "tsx src/litellm-proxy.ts",
|
|
46
|
-
"test": "vitest run",
|
|
47
|
-
"test:deepccc": "vitest run --root deepccc-agent",
|
|
48
|
-
"test:watch": "vitest",
|
|
49
|
-
"postinstall": "node scripts/postinstall-sharp-check.mjs"
|
|
50
|
-
},
|
|
51
|
-
"dependencies": {
|
|
52
|
-
"@ai-sdk/anthropic": "^3.0.105",
|
|
53
|
-
"@ai-sdk/openai-compatible": "^2.0.47",
|
|
54
|
-
"@larksuiteoapi/node-sdk": "^1.59.0",
|
|
55
|
-
"@openilink/openilink-sdk-node": "^0.6.0",
|
|
56
|
-
"@vscode/ripgrep": "^1.18.0",
|
|
57
|
-
"ai": "^6.0.184",
|
|
58
|
-
"nodemailer": "^8.0.7",
|
|
59
|
-
"qrcode-terminal": "^0.12.0",
|
|
60
|
-
"sharp": "^0.34.5",
|
|
61
|
-
"tsx": "^4.0.0",
|
|
62
|
-
"ws": "^8.18.0"
|
|
63
|
-
},
|
|
64
|
-
"devDependencies": {
|
|
65
|
-
"@types/node": "^20.0.0",
|
|
66
|
-
"@types/qrcode-terminal": "^0.12.2",
|
|
67
|
-
"@types/ws": "^8.18.1",
|
|
68
|
-
"typescript": "^5.0.0",
|
|
69
|
-
"vitest": "^3.2.4"
|
|
70
|
-
},
|
|
71
|
-
"engines": {
|
|
72
|
-
"node": ">=20"
|
|
73
|
-
}
|
|
74
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "chatccc",
|
|
3
|
+
"version": "0.2.248",
|
|
4
|
+
"description": "Feishu bot bridge for Claude Code",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./src/index.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"chatccc": "bin/chatccc.mjs",
|
|
10
|
+
"cccagent": "bin/cccagent.mjs"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"src/",
|
|
14
|
+
"deepccc-agent/",
|
|
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
|
+
"dev": "tsx src/index.ts",
|
|
34
|
+
"chatccc": "tsx src/index.ts",
|
|
35
|
+
"start": "tsx src/index.ts",
|
|
36
|
+
"demo:bot-test": "tsx demo/bot_test.ts",
|
|
37
|
+
"demo:bot-test:local": "tsx demo/bot_test.ts --local",
|
|
38
|
+
"demo:create-group": "tsx src/index.ts",
|
|
39
|
+
"demo:create-group:local": "tsx src/index.ts --local",
|
|
40
|
+
"demo:permission-check": "tsx demo/permission_check.ts",
|
|
41
|
+
"demo:claude-hi": "tsx demo/claude_say_hi.ts",
|
|
42
|
+
"demo:codex-hi": "tsx demo/codex_say_hi.ts",
|
|
43
|
+
"demo:codex-app-server-approval": "tsx demo/codex-app-server-approval/approval_demo.ts",
|
|
44
|
+
"demo:ilink-echo": "tsx demo/ilink_echo_probe.ts",
|
|
45
|
+
"claude-proxy": "tsx src/litellm-proxy.ts",
|
|
46
|
+
"test": "vitest run",
|
|
47
|
+
"test:deepccc": "vitest run --root deepccc-agent",
|
|
48
|
+
"test:watch": "vitest",
|
|
49
|
+
"postinstall": "node scripts/postinstall-sharp-check.mjs"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@ai-sdk/anthropic": "^3.0.105",
|
|
53
|
+
"@ai-sdk/openai-compatible": "^2.0.47",
|
|
54
|
+
"@larksuiteoapi/node-sdk": "^1.59.0",
|
|
55
|
+
"@openilink/openilink-sdk-node": "^0.6.0",
|
|
56
|
+
"@vscode/ripgrep": "^1.18.0",
|
|
57
|
+
"ai": "^6.0.184",
|
|
58
|
+
"nodemailer": "^8.0.7",
|
|
59
|
+
"qrcode-terminal": "^0.12.0",
|
|
60
|
+
"sharp": "^0.34.5",
|
|
61
|
+
"tsx": "^4.0.0",
|
|
62
|
+
"ws": "^8.18.0"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@types/node": "^20.0.0",
|
|
66
|
+
"@types/qrcode-terminal": "^0.12.2",
|
|
67
|
+
"@types/ws": "^8.18.1",
|
|
68
|
+
"typescript": "^5.0.0",
|
|
69
|
+
"vitest": "^3.2.4"
|
|
70
|
+
},
|
|
71
|
+
"engines": {
|
|
72
|
+
"node": ">=20"
|
|
73
|
+
}
|
|
74
|
+
}
|