flashclaw 1.0.0

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.
Files changed (138) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +305 -0
  3. package/config/plugins.json +23 -0
  4. package/dist/agent-runner.d.ts +103 -0
  5. package/dist/agent-runner.d.ts.map +1 -0
  6. package/dist/agent-runner.js +530 -0
  7. package/dist/agent-runner.js.map +1 -0
  8. package/dist/cli.d.ts +7 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +497 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/commands.d.ts +68 -0
  13. package/dist/commands.d.ts.map +1 -0
  14. package/dist/commands.js +252 -0
  15. package/dist/commands.js.map +1 -0
  16. package/dist/config-schema.d.ts +21 -0
  17. package/dist/config-schema.d.ts.map +1 -0
  18. package/dist/config-schema.js +26 -0
  19. package/dist/config-schema.js.map +1 -0
  20. package/dist/config.d.ts +11 -0
  21. package/dist/config.d.ts.map +1 -0
  22. package/dist/config.js +36 -0
  23. package/dist/config.js.map +1 -0
  24. package/dist/core/api-client.d.ts +236 -0
  25. package/dist/core/api-client.d.ts.map +1 -0
  26. package/dist/core/api-client.js +369 -0
  27. package/dist/core/api-client.js.map +1 -0
  28. package/dist/core/memory.d.ts +291 -0
  29. package/dist/core/memory.d.ts.map +1 -0
  30. package/dist/core/memory.js +754 -0
  31. package/dist/core/memory.js.map +1 -0
  32. package/dist/core/model-capabilities.d.ts +45 -0
  33. package/dist/core/model-capabilities.d.ts.map +1 -0
  34. package/dist/core/model-capabilities.js +85 -0
  35. package/dist/core/model-capabilities.js.map +1 -0
  36. package/dist/db.d.ts +103 -0
  37. package/dist/db.d.ts.map +1 -0
  38. package/dist/db.js +380 -0
  39. package/dist/db.js.map +1 -0
  40. package/dist/errors.d.ts +22 -0
  41. package/dist/errors.d.ts.map +1 -0
  42. package/dist/errors.js +44 -0
  43. package/dist/errors.js.map +1 -0
  44. package/dist/health.d.ts +27 -0
  45. package/dist/health.d.ts.map +1 -0
  46. package/dist/health.js +55 -0
  47. package/dist/health.js.map +1 -0
  48. package/dist/index.d.ts +11 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +1181 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/logger.d.ts +9 -0
  53. package/dist/logger.d.ts.map +1 -0
  54. package/dist/logger.js +19 -0
  55. package/dist/logger.js.map +1 -0
  56. package/dist/message-queue.d.ts +69 -0
  57. package/dist/message-queue.d.ts.map +1 -0
  58. package/dist/message-queue.js +198 -0
  59. package/dist/message-queue.js.map +1 -0
  60. package/dist/metrics.d.ts +46 -0
  61. package/dist/metrics.d.ts.map +1 -0
  62. package/dist/metrics.js +101 -0
  63. package/dist/metrics.js.map +1 -0
  64. package/dist/paths.d.ts +81 -0
  65. package/dist/paths.d.ts.map +1 -0
  66. package/dist/paths.js +127 -0
  67. package/dist/paths.js.map +1 -0
  68. package/dist/plugins/index.d.ts +9 -0
  69. package/dist/plugins/index.d.ts.map +1 -0
  70. package/dist/plugins/index.js +13 -0
  71. package/dist/plugins/index.js.map +1 -0
  72. package/dist/plugins/installer.d.ts +120 -0
  73. package/dist/plugins/installer.d.ts.map +1 -0
  74. package/dist/plugins/installer.js +1008 -0
  75. package/dist/plugins/installer.js.map +1 -0
  76. package/dist/plugins/loader.d.ts +37 -0
  77. package/dist/plugins/loader.d.ts.map +1 -0
  78. package/dist/plugins/loader.js +429 -0
  79. package/dist/plugins/loader.js.map +1 -0
  80. package/dist/plugins/manager.d.ts +72 -0
  81. package/dist/plugins/manager.d.ts.map +1 -0
  82. package/dist/plugins/manager.js +187 -0
  83. package/dist/plugins/manager.js.map +1 -0
  84. package/dist/plugins/types.d.ts +101 -0
  85. package/dist/plugins/types.d.ts.map +1 -0
  86. package/dist/plugins/types.js +12 -0
  87. package/dist/plugins/types.js.map +1 -0
  88. package/dist/session-tracker.d.ts +81 -0
  89. package/dist/session-tracker.d.ts.map +1 -0
  90. package/dist/session-tracker.js +228 -0
  91. package/dist/session-tracker.js.map +1 -0
  92. package/dist/task-scheduler.d.ts +47 -0
  93. package/dist/task-scheduler.d.ts.map +1 -0
  94. package/dist/task-scheduler.js +331 -0
  95. package/dist/task-scheduler.js.map +1 -0
  96. package/dist/types.d.ts +57 -0
  97. package/dist/types.d.ts.map +1 -0
  98. package/dist/types.js +2 -0
  99. package/dist/types.js.map +1 -0
  100. package/dist/utils/env-substitute.d.ts +63 -0
  101. package/dist/utils/env-substitute.d.ts.map +1 -0
  102. package/dist/utils/env-substitute.js +133 -0
  103. package/dist/utils/env-substitute.js.map +1 -0
  104. package/dist/utils/log-rotate.d.ts +19 -0
  105. package/dist/utils/log-rotate.d.ts.map +1 -0
  106. package/dist/utils/log-rotate.js +85 -0
  107. package/dist/utils/log-rotate.js.map +1 -0
  108. package/dist/utils/rate-limiter.d.ts +38 -0
  109. package/dist/utils/rate-limiter.d.ts.map +1 -0
  110. package/dist/utils/rate-limiter.js +79 -0
  111. package/dist/utils/rate-limiter.js.map +1 -0
  112. package/dist/utils/retry.d.ts +10 -0
  113. package/dist/utils/retry.d.ts.map +1 -0
  114. package/dist/utils/retry.js +47 -0
  115. package/dist/utils/retry.js.map +1 -0
  116. package/dist/utils.d.ts +86 -0
  117. package/dist/utils.d.ts.map +1 -0
  118. package/dist/utils.js +218 -0
  119. package/dist/utils.js.map +1 -0
  120. package/package.json +78 -0
  121. package/plugins/cancel-task/index.ts +161 -0
  122. package/plugins/cancel-task/plugin.json +9 -0
  123. package/plugins/feishu/index.ts +944 -0
  124. package/plugins/feishu/plugin.json +29 -0
  125. package/plugins/list-tasks/index.ts +150 -0
  126. package/plugins/list-tasks/plugin.json +9 -0
  127. package/plugins/memory/index.ts +190 -0
  128. package/plugins/memory/plugin.json +7 -0
  129. package/plugins/pause-task/index.ts +95 -0
  130. package/plugins/pause-task/plugin.json +8 -0
  131. package/plugins/register-group/index.ts +147 -0
  132. package/plugins/register-group/plugin.json +7 -0
  133. package/plugins/resume-task/index.ts +92 -0
  134. package/plugins/resume-task/plugin.json +8 -0
  135. package/plugins/schedule-task/index.ts +248 -0
  136. package/plugins/schedule-task/plugin.json +9 -0
  137. package/plugins/send-message/index.ts +75 -0
  138. package/plugins/send-message/plugin.json +9 -0
