feique 1.1.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.
- package/LICENSE +21 -0
- package/README.en.md +220 -0
- package/README.md +265 -0
- package/dist/backend/claude.d.ts +36 -0
- package/dist/backend/claude.js +358 -0
- package/dist/backend/claude.js.map +1 -0
- package/dist/backend/codex.d.ts +31 -0
- package/dist/backend/codex.js +100 -0
- package/dist/backend/codex.js.map +1 -0
- package/dist/backend/factory.d.ts +9 -0
- package/dist/backend/factory.js +56 -0
- package/dist/backend/factory.js.map +1 -0
- package/dist/backend/types.d.ts +54 -0
- package/dist/backend/types.js +2 -0
- package/dist/backend/types.js.map +1 -0
- package/dist/bridge/commands.d.ts +135 -0
- package/dist/bridge/commands.js +860 -0
- package/dist/bridge/commands.js.map +1 -0
- package/dist/bridge/service.d.ts +160 -0
- package/dist/bridge/service.js +3785 -0
- package/dist/bridge/service.js.map +1 -0
- package/dist/bridge/task-queue.d.ts +14 -0
- package/dist/bridge/task-queue.js +81 -0
- package/dist/bridge/task-queue.js.map +1 -0
- package/dist/bridge/types.d.ts +39 -0
- package/dist/bridge/types.js +2 -0
- package/dist/bridge/types.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +1199 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex/capabilities.d.ts +20 -0
- package/dist/codex/capabilities.js +41 -0
- package/dist/codex/capabilities.js.map +1 -0
- package/dist/codex/runner.d.ts +47 -0
- package/dist/codex/runner.js +294 -0
- package/dist/codex/runner.js.map +1 -0
- package/dist/codex/session-index.d.ts +22 -0
- package/dist/codex/session-index.js +205 -0
- package/dist/codex/session-index.js.map +1 -0
- package/dist/collaboration/awareness.d.ts +36 -0
- package/dist/collaboration/awareness.js +107 -0
- package/dist/collaboration/awareness.js.map +1 -0
- package/dist/collaboration/digest.d.ts +65 -0
- package/dist/collaboration/digest.js +178 -0
- package/dist/collaboration/digest.js.map +1 -0
- package/dist/collaboration/handoff.d.ts +66 -0
- package/dist/collaboration/handoff.js +94 -0
- package/dist/collaboration/handoff.js.map +1 -0
- package/dist/collaboration/insights.d.ts +24 -0
- package/dist/collaboration/insights.js +243 -0
- package/dist/collaboration/insights.js.map +1 -0
- package/dist/collaboration/knowledge.d.ts +26 -0
- package/dist/collaboration/knowledge.js +105 -0
- package/dist/collaboration/knowledge.js.map +1 -0
- package/dist/collaboration/timeline.d.ts +31 -0
- package/dist/collaboration/timeline.js +150 -0
- package/dist/collaboration/timeline.js.map +1 -0
- package/dist/collaboration/trust.d.ts +49 -0
- package/dist/collaboration/trust.js +176 -0
- package/dist/collaboration/trust.js.map +1 -0
- package/dist/config/codex-skill.d.ts +7 -0
- package/dist/config/codex-skill.js +44 -0
- package/dist/config/codex-skill.js.map +1 -0
- package/dist/config/doctor.d.ts +12 -0
- package/dist/config/doctor.js +314 -0
- package/dist/config/doctor.js.map +1 -0
- package/dist/config/init.d.ts +3 -0
- package/dist/config/init.js +123 -0
- package/dist/config/init.js.map +1 -0
- package/dist/config/load.d.ts +33 -0
- package/dist/config/load.js +252 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/mutate.d.ts +21 -0
- package/dist/config/mutate.js +86 -0
- package/dist/config/mutate.js.map +1 -0
- package/dist/config/paths.d.ts +3 -0
- package/dist/config/paths.js +33 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/schema.d.ts +308 -0
- package/dist/config/schema.js +250 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/control-plane/project-session.d.ts +67 -0
- package/dist/control-plane/project-session.js +234 -0
- package/dist/control-plane/project-session.js.map +1 -0
- package/dist/feishu/base.d.ts +19 -0
- package/dist/feishu/base.js +93 -0
- package/dist/feishu/base.js.map +1 -0
- package/dist/feishu/cards.d.ts +22 -0
- package/dist/feishu/cards.js +144 -0
- package/dist/feishu/cards.js.map +1 -0
- package/dist/feishu/client.d.ts +61 -0
- package/dist/feishu/client.js +315 -0
- package/dist/feishu/client.js.map +1 -0
- package/dist/feishu/diagnostics.d.ts +42 -0
- package/dist/feishu/diagnostics.js +194 -0
- package/dist/feishu/diagnostics.js.map +1 -0
- package/dist/feishu/doc.d.ts +13 -0
- package/dist/feishu/doc.js +59 -0
- package/dist/feishu/doc.js.map +1 -0
- package/dist/feishu/extractors.d.ts +7 -0
- package/dist/feishu/extractors.js +215 -0
- package/dist/feishu/extractors.js.map +1 -0
- package/dist/feishu/long-connection.d.ts +12 -0
- package/dist/feishu/long-connection.js +41 -0
- package/dist/feishu/long-connection.js.map +1 -0
- package/dist/feishu/message-resource.d.ts +14 -0
- package/dist/feishu/message-resource.js +309 -0
- package/dist/feishu/message-resource.js.map +1 -0
- package/dist/feishu/replay.d.ts +37 -0
- package/dist/feishu/replay.js +114 -0
- package/dist/feishu/replay.js.map +1 -0
- package/dist/feishu/task.d.ts +18 -0
- package/dist/feishu/task.js +86 -0
- package/dist/feishu/task.js.map +1 -0
- package/dist/feishu/text.d.ts +23 -0
- package/dist/feishu/text.js +155 -0
- package/dist/feishu/text.js.map +1 -0
- package/dist/feishu/webhook.d.ts +23 -0
- package/dist/feishu/webhook.js +130 -0
- package/dist/feishu/webhook.js.map +1 -0
- package/dist/feishu/wiki.d.ts +52 -0
- package/dist/feishu/wiki.js +300 -0
- package/dist/feishu/wiki.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge/search.d.ts +11 -0
- package/dist/knowledge/search.js +83 -0
- package/dist/knowledge/search.js.map +1 -0
- package/dist/logging.d.ts +3 -0
- package/dist/logging.js +40 -0
- package/dist/logging.js.map +1 -0
- package/dist/mcp/server.d.ts +34 -0
- package/dist/mcp/server.js +1196 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/memory/embedding-factory.d.ts +6 -0
- package/dist/memory/embedding-factory.js +20 -0
- package/dist/memory/embedding-factory.js.map +1 -0
- package/dist/memory/embeddings.d.ts +40 -0
- package/dist/memory/embeddings.js +150 -0
- package/dist/memory/embeddings.js.map +1 -0
- package/dist/memory/ollama-embeddings.d.ts +63 -0
- package/dist/memory/ollama-embeddings.js +215 -0
- package/dist/memory/ollama-embeddings.js.map +1 -0
- package/dist/memory/retrieve.d.ts +17 -0
- package/dist/memory/retrieve.js +29 -0
- package/dist/memory/retrieve.js.map +1 -0
- package/dist/memory/summarize.d.ts +13 -0
- package/dist/memory/summarize.js +58 -0
- package/dist/memory/summarize.js.map +1 -0
- package/dist/observability/cost.d.ts +12 -0
- package/dist/observability/cost.js +22 -0
- package/dist/observability/cost.js.map +1 -0
- package/dist/observability/dashboard-html.d.ts +5 -0
- package/dist/observability/dashboard-html.js +304 -0
- package/dist/observability/dashboard-html.js.map +1 -0
- package/dist/observability/metrics.d.ts +36 -0
- package/dist/observability/metrics.js +230 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/observability/readiness.d.ts +31 -0
- package/dist/observability/readiness.js +57 -0
- package/dist/observability/readiness.js.map +1 -0
- package/dist/observability/server.d.ts +84 -0
- package/dist/observability/server.js +181 -0
- package/dist/observability/server.js.map +1 -0
- package/dist/projects/paths.d.ts +9 -0
- package/dist/projects/paths.js +30 -0
- package/dist/projects/paths.js.map +1 -0
- package/dist/runtime/instance-lock.d.ts +12 -0
- package/dist/runtime/instance-lock.js +99 -0
- package/dist/runtime/instance-lock.js.map +1 -0
- package/dist/runtime/process.d.ts +2 -0
- package/dist/runtime/process.js +43 -0
- package/dist/runtime/process.js.map +1 -0
- package/dist/runtime/shutdown.d.ts +11 -0
- package/dist/runtime/shutdown.js +38 -0
- package/dist/runtime/shutdown.js.map +1 -0
- package/dist/security/access.d.ts +13 -0
- package/dist/security/access.js +160 -0
- package/dist/security/access.js.map +1 -0
- package/dist/service/install.d.ts +19 -0
- package/dist/service/install.js +35 -0
- package/dist/service/install.js.map +1 -0
- package/dist/service/templates.d.ts +22 -0
- package/dist/service/templates.js +118 -0
- package/dist/service/templates.js.map +1 -0
- package/dist/state/audit-log.d.ts +33 -0
- package/dist/state/audit-log.js +116 -0
- package/dist/state/audit-log.js.map +1 -0
- package/dist/state/config-history-store.d.ts +27 -0
- package/dist/state/config-history-store.js +65 -0
- package/dist/state/config-history-store.js.map +1 -0
- package/dist/state/handoff-store.d.ts +20 -0
- package/dist/state/handoff-store.js +97 -0
- package/dist/state/handoff-store.js.map +1 -0
- package/dist/state/idempotency-store.d.ts +19 -0
- package/dist/state/idempotency-store.js +84 -0
- package/dist/state/idempotency-store.js.map +1 -0
- package/dist/state/memory-store.d.ts +137 -0
- package/dist/state/memory-store.js +713 -0
- package/dist/state/memory-store.js.map +1 -0
- package/dist/state/pending-command-store.d.ts +30 -0
- package/dist/state/pending-command-store.js +108 -0
- package/dist/state/pending-command-store.js.map +1 -0
- package/dist/state/run-state-store.d.ts +58 -0
- package/dist/state/run-state-store.js +269 -0
- package/dist/state/run-state-store.js.map +1 -0
- package/dist/state/session-store.d.ts +56 -0
- package/dist/state/session-store.js +275 -0
- package/dist/state/session-store.js.map +1 -0
- package/dist/state/trust-store.d.ts +15 -0
- package/dist/state/trust-store.js +53 -0
- package/dist/state/trust-store.js.map +1 -0
- package/dist/utils/fs.d.ts +4 -0
- package/dist/utils/fs.js +26 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/json.d.ts +1 -0
- package/dist/utils/json.js +9 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/path.d.ts +3 -0
- package/dist/utils/path.js +22 -0
- package/dist/utils/path.js.map +1 -0
- package/dist/utils/serial-executor.d.ts +5 -0
- package/dist/utils/serial-executor.js +12 -0
- package/dist/utils/serial-executor.js.map +1 -0
- package/package.json +71 -0
- package/skills/feique-session/SKILL.md +27 -0
|
@@ -0,0 +1,860 @@
|
|
|
1
|
+
export function parseBridgeCommand(input) {
|
|
2
|
+
const trimmed = normalizeIncomingText(input);
|
|
3
|
+
if (!trimmed.startsWith('/')) {
|
|
4
|
+
const naturalLanguageCommand = parseNaturalLanguageCommand(trimmed);
|
|
5
|
+
if (naturalLanguageCommand) {
|
|
6
|
+
return naturalLanguageCommand;
|
|
7
|
+
}
|
|
8
|
+
return { kind: 'prompt', prompt: trimmed };
|
|
9
|
+
}
|
|
10
|
+
const [command, ...rest] = trimmed.split(/\s+/);
|
|
11
|
+
const argument = rest.join(' ').trim();
|
|
12
|
+
switch (command) {
|
|
13
|
+
case '/help':
|
|
14
|
+
return { kind: 'help' };
|
|
15
|
+
case '/status':
|
|
16
|
+
return { kind: 'status', detail: argument === 'detail' };
|
|
17
|
+
case '/projects':
|
|
18
|
+
return { kind: 'projects' };
|
|
19
|
+
case '/new':
|
|
20
|
+
return { kind: 'new' };
|
|
21
|
+
case '/cancel':
|
|
22
|
+
return { kind: 'cancel' };
|
|
23
|
+
case '/kb':
|
|
24
|
+
return parseKnowledgeCommand(argument);
|
|
25
|
+
case '/doc':
|
|
26
|
+
return parseDocCommand(argument);
|
|
27
|
+
case '/task':
|
|
28
|
+
return parseTaskCommand(argument);
|
|
29
|
+
case '/base':
|
|
30
|
+
return parseBaseCommand(argument);
|
|
31
|
+
case '/memory':
|
|
32
|
+
return parseMemoryCommand(argument);
|
|
33
|
+
case '/wiki':
|
|
34
|
+
return parseWikiCommand(argument);
|
|
35
|
+
case '/project':
|
|
36
|
+
return { kind: 'project', alias: argument || undefined };
|
|
37
|
+
case '/session':
|
|
38
|
+
return parseSessionCommand(argument);
|
|
39
|
+
case '/admin':
|
|
40
|
+
return parseAdminCommand(argument);
|
|
41
|
+
case '/backend':
|
|
42
|
+
return { kind: 'backend', name: argument || undefined };
|
|
43
|
+
case '/team':
|
|
44
|
+
return { kind: 'team' };
|
|
45
|
+
case '/learn':
|
|
46
|
+
return argument ? { kind: 'learn', value: argument } : { kind: 'prompt', prompt: trimmed };
|
|
47
|
+
case '/recall':
|
|
48
|
+
return argument ? { kind: 'recall', query: argument } : { kind: 'prompt', prompt: trimmed };
|
|
49
|
+
case '/handoff':
|
|
50
|
+
return { kind: 'handoff', summary: argument || undefined };
|
|
51
|
+
case '/pickup':
|
|
52
|
+
return { kind: 'pickup', id: argument || undefined };
|
|
53
|
+
case '/review':
|
|
54
|
+
return { kind: 'review' };
|
|
55
|
+
case '/approve':
|
|
56
|
+
return { kind: 'approve', comment: argument || undefined };
|
|
57
|
+
case '/reject':
|
|
58
|
+
return { kind: 'reject', reason: argument || undefined };
|
|
59
|
+
case '/insights':
|
|
60
|
+
return { kind: 'insights' };
|
|
61
|
+
case '/trust':
|
|
62
|
+
return parseTrustCommand(argument);
|
|
63
|
+
case '/timeline':
|
|
64
|
+
return { kind: 'timeline', project: argument || undefined };
|
|
65
|
+
case '/digest':
|
|
66
|
+
return { kind: 'digest' };
|
|
67
|
+
default:
|
|
68
|
+
return { kind: 'prompt', prompt: trimmed };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export function normalizeIncomingText(input) {
|
|
72
|
+
return input
|
|
73
|
+
.trim()
|
|
74
|
+
.replace(/^@[^\s]+\s+/, '')
|
|
75
|
+
.replace(/\u00a0/g, ' ')
|
|
76
|
+
.trim();
|
|
77
|
+
}
|
|
78
|
+
export function buildHelpText() {
|
|
79
|
+
return [
|
|
80
|
+
'飞鹊 (Feique)',
|
|
81
|
+
'',
|
|
82
|
+
'基础控制',
|
|
83
|
+
'/help 查看帮助',
|
|
84
|
+
'/projects 列出可用项目',
|
|
85
|
+
'/project <alias> 切换当前项目',
|
|
86
|
+
'/status 查看当前项目、会话与运行状态',
|
|
87
|
+
'/status detail 查看当前项目的详细运行状态、排队耗时与最近失败',
|
|
88
|
+
'/new 为当前项目新开会话',
|
|
89
|
+
'/cancel 取消当前项目正在运行的任务',
|
|
90
|
+
'',
|
|
91
|
+
'后端切换',
|
|
92
|
+
'/backend 查看当前项目的活跃后端',
|
|
93
|
+
'/backend codex 切换当前项目到 Codex 后端',
|
|
94
|
+
'/backend claude 切换当前项目到 Claude Code 后端',
|
|
95
|
+
'',
|
|
96
|
+
'会话管理',
|
|
97
|
+
'/session list 列出当前项目保存过的会话',
|
|
98
|
+
'/session use <thread_id> 切换到指定会话',
|
|
99
|
+
'/session new 让下一条消息新开会话',
|
|
100
|
+
'/session drop [thread_id] 删除指定或当前会话',
|
|
101
|
+
'/session adopt latest 接管当前项目最近的本地会话',
|
|
102
|
+
'/session adopt list 列出当前项目可接管的本地会话',
|
|
103
|
+
'/session adopt <thread_id> 接管指定本地会话',
|
|
104
|
+
'',
|
|
105
|
+
'知识与记忆',
|
|
106
|
+
'/kb status 查看当前项目知识库目录',
|
|
107
|
+
'/kb search <query> 搜索项目文档/知识库',
|
|
108
|
+
'/doc read <url|token> 读取飞书文档纯文本摘要',
|
|
109
|
+
'/doc create <title> 创建一篇飞书文档',
|
|
110
|
+
'/task list [limit] 列出最近任务',
|
|
111
|
+
'/task get <task_guid> 查看任务详情',
|
|
112
|
+
'/task create <summary> 创建任务',
|
|
113
|
+
'/task complete <task_guid> 完成任务',
|
|
114
|
+
'/base tables <app_token> 列出多维表格中的数据表',
|
|
115
|
+
'/base records <app_token> <table_id> [limit] 列出多维表格记录',
|
|
116
|
+
'/base create <app_token> <table_id> <json> 新建多维表格记录',
|
|
117
|
+
'/base update <app_token> <table_id> <record_id> <json> 更新多维表格记录',
|
|
118
|
+
'/memory status 查看当前项目记忆状态',
|
|
119
|
+
'/memory stats 查看当前项目记忆统计',
|
|
120
|
+
'/memory status group 查看当前群共享记忆状态',
|
|
121
|
+
'/memory stats group 查看当前群共享记忆统计',
|
|
122
|
+
'/memory recent 查看最近保存的项目记忆',
|
|
123
|
+
'/memory recent group 查看最近保存的群共享记忆',
|
|
124
|
+
'/memory recent --tag <tag> 按标签筛选最近项目记忆',
|
|
125
|
+
'/memory recent --source <source> 按来源筛选最近项目记忆',
|
|
126
|
+
'/memory recent --created-by <actor_id> 按创建者筛选最近项目记忆',
|
|
127
|
+
'/memory search <query> 搜索当前项目记忆',
|
|
128
|
+
'/memory search --tag <tag> <query> 按标签筛选项目记忆',
|
|
129
|
+
'/memory search --source <source> <query> 按来源筛选项目记忆',
|
|
130
|
+
'/memory search --created-by <actor_id> <query> 按创建者筛选项目记忆',
|
|
131
|
+
'/memory search group <query> 搜索当前群共享记忆',
|
|
132
|
+
'/memory save <text> 保存一条项目记忆',
|
|
133
|
+
'/memory save group <text> 保存一条群共享记忆',
|
|
134
|
+
'/memory pin <id> 置顶一条项目记忆',
|
|
135
|
+
'/memory pin group <id> 置顶一条群共享记忆',
|
|
136
|
+
'/memory unpin <id> 取消置顶项目记忆',
|
|
137
|
+
'/memory forget <id> 归档一条项目记忆',
|
|
138
|
+
'/memory forget all-expired 归档当前作用域下已过期记忆',
|
|
139
|
+
'/memory forget group <id> 归档一条群共享记忆',
|
|
140
|
+
'/memory restore <id> 恢复一条已归档项目记忆',
|
|
141
|
+
'/memory restore group <id> 恢复一条已归档群共享记忆',
|
|
142
|
+
'',
|
|
143
|
+
'飞书知识库',
|
|
144
|
+
'/wiki spaces 列出可访问的飞书知识空间',
|
|
145
|
+
'/wiki search <query> 搜索飞书知识库',
|
|
146
|
+
'/wiki read <url|token> 读取飞书文档纯文本摘要',
|
|
147
|
+
'/wiki create <title> 在默认知识空间创建文档',
|
|
148
|
+
'/wiki create <space_id> <title> 在指定知识空间创建文档',
|
|
149
|
+
'/wiki rename <node_token> <title> 更新知识库节点标题',
|
|
150
|
+
'/wiki copy <node_token> [target_space_id] 复制节点到默认或指定知识空间',
|
|
151
|
+
'/wiki move <source_space_id> <node_token> [target_space_id] 移动节点到默认或指定知识空间',
|
|
152
|
+
'/wiki members [space_id] 查看知识空间成员',
|
|
153
|
+
'/wiki grant <space_id> <member_type> <member_id> [member|admin] 添加知识空间成员',
|
|
154
|
+
'/wiki revoke <space_id> <member_type> <member_id> [member|admin] 移除知识空间成员',
|
|
155
|
+
'',
|
|
156
|
+
'团队协作',
|
|
157
|
+
'/team 查看团队成员当前 AI 协作态势',
|
|
158
|
+
'/learn <内容> 记录一条团队知识(标题:内容 或直接输入)',
|
|
159
|
+
'/recall <关键词> 检索团队沉淀的知识',
|
|
160
|
+
'/handoff [摘要] 将当前会话交接给其他成员',
|
|
161
|
+
'/pickup [id] 接手一个待交接的任务',
|
|
162
|
+
'/review 将最近的 AI 输出提交评审',
|
|
163
|
+
'/approve [评语] 批准当前评审',
|
|
164
|
+
'/reject [原因] 打回当前评审',
|
|
165
|
+
'/insights 查看团队 AI 协作效率体检报告',
|
|
166
|
+
'/trust 查看当前项目的信任等级',
|
|
167
|
+
'/trust set <observe|suggest|execute|autonomous> 设置信任等级',
|
|
168
|
+
'/timeline [项目] 查看项目协作时间线',
|
|
169
|
+
'/digest 立即生成团队 AI 协作日报',
|
|
170
|
+
'',
|
|
171
|
+
'管理员',
|
|
172
|
+
'/admin status 查看管理员配置摘要',
|
|
173
|
+
'/admin viewer list 查看全局 viewer chat_id 列表',
|
|
174
|
+
'/admin viewer add <chat_id> 添加全局 viewer chat_id',
|
|
175
|
+
'/admin viewer remove <chat_id> 移除全局 viewer chat_id',
|
|
176
|
+
'/admin operator list 查看全局 operator chat_id 列表',
|
|
177
|
+
'/admin operator add <chat_id> 添加全局 operator chat_id',
|
|
178
|
+
'/admin operator remove <chat_id> 移除全局 operator chat_id',
|
|
179
|
+
'/admin service-observer list 查看全局 service observer chat_id 列表',
|
|
180
|
+
'/admin service-observer add <chat_id> 添加全局 service observer chat_id',
|
|
181
|
+
'/admin service-observer remove <chat_id> 移除全局 service observer chat_id',
|
|
182
|
+
'/admin service-restart list 查看全局 service restart chat_id 列表',
|
|
183
|
+
'/admin service-restart add <chat_id> 添加全局 service restart chat_id',
|
|
184
|
+
'/admin service-restart remove <chat_id> 移除全局 service restart chat_id',
|
|
185
|
+
'/admin config-admin list 查看全局 config admin chat_id 列表',
|
|
186
|
+
'/admin config-admin add <chat_id> 添加全局 config admin chat_id',
|
|
187
|
+
'/admin config-admin remove <chat_id> 移除全局 config admin chat_id',
|
|
188
|
+
'/admin runs 查看所有 active/queued 运行及最近失败',
|
|
189
|
+
'/admin admin list 查看管理员 chat_id 列表',
|
|
190
|
+
'/admin admin add <chat_id> 添加管理员 chat_id',
|
|
191
|
+
'/admin admin remove <chat_id> 移除管理员 chat_id',
|
|
192
|
+
'/admin group list 查看已允许的群聊 chat_id',
|
|
193
|
+
'/admin group add <chat_id> 允许一个群聊接入',
|
|
194
|
+
'/admin group remove <chat_id> 移除一个群聊接入',
|
|
195
|
+
'/admin chat list 查看已允许的私聊 chat_id',
|
|
196
|
+
'/admin chat add <chat_id> 允许一个私聊接入',
|
|
197
|
+
'/admin chat remove <chat_id> 移除一个私聊接入',
|
|
198
|
+
'/admin project list 查看当前项目列表',
|
|
199
|
+
'/admin project add <alias> <root> 动态接入已有项目目录',
|
|
200
|
+
'/admin project create <alias> <root> 创建目录并接入新项目',
|
|
201
|
+
'/admin project remove <alias> 移除项目',
|
|
202
|
+
'/admin project set <alias> <field> <value> 修改项目配置',
|
|
203
|
+
'/admin config history 查看最近 5 次配置快照',
|
|
204
|
+
'/admin config rollback <id|latest> 回滚到最近配置快照',
|
|
205
|
+
'/admin service restart 保存配置并重启服务',
|
|
206
|
+
'',
|
|
207
|
+
'所有命令均支持自然语言触发,例如:',
|
|
208
|
+
'基础: 查看状态 / 项目列表 / 新会话 / 取消当前任务 / 切换到项目 repo-a',
|
|
209
|
+
'协作: 谁在用AI / 大家在忙什么 / 效率怎么样 / 哪里有瓶颈',
|
|
210
|
+
'知识: 记住:XXX / 有没有关于XXX的经验 / 查一下知识 XXX',
|
|
211
|
+
'交接: 交接一下 / 我来接手 / 评审一下 / 通过 / 打回',
|
|
212
|
+
'管理: 信任等级 / 提升信任 / 时间线 / 日报 / 团队总结',
|
|
213
|
+
'',
|
|
214
|
+
'直接发送文本会进入当前项目的 AI 会话。',
|
|
215
|
+
].join('\n');
|
|
216
|
+
}
|
|
217
|
+
export function describeBridgeCommand(command) {
|
|
218
|
+
switch (command.kind) {
|
|
219
|
+
case 'help':
|
|
220
|
+
return '查看帮助';
|
|
221
|
+
case 'status':
|
|
222
|
+
return command.detail ? '查看详细状态' : '查看当前状态';
|
|
223
|
+
case 'projects':
|
|
224
|
+
return '查看项目列表';
|
|
225
|
+
case 'new':
|
|
226
|
+
return '新建会话';
|
|
227
|
+
case 'cancel':
|
|
228
|
+
return '取消当前运行';
|
|
229
|
+
case 'kb':
|
|
230
|
+
return command.action === 'search' ? `搜索知识库: ${command.query ?? ''}`.trim() : '查看知识库状态';
|
|
231
|
+
case 'doc':
|
|
232
|
+
return `文档操作: ${command.action}${command.value ? ` ${command.value}` : ''}`;
|
|
233
|
+
case 'task':
|
|
234
|
+
return `任务操作: ${command.action}${command.value ? ` ${command.value}` : ''}`;
|
|
235
|
+
case 'base':
|
|
236
|
+
return `多维表格操作: ${command.action}${command.appToken ? ` ${command.appToken}` : ''}`;
|
|
237
|
+
case 'memory':
|
|
238
|
+
return `记忆操作: ${command.action}`;
|
|
239
|
+
case 'wiki':
|
|
240
|
+
return `知识库操作: ${command.action}`;
|
|
241
|
+
case 'project':
|
|
242
|
+
if (!command.alias) {
|
|
243
|
+
return '查看当前项目';
|
|
244
|
+
}
|
|
245
|
+
return command.followupPrompt
|
|
246
|
+
? `切换到项目 ${command.alias},并执行:${truncateForDescription(command.followupPrompt)}`
|
|
247
|
+
: `切换到项目 ${command.alias}`;
|
|
248
|
+
case 'session':
|
|
249
|
+
if (command.action === 'adopt') {
|
|
250
|
+
return `接管会话 ${command.target ?? 'latest'}`;
|
|
251
|
+
}
|
|
252
|
+
return `会话操作: ${command.action}${'threadId' in command && command.threadId ? ` ${command.threadId}` : ''}`;
|
|
253
|
+
case 'admin':
|
|
254
|
+
if (command.resource === 'project') {
|
|
255
|
+
return `管理员项目操作: ${command.action}${command.alias ? ` ${command.alias}` : ''}`;
|
|
256
|
+
}
|
|
257
|
+
if (command.resource === 'config') {
|
|
258
|
+
return `配置操作: ${command.action}${command.value ? ` ${command.value}` : ''}`;
|
|
259
|
+
}
|
|
260
|
+
return `管理员操作: ${command.resource} ${command.action}${'value' in command && command.value ? ` ${command.value}` : ''}`;
|
|
261
|
+
case 'backend':
|
|
262
|
+
return command.name ? `切换后端到 ${command.name}` : '查看当前后端';
|
|
263
|
+
case 'team':
|
|
264
|
+
return '查看团队协作态势';
|
|
265
|
+
case 'learn':
|
|
266
|
+
return `记录团队知识: ${truncateForDescription(command.value)}`;
|
|
267
|
+
case 'recall':
|
|
268
|
+
return `检索团队知识: ${truncateForDescription(command.query)}`;
|
|
269
|
+
case 'handoff':
|
|
270
|
+
return '发起会话交接';
|
|
271
|
+
case 'pickup':
|
|
272
|
+
return '接手交接任务';
|
|
273
|
+
case 'review':
|
|
274
|
+
return '发起评审';
|
|
275
|
+
case 'approve':
|
|
276
|
+
return '批准评审';
|
|
277
|
+
case 'reject':
|
|
278
|
+
return '打回评审';
|
|
279
|
+
case 'insights':
|
|
280
|
+
return '查看团队效率体检';
|
|
281
|
+
case 'trust':
|
|
282
|
+
return command.action === 'set' ? `设置信任等级: ${command.level}` : '查看信任状态';
|
|
283
|
+
case 'timeline':
|
|
284
|
+
return command.project ? `查看项目 ${command.project} 时间线` : '查看项目时间线';
|
|
285
|
+
case 'digest':
|
|
286
|
+
return '生成团队 AI 协作日报';
|
|
287
|
+
case 'prompt':
|
|
288
|
+
return truncateForDescription(command.prompt);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
export function isReadOnlyCommand(command) {
|
|
292
|
+
switch (command.kind) {
|
|
293
|
+
case 'help':
|
|
294
|
+
case 'status':
|
|
295
|
+
case 'projects':
|
|
296
|
+
return true;
|
|
297
|
+
case 'kb':
|
|
298
|
+
return true;
|
|
299
|
+
case 'project':
|
|
300
|
+
return !command.alias;
|
|
301
|
+
case 'doc':
|
|
302
|
+
return command.action === 'read';
|
|
303
|
+
case 'task':
|
|
304
|
+
return command.action === 'list' || command.action === 'get';
|
|
305
|
+
case 'base':
|
|
306
|
+
return command.action === 'tables' || command.action === 'records';
|
|
307
|
+
case 'memory':
|
|
308
|
+
return command.action === 'status' || command.action === 'stats' || command.action === 'search' || command.action === 'recent';
|
|
309
|
+
case 'wiki':
|
|
310
|
+
return command.action === 'spaces' || command.action === 'search' || command.action === 'read' || command.action === 'members';
|
|
311
|
+
case 'session':
|
|
312
|
+
return command.action === 'list';
|
|
313
|
+
case 'backend':
|
|
314
|
+
return !command.name;
|
|
315
|
+
case 'team':
|
|
316
|
+
case 'recall':
|
|
317
|
+
case 'insights':
|
|
318
|
+
case 'timeline':
|
|
319
|
+
case 'digest':
|
|
320
|
+
return true;
|
|
321
|
+
case 'trust':
|
|
322
|
+
return !command.action;
|
|
323
|
+
case 'admin':
|
|
324
|
+
if (command.resource === 'service') {
|
|
325
|
+
return command.action === 'status' || command.action === 'runs';
|
|
326
|
+
}
|
|
327
|
+
if (command.resource === 'project') {
|
|
328
|
+
return command.action === 'list';
|
|
329
|
+
}
|
|
330
|
+
if (command.resource === 'config') {
|
|
331
|
+
return command.action === 'history';
|
|
332
|
+
}
|
|
333
|
+
return command.action === 'status' || command.action === 'list';
|
|
334
|
+
default:
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
function parseNaturalLanguageCommand(input) {
|
|
339
|
+
const normalized = stripNaturalLanguagePrefix(input
|
|
340
|
+
.trim()
|
|
341
|
+
.replace(/[。!?!?;;]+$/u, '')
|
|
342
|
+
.replace(/\s+/g, ' '));
|
|
343
|
+
if (!normalized) {
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
if (/^(帮助|查看帮助|命令帮助|帮助手册)$/.test(normalized)) {
|
|
347
|
+
return { kind: 'help' };
|
|
348
|
+
}
|
|
349
|
+
if (/^(?:(?:查看|看|查)(?:一下|下)?|看看)?(?:当前)?(?:运行)?状态$/.test(normalized)) {
|
|
350
|
+
return { kind: 'status' };
|
|
351
|
+
}
|
|
352
|
+
if (/^(?:(?:查看|看|查)(?:一下|下)?|看看)?(?:当前)?(?:详细状态|状态详情|详细运行状态)$/.test(normalized)) {
|
|
353
|
+
return { kind: 'status', detail: true };
|
|
354
|
+
}
|
|
355
|
+
if (/^(?:(?:查看|看|查)(?:一下|下)?|看看)?(?:项目列表|可用项目|有哪些项目|查看项目|列出项目)$/.test(normalized)) {
|
|
356
|
+
return { kind: 'projects' };
|
|
357
|
+
}
|
|
358
|
+
if (/^(?:(?:查看|看|查)(?:一下|下)?|看看)?(?:当前)?项目(?:是哪个|是什么)?$|^我现在在哪个项目$/.test(normalized)) {
|
|
359
|
+
return { kind: 'project' };
|
|
360
|
+
}
|
|
361
|
+
if (/^(新会话|开启新会话|重新开始会话|下一条消息新开会话|开(?:个|一个)?新会话|重新开(?:个|一个)?会话|新开会话)$/.test(normalized)) {
|
|
362
|
+
return { kind: 'new' };
|
|
363
|
+
}
|
|
364
|
+
if (/^(取消当前任务|停止当前任务|取消运行|停止运行|停止任务|停掉当前任务|终止当前任务|取消这次运行)$/.test(normalized)) {
|
|
365
|
+
return { kind: 'cancel' };
|
|
366
|
+
}
|
|
367
|
+
if (/^(查看文档|读取文档|打开文档)\s+(\S+)$/.test(normalized)) {
|
|
368
|
+
const match = normalized.match(/^(?:查看文档|读取文档|打开文档)\s+(\S+)$/);
|
|
369
|
+
return match?.[1] ? { kind: 'doc', action: 'read', value: match[1] } : null;
|
|
370
|
+
}
|
|
371
|
+
if (/^(创建任务|新建任务)\s+(.+)$/.test(normalized)) {
|
|
372
|
+
const match = normalized.match(/^(?:创建任务|新建任务)\s+(.+)$/);
|
|
373
|
+
return match?.[1] ? { kind: 'task', action: 'create', value: match[1].trim() } : null;
|
|
374
|
+
}
|
|
375
|
+
if (/^(完成任务|关闭任务)\s+(\S+)$/.test(normalized)) {
|
|
376
|
+
const match = normalized.match(/^(?:完成任务|关闭任务)\s+(\S+)$/);
|
|
377
|
+
return match?.[1] ? { kind: 'task', action: 'complete', value: match[1] } : null;
|
|
378
|
+
}
|
|
379
|
+
if (/^(查看会话|会话列表|列出会话|查看当前会话|看看会话列表|有哪些会话)$/.test(normalized)) {
|
|
380
|
+
return { kind: 'session', action: 'list' };
|
|
381
|
+
}
|
|
382
|
+
if (/^(接管最新会话|接管最近会话|接管最新 Codex 会话|接上最新会话|续上最新会话|恢复最新会话)$/i.test(normalized)) {
|
|
383
|
+
return { kind: 'session', action: 'adopt', target: 'latest' };
|
|
384
|
+
}
|
|
385
|
+
if (/^(查看可接管会话|列出可接管会话|可接管会话列表|查看可恢复会话|可恢复会话列表)$/.test(normalized)) {
|
|
386
|
+
return { kind: 'session', action: 'adopt', target: 'list' };
|
|
387
|
+
}
|
|
388
|
+
// ── /team: 团队态势感知 ──
|
|
389
|
+
if (/^(?:(?:查看|看|查)(?:一下|下)?|看看)?(?:团队(?:协作)?态势|团队状态|团队活动|谁在做什么|团队在做什么|谁在用\s*AI|大家在忙什么|团队成员(?:在做什么|状态)|现在谁在(?:干活|工作|用AI)|看看团队)$/.test(normalized)) {
|
|
390
|
+
return { kind: 'team' };
|
|
391
|
+
}
|
|
392
|
+
// ── /learn: 知识记录 ──
|
|
393
|
+
const learnMatch = normalized.match(/^(?:记住|记录(?:一下)?|保存(?:知识|经验|一下)?|团队知识|知识记录)[::\s]+(.+)$/);
|
|
394
|
+
if (learnMatch?.[1]) {
|
|
395
|
+
return { kind: 'learn', value: learnMatch[1].trim() };
|
|
396
|
+
}
|
|
397
|
+
// ── /recall: 知识检索 ──
|
|
398
|
+
// "有没有关于X的知识/经验"
|
|
399
|
+
const recallHasMatch = normalized.match(/^有没有(?:关于|涉及)(.+?)的?(?:知识|经验|记录)$/);
|
|
400
|
+
if (recallHasMatch?.[1]) {
|
|
401
|
+
return { kind: 'recall', query: recallHasMatch[1].trim() };
|
|
402
|
+
}
|
|
403
|
+
// "关于X有什么知识/经验"
|
|
404
|
+
const recallAboutMatch = normalized.match(/^关于(.+?)(?:有什么|有没有)(?:知识|经验|记录)$/);
|
|
405
|
+
if (recallAboutMatch?.[1]) {
|
|
406
|
+
return { kind: 'recall', query: recallAboutMatch[1].trim() };
|
|
407
|
+
}
|
|
408
|
+
// "搜搜/查查/找找 X" or "查一下知识 X" or "检索 X"
|
|
409
|
+
const recallSearchMatch = normalized.match(/^(?:搜搜|查查|查一下|找找|搜索|检索|回忆)(?:看)?(?:知识|经验|团队知识|以前的经验)?[::\s]+(.+)$/);
|
|
410
|
+
if (recallSearchMatch?.[1]) {
|
|
411
|
+
return { kind: 'recall', query: recallSearchMatch[1].trim() };
|
|
412
|
+
}
|
|
413
|
+
// ── /handoff: 会话交接 ──
|
|
414
|
+
const handoffMatch = normalized.match(/^(?:交接(?:一下|出去)?|转交(?:一下)?|交给(?:别人|其他人|下一个人)|(?:这个)?任务交出去|我做不完了|谁来接(?:手|一下)?|把(?:这个|当前)(?:任务|会话)交(?:出去|接))(?:[,,::\s]+(.+))?$/);
|
|
415
|
+
if (handoffMatch) {
|
|
416
|
+
return { kind: 'handoff', summary: handoffMatch[1]?.trim() || undefined };
|
|
417
|
+
}
|
|
418
|
+
// ── /pickup: 接手任务 ──
|
|
419
|
+
if (/^(?:我来(?:接手?|处理|做|搞)|我接(?:手|了)?|让我来|我来吧|接手(?:任务)?|我来接(?:这个)?(?:任务|活)?)$/.test(normalized)) {
|
|
420
|
+
return { kind: 'pickup' };
|
|
421
|
+
}
|
|
422
|
+
// ── /review: 评审 ──
|
|
423
|
+
if (/^(?:评审(?:一下)?|提交评审|看看(?:这个)?结果|帮(?:忙)?(?:看看|审查|评审)(?:结果)?|review(?:一下)?|审查(?:一下)?)$/i.test(normalized)) {
|
|
424
|
+
return { kind: 'review' };
|
|
425
|
+
}
|
|
426
|
+
// ── /approve: 批准(短句高置信度匹配)──
|
|
427
|
+
const approveMatch = normalized.match(/^(?:通过|批准|同意|没问题|可以|LGTM|approved?|OK|没啥问题|挺好的?|就这样吧|可以的)(?:[,,::\s]+(.+))?$/i);
|
|
428
|
+
if (approveMatch) {
|
|
429
|
+
return { kind: 'approve', comment: approveMatch[1]?.trim() || undefined };
|
|
430
|
+
}
|
|
431
|
+
// ── /reject: 打回 ──
|
|
432
|
+
const rejectMatch = normalized.match(/^(?:不行|打回|驳回|退回|有问题|不通过|需要修改|reject(?:ed)?|不可以|不同意)(?:[,,::\s]+(.+))?$/i);
|
|
433
|
+
if (rejectMatch) {
|
|
434
|
+
return { kind: 'reject', reason: rejectMatch[1]?.trim() || undefined };
|
|
435
|
+
}
|
|
436
|
+
// ── /insights: 效率体检 ──
|
|
437
|
+
if (/^(?:(?:查看|看|查)(?:一下|下)?|看看)?(?:团队体检|效率体检|效率报告|协作体检|瓶颈分析|哪里有瓶颈|效率怎么样|有什么(?:问题|瓶颈)|团队健康|(?:AI)?(?:使用|协作)(?:效率|情况|分析)|有没有(?:问题|瓶颈|异常))$/.test(normalized)) {
|
|
438
|
+
return { kind: 'insights' };
|
|
439
|
+
}
|
|
440
|
+
// ── /trust: 信任管理 ──
|
|
441
|
+
if (/^(?:(?:查看|看|查)(?:一下|下)?|看看)?(?:信任(?:等级|状态|级别)|项目信任|当前信任)$/.test(normalized)) {
|
|
442
|
+
return { kind: 'trust' };
|
|
443
|
+
}
|
|
444
|
+
const trustSetMatch = normalized.match(/^(?:设置|修改|调整)信任(?:等级|级别)?(?:为|到)\s*(observe|suggest|execute|autonomous|观察|建议|执行|自主)$/i);
|
|
445
|
+
if (trustSetMatch) {
|
|
446
|
+
const levelMap = { '观察': 'observe', '建议': 'suggest', '执行': 'execute', '自主': 'autonomous' };
|
|
447
|
+
const raw = trustSetMatch[1].toLowerCase();
|
|
448
|
+
return { kind: 'trust', action: 'set', level: levelMap[raw] ?? raw };
|
|
449
|
+
}
|
|
450
|
+
if (/^提升信任(?:等级)?$/.test(normalized)) {
|
|
451
|
+
return { kind: 'trust', action: 'set', level: '_promote' };
|
|
452
|
+
}
|
|
453
|
+
if (/^降低信任(?:等级)?$/.test(normalized)) {
|
|
454
|
+
return { kind: 'trust', action: 'set', level: '_demote' };
|
|
455
|
+
}
|
|
456
|
+
// ── /timeline: 项目时间线 ──
|
|
457
|
+
if (/^(?:(?:查看|看|查)(?:一下|下)?|看看)?(?:(?:项目)?时间线|最近(?:发生了什么|有什么动态|动态)|项目(?:动态|历史|活动|进展)|发生了什么事?)$/.test(normalized)) {
|
|
458
|
+
return { kind: 'timeline' };
|
|
459
|
+
}
|
|
460
|
+
const timelineProjectMatch = normalized.match(/^(?:(?:查看|看|查)(?:一下|下)?|看看)?(\S+?)(?:的|项目的?)(?:时间线|动态|历史|活动|进展)$/);
|
|
461
|
+
if (timelineProjectMatch) {
|
|
462
|
+
return { kind: 'timeline', project: timelineProjectMatch[1] };
|
|
463
|
+
}
|
|
464
|
+
// ── /digest: 团队日报 ──
|
|
465
|
+
if (/^(?:(?:查看|看|查|生成|出个|出一下|来个|出)(?:一下|下)?)?(?:(?:团队)?(?:AI)?(?:协作)?日报|今天(?:的)?(?:报告|总结|摘要)|团队(?:总结|报告|摘要)|每日摘要|daily\s*digest)$/i.test(normalized)) {
|
|
466
|
+
return { kind: 'digest' };
|
|
467
|
+
}
|
|
468
|
+
const projectWithPromptMatch = normalized.match(/^(?:把)?(?:当前)?(?:项目)?(?:切换到|切到|切换至|转到|进入|使用|换到|改到)\s*([^,,。;;::\s]+?)\s*(?:项目)?(?:[,,。;;::]\s*|\s*(?:然后|并且|并|再)\s*)(.+)$/);
|
|
469
|
+
if (projectWithPromptMatch) {
|
|
470
|
+
const [, alias, followupPrompt] = projectWithPromptMatch;
|
|
471
|
+
if (alias && followupPrompt) {
|
|
472
|
+
return { kind: 'project', alias, followupPrompt: followupPrompt.replace(/^(?:然后|并且|并|再)\s*/u, '').trim() };
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
const projectMatch = normalized.match(/^(?:把)?(?:当前)?(?:项目)?(?:切换到项目|切到项目|使用项目|切换到|切到|切换至|转到|进入|使用|换到|改到)\s+(\S+?)(?:\s*项目)?$/);
|
|
476
|
+
if (projectMatch) {
|
|
477
|
+
return { kind: 'project', alias: projectMatch[1] };
|
|
478
|
+
}
|
|
479
|
+
const projectShortMatch = normalized.match(/^(?:把)?(?:当前)?(?:项目)?(?:切换到|切到|切换至|转到|进入|使用|换到|改到)([^,,。;;::\s]+)项目$/);
|
|
480
|
+
if (projectShortMatch) {
|
|
481
|
+
return { kind: 'project', alias: projectShortMatch[1] };
|
|
482
|
+
}
|
|
483
|
+
const adoptSessionMatch = normalized.match(/^(?:接管会话|使用会话|接上会话|恢复会话|续上会话)\s+(\S+)$/);
|
|
484
|
+
if (adoptSessionMatch) {
|
|
485
|
+
return { kind: 'session', action: 'adopt', target: adoptSessionMatch[1] };
|
|
486
|
+
}
|
|
487
|
+
const backendMatch = normalized.match(/^(?:切换(?:到|为)?|使用|换(?:到|成)?|改(?:到|为)?)?\s*(?:后端(?:(?:切换)?(?:到|为)?)?)\s*(codex|claude)\s*(?:后端)?$/i);
|
|
488
|
+
if (backendMatch) {
|
|
489
|
+
return { kind: 'backend', name: backendMatch[1].toLowerCase() };
|
|
490
|
+
}
|
|
491
|
+
if (/^(?:(?:查看|看|查)(?:一下|下)?|看看)?(?:当前)?后端(?:是什么|是哪个)?$/.test(normalized)) {
|
|
492
|
+
return { kind: 'backend' };
|
|
493
|
+
}
|
|
494
|
+
if (/^(管理员状态|查看管理员状态|看一下管理员状态)$/.test(normalized)) {
|
|
495
|
+
return { kind: 'admin', resource: 'service', action: 'status' };
|
|
496
|
+
}
|
|
497
|
+
if (/^(查看运行列表|查看运行状态列表|管理员运行列表|查看排队列表|查看任务列表)$/.test(normalized)) {
|
|
498
|
+
return { kind: 'admin', resource: 'service', action: 'runs' };
|
|
499
|
+
}
|
|
500
|
+
if (/^(重启服务|重启机器人|重启 feique 服务|重启一下服务|重启一下机器人)$/i.test(normalized)) {
|
|
501
|
+
return { kind: 'admin', resource: 'service', action: 'restart' };
|
|
502
|
+
}
|
|
503
|
+
const addAdminMatch = normalized.match(/^添加管理员\s+(\S+)$/);
|
|
504
|
+
if (addAdminMatch) {
|
|
505
|
+
return { kind: 'admin', resource: 'admin', action: 'add', value: addAdminMatch[1] };
|
|
506
|
+
}
|
|
507
|
+
const removeAdminMatch = normalized.match(/^移除管理员\s+(\S+)$/);
|
|
508
|
+
if (removeAdminMatch) {
|
|
509
|
+
return { kind: 'admin', resource: 'admin', action: 'remove', value: removeAdminMatch[1] };
|
|
510
|
+
}
|
|
511
|
+
const addGroupMatch = normalized.match(/^(?:允许群聊|接入群聊|添加群聊)\s+(\S+)$/);
|
|
512
|
+
if (addGroupMatch) {
|
|
513
|
+
return { kind: 'admin', resource: 'group', action: 'add', value: addGroupMatch[1] };
|
|
514
|
+
}
|
|
515
|
+
const removeGroupMatch = normalized.match(/^(?:移除群聊|拒绝群聊|禁用群聊)\s+(\S+)$/);
|
|
516
|
+
if (removeGroupMatch) {
|
|
517
|
+
return { kind: 'admin', resource: 'group', action: 'remove', value: removeGroupMatch[1] };
|
|
518
|
+
}
|
|
519
|
+
const addChatMatch = normalized.match(/^(?:允许私聊|接入私聊|添加私聊)\s+(\S+)$/);
|
|
520
|
+
if (addChatMatch) {
|
|
521
|
+
return { kind: 'admin', resource: 'chat', action: 'add', value: addChatMatch[1] };
|
|
522
|
+
}
|
|
523
|
+
const removeChatMatch = normalized.match(/^(?:移除私聊|拒绝私聊|禁用私聊)\s+(\S+)$/);
|
|
524
|
+
if (removeChatMatch) {
|
|
525
|
+
return { kind: 'admin', resource: 'chat', action: 'remove', value: removeChatMatch[1] };
|
|
526
|
+
}
|
|
527
|
+
const createProjectMatch = normalized.match(/^(?:创建项目|新建项目)\s+(\S+)\s+(.+)$/);
|
|
528
|
+
if (createProjectMatch) {
|
|
529
|
+
const [, alias, root] = createProjectMatch;
|
|
530
|
+
if (!alias || !root) {
|
|
531
|
+
return null;
|
|
532
|
+
}
|
|
533
|
+
return { kind: 'admin', resource: 'project', action: 'create', alias, value: root.trim() };
|
|
534
|
+
}
|
|
535
|
+
const addProjectMatch = normalized.match(/^添加项目\s+(\S+)\s+(.+)$/);
|
|
536
|
+
if (addProjectMatch) {
|
|
537
|
+
const [, alias, root] = addProjectMatch;
|
|
538
|
+
if (!alias || !root) {
|
|
539
|
+
return null;
|
|
540
|
+
}
|
|
541
|
+
return { kind: 'admin', resource: 'project', action: 'add', alias, value: root.trim() };
|
|
542
|
+
}
|
|
543
|
+
const removeProjectMatch = normalized.match(/^移除项目\s+(\S+)$/);
|
|
544
|
+
if (removeProjectMatch) {
|
|
545
|
+
return { kind: 'admin', resource: 'project', action: 'remove', alias: removeProjectMatch[1] };
|
|
546
|
+
}
|
|
547
|
+
const updateProjectMatch = normalized.match(/^(?:设置项目|修改项目)\s+(\S+)\s+(\S+)\s+(.+)$/);
|
|
548
|
+
if (updateProjectMatch) {
|
|
549
|
+
const [, alias, field, value] = updateProjectMatch;
|
|
550
|
+
if (!alias || !field || !value) {
|
|
551
|
+
return null;
|
|
552
|
+
}
|
|
553
|
+
return {
|
|
554
|
+
kind: 'admin',
|
|
555
|
+
resource: 'project',
|
|
556
|
+
action: 'set',
|
|
557
|
+
alias,
|
|
558
|
+
field,
|
|
559
|
+
value: value.trim(),
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
return null;
|
|
563
|
+
}
|
|
564
|
+
function stripNaturalLanguagePrefix(input) {
|
|
565
|
+
let value = input.trim();
|
|
566
|
+
const prefixPattern = /^(?:请(?:帮我)?|帮我|帮忙|麻烦(?:你|帮我)?|劳驾(?:帮我)?|辛苦(?:帮我)?|能不能(?:帮我)?|可以(?:帮我)?|可否(?:帮我)?)(?:\s+|(?=把)|(?=看)|(?=查)|(?=切)|(?=转)|(?=进)|(?=用)|(?=开)|(?=取)|(?=停)|(?=重)|(?=接)|(?=恢)|(?=创)|(?=完)|(?=当)|(?=项))/u;
|
|
567
|
+
while (prefixPattern.test(value)) {
|
|
568
|
+
value = value.replace(prefixPattern, '').trim();
|
|
569
|
+
}
|
|
570
|
+
return value.replace(/^把(?=项目|当前项目|切换到|切到|切换至|转到|进入|使用|换到|改到)/u, '').trim();
|
|
571
|
+
}
|
|
572
|
+
function truncateForDescription(input, limit = 36) {
|
|
573
|
+
return input.length > limit ? `${input.slice(0, limit)}...` : input;
|
|
574
|
+
}
|
|
575
|
+
function parseTrustCommand(argument) {
|
|
576
|
+
if (!argument)
|
|
577
|
+
return { kind: 'trust' };
|
|
578
|
+
const parts = argument.split(/\s+/).filter(Boolean);
|
|
579
|
+
if (parts[0] === 'set' && parts[1]) {
|
|
580
|
+
return { kind: 'trust', action: 'set', level: parts[1] };
|
|
581
|
+
}
|
|
582
|
+
return { kind: 'trust' };
|
|
583
|
+
}
|
|
584
|
+
function parseAdminCommand(argument) {
|
|
585
|
+
const [resource, action, ...rest] = argument.split(/\s+/).filter(Boolean);
|
|
586
|
+
if (!resource || resource === 'status') {
|
|
587
|
+
return { kind: 'admin', resource: 'service', action: 'status' };
|
|
588
|
+
}
|
|
589
|
+
if (resource === 'runs') {
|
|
590
|
+
return { kind: 'admin', resource: 'service', action: 'runs' };
|
|
591
|
+
}
|
|
592
|
+
if (resource === 'service') {
|
|
593
|
+
if (action === 'restart') {
|
|
594
|
+
return { kind: 'admin', resource: 'service', action: 'restart' };
|
|
595
|
+
}
|
|
596
|
+
if (action === 'runs') {
|
|
597
|
+
return { kind: 'admin', resource: 'service', action: 'runs' };
|
|
598
|
+
}
|
|
599
|
+
return { kind: 'admin', resource: 'service', action: 'status' };
|
|
600
|
+
}
|
|
601
|
+
if (resource === 'config') {
|
|
602
|
+
if (!action || action === 'history') {
|
|
603
|
+
return { kind: 'admin', resource: 'config', action: 'history' };
|
|
604
|
+
}
|
|
605
|
+
if (action === 'rollback') {
|
|
606
|
+
return { kind: 'admin', resource: 'config', action: 'rollback', value: rest.join(' ').trim() || undefined };
|
|
607
|
+
}
|
|
608
|
+
return { kind: 'prompt', prompt: `/admin${argument ? ` ${argument}` : ''}`.trim() };
|
|
609
|
+
}
|
|
610
|
+
if (resource === 'project') {
|
|
611
|
+
if (action === 'list' || !action) {
|
|
612
|
+
return { kind: 'admin', resource: 'project', action: 'list' };
|
|
613
|
+
}
|
|
614
|
+
if (action === 'add') {
|
|
615
|
+
return { kind: 'admin', resource: 'project', action: 'add', alias: rest[0], value: rest.slice(1).join(' ').trim() || undefined };
|
|
616
|
+
}
|
|
617
|
+
if (action === 'create') {
|
|
618
|
+
return { kind: 'admin', resource: 'project', action: 'create', alias: rest[0], value: rest.slice(1).join(' ').trim() || undefined };
|
|
619
|
+
}
|
|
620
|
+
if (action === 'remove') {
|
|
621
|
+
return { kind: 'admin', resource: 'project', action: 'remove', alias: rest[0] };
|
|
622
|
+
}
|
|
623
|
+
if (action === 'set') {
|
|
624
|
+
return {
|
|
625
|
+
kind: 'admin',
|
|
626
|
+
resource: 'project',
|
|
627
|
+
action: 'set',
|
|
628
|
+
alias: rest[0],
|
|
629
|
+
field: rest[1],
|
|
630
|
+
value: rest.slice(2).join(' ').trim() || undefined,
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
return { kind: 'prompt', prompt: `/admin${argument ? ` ${argument}` : ''}`.trim() };
|
|
634
|
+
}
|
|
635
|
+
if (resource === 'viewer' ||
|
|
636
|
+
resource === 'operator' ||
|
|
637
|
+
resource === 'admin' ||
|
|
638
|
+
resource === 'service-observer' ||
|
|
639
|
+
resource === 'service-restart' ||
|
|
640
|
+
resource === 'config-admin' ||
|
|
641
|
+
resource === 'group' ||
|
|
642
|
+
resource === 'chat') {
|
|
643
|
+
if (action === 'list' || !action) {
|
|
644
|
+
return { kind: 'admin', resource, action: 'list' };
|
|
645
|
+
}
|
|
646
|
+
if (action === 'add' || action === 'remove') {
|
|
647
|
+
return { kind: 'admin', resource, action, value: rest.join(' ').trim() || undefined };
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
return { kind: 'prompt', prompt: `/admin${argument ? ` ${argument}` : ''}`.trim() };
|
|
651
|
+
}
|
|
652
|
+
function parseSessionCommand(argument) {
|
|
653
|
+
const [subcommand, ...rest] = argument.split(/\s+/).filter(Boolean);
|
|
654
|
+
const threadId = rest.join(' ').trim() || undefined;
|
|
655
|
+
switch (subcommand) {
|
|
656
|
+
case 'list':
|
|
657
|
+
return { kind: 'session', action: 'list' };
|
|
658
|
+
case 'use':
|
|
659
|
+
return { kind: 'session', action: 'use', threadId };
|
|
660
|
+
case 'new':
|
|
661
|
+
return { kind: 'session', action: 'new' };
|
|
662
|
+
case 'drop':
|
|
663
|
+
return { kind: 'session', action: 'drop', threadId };
|
|
664
|
+
case 'adopt':
|
|
665
|
+
return { kind: 'session', action: 'adopt', target: threadId };
|
|
666
|
+
default:
|
|
667
|
+
return { kind: 'prompt', prompt: `/session${argument ? ` ${argument}` : ''}`.trim() };
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
function parseKnowledgeCommand(argument) {
|
|
671
|
+
const [subcommand, ...rest] = argument.split(/\s+/).filter(Boolean);
|
|
672
|
+
const query = rest.join(' ').trim() || undefined;
|
|
673
|
+
switch (subcommand) {
|
|
674
|
+
case 'status':
|
|
675
|
+
return { kind: 'kb', action: 'status' };
|
|
676
|
+
case 'search':
|
|
677
|
+
return { kind: 'kb', action: 'search', query };
|
|
678
|
+
default:
|
|
679
|
+
return { kind: 'prompt', prompt: `/kb${argument ? ` ${argument}` : ''}`.trim() };
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
function parseDocCommand(argument) {
|
|
683
|
+
const [subcommand, ...rest] = argument.split(/\s+/).filter(Boolean);
|
|
684
|
+
const value = rest.join(' ').trim() || undefined;
|
|
685
|
+
switch (subcommand) {
|
|
686
|
+
case 'read':
|
|
687
|
+
return { kind: 'doc', action: 'read', value };
|
|
688
|
+
case 'create':
|
|
689
|
+
return { kind: 'doc', action: 'create', value };
|
|
690
|
+
default:
|
|
691
|
+
return { kind: 'prompt', prompt: `/doc${argument ? ` ${argument}` : ''}`.trim() };
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
function parseTaskCommand(argument) {
|
|
695
|
+
const [subcommand, ...rest] = argument.split(/\s+/).filter(Boolean);
|
|
696
|
+
const value = rest.join(' ').trim() || undefined;
|
|
697
|
+
switch (subcommand) {
|
|
698
|
+
case 'list':
|
|
699
|
+
return { kind: 'task', action: 'list', value };
|
|
700
|
+
case 'get':
|
|
701
|
+
return { kind: 'task', action: 'get', value };
|
|
702
|
+
case 'create':
|
|
703
|
+
return { kind: 'task', action: 'create', value };
|
|
704
|
+
case 'complete':
|
|
705
|
+
return { kind: 'task', action: 'complete', value };
|
|
706
|
+
default:
|
|
707
|
+
return { kind: 'prompt', prompt: `/task${argument ? ` ${argument}` : ''}`.trim() };
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
function parseBaseCommand(argument) {
|
|
711
|
+
const [subcommand, ...rest] = argument.split(/\s+/).filter(Boolean);
|
|
712
|
+
switch (subcommand) {
|
|
713
|
+
case 'tables':
|
|
714
|
+
return { kind: 'base', action: 'tables', appToken: rest[0] };
|
|
715
|
+
case 'records':
|
|
716
|
+
return { kind: 'base', action: 'records', appToken: rest[0], tableId: rest[1], value: rest[2] };
|
|
717
|
+
case 'create':
|
|
718
|
+
return {
|
|
719
|
+
kind: 'base',
|
|
720
|
+
action: 'create',
|
|
721
|
+
appToken: rest[0],
|
|
722
|
+
tableId: rest[1],
|
|
723
|
+
value: rest.slice(2).join(' ').trim() || undefined,
|
|
724
|
+
};
|
|
725
|
+
case 'update':
|
|
726
|
+
return {
|
|
727
|
+
kind: 'base',
|
|
728
|
+
action: 'update',
|
|
729
|
+
appToken: rest[0],
|
|
730
|
+
tableId: rest[1],
|
|
731
|
+
recordId: rest[2],
|
|
732
|
+
value: rest.slice(3).join(' ').trim() || undefined,
|
|
733
|
+
};
|
|
734
|
+
default:
|
|
735
|
+
return { kind: 'prompt', prompt: `/base${argument ? ` ${argument}` : ''}`.trim() };
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
function parseMemoryCommand(argument) {
|
|
739
|
+
const parts = argument.split(/\s+/).filter(Boolean);
|
|
740
|
+
const subcommand = parts[0];
|
|
741
|
+
const possibleScope = parts[1] === 'group' ? 'group' : undefined;
|
|
742
|
+
const scope = possibleScope;
|
|
743
|
+
const payloadStart = scope ? 2 : 1;
|
|
744
|
+
const payload = parts.slice(payloadStart);
|
|
745
|
+
const { value, filters } = parseMemoryPayload(payload);
|
|
746
|
+
switch (subcommand) {
|
|
747
|
+
case 'status':
|
|
748
|
+
return { kind: 'memory', action: 'status', scope };
|
|
749
|
+
case 'stats':
|
|
750
|
+
return { kind: 'memory', action: 'stats', scope };
|
|
751
|
+
case 'search':
|
|
752
|
+
return { kind: 'memory', action: 'search', scope, value, filters };
|
|
753
|
+
case 'recent':
|
|
754
|
+
return { kind: 'memory', action: 'recent', scope, filters };
|
|
755
|
+
case 'save':
|
|
756
|
+
return { kind: 'memory', action: 'save', scope, value, filters };
|
|
757
|
+
case 'pin':
|
|
758
|
+
return { kind: 'memory', action: 'pin', scope, value };
|
|
759
|
+
case 'unpin':
|
|
760
|
+
return { kind: 'memory', action: 'unpin', scope, value };
|
|
761
|
+
case 'forget':
|
|
762
|
+
return { kind: 'memory', action: 'forget', scope, value };
|
|
763
|
+
case 'restore':
|
|
764
|
+
return { kind: 'memory', action: 'restore', scope, value };
|
|
765
|
+
default:
|
|
766
|
+
return { kind: 'prompt', prompt: `/memory${argument ? ` ${argument}` : ''}`.trim() };
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
function parseMemoryPayload(parts) {
|
|
770
|
+
const filters = {};
|
|
771
|
+
const positional = [];
|
|
772
|
+
for (let index = 0; index < parts.length; index += 1) {
|
|
773
|
+
const part = parts[index];
|
|
774
|
+
if (!part) {
|
|
775
|
+
continue;
|
|
776
|
+
}
|
|
777
|
+
if (part === '--tag') {
|
|
778
|
+
const tag = parts[index + 1];
|
|
779
|
+
if (tag) {
|
|
780
|
+
filters.tag = tag;
|
|
781
|
+
index += 1;
|
|
782
|
+
}
|
|
783
|
+
continue;
|
|
784
|
+
}
|
|
785
|
+
if (part === '--source') {
|
|
786
|
+
const source = parts[index + 1];
|
|
787
|
+
if (source) {
|
|
788
|
+
filters.source = source;
|
|
789
|
+
index += 1;
|
|
790
|
+
}
|
|
791
|
+
continue;
|
|
792
|
+
}
|
|
793
|
+
if (part === '--created-by') {
|
|
794
|
+
const createdBy = parts[index + 1];
|
|
795
|
+
if (createdBy) {
|
|
796
|
+
filters.created_by = createdBy;
|
|
797
|
+
index += 1;
|
|
798
|
+
}
|
|
799
|
+
continue;
|
|
800
|
+
}
|
|
801
|
+
positional.push(part);
|
|
802
|
+
}
|
|
803
|
+
return {
|
|
804
|
+
value: positional.join(' ').trim() || undefined,
|
|
805
|
+
filters: Object.keys(filters).length > 0 ? filters : undefined,
|
|
806
|
+
};
|
|
807
|
+
}
|
|
808
|
+
function parseWikiCommand(argument) {
|
|
809
|
+
const [subcommand, ...rest] = argument.split(/\s+/).filter(Boolean);
|
|
810
|
+
const value = rest.join(' ').trim() || undefined;
|
|
811
|
+
switch (subcommand) {
|
|
812
|
+
case 'spaces':
|
|
813
|
+
return { kind: 'wiki', action: 'spaces' };
|
|
814
|
+
case 'search':
|
|
815
|
+
return { kind: 'wiki', action: 'search', value };
|
|
816
|
+
case 'read':
|
|
817
|
+
return { kind: 'wiki', action: 'read', value };
|
|
818
|
+
case 'create': {
|
|
819
|
+
if (rest.length <= 1) {
|
|
820
|
+
return { kind: 'wiki', action: 'create', value };
|
|
821
|
+
}
|
|
822
|
+
return { kind: 'wiki', action: 'create', value: rest.slice(1).join(' ').trim(), extra: rest[0] };
|
|
823
|
+
}
|
|
824
|
+
case 'rename': {
|
|
825
|
+
const token = rest[0];
|
|
826
|
+
const title = rest.slice(1).join(' ').trim() || undefined;
|
|
827
|
+
return { kind: 'wiki', action: 'rename', value: title, extra: token };
|
|
828
|
+
}
|
|
829
|
+
case 'copy': {
|
|
830
|
+
const token = rest[0];
|
|
831
|
+
const targetSpaceId = rest[1];
|
|
832
|
+
return { kind: 'wiki', action: 'copy', value: token, extra: targetSpaceId };
|
|
833
|
+
}
|
|
834
|
+
case 'move': {
|
|
835
|
+
const sourceSpaceId = rest[0];
|
|
836
|
+
const token = rest[1];
|
|
837
|
+
const targetSpaceId = rest[2];
|
|
838
|
+
return { kind: 'wiki', action: 'move', value: token, extra: sourceSpaceId, target: targetSpaceId };
|
|
839
|
+
}
|
|
840
|
+
case 'members':
|
|
841
|
+
return { kind: 'wiki', action: 'members', value };
|
|
842
|
+
case 'grant': {
|
|
843
|
+
const spaceId = rest[0];
|
|
844
|
+
const memberType = rest[1];
|
|
845
|
+
const memberId = rest[2];
|
|
846
|
+
const role = rest[3];
|
|
847
|
+
return { kind: 'wiki', action: 'grant', extra: spaceId, target: memberType, value: memberId, role };
|
|
848
|
+
}
|
|
849
|
+
case 'revoke': {
|
|
850
|
+
const spaceId = rest[0];
|
|
851
|
+
const memberType = rest[1];
|
|
852
|
+
const memberId = rest[2];
|
|
853
|
+
const role = rest[3];
|
|
854
|
+
return { kind: 'wiki', action: 'revoke', extra: spaceId, target: memberType, value: memberId, role };
|
|
855
|
+
}
|
|
856
|
+
default:
|
|
857
|
+
return { kind: 'prompt', prompt: `/wiki${argument ? ` ${argument}` : ''}`.trim() };
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
//# sourceMappingURL=commands.js.map
|