@@ -0,0 +1,252 @@
1
+ /**
2
+ * Chat Commands Module
3
+ *
4
+ * 处理用户在聊天中发送的斜杠命令
5
+ * 如 /status, /new, /help 等
6
+ */
7
+ import pino from 'pino';
8
+ const logger = pino({
9
+ level: process.env.LOG_LEVEL || 'info',
10
+ transport: { target: 'pino-pretty', options: { colorize: true } }
11
+ });
12
+ /**
13
+ * 检查消息是否是命令
14
+ */
15
+ export function isCommand(content) {
16
+ return content.trim().startsWith('/');
17
+ }
18
+ /**
19
+ * 解析命令
20
+ */
21
+ function parseCommand(content) {
22
+ const trimmed = content.trim();
23
+ const parts = trimmed.slice(1).split(/\s+/);
24
+ return {
25
+ command: parts[0]?.toLowerCase() || '',
26
+ args: parts.slice(1)
27
+ };
28
+ }
29
+ /**
30
+ * 处理命令
31
+ */
32
+ export function handleCommand(content, context) {
33
+ if (!isCommand(content)) {
34
+ return { isCommand: false };
35
+ }
36
+ const { command, args } = parseCommand(content);
37
+ logger.info({ command, args, chatId: context.chatId }, '⚡ 收到命令');
38
+ switch (command) {
39
+ case 'help':
40
+ case 'h':
41
+ case '帮助':
42
+ return handleHelp();
43
+ case 'status':
44
+ case 's':
45
+ case '状态':
46
+ return handleStatus(context);
47
+ case 'new':
48
+ case 'reset':
49
+ case '重置':
50
+ return handleReset(context);
51
+ case 'tasks':
52
+ case '任务':
53
+ return handleTasks(context);
54
+ case 'ping':
55
+ return handlePing();
56
+ case 'compact':
57
+ return handleCompact(context);
58
+ default:
59
+ return {
60
+ isCommand: true,
61
+ shouldRespond: true,
62
+ response: `❌ 未知命令: /${command}\n\n使用 /help 查看可用命令`
63
+ };
64
+ }
65
+ }
66
+ /**
67
+ * /help - 显示帮助
68
+ */
69
+ function handleHelp() {
70
+ const helpText = `⚡ **FlashClaw 命令**
71
+
72
+ 📋 **基础命令**
73
+ \`/help\` - 显示此帮助
74
+ \`/status\` - 查看会话状态
75
+ \`/new\` - 重置当前会话
76
+ \`/compact\` - 压缩会话上下文
77
+ \`/tasks\` - 查看定时任务
78
+ \`/ping\` - 测试机器人响应
79
+
80
+ 💡 **提示**
81
+ • 私聊直接发消息即可对话
82
+ • 群聊需要 @机器人 触发响应
83
+ • 使用 "记住..." 保存长期记忆
84
+ • 上下文达到 70% 时会自动提示压缩`;
85
+ return {
86
+ isCommand: true,
87
+ shouldRespond: true,
88
+ response: helpText
89
+ };
90
+ }
91
+ /**
92
+ * 简单哈希函数,用于脱敏显示
93
+ */
94
+ function hashId(id) {
95
+ let hash = 0;
96
+ for (let i = 0; i < id.length; i++) {
97
+ const char = id.charCodeAt(i);
98
+ hash = ((hash << 5) - hash) + char;
99
+ hash = hash & hash;
100
+ }
101
+ return Math.abs(hash).toString(16).slice(0, 8);
102
+ }
103
+ /**
104
+ * /status - 显示会话状态
105
+ */
106
+ function handleStatus(context) {
107
+ const stats = context.getSessionStats?.();
108
+ // 脱敏处理:用户 ID 和会话 ID 都用哈希显示
109
+ const maskedChatId = hashId(context.chatId);
110
+ const maskedUserId = hashId(context.userId);
111
+ // 如果用户名看起来像 ID(ou_ 开头或很长的字符串),则使用脱敏后的 ID
112
+ const displayName = (context.userName &&
113
+ !context.userName.startsWith('ou_') &&
114
+ context.userName.length < 20)
115
+ ? context.userName
116
+ : `用户#${maskedUserId}`;
117
+ let statusText = `⚡ **会话状态**\n\n`;
118
+ statusText += `📍 **会话**: \`#${maskedChatId}\`\n`;
119
+ statusText += `👤 **用户**: ${displayName}\n`;
120
+ statusText += `📱 **平台**: ${context.platform}\n`;
121
+ if (stats) {
122
+ statusText += `\n📊 **统计**\n`;
123
+ statusText += `• 消息数: ${stats.messageCount}\n`;
124
+ if (stats.tokenCount !== undefined && stats.tokenCount > 0) {
125
+ const usagePercent = stats.maxTokens
126
+ ? Math.round((stats.tokenCount / stats.maxTokens) * 100)
127
+ : 0;
128
+ statusText += `• Token: ${stats.tokenCount.toLocaleString()}`;
129
+ if (stats.maxTokens) {
130
+ statusText += ` / ${stats.maxTokens.toLocaleString()} (${usagePercent}%)`;
131
+ }
132
+ statusText += `\n`;
133
+ }
134
+ else {
135
+ statusText += `• Token: _统计中..._\n`;
136
+ }
137
+ if (stats.model) {
138
+ statusText += `• 模型: ${stats.model}\n`;
139
+ }
140
+ if (stats.startedAt) {
141
+ statusText += `• 开始于: ${new Date(stats.startedAt).toLocaleString('zh-CN')}\n`;
142
+ }
143
+ }
144
+ else {
145
+ statusText += `\n_会话统计暂不可用_`;
146
+ }
147
+ return {
148
+ isCommand: true,
149
+ shouldRespond: true,
150
+ response: statusText
151
+ };
152
+ }
153
+ /**
154
+ * /new - 重置会话
155
+ */
156
+ function handleReset(context) {
157
+ if (context.resetSession) {
158
+ context.resetSession();
159
+ logger.info({ chatId: context.chatId }, '⚡ 会话已重置');
160
+ return {
161
+ isCommand: true,
162
+ shouldRespond: true,
163
+ response: `✅ **会话已重置**\n\n新的对话已开始,之前的上下文已清除。`
164
+ };
165
+ }
166
+ return {
167
+ isCommand: true,
168
+ shouldRespond: true,
169
+ response: `⚠️ 会话重置功能暂不可用`
170
+ };
171
+ }
172
+ /**
173
+ * /tasks - 显示定时任务
174
+ */
175
+ function handleTasks(context) {
176
+ const tasks = context.getTasks?.() || [];
177
+ if (tasks.length === 0) {
178
+ return {
179
+ isCommand: true,
180
+ shouldRespond: true,
181
+ response: `📋 **定时任务**\n\n_当前没有定时任务_\n\n使用自然语言创建任务,如:\n"每天早上9点提醒我喝水"`
182
+ };
183
+ }
184
+ let tasksText = `📋 **定时任务** (${tasks.length}个)\n\n`;
185
+ for (const task of tasks) {
186
+ const statusIcon = task.status === 'active' ? '🟢' :
187
+ task.status === 'paused' ? '⏸️' : '⚪';
188
+ tasksText += `${statusIcon} **${task.id.slice(-6)}**\n`;
189
+ tasksText += ` ${task.prompt.slice(0, 50)}${task.prompt.length > 50 ? '...' : ''}\n`;
190
+ if (task.nextRun) {
191
+ tasksText += ` ⏰ 下次: ${new Date(task.nextRun).toLocaleString('zh-CN')}\n`;
192
+ }
193
+ tasksText += `\n`;
194
+ }
195
+ return {
196
+ isCommand: true,
197
+ shouldRespond: true,
198
+ response: tasksText
199
+ };
200
+ }
201
+ /**
202
+ * /ping - 测试响应
203
+ */
204
+ function handlePing() {
205
+ return {
206
+ isCommand: true,
207
+ shouldRespond: true,
208
+ response: `🏓 Pong! FlashClaw 运行正常`
209
+ };
210
+ }
211
+ /**
212
+ * /compact - 压缩会话上下文
213
+ */
214
+ function handleCompact(context) {
215
+ if (!context.compactSession) {
216
+ return {
217
+ isCommand: true,
218
+ shouldRespond: true,
219
+ response: `⚠️ 会话压缩功能暂不可用`
220
+ };
221
+ }
222
+ // 返回一个立即响应,实际压缩在后台进行
223
+ // 压缩完成后会发送另一条消息
224
+ return {
225
+ isCommand: true,
226
+ shouldRespond: true,
227
+ response: `⏳ **正在压缩会话...**\n\n这可能需要几秒钟,压缩完成后会通知你。`
228
+ };
229
+ }
230
+ /**
231
+ * 检查是否需要提示用户压缩会话
232
+ * @param tokenCount 当前 token 数
233
+ * @param maxTokens 最大 token 数
234
+ * @param threshold 阈值(默认 0.7 = 70%)
235
+ */
236
+ export function shouldSuggestCompact(tokenCount, maxTokens, threshold = 0.7) {
237
+ if (!tokenCount || !maxTokens)
238
+ return false;
239
+ return tokenCount / maxTokens >= threshold;
240
+ }
241
+ /**
242
+ * 生成压缩提示消息
243
+ */
244
+ export function getCompactSuggestion(tokenCount, maxTokens) {
245
+ const percentage = Math.round((tokenCount / maxTokens) * 100);
246
+ return `⚠️ **上下文使用率 ${percentage}%**\n\n` +
247
+ `当前会话已使用 ${tokenCount.toLocaleString()} / ${maxTokens.toLocaleString()} tokens。\n\n` +
248
+ `建议操作:\n` +
249
+ `• 发送 \`/compact\` 压缩上下文(保留摘要)\n` +
250
+ `• 发送 \`/new\` 重置会话(清除所有)`;
251
+ }
252
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { z } from 'zod';
2
+ export declare const envSchema: z.ZodObject<{
3
+ ANTHROPIC_API_KEY: z.ZodOptional<z.ZodString>;
4
+ ANTHROPIC_BASE_URL: z.ZodOptional<z.ZodString>;
5
+ ANTHROPIC_AUTH_TOKEN: z.ZodOptional<z.ZodString>;
6
+ AI_MODEL: z.ZodDefault<z.ZodString>;
7
+ FEISHU_APP_ID: z.ZodOptional<z.ZodString>;
8
+ FEISHU_APP_SECRET: z.ZodOptional<z.ZodString>;
9
+ BOT_NAME: z.ZodDefault<z.ZodString>;
10
+ LOG_LEVEL: z.ZodDefault<z.ZodEnum<{
11
+ error: "error";
12
+ info: "info";
13
+ warn: "warn";
14
+ debug: "debug";
15
+ }>>;
16
+ TIMEZONE: z.ZodDefault<z.ZodString>;
17
+ AGENT_TIMEOUT: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
18
+ }, z.core.$strip>;
19
+ export type EnvConfig = z.infer<typeof envSchema>;
20
+ export declare function validateEnv(env: Record<string, string | undefined>): EnvConfig;
21
+ //# sourceMappingURL=config-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["../src/config-schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;iBAgBpB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAElD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAO9E"}
@@ -0,0 +1,26 @@
1
+ // src/config-schema.ts
2
+ import { z } from 'zod';
3
+ export const envSchema = z.object({
4
+ // AI API 配置
5
+ ANTHROPIC_API_KEY: z.string().optional(),
6
+ ANTHROPIC_BASE_URL: z.string().url().optional(),
7
+ ANTHROPIC_AUTH_TOKEN: z.string().optional(),
8
+ AI_MODEL: z.string().default('claude-4-5-sonnet-20250929'),
9
+ // 飞书配置
10
+ FEISHU_APP_ID: z.string().optional(),
11
+ FEISHU_APP_SECRET: z.string().optional(),
12
+ // 其他配置
13
+ BOT_NAME: z.string().default('FlashClaw'),
14
+ LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
15
+ TIMEZONE: z.string().default('Asia/Shanghai'),
16
+ AGENT_TIMEOUT: z.coerce.number().default(300000),
17
+ });
18
+ export function validateEnv(env) {
19
+ const result = envSchema.safeParse(env);
20
+ if (!result.success) {
21
+ const errors = result.error.issues.map((e) => `${e.path.join('.')}: ${e.message}`).join('\n');
22
+ throw new Error(`配置校验失败:\n${errors}`);
23
+ }
24
+ return result.data;
25
+ }
26
+ //# sourceMappingURL=config-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-schema.js","sourceRoot":"","sources":["../src/config-schema.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,YAAY;IACZ,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACxC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC/C,oBAAoB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,4BAA4B,CAAC;IAE1D,OAAO;IACP,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAExC,OAAO;IACP,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC;IACzC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACrE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC;IAC7C,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;CACjD,CAAC,CAAC;AAIH,MAAM,UAAU,WAAW,CAAC,GAAuC;IACjE,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAa,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1G,MAAM,IAAI,KAAK,CAAC,YAAY,MAAM,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
@@ -0,0 +1,11 @@
1
+ export declare const BOT_NAME: string;
2
+ export declare const SCHEDULER_POLL_INTERVAL = 60000;
3
+ export declare const IPC_POLL_INTERVAL = 1000;
4
+ export declare const MOUNT_ALLOWLIST_PATH: string;
5
+ export declare const STORE_DIR: string;
6
+ export declare const GROUPS_DIR: string;
7
+ export declare const DATA_DIR: string;
8
+ export declare const MAIN_GROUP_FOLDER = "main";
9
+ export declare const AGENT_TIMEOUT: number;
10
+ export declare const TIMEZONE: string;
11
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,QAAQ,QAAsC,CAAC;AAG5D,eAAO,MAAM,uBAAuB,QAAQ,CAAC;AAC7C,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAkBtC,eAAO,MAAM,oBAAoB,QAAoD,CAAC;AACtF,eAAO,MAAM,SAAS,QAAsC,CAAC;AAC7D,eAAO,MAAM,UAAU,QAAuC,CAAC;AAC/D,eAAO,MAAM,QAAQ,QAAqC,CAAC;AAC3D,eAAO,MAAM,iBAAiB,SAAS,CAAC;AAGxC,eAAO,MAAM,aAAa,QAAsD,CAAC;AAKjF,eAAO,MAAM,QAAQ,QAAqE,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,36 @@
1
+ import path from 'path';
2
+ import os from 'os';
3
+ import dotenv from 'dotenv';
4
+ // Load environment variables from .env file
5
+ dotenv.config();
6
+ // ==================== Bot Configuration ====================
7
+ // Bot name for display in messages (customizable via .env)
8
+ export const BOT_NAME = process.env.BOT_NAME || 'FlashClaw';
9
+ // ==================== Polling Intervals ====================
10
+ export const SCHEDULER_POLL_INTERVAL = 60000;
11
+ export const IPC_POLL_INTERVAL = 1000;
12
+ // ==================== Paths ====================
13
+ const PROJECT_ROOT = process.cwd();
14
+ function getHomeDir() {
15
+ return process.env.HOME || os.homedir() || '/home/user';
16
+ }
17
+ function getConfigDir() {
18
+ const IS_WINDOWS = process.platform === 'win32';
19
+ if (IS_WINDOWS) {
20
+ return path.join(process.env.APPDATA || path.join(getHomeDir(), 'AppData', 'Roaming'), 'flashclaw');
21
+ }
22
+ return path.join(getHomeDir(), '.config', 'flashclaw');
23
+ }
24
+ // Mount security: allowlist stored OUTSIDE project root
25
+ export const MOUNT_ALLOWLIST_PATH = path.join(getConfigDir(), 'mount-allowlist.json');
26
+ export const STORE_DIR = path.resolve(PROJECT_ROOT, 'store');
27
+ export const GROUPS_DIR = path.resolve(PROJECT_ROOT, 'groups');
28
+ export const DATA_DIR = path.resolve(PROJECT_ROOT, 'data');
29
+ export const MAIN_GROUP_FOLDER = 'main';
30
+ // ==================== Agent Configuration ====================
31
+ export const AGENT_TIMEOUT = parseInt(process.env.AGENT_TIMEOUT || '300000', 10); // 5 minutes default
32
+ // ==================== Timezone ====================
33
+ // Timezone for scheduled tasks (cron expressions, etc.)
34
+ // Uses system timezone by default
35
+ export const TIMEZONE = process.env.TZ || Intl.DateTimeFormat().resolvedOptions().timeZone;
36
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,4CAA4C;AAC5C,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,8DAA8D;AAC9D,2DAA2D;AAC3D,MAAM,CAAC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,WAAW,CAAC;AAE5D,8DAA8D;AAC9D,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,CAAC;AAC7C,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAEtC,kDAAkD;AAClD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAEnC,SAAS,UAAU;IACjB,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,YAAY,CAAC;AAC1D,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;IAChD,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,WAAW,CAAC,CAAC;IACtG,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AACzD,CAAC;AAED,wDAAwD;AACxD,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,sBAAsB,CAAC,CAAC;AACtF,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;AAC7D,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;AAC/D,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAExC,gEAAgE;AAChE,MAAM,CAAC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB;AAEtG,qDAAqD;AACrD,wDAAwD;AACxD,kCAAkC;AAClC,MAAM,CAAC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC"}
@@ -0,0 +1,236 @@
1
+ /**
2
+ * FlashClaw API 客户端
3
+ * 直接调用 Anthropic API,支持 MiniMax 等兼容 API
4
+ *
5
+ * 特性:
6
+ * - 支持多模型提供商
7
+ * - 工具调用 (Tool Use)
8
+ * - 流式响应 (Streaming)
9
+ * - 错误重试
10
+ */
11
+ import Anthropic from '@anthropic-ai/sdk';
12
+ /**
13
+ * API 配置
14
+ */
15
+ export interface ApiConfig {
16
+ /** API 密钥 */
17
+ apiKey: string;
18
+ /** 自定义 API 端点(支持 MiniMax 等兼容 API) */
19
+ baseURL?: string;
20
+ /** 模型名称 */
21
+ model?: string;
22
+ /** 最大重试次数 */
23
+ maxRetries?: number;
24
+ /** 请求超时时间(毫秒) */
25
+ timeout?: number;
26
+ }
27
+ /**
28
+ * 图片内容块
29
+ */
30
+ export interface ImageBlock {
31
+ type: 'image';
32
+ source: {
33
+ type: 'base64';
34
+ media_type: 'image/png' | 'image/jpeg' | 'image/gif' | 'image/webp';
35
+ data: string;
36
+ };
37
+ }
38
+ /**
39
+ * 文本内容块
40
+ */
41
+ export interface TextBlock {
42
+ type: 'text';
43
+ text: string;
44
+ }
45
+ /**
46
+ * 消息内容类型
47
+ */
48
+ export type MessageContent = string | (TextBlock | ImageBlock)[];
49
+ /**
50
+ * 聊天消息
51
+ */
52
+ export interface ChatMessage {
53
+ /** 角色:user 或 assistant */
54
+ role: 'user' | 'assistant';
55
+ /** 消息内容 - 可以是纯文本或包含图片的数组 */
56
+ content: MessageContent;
57
+ }
58
+ /**
59
+ * 工具定义 Schema
60
+ */
61
+ export interface ToolSchema {
62
+ /** 工具名称 */
63
+ name: string;
64
+ /** 工具描述 */
65
+ description: string;
66
+ /** 参数 JSON Schema */
67
+ input_schema: {
68
+ type: 'object';
69
+ properties: Record<string, unknown>;
70
+ required?: string[];
71
+ };
72
+ }
73
+ /**
74
+ * 聊天选项
75
+ */
76
+ export interface ChatOptions {
77
+ /** 系统提示词 */
78
+ system?: string;
79
+ /** 可用工具列表 */
80
+ tools?: ToolSchema[];
81
+ /** 最大输出 token 数 */
82
+ maxTokens?: number;
83
+ /** 温度参数 (0-1) */
84
+ temperature?: number;
85
+ /** 停止序列 */
86
+ stopSequences?: string[];
87
+ }
88
+ /**
89
+ * 流式事件类型
90
+ */
91
+ export type StreamEvent = {
92
+ type: 'text';
93
+ text: string;
94
+ } | {
95
+ type: 'tool_use';
96
+ id: string;
97
+ name: string;
98
+ input: unknown;
99
+ } | {
100
+ type: 'done';
101
+ message: Anthropic.Message;
102
+ };
103
+ /**
104
+ * 工具执行器类型
105
+ */
106
+ export type ToolExecutor = (name: string, params: unknown) => Promise<unknown>;
107
+ /**
108
+ * FlashClaw API 客户端
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * const client = new ApiClient({
113
+ * apiKey: process.env.ANTHROPIC_API_KEY!,
114
+ * });
115
+ *
116
+ * const response = await client.chat([
117
+ * { role: 'user', content: '你好!' }
118
+ * ]);
119
+ *
120
+ * console.log(response.content[0]);
121
+ * ```
122
+ */
123
+ export declare class ApiClient {
124
+ private client;
125
+ private model;
126
+ private maxRetries;
127
+ private timeout;
128
+ constructor(config: ApiConfig);
129
+ /**
130
+ * 发送消息并获取回复
131
+ *
132
+ * @param messages - 聊天消息历史
133
+ * @param options - 聊天选项
134
+ * @returns API 响应消息
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * const response = await client.chat(
139
+ * [{ role: 'user', content: '解释量子计算' }],
140
+ * { system: '你是一位物理学教授', maxTokens: 1024 }
141
+ * );
142
+ * ```
143
+ */
144
+ chat(messages: ChatMessage[], options?: ChatOptions): Promise<Anthropic.Message>;
145
+ /**
146
+ * 流式发送消息
147
+ *
148
+ * @param messages - 聊天消息历史
149
+ * @param options - 聊天选项
150
+ * @returns 异步迭代器,产生流式事件
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * for await (const event of client.chatStream(messages)) {
155
+ * if (event.type === 'text') {
156
+ * process.stdout.write(event.text);
157
+ * }
158
+ * }
159
+ * ```
160
+ */
161
+ chatStream(messages: ChatMessage[], options?: ChatOptions): AsyncGenerator<StreamEvent>;
162
+ /**
163
+ * 处理工具调用
164
+ * 自动执行工具并获取最终回复
165
+ *
166
+ * @param response - 包含工具调用的 API 响应
167
+ * @param messages - 原始消息历史
168
+ * @param executeTool - 工具执行函数
169
+ * @param options - 聊天选项(用于后续请求)
170
+ * @returns 最终文本回复
171
+ *
172
+ * @example
173
+ * ```typescript
174
+ * const response = await client.chat(messages, { tools });
175
+ *
176
+ * if (response.stop_reason === 'tool_use') {
177
+ * const finalText = await client.handleToolUse(
178
+ * response,
179
+ * messages,
180
+ * async (name, params) => {
181
+ * // 执行工具逻辑
182
+ * return { result: 'done' };
183
+ * }
184
+ * );
185
+ * }
186
+ * ```
187
+ */
188
+ handleToolUse(response: Anthropic.Message, messages: ChatMessage[], executeTool: ToolExecutor, options?: ChatOptions): Promise<string>;
189
+ /**
190
+ * 从响应中提取文本内容
191
+ *
192
+ * @param response - API 响应
193
+ * @returns 文本内容
194
+ */
195
+ extractText(response: Anthropic.Message): string;
196
+ /**
197
+ * 获取当前使用的模型
198
+ */
199
+ getModel(): string;
200
+ /**
201
+ * 设置模型
202
+ *
203
+ * @param model - 模型名称
204
+ */
205
+ setModel(model: string): void;
206
+ /**
207
+ * 判断错误是否可重试
208
+ */
209
+ private isRetryableError;
210
+ /**
211
+ * 延迟函数
212
+ */
213
+ private sleep;
214
+ }
215
+ /**
216
+ * 创建默认 API 客户端
217
+ * 从环境变量读取配置
218
+ *
219
+ * @returns API 客户端实例,如果配置缺失则返回 null
220
+ */
221
+ export declare function createApiClient(): ApiClient | null;
222
+ declare global {
223
+ var __flashclaw_api_client: ApiClient | null | undefined;
224
+ }
225
+ /**
226
+ * 获取全局 API 客户端单例
227
+ * 确保 jiti 热加载的插件访问同一实例
228
+ *
229
+ * @returns API 客户端实例,如果配置缺失则返回 null
230
+ */
231
+ export declare function getApiClient(): ApiClient | null;
232
+ /**
233
+ * 重置 API 客户端(用于配置变更后重新初始化)
234
+ */
235
+ export declare function resetApiClient(): void;
236
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/core/api-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAI1C;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,aAAa;IACb,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE;QACN,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,WAAW,GAAG,YAAY,GAAG,WAAW,GAAG,YAAY,CAAC;QACpE,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,CAAC,SAAS,GAAG,UAAU,CAAC,EAAE,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0BAA0B;IAC1B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,4BAA4B;IAC5B,OAAO,EAAE,cAAc,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,WAAW;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,YAAY,EAAE;QACZ,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,YAAY;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa;IACb,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,mBAAmB;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW;IACX,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAA;CAAE,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAI/E;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,SAAS;IAY7B;;;;;;;;;;;;;;OAcG;IACG,IAAI,CACR,QAAQ,EAAE,WAAW,EAAE,EACvB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;IAuD7B;;;;;;;;;;;;;;;OAeG;IACI,UAAU,CACf,QAAQ,EAAE,WAAW,EAAE,EACvB,OAAO,CAAC,EAAE,WAAW,GACpB,cAAc,CAAC,WAAW,CAAC;IAyE9B;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACG,aAAa,CACjB,QAAQ,EAAE,SAAS,CAAC,OAAO,EAC3B,QAAQ,EAAE,WAAW,EAAE,EACvB,WAAW,EAAE,YAAY,EACzB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,CAAC;IAmFlB;;;;;OAKG;IACH,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO,GAAG,MAAM;IAOhD;;OAEG;IACH,QAAQ,IAAI,MAAM;IAIlB;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAYxB;;OAEG;IACH,OAAO,CAAC,KAAK;CAGd;AAID;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,SAAS,GAAG,IAAI,CAclD;AAKD,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,sBAAsB,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,CAAC;CAC1D;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,SAAS,GAAG,IAAI,CAK/C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAErC"}