team-anya-cli 0.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/README.md +38 -0
- package/anya/prompts/execution-guides/git-delivery.md +38 -0
- package/anya/prompts/execution-guides/testing-and-self-heal.md +28 -0
- package/anya/prompts/protocols/brief-assembly.md +55 -0
- package/anya/prompts/protocols/report.md +175 -0
- package/anya/prompts/protocols/review.md +90 -0
- package/anya/prompts/task-claude-md.template.md +32 -0
- package/apps/server/dist/broker/cc-broker.js +257 -0
- package/apps/server/dist/cli.js +296 -0
- package/apps/server/dist/config.js +76 -0
- package/apps/server/dist/daemon.js +51 -0
- package/apps/server/dist/gateway/chat-sync.js +135 -0
- package/apps/server/dist/gateway/command-router.js +114 -0
- package/apps/server/dist/gateway/commands/cancel.js +32 -0
- package/apps/server/dist/gateway/commands/help.js +16 -0
- package/apps/server/dist/gateway/commands/index.js +26 -0
- package/apps/server/dist/gateway/commands/restart.js +34 -0
- package/apps/server/dist/gateway/commands/status.js +34 -0
- package/apps/server/dist/gateway/commands/tasks.js +33 -0
- package/apps/server/dist/gateway/feishu-sender.js +346 -0
- package/apps/server/dist/gateway/feishu-ws.js +254 -0
- package/apps/server/dist/gateway/http.js +994 -0
- package/apps/server/dist/gateway/media-downloader.js +149 -0
- package/apps/server/dist/gateway/message-events.js +10 -0
- package/apps/server/dist/gateway/message-intake.js +50 -0
- package/apps/server/dist/gateway/message-queue.js +104 -0
- package/apps/server/dist/gateway/session-reader.js +142 -0
- package/apps/server/dist/gateway/ws-push.js +115 -0
- package/apps/server/dist/loid/brain.js +104 -0
- package/apps/server/dist/loid/clarifier.js +162 -0
- package/apps/server/dist/loid/context-builder.js +413 -0
- package/apps/server/dist/loid/mcp-server.js +104 -0
- package/apps/server/dist/loid/memory-settler.js +189 -0
- package/apps/server/dist/loid/opportunity-manager.js +148 -0
- package/apps/server/dist/loid/profile-updater.js +179 -0
- package/apps/server/dist/loid/reporter.js +148 -0
- package/apps/server/dist/loid/schemas.js +117 -0
- package/apps/server/dist/loid/self-calibrator.js +314 -0
- package/apps/server/dist/loid/session-manager.js +217 -0
- package/apps/server/dist/loid/session.js +271 -0
- package/apps/server/dist/loid/worktree-manager.js +191 -0
- package/apps/server/dist/main.js +337 -0
- package/apps/server/dist/tracing/index.js +2 -0
- package/apps/server/dist/tracing/trace-context.js +92 -0
- package/apps/server/dist/types/message.js +2 -0
- package/apps/server/dist/yor/yor-mcp-server.js +104 -0
- package/apps/server/dist/yor/yor-orchestrator.js +233 -0
- package/apps/web/dist/assets/index-CHIT0Dya.css +1 -0
- package/apps/web/dist/assets/index-CJzAjoVH.js +798 -0
- package/apps/web/dist/index.html +13 -0
- package/package.json +42 -0
- package/packages/cc-client/dist/claude-code-backend.js +664 -0
- package/packages/cc-client/dist/index.js +2 -0
- package/packages/cc-client/package.json +11 -0
- package/packages/core/dist/constants.js +59 -0
- package/packages/core/dist/errors.js +35 -0
- package/packages/core/dist/index.js +7 -0
- package/packages/core/dist/office-init.js +97 -0
- package/packages/core/dist/scope/checker.js +114 -0
- package/packages/core/dist/scope/defaults.js +40 -0
- package/packages/core/dist/scope/index.js +3 -0
- package/packages/core/dist/state-machine.js +85 -0
- package/packages/core/dist/types/audit.js +12 -0
- package/packages/core/dist/types/backend.js +2 -0
- package/packages/core/dist/types/commitment.js +17 -0
- package/packages/core/dist/types/communication.js +18 -0
- package/packages/core/dist/types/index.js +8 -0
- package/packages/core/dist/types/opportunity.js +27 -0
- package/packages/core/dist/types/org.js +26 -0
- package/packages/core/dist/types/task.js +46 -0
- package/packages/core/package.json +10 -0
- package/packages/db/dist/client.js +69 -0
- package/packages/db/dist/index.js +603 -0
- package/packages/db/dist/schema/audit-events.js +13 -0
- package/packages/db/dist/schema/cc-sessions.js +14 -0
- package/packages/db/dist/schema/chats.js +33 -0
- package/packages/db/dist/schema/commitments.js +18 -0
- package/packages/db/dist/schema/communication-events.js +14 -0
- package/packages/db/dist/schema/index.js +12 -0
- package/packages/db/dist/schema/message-log.js +20 -0
- package/packages/db/dist/schema/opportunities.js +23 -0
- package/packages/db/dist/schema/org.js +36 -0
- package/packages/db/dist/schema/projects.js +23 -0
- package/packages/db/dist/schema/tasks.js +46 -0
- package/packages/db/dist/schema/trace-spans.js +19 -0
- package/packages/db/package.json +12 -0
- package/packages/db/src/migrations/0000_simple_magneto.sql +148 -0
- package/packages/db/src/migrations/0001_nifty_morph.sql +42 -0
- package/packages/db/src/migrations/0002_common_joshua_kane.sql +20 -0
- package/packages/db/src/migrations/0003_add_cc_sessions.sql +13 -0
- package/packages/db/src/migrations/0004_jittery_triathlon.sql +1 -0
- package/packages/db/src/migrations/meta/0000_snapshot.json +987 -0
- package/packages/db/src/migrations/meta/0001_snapshot.json +1280 -0
- package/packages/db/src/migrations/meta/0002_snapshot.json +1417 -0
- package/packages/db/src/migrations/meta/0004_snapshot.json +1505 -0
- package/packages/db/src/migrations/meta/_journal.json +41 -0
- package/packages/mcp-tools/dist/index.js +41 -0
- package/packages/mcp-tools/dist/layer1/audit-append.js +38 -0
- package/packages/mcp-tools/dist/layer1/audit-query.js +51 -0
- package/packages/mcp-tools/dist/layer1/memory-brief.js +168 -0
- package/packages/mcp-tools/dist/layer1/memory-context.js +124 -0
- package/packages/mcp-tools/dist/layer1/memory-digest.js +126 -0
- package/packages/mcp-tools/dist/layer1/memory-forget.js +108 -0
- package/packages/mcp-tools/dist/layer1/memory-learn.js +63 -0
- package/packages/mcp-tools/dist/layer1/memory-recall.js +287 -0
- package/packages/mcp-tools/dist/layer1/memory-reflect.js +80 -0
- package/packages/mcp-tools/dist/layer1/memory-remember.js +119 -0
- package/packages/mcp-tools/dist/layer1/memory-search.js +263 -0
- package/packages/mcp-tools/dist/layer1/memory-write.js +21 -0
- package/packages/mcp-tools/dist/layer1/org-lookup.js +47 -0
- package/packages/mcp-tools/dist/layer1/project-get.js +28 -0
- package/packages/mcp-tools/dist/layer1/project-list.js +20 -0
- package/packages/mcp-tools/dist/layer1/report-daily.js +68 -0
- package/packages/mcp-tools/dist/layer1/task-get.js +29 -0
- package/packages/mcp-tools/dist/layer1/task-update.js +34 -0
- package/packages/mcp-tools/dist/layer2/loid/decision-log.js +15 -0
- package/packages/mcp-tools/dist/layer2/loid/decision-no-action.js +15 -0
- package/packages/mcp-tools/dist/layer2/loid/delivery-create-pr.js +30 -0
- package/packages/mcp-tools/dist/layer2/loid/delivery-share.js +12 -0
- package/packages/mcp-tools/dist/layer2/loid/delivery-submit.js +77 -0
- package/packages/mcp-tools/dist/layer2/loid/delivery-upload.js +18 -0
- package/packages/mcp-tools/dist/layer2/loid/project-remove.js +16 -0
- package/packages/mcp-tools/dist/layer2/loid/project-upsert.js +33 -0
- package/packages/mcp-tools/dist/layer2/loid/task-dispatch.js +177 -0
- package/packages/mcp-tools/dist/layer2/loid/task-lookup.js +38 -0
- package/packages/mcp-tools/dist/layer2/loid/yor-approve.js +8 -0
- package/packages/mcp-tools/dist/layer2/loid/yor-kill.js +7 -0
- package/packages/mcp-tools/dist/layer2/loid/yor-rework.js +7 -0
- package/packages/mcp-tools/dist/layer2/loid/yor-spawn.js +15 -0
- package/packages/mcp-tools/dist/layer2/loid/yor-status.js +8 -0
- package/packages/mcp-tools/dist/layer2/yor/task-block.js +11 -0
- package/packages/mcp-tools/dist/layer2/yor/task-deliver.js +35 -0
- package/packages/mcp-tools/dist/layer2/yor/task-progress.js +21 -0
- package/packages/mcp-tools/dist/layer3/adapters/feishu-adapter.js +191 -0
- package/packages/mcp-tools/dist/layer3/adapters/types.js +28 -0
- package/packages/mcp-tools/dist/layer3/channel-receive.js +11 -0
- package/packages/mcp-tools/dist/layer3/channel-send.js +90 -0
- package/packages/mcp-tools/dist/layer3/file-upload.js +44 -0
- package/packages/mcp-tools/dist/registry.js +779 -0
- package/packages/mcp-tools/package.json +13 -0
- package/workspace/.claude/settings.local.json +9 -0
- package/workspace/.mcp.json +12 -0
- package/workspace/CHARTER.md +73 -0
- package/workspace/CLAUDE.md +49 -0
- package/workspace/PROTOCOL.md +126 -0
- package/workspace/TOOLS.md +464 -0
- package/workspace/audit/.gitkeep +0 -0
- package/workspace/loid/CLAUDE.md +12 -0
- package/workspace/loid/PLAYBOOK.md +198 -0
- package/workspace/loid/PROFILE.md +78 -0
- package/workspace/memory/commitments/.gitkeep +0 -0
- package/workspace/memory/execution/.gitkeep +0 -0
- package/workspace/memory/people/.gitkeep +0 -0
- package/workspace/memory/projects/.gitkeep +0 -0
- package/workspace/memory/self/.gitkeep +0 -0
- package/workspace/reference/identity/.gitkeep +0 -0
- package/workspace/reference/org/escalation.yaml +24 -0
- package/workspace/reference/org/ownership.yaml +28 -0
- package/workspace/reports/.gitkeep +0 -0
- package/workspace/yor/CLAUDE.md +22 -0
- package/workspace/yor/PLAYBOOK.md +73 -0
- package/workspace/yor/PROFILE.md +52 -0
- package/workspace/yor/SELF-HEAL.md +39 -0
|
@@ -0,0 +1,779 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
// ── Zod Schemas ──
|
|
3
|
+
// Layer 1: 共享基础 — 新版记忆工具
|
|
4
|
+
export const MemoryRecallInputSchema = z.object({
|
|
5
|
+
query: z.string().describe('自然语言查询'),
|
|
6
|
+
scope: z.array(z.string()).optional().describe('限定范围: ["people/wang_lei", "execution"]'),
|
|
7
|
+
person: z.string().optional().describe('快捷方式: 等价于 scope: ["people/{person}"]'),
|
|
8
|
+
project: z.string().optional().describe('快捷方式: 等价于 scope: ["projects/{project}"]'),
|
|
9
|
+
depth: z.enum(['summary', 'full']).optional().describe('返回深度,默认 summary'),
|
|
10
|
+
limit: z.number().optional().describe('返回条数,默认 5'),
|
|
11
|
+
});
|
|
12
|
+
export const MemoryRememberInputSchema = z.object({
|
|
13
|
+
category: z.enum(['people', 'project', 'execution', 'commitment', 'self']).describe('记忆类别'),
|
|
14
|
+
target: z.string().optional().describe('people 时 sender_id, project 时 project_id'),
|
|
15
|
+
content: z.string().describe('要记住的内容'),
|
|
16
|
+
sub_type: z.string().optional().describe('子类型: project→pitfall|convention|decision, execution→pattern|failure|tool, self→boundary|mistake|correction'),
|
|
17
|
+
importance: z.number().optional().describe('重要度 0-1,默认 0.5'),
|
|
18
|
+
source: z.string().optional().describe('来源 task_id'),
|
|
19
|
+
expires_at: z.string().optional().describe('过期时间(commitment 用)'),
|
|
20
|
+
});
|
|
21
|
+
export const MemoryDigestInputSchema = z.object({
|
|
22
|
+
conversation: z.string().describe('对话内容或执行日志'),
|
|
23
|
+
sender_id: z.string().optional().describe('对话对象 ID'),
|
|
24
|
+
task_id: z.string().optional().describe('关联任务 ID'),
|
|
25
|
+
project_id: z.string().optional().describe('关联项目 ID'),
|
|
26
|
+
});
|
|
27
|
+
export const MemoryBriefInputSchema = z.object({
|
|
28
|
+
sender_id: z.string().optional().describe('正在跟谁沟通'),
|
|
29
|
+
project_id: z.string().optional().describe('涉及哪个项目'),
|
|
30
|
+
task_type: z.string().optional().describe('任务类型关键词'),
|
|
31
|
+
token_budget: z.number().optional().describe('Token 预算,默认 1500'),
|
|
32
|
+
});
|
|
33
|
+
export const MemoryForgetInputSchema = z.object({
|
|
34
|
+
mode: z.enum(['invalidate']).describe('遗忘模式: invalidate=主动失效'),
|
|
35
|
+
scope: z.string().optional().describe('失效范围,如 "projects/my-app/pitfalls"'),
|
|
36
|
+
target: z.string().optional().describe('失效的具体条目内容关键词'),
|
|
37
|
+
reason: z.string().optional().describe('失效原因'),
|
|
38
|
+
});
|
|
39
|
+
// Layer 1: 共享基础 — 旧版(保留 Schema 定义以便编译兼容,但不再注册到工具表)
|
|
40
|
+
/** @deprecated 使用 MemoryBriefInputSchema */
|
|
41
|
+
export const MemoryContextInputSchema = z.object({
|
|
42
|
+
scene: z.enum(['task_execution', 'escalation', 'opportunity_eval', 'daily_report']).describe('上下文场景'),
|
|
43
|
+
vars: z.record(z.string()).describe('场景变量(current_task, current_project 等)'),
|
|
44
|
+
});
|
|
45
|
+
/** @deprecated 使用 MemoryRecallInputSchema */
|
|
46
|
+
export const MemorySearchInputSchema = z.object({
|
|
47
|
+
query: z.string().describe('搜索关键词'),
|
|
48
|
+
type: z.string().optional().describe('记忆类型过滤'),
|
|
49
|
+
tags: z.array(z.string()).optional().describe('标签过滤'),
|
|
50
|
+
project_id: z.string().optional().describe('项目 ID 过滤'),
|
|
51
|
+
limit: z.number().optional().describe('返回条数限制(默认 5)'),
|
|
52
|
+
});
|
|
53
|
+
/** @deprecated 使用 MemoryRememberInputSchema */
|
|
54
|
+
export const MemoryLearnInputSchema = z.object({
|
|
55
|
+
content: z.string().describe('记忆内容'),
|
|
56
|
+
type: z.string().describe('记忆类型'),
|
|
57
|
+
tags: z.array(z.string()).describe('标签'),
|
|
58
|
+
importance: z.number().optional().describe('重要度 0-1,默认 0.5'),
|
|
59
|
+
task_id: z.string().optional().describe('关联任务 ID'),
|
|
60
|
+
project_id: z.string().optional().describe('关联项目 ID'),
|
|
61
|
+
expires_at: z.string().optional().describe('过期时间(ISO 时间戳)'),
|
|
62
|
+
});
|
|
63
|
+
/** @deprecated 使用 MemoryDigestInputSchema */
|
|
64
|
+
export const MemoryReflectInputSchema = z.object({
|
|
65
|
+
task_id: z.string().optional().describe('限定反思范围的任务 ID'),
|
|
66
|
+
recent_events: z.string().optional().describe('可选的手动上下文'),
|
|
67
|
+
});
|
|
68
|
+
export const OrgLookupInputSchema = z.object({
|
|
69
|
+
member_id: z.string().optional().describe('成员 ID'),
|
|
70
|
+
scope: z.enum(['repo', 'module']).optional().describe('归属范围'),
|
|
71
|
+
target: z.string().optional().describe('目标(仓库名或模块名)'),
|
|
72
|
+
});
|
|
73
|
+
export const TaskGetInputSchema = z.object({
|
|
74
|
+
task_id: z.string().describe('任务 ID'),
|
|
75
|
+
});
|
|
76
|
+
export const AuditAppendInputSchema = z.object({
|
|
77
|
+
event_type: z.string().describe('事件类型'),
|
|
78
|
+
actor: z.string().describe('操作者'),
|
|
79
|
+
task_id: z.string().optional().describe('关联任务 ID'),
|
|
80
|
+
summary: z.string().describe('事件摘要'),
|
|
81
|
+
detail: z.record(z.unknown()).optional().describe('详细信息'),
|
|
82
|
+
});
|
|
83
|
+
export const AuditQueryInputSchema = z.object({
|
|
84
|
+
task_id: z.string().optional().describe('按任务 ID 过滤'),
|
|
85
|
+
event_type: z.string().optional().describe('按事件类型过滤'),
|
|
86
|
+
actor: z.string().optional().describe('按操作者过滤'),
|
|
87
|
+
since: z.string().optional().describe('起始时间(ISO 时间戳)'),
|
|
88
|
+
limit: z.number().optional().describe('返回条数限制(默认 20)'),
|
|
89
|
+
});
|
|
90
|
+
export const ReportDailyInputSchema = z.object({
|
|
91
|
+
date: z.string().describe('日期(YYYY-MM-DD)'),
|
|
92
|
+
});
|
|
93
|
+
export const TaskUpdateInputSchema = z.object({
|
|
94
|
+
task_id: z.string().describe('任务 ID'),
|
|
95
|
+
status: z.string().describe('目标状态(NEW/NEED_CLARIFICATION/READY/IN_PROGRESS/DELIVERING/DONE/BLOCKED/CANCELLED)'),
|
|
96
|
+
reason: z.string().optional().describe('状态变更原因'),
|
|
97
|
+
});
|
|
98
|
+
// Layer 1: 共享基础 — 项目工具
|
|
99
|
+
export const ProjectListInputSchema = z.object({
|
|
100
|
+
platform: z.enum(['github', 'gitlab', 'local']).optional().describe('按平台过滤'),
|
|
101
|
+
include_deleted: z.boolean().optional().describe('是否包含已归档的项目,默认 false'),
|
|
102
|
+
});
|
|
103
|
+
export const ProjectGetInputSchema = z.object({
|
|
104
|
+
project_id: z.string().describe('项目 ID'),
|
|
105
|
+
});
|
|
106
|
+
// Layer 2: Loid 专属 — 项目管理
|
|
107
|
+
export const ProjectUpsertInputSchema = z.object({
|
|
108
|
+
project_id: z.string().describe('项目 ID(如 my-app)'),
|
|
109
|
+
name: z.string().describe('项目显示名称'),
|
|
110
|
+
description: z.string().optional().describe('项目简介'),
|
|
111
|
+
platform: z.enum(['github', 'gitlab', 'local']).optional().describe('平台,默认 github'),
|
|
112
|
+
repos: z.array(z.object({
|
|
113
|
+
name: z.string().describe('仓库名或子目录名'),
|
|
114
|
+
git_url: z.string().optional().describe('git 克隆地址'),
|
|
115
|
+
repo_path: z.string().optional().describe('本地绝对路径'),
|
|
116
|
+
default_branch: z.string().optional().describe('默认分支,默认 main'),
|
|
117
|
+
})).optional().describe('仓库列表'),
|
|
118
|
+
claude_md: z.string().optional().describe('项目级 CLAUDE.md 内容'),
|
|
119
|
+
});
|
|
120
|
+
export const ProjectRemoveInputSchema = z.object({
|
|
121
|
+
project_id: z.string().describe('要归档的项目 ID'),
|
|
122
|
+
reason: z.string().describe('归档原因(审计用)'),
|
|
123
|
+
});
|
|
124
|
+
// Layer 2: Loid 专属 - yor.*
|
|
125
|
+
export const YorSpawnInputSchema = z.object({
|
|
126
|
+
task_id: z.string().describe('任务 ID'),
|
|
127
|
+
working_dir: z.string().describe('Yor 工作目录'),
|
|
128
|
+
brief_path: z.string().describe('brief 文件路径'),
|
|
129
|
+
env: z.record(z.string()).optional().describe('额外环境变量'),
|
|
130
|
+
});
|
|
131
|
+
export const YorKillInputSchema = z.object({
|
|
132
|
+
task_id: z.string().describe('要终止的 Yor 任务 ID'),
|
|
133
|
+
});
|
|
134
|
+
export const YorStatusInputSchema = z.object({});
|
|
135
|
+
export const YorReworkInputSchema = z.object({
|
|
136
|
+
task_id: z.string().describe('要返工的 Yor 任务 ID'),
|
|
137
|
+
feedback: z.string().describe('返工反馈(审核问题 + 修改要求)'),
|
|
138
|
+
});
|
|
139
|
+
export const YorApproveInputSchema = z.object({
|
|
140
|
+
task_id: z.string().describe('要批准的 Yor 任务 ID'),
|
|
141
|
+
message: z.string().optional().describe('批准消息(可选,默认 "审核通过")'),
|
|
142
|
+
});
|
|
143
|
+
// Layer 2: Loid 专属 - delivery.*
|
|
144
|
+
export const DeliverySubmitInputSchema = z.object({
|
|
145
|
+
task_id: z.string().describe('任务 ID'),
|
|
146
|
+
title: z.string().describe('PR/MR 标题'),
|
|
147
|
+
description: z.string().describe('PR/MR 描述'),
|
|
148
|
+
base_branch: z.string().optional().describe('目标分支(默认由项目配置决定)'),
|
|
149
|
+
working_dir: z.string().describe('执行命令的工作目录'),
|
|
150
|
+
});
|
|
151
|
+
export const DeliveryUploadInputSchema = z.object({
|
|
152
|
+
file_path: z.string().describe('要上传的文件路径'),
|
|
153
|
+
target: z.string().describe('上传目标'),
|
|
154
|
+
});
|
|
155
|
+
export const DeliveryShareInputSchema = z.object({
|
|
156
|
+
url: z.string().describe('要分享的链接'),
|
|
157
|
+
target: z.string().describe('分享目标'),
|
|
158
|
+
message: z.string().describe('分享消息'),
|
|
159
|
+
});
|
|
160
|
+
// Layer 2: Loid 专属
|
|
161
|
+
export const TaskDispatchInputSchema = z.object({
|
|
162
|
+
title: z.string().describe('任务标题'),
|
|
163
|
+
brief: z.string().describe('执行 brief(Markdown 格式,只写做什么和标准,不写怎么做)'),
|
|
164
|
+
project_id: z.string().optional().describe('目标项目/仓库 ID'),
|
|
165
|
+
objective: z.string().describe('任务目标(一句话概括要达成什么)'),
|
|
166
|
+
acceptance_criteria: z.array(z.string()).describe('验收标准列表(至少一条可验证的完成条件)'),
|
|
167
|
+
context: z.string().optional().describe('背景信息(业务上下文、技术约束等)'),
|
|
168
|
+
conversation_id: z.string().optional().describe('关联的对话 ID'),
|
|
169
|
+
source_message_id: z.string().optional().describe('触发消息 ID'),
|
|
170
|
+
created_by: z.string().optional().describe('任务创建者(发起人名字或 ID,从对话上下文中提取)'),
|
|
171
|
+
source_chat_id: z.string().optional().describe('触发任务的聊天 ID(从对话上下文中提取)'),
|
|
172
|
+
});
|
|
173
|
+
export const TaskLookupInputSchema = z.object({
|
|
174
|
+
task_id: z.string().optional().describe('指定任务 ID'),
|
|
175
|
+
status: z.string().optional().describe('按状态过滤'),
|
|
176
|
+
});
|
|
177
|
+
export const DecisionLogInputSchema = z.object({
|
|
178
|
+
decision: z.string().describe('决策内容'),
|
|
179
|
+
reasoning: z.string().describe('决策理由'),
|
|
180
|
+
task_id: z.string().optional().describe('关联任务 ID'),
|
|
181
|
+
});
|
|
182
|
+
// Layer 2: Yor 专属 - 任务状态
|
|
183
|
+
export const TaskDeliverInputSchema = z.object({
|
|
184
|
+
outcome: z.string().describe('执行结果摘要'),
|
|
185
|
+
changed_files: z.array(z.string()).describe('变更的文件列表'),
|
|
186
|
+
test_passed: z.boolean().describe('测试是否全部通过'),
|
|
187
|
+
test_output: z.string().optional().describe('测试输出摘要'),
|
|
188
|
+
pr_link: z.string().optional().describe('PR 链接'),
|
|
189
|
+
});
|
|
190
|
+
export const TaskBlockInputSchema = z.object({
|
|
191
|
+
reason: z.string().describe('阻塞原因'),
|
|
192
|
+
category: z.enum(['brief_unclear', 'scope_exceeded', 'heal_failed', 'permission', 'refactor_needed']).describe('阻塞分类'),
|
|
193
|
+
attempted_solutions: z.array(z.string()).describe('已尝试的解决方案'),
|
|
194
|
+
logs: z.string().optional().describe('相关日志'),
|
|
195
|
+
});
|
|
196
|
+
export const TaskProgressInputSchema = z.object({
|
|
197
|
+
milestone: z.string().describe('里程碑描述'),
|
|
198
|
+
detail: z.string().optional().describe('详细说明'),
|
|
199
|
+
next_step: z.string().optional().describe('下一步计划'),
|
|
200
|
+
});
|
|
201
|
+
// Layer 3: 外部桥梁
|
|
202
|
+
export const ChannelSendInputSchema = z.object({
|
|
203
|
+
target: z.string().describe('飞书群聊 ID(如 oc_xxx)'),
|
|
204
|
+
message: z.string().describe('消息内容'),
|
|
205
|
+
task_id: z.string().optional().describe('关联任务 ID(审计追溯用)'),
|
|
206
|
+
file: z.object({
|
|
207
|
+
file_path: z.string().describe('文件路径'),
|
|
208
|
+
file_name: z.string().optional().describe('自定义文件名'),
|
|
209
|
+
file_type: z.string().optional().describe('文件类型(opus/mp4/pdf/doc/xls/ppt/stream)'),
|
|
210
|
+
duration: z.number().optional().describe('音视频时长 ms'),
|
|
211
|
+
}).optional().describe('发送文件'),
|
|
212
|
+
mentions: z.array(z.string()).optional().describe('@的用户 ID 列表'),
|
|
213
|
+
reply_to: z.string().optional().describe('回复的消息 ID'),
|
|
214
|
+
});
|
|
215
|
+
export const FileUploadInputSchema = z.object({
|
|
216
|
+
file_path: z.string().describe('要上传的文件路径'),
|
|
217
|
+
file_name: z.string().optional().describe('自定义文件名(默认使用原始文件名)'),
|
|
218
|
+
});
|
|
219
|
+
export const ChannelReceiveInputSchema = z.object({
|
|
220
|
+
since: z.string().optional().describe('起始时间(ISO 时间戳)'),
|
|
221
|
+
source: z.string().optional().describe('消息来源过滤'),
|
|
222
|
+
limit: z.number().optional().describe('返回条数限制'),
|
|
223
|
+
});
|
|
224
|
+
// ── 完整工具注册表 ──
|
|
225
|
+
export const TOOL_REGISTRY = [
|
|
226
|
+
// Layer 1: 共享基础 — 记忆工具(v2)
|
|
227
|
+
{
|
|
228
|
+
name: 'memory.recall',
|
|
229
|
+
description: '召回记忆。支持按人/项目直读,或自然语言搜索所有记忆目录。',
|
|
230
|
+
inputSchema: MemoryRecallInputSchema,
|
|
231
|
+
layer: 1,
|
|
232
|
+
roles: ['loid', 'yor'],
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
name: 'memory.remember',
|
|
236
|
+
description: '写入记忆。按类别(people/project/execution/commitment/self)+ 目标写入 YAML 文件。',
|
|
237
|
+
inputSchema: MemoryRememberInputSchema,
|
|
238
|
+
layer: 1,
|
|
239
|
+
roles: ['loid', 'yor'],
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
name: 'memory.digest',
|
|
243
|
+
description: '消化对话/日志,自动提取记忆。从文本中识别失败/决策/承诺/经验并写入对应记忆目录。',
|
|
244
|
+
inputSchema: MemoryDigestInputSchema,
|
|
245
|
+
layer: 1,
|
|
246
|
+
roles: ['loid', 'yor'],
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
name: 'memory.brief',
|
|
250
|
+
description: '组装记忆摘要。按优先级(人→项目→执行经验→承诺→自我)在 token 预算内拼装 markdown 摘要。',
|
|
251
|
+
inputSchema: MemoryBriefInputSchema,
|
|
252
|
+
layer: 1,
|
|
253
|
+
roles: ['loid', 'yor'],
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
name: 'memory.forget',
|
|
257
|
+
description: '遗忘/失效记忆。将指定范围内匹配的记忆条目 heat 设为 0。',
|
|
258
|
+
inputSchema: MemoryForgetInputSchema,
|
|
259
|
+
layer: 1,
|
|
260
|
+
roles: ['loid', 'yor'],
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
name: 'org.lookup',
|
|
264
|
+
description: '查人员/归属/升级路径。按成员 ID 查身份,按目标查归属权。',
|
|
265
|
+
inputSchema: OrgLookupInputSchema,
|
|
266
|
+
layer: 1,
|
|
267
|
+
roles: ['loid', 'yor'],
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
name: 'task.get',
|
|
271
|
+
description: '获取任务完整状态。包含任务记录、澄清、承诺、审计事件和文件内容。',
|
|
272
|
+
inputSchema: TaskGetInputSchema,
|
|
273
|
+
layer: 1,
|
|
274
|
+
roles: ['loid', 'yor'],
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
name: 'audit.append',
|
|
278
|
+
description: '写审计事件。双写 DB + JSONL 文件,保障可回放。',
|
|
279
|
+
inputSchema: AuditAppendInputSchema,
|
|
280
|
+
layer: 1,
|
|
281
|
+
roles: ['loid', 'yor'],
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
name: 'audit.query',
|
|
285
|
+
description: '查询审计事件。按任务、类型、操作者、时间范围过滤。',
|
|
286
|
+
inputSchema: AuditQueryInputSchema,
|
|
287
|
+
layer: 1,
|
|
288
|
+
roles: ['loid', 'yor'],
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
name: 'report.daily',
|
|
292
|
+
description: '生成日报。汇总今日完成/进行中/阻塞/承诺/机会。',
|
|
293
|
+
inputSchema: ReportDailyInputSchema,
|
|
294
|
+
layer: 1,
|
|
295
|
+
roles: ['loid'],
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: 'task.update',
|
|
299
|
+
description: '原子级任务状态更新。校验状态转换合法性(state machine),同时写 audit log。',
|
|
300
|
+
inputSchema: TaskUpdateInputSchema,
|
|
301
|
+
layer: 1,
|
|
302
|
+
roles: ['loid', 'yor'],
|
|
303
|
+
},
|
|
304
|
+
// Layer 1: 共享基础 — 项目工具
|
|
305
|
+
{
|
|
306
|
+
name: 'project.list',
|
|
307
|
+
description: '列出所有已注册项目。可按平台过滤,返回项目概览(不含大字段)。',
|
|
308
|
+
inputSchema: ProjectListInputSchema,
|
|
309
|
+
layer: 1,
|
|
310
|
+
roles: ['loid', 'yor'],
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
name: 'project.get',
|
|
314
|
+
description: '查询单个项目的完整配置,包括平台、仓库列表、CLAUDE.md 内容。',
|
|
315
|
+
inputSchema: ProjectGetInputSchema,
|
|
316
|
+
layer: 1,
|
|
317
|
+
roles: ['loid', 'yor'],
|
|
318
|
+
},
|
|
319
|
+
// Layer 2: Loid 专属 - 项目管理
|
|
320
|
+
{
|
|
321
|
+
name: 'project.upsert',
|
|
322
|
+
description: '创建或更新项目配置。同步仓库列表,写审计日志。',
|
|
323
|
+
inputSchema: ProjectUpsertInputSchema,
|
|
324
|
+
layer: 2,
|
|
325
|
+
roles: ['loid'],
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
name: 'project.remove',
|
|
329
|
+
description: '归档项目(软删除)。需提供归档原因,数据不会真正删除。',
|
|
330
|
+
inputSchema: ProjectRemoveInputSchema,
|
|
331
|
+
layer: 2,
|
|
332
|
+
roles: ['loid'],
|
|
333
|
+
},
|
|
334
|
+
// Layer 2: Loid 专属 - yor/delivery
|
|
335
|
+
{
|
|
336
|
+
name: 'yor.spawn',
|
|
337
|
+
description: '启动 Yor 执行器进程。指定工作目录和 brief 路径。',
|
|
338
|
+
inputSchema: YorSpawnInputSchema,
|
|
339
|
+
layer: 2,
|
|
340
|
+
roles: ['loid'],
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
name: 'yor.kill',
|
|
344
|
+
description: '终止 Yor 执行器进程。',
|
|
345
|
+
inputSchema: YorKillInputSchema,
|
|
346
|
+
layer: 2,
|
|
347
|
+
roles: ['loid'],
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
name: 'yor.status',
|
|
351
|
+
description: '查询所有 Yor 执行器状态。返回实例列表及运行状态。',
|
|
352
|
+
inputSchema: YorStatusInputSchema,
|
|
353
|
+
layer: 2,
|
|
354
|
+
roles: ['loid'],
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
name: 'yor.rework',
|
|
358
|
+
description: '向运行中的 Yor 发送返工指令。审核交付后发现问题时调用,将反馈注入 Yor CC 让它继续修改。',
|
|
359
|
+
inputSchema: YorReworkInputSchema,
|
|
360
|
+
layer: 2,
|
|
361
|
+
roles: ['loid'],
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
name: 'yor.approve',
|
|
365
|
+
description: '批准 Yor 交付并关闭实例。审核通过后调用,发送确认消息并延迟关闭 Yor CC。',
|
|
366
|
+
inputSchema: YorApproveInputSchema,
|
|
367
|
+
layer: 2,
|
|
368
|
+
roles: ['loid'],
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
name: 'delivery.submit',
|
|
372
|
+
description: '提交交付产物。根据项目平台自动选择:GitHub → PR(gh CLI),GitLab → MR(glab CLI),本地任务 → 记录 commit hash。',
|
|
373
|
+
inputSchema: DeliverySubmitInputSchema,
|
|
374
|
+
layer: 2,
|
|
375
|
+
roles: ['loid'],
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
name: 'delivery.upload',
|
|
379
|
+
description: '上传文件产物(尚未实现)。',
|
|
380
|
+
inputSchema: DeliveryUploadInputSchema,
|
|
381
|
+
layer: 2,
|
|
382
|
+
roles: ['loid'],
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
name: 'delivery.share',
|
|
386
|
+
description: '分享链接/产物(尚未实现)。',
|
|
387
|
+
inputSchema: DeliveryShareInputSchema,
|
|
388
|
+
layer: 2,
|
|
389
|
+
roles: ['loid'],
|
|
390
|
+
},
|
|
391
|
+
// Layer 2: Loid 专属
|
|
392
|
+
{
|
|
393
|
+
name: 'task.dispatch',
|
|
394
|
+
description: `派工给执行者(Yor)。创建任务、写入 brief、自动准备隔离工作区。
|
|
395
|
+
|
|
396
|
+
Brief 格式模板:
|
|
397
|
+
\`\`\`markdown
|
|
398
|
+
# {任务标题}
|
|
399
|
+
|
|
400
|
+
## What
|
|
401
|
+
{一句话说清楚要做什么}
|
|
402
|
+
|
|
403
|
+
## Why
|
|
404
|
+
{业务背景、为什么要做}
|
|
405
|
+
|
|
406
|
+
## DoD
|
|
407
|
+
- [ ] {可验证的条件 1}
|
|
408
|
+
- [ ] {可验证的条件 2}
|
|
409
|
+
- [ ] 测试通过 + lint 通过
|
|
410
|
+
|
|
411
|
+
## Constraints
|
|
412
|
+
- 项目: {project_id}
|
|
413
|
+
- 涉及: {文件/模块范围}
|
|
414
|
+
- 不改: {out-of-scope}
|
|
415
|
+
|
|
416
|
+
## 执行指引
|
|
417
|
+
{告诉 Yor 怎么交付:Git PR / 文件产物 / 调研报告等}
|
|
418
|
+
- 代码变更 → 引用 execution-guides/git-delivery.md
|
|
419
|
+
- 需要测试 → 引用 execution-guides/testing-and-self-heal.md
|
|
420
|
+
\`\`\`
|
|
421
|
+
|
|
422
|
+
Brief 只写做什么和标准,不写怎么做。
|
|
423
|
+
|
|
424
|
+
重要:必须填写 objective(任务目标)和 acceptance_criteria(验收标准),从用户需求中提炼。
|
|
425
|
+
同时从当前对话上下文中提取 created_by(sender_name 或 sender_id)和 source_chat_id(chat_id),确保任务可追溯。
|
|
426
|
+
|
|
427
|
+
返回值包含 task_id、brief_path 和 working_dir(已准备好的隔离工作区绝对路径)。
|
|
428
|
+
派工两步走:task.dispatch(MCP) → yor.spawn(MCP,传入返回的 working_dir 和 brief_path)。
|
|
429
|
+
如果返回 status="blocked",说明工作区准备失败,error 字段包含原因,此时不要调用 yor.spawn,应通知人类。`,
|
|
430
|
+
inputSchema: TaskDispatchInputSchema,
|
|
431
|
+
layer: 2,
|
|
432
|
+
roles: ['loid'],
|
|
433
|
+
},
|
|
434
|
+
// task.review 已移除:Loid 通过 task.update + channel.send 自主决定验收结果
|
|
435
|
+
{
|
|
436
|
+
name: 'task.lookup',
|
|
437
|
+
description: '查询任务列表。可按 task_id 或 status 过滤,不传参数返回所有活跃任务。',
|
|
438
|
+
inputSchema: TaskLookupInputSchema,
|
|
439
|
+
layer: 2,
|
|
440
|
+
roles: ['loid'],
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
name: 'decision.log',
|
|
444
|
+
description: '记录决策理由到审计日志。每个重要决策都应记录。',
|
|
445
|
+
inputSchema: DecisionLogInputSchema,
|
|
446
|
+
layer: 2,
|
|
447
|
+
roles: ['loid'],
|
|
448
|
+
},
|
|
449
|
+
// Layer 2: Yor 专属 - 任务状态
|
|
450
|
+
{
|
|
451
|
+
name: 'task.deliver',
|
|
452
|
+
description: '提交执行成果。完成任务后调用,报告变更文件、测试结果、PR 链接。',
|
|
453
|
+
inputSchema: TaskDeliverInputSchema,
|
|
454
|
+
layer: 2,
|
|
455
|
+
roles: ['yor'],
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
name: 'task.block',
|
|
459
|
+
description: '报告阻塞。遇到无法解决的问题时调用,说明原因、分类和已尝试的方案。',
|
|
460
|
+
inputSchema: TaskBlockInputSchema,
|
|
461
|
+
layer: 2,
|
|
462
|
+
roles: ['yor'],
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
name: 'task.progress',
|
|
466
|
+
description: '中间进度汇报。长任务中报告里程碑,不改变任务状态。',
|
|
467
|
+
inputSchema: TaskProgressInputSchema,
|
|
468
|
+
layer: 2,
|
|
469
|
+
roles: ['yor'],
|
|
470
|
+
},
|
|
471
|
+
// Layer 3: 外部桥梁
|
|
472
|
+
{
|
|
473
|
+
name: 'channel.send',
|
|
474
|
+
description: '向飞书群发消息。target 填群聊 ID。支持发送文件(file)、@用户(mentions)和回复消息(reply_to)。',
|
|
475
|
+
inputSchema: ChannelSendInputSchema,
|
|
476
|
+
layer: 3,
|
|
477
|
+
roles: ['loid', 'yor'],
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
name: 'file.upload',
|
|
481
|
+
description: '通用文件上传(与通道无关)。上传文件到项目存储,返回 URL。当前使用本地存储。',
|
|
482
|
+
inputSchema: FileUploadInputSchema,
|
|
483
|
+
layer: 3,
|
|
484
|
+
roles: ['loid'],
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
name: 'channel.receive',
|
|
488
|
+
description: '拉取新消息(暂不实现,消息通过 gateway 推送)。',
|
|
489
|
+
inputSchema: ChannelReceiveInputSchema,
|
|
490
|
+
layer: 3,
|
|
491
|
+
roles: ['loid'],
|
|
492
|
+
},
|
|
493
|
+
];
|
|
494
|
+
/**
|
|
495
|
+
* 按角色获取可用工具列表
|
|
496
|
+
*/
|
|
497
|
+
export function getToolsForRole(role) {
|
|
498
|
+
return TOOL_REGISTRY.filter(t => t.roles.includes(role));
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* 创建工具路由器
|
|
502
|
+
*
|
|
503
|
+
* 按角色过滤可用工具,统一路由 MCP 工具调用到对应的实现函数。
|
|
504
|
+
* Loid/Yor MCP server 只需调用 createToolRouter 即可获得完整工具集。
|
|
505
|
+
*/
|
|
506
|
+
export function createToolRouter(role, deps) {
|
|
507
|
+
const tools = getToolsForRole(role);
|
|
508
|
+
const logger = deps.logger ?? { info: console.log, error: console.error };
|
|
509
|
+
const textResult = (text) => ({
|
|
510
|
+
content: [{ type: 'text', text }],
|
|
511
|
+
});
|
|
512
|
+
/** 按工具名提取关键参数,日志摘要用 */
|
|
513
|
+
function summarizeArgs(toolName, args) {
|
|
514
|
+
switch (toolName) {
|
|
515
|
+
case 'task.dispatch':
|
|
516
|
+
return `title="${String(args.title ?? '').slice(0, 40)}"`;
|
|
517
|
+
case 'task.lookup':
|
|
518
|
+
return args.task_id ? `id=${args.task_id}` : args.status ? `status=${args.status}` : '活跃任务';
|
|
519
|
+
case 'decision.log':
|
|
520
|
+
return `"${String(args.decision ?? '').slice(0, 50)}"`;
|
|
521
|
+
case 'channel.send':
|
|
522
|
+
return `target=${args.target}${args.file ? ' +file' : ''}`;
|
|
523
|
+
case 'file.upload':
|
|
524
|
+
return `file=${args.file_path}`;
|
|
525
|
+
case 'task.deliver':
|
|
526
|
+
return `files=${args.changed_files?.length ?? 0} test=${args.test_passed}`;
|
|
527
|
+
case 'task.block':
|
|
528
|
+
return `category=${args.category} reason="${String(args.reason ?? '').slice(0, 40)}"`;
|
|
529
|
+
case 'task.progress':
|
|
530
|
+
return `"${String(args.milestone ?? '').slice(0, 50)}"`;
|
|
531
|
+
case 'memory.recall':
|
|
532
|
+
return `query="${String(args.query ?? '').slice(0, 40)}"${args.person ? ` person=${args.person}` : ''}${args.project ? ` project=${args.project}` : ''}`;
|
|
533
|
+
case 'memory.remember':
|
|
534
|
+
return `category=${args.category}${args.target ? '/' + args.target : ''} "${String(args.content ?? '').slice(0, 30)}"`;
|
|
535
|
+
case 'memory.digest':
|
|
536
|
+
return `${args.sender_id ? 'sender=' + args.sender_id : ''}${args.task_id ? ' task=' + args.task_id : ''} len=${String(args.conversation ?? '').length}`;
|
|
537
|
+
case 'memory.brief':
|
|
538
|
+
return `${args.sender_id ? 'sender=' + args.sender_id : ''}${args.project_id ? ' project=' + args.project_id : ''}`;
|
|
539
|
+
case 'memory.forget':
|
|
540
|
+
return `mode=${args.mode} scope=${args.scope ?? 'all'}`;
|
|
541
|
+
case 'task.update':
|
|
542
|
+
return `task=${args.task_id} status=${args.status}`;
|
|
543
|
+
case 'yor.spawn':
|
|
544
|
+
return `task=${args.task_id} dir=${args.working_dir}`;
|
|
545
|
+
case 'yor.kill':
|
|
546
|
+
return `task=${args.task_id}`;
|
|
547
|
+
case 'yor.status':
|
|
548
|
+
return '';
|
|
549
|
+
case 'yor.rework':
|
|
550
|
+
return `task=${args.task_id} feedback="${String(args.feedback ?? '').slice(0, 40)}"`;
|
|
551
|
+
case 'yor.approve':
|
|
552
|
+
return `task=${args.task_id}`;
|
|
553
|
+
case 'delivery.submit':
|
|
554
|
+
return `task=${args.task_id} title="${String(args.title ?? '').slice(0, 40)}"`;
|
|
555
|
+
case 'delivery.upload':
|
|
556
|
+
return `file=${args.file_path}`;
|
|
557
|
+
case 'delivery.share':
|
|
558
|
+
return `url=${args.url}`;
|
|
559
|
+
case 'project.list':
|
|
560
|
+
return `${args.platform ? 'platform=' + args.platform : 'all'}${args.include_deleted ? ' +deleted' : ''}`;
|
|
561
|
+
case 'project.get':
|
|
562
|
+
return `id=${args.project_id}`;
|
|
563
|
+
case 'project.upsert':
|
|
564
|
+
return `id=${args.project_id} name="${String(args.name ?? '').slice(0, 30)}"`;
|
|
565
|
+
case 'project.remove':
|
|
566
|
+
return `id=${args.project_id} reason="${String(args.reason ?? '').slice(0, 40)}"`;
|
|
567
|
+
default:
|
|
568
|
+
return JSON.stringify(args).slice(0, 80);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
async function handleToolCall(toolName, args) {
|
|
572
|
+
// 检查工具是否对当前角色可用
|
|
573
|
+
const toolDef = tools.find(t => t.name === toolName);
|
|
574
|
+
if (!toolDef) {
|
|
575
|
+
return textResult(JSON.stringify({ error: `工具 ${toolName} 不可用(角色: ${role})` }));
|
|
576
|
+
}
|
|
577
|
+
const argsSummary = summarizeArgs(toolName, args);
|
|
578
|
+
logger.info(`[anya:pipeline] [MCP←${role === 'loid' ? 'Loid' : 'Yor'}] ${toolName}(${argsSummary})`);
|
|
579
|
+
try {
|
|
580
|
+
const result = await routeToolCall(toolName, args);
|
|
581
|
+
return textResult(JSON.stringify(result));
|
|
582
|
+
}
|
|
583
|
+
catch (err) {
|
|
584
|
+
logger.error(`[anya:pipeline] ${toolName} 执行失败:`, err);
|
|
585
|
+
return textResult(JSON.stringify({ error: String(err) }));
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
async function routeToolCall(toolName, args) {
|
|
589
|
+
switch (toolName) {
|
|
590
|
+
// Layer 1: 共享基础 — 记忆工具(v2)
|
|
591
|
+
case 'memory.recall': {
|
|
592
|
+
const { memoryRecall } = await import('./layer1/memory-recall.js');
|
|
593
|
+
return memoryRecall(deps.workspacePath, args);
|
|
594
|
+
}
|
|
595
|
+
case 'memory.remember': {
|
|
596
|
+
const { memoryRemember } = await import('./layer1/memory-remember.js');
|
|
597
|
+
return memoryRemember(deps.db, deps.workspacePath, args);
|
|
598
|
+
}
|
|
599
|
+
case 'memory.digest': {
|
|
600
|
+
const { memoryDigest } = await import('./layer1/memory-digest.js');
|
|
601
|
+
return memoryDigest(deps.db, deps.workspacePath, args);
|
|
602
|
+
}
|
|
603
|
+
case 'memory.brief': {
|
|
604
|
+
const { memoryBrief } = await import('./layer1/memory-brief.js');
|
|
605
|
+
return memoryBrief(deps.workspacePath, args);
|
|
606
|
+
}
|
|
607
|
+
case 'memory.forget': {
|
|
608
|
+
const { memoryForget } = await import('./layer1/memory-forget.js');
|
|
609
|
+
return memoryForget(deps.db, deps.workspacePath, args);
|
|
610
|
+
}
|
|
611
|
+
case 'org.lookup': {
|
|
612
|
+
const { orgLookup } = await import('./layer1/org-lookup.js');
|
|
613
|
+
return orgLookup(deps.db, deps.workspacePath, args);
|
|
614
|
+
}
|
|
615
|
+
case 'task.get': {
|
|
616
|
+
const { taskGet } = await import('./layer1/task-get.js');
|
|
617
|
+
return taskGet(deps.db, deps.workspacePath, args);
|
|
618
|
+
}
|
|
619
|
+
case 'audit.append': {
|
|
620
|
+
const { auditAppend } = await import('./layer1/audit-append.js');
|
|
621
|
+
return auditAppend(deps.db, deps.workspacePath, args);
|
|
622
|
+
}
|
|
623
|
+
case 'audit.query': {
|
|
624
|
+
const { auditQuery } = await import('./layer1/audit-query.js');
|
|
625
|
+
return auditQuery(deps.db, args);
|
|
626
|
+
}
|
|
627
|
+
case 'report.daily': {
|
|
628
|
+
const { reportDaily } = await import('./layer1/report-daily.js');
|
|
629
|
+
return reportDaily(deps.db, deps.workspacePath, args);
|
|
630
|
+
}
|
|
631
|
+
case 'task.update': {
|
|
632
|
+
const { taskUpdate } = await import('./layer1/task-update.js');
|
|
633
|
+
return taskUpdate(deps.db, args);
|
|
634
|
+
}
|
|
635
|
+
// Layer 1: 共享基础 — 项目工具
|
|
636
|
+
case 'project.list': {
|
|
637
|
+
const { projectList } = await import('./layer1/project-list.js');
|
|
638
|
+
return projectList(deps.db, deps.workspacePath, args);
|
|
639
|
+
}
|
|
640
|
+
case 'project.get': {
|
|
641
|
+
const { projectGet } = await import('./layer1/project-get.js');
|
|
642
|
+
return projectGet(deps.db, deps.workspacePath, args);
|
|
643
|
+
}
|
|
644
|
+
// Layer 2: Loid 专属 - 项目管理
|
|
645
|
+
case 'project.upsert': {
|
|
646
|
+
const { projectUpsert } = await import('./layer2/loid/project-upsert.js');
|
|
647
|
+
return projectUpsert(deps.db, deps.workspacePath, args);
|
|
648
|
+
}
|
|
649
|
+
case 'project.remove': {
|
|
650
|
+
const { projectRemove } = await import('./layer2/loid/project-remove.js');
|
|
651
|
+
return projectRemove(deps.db, deps.workspacePath, args);
|
|
652
|
+
}
|
|
653
|
+
// Layer 2: Loid 专属 - yor/delivery
|
|
654
|
+
case 'yor.spawn': {
|
|
655
|
+
const { yorSpawn } = await import('./layer2/loid/yor-spawn.js');
|
|
656
|
+
if (!deps.yorOrchestrator)
|
|
657
|
+
throw new Error('yorOrchestrator 未注入');
|
|
658
|
+
return yorSpawn({ yorOrchestrator: deps.yorOrchestrator, logger: deps.logger }, args);
|
|
659
|
+
}
|
|
660
|
+
case 'yor.kill': {
|
|
661
|
+
const { yorKill } = await import('./layer2/loid/yor-kill.js');
|
|
662
|
+
if (!deps.yorOrchestrator)
|
|
663
|
+
throw new Error('yorOrchestrator 未注入');
|
|
664
|
+
return yorKill({ yorOrchestrator: deps.yorOrchestrator, logger: deps.logger }, args);
|
|
665
|
+
}
|
|
666
|
+
case 'yor.status': {
|
|
667
|
+
const { yorStatus } = await import('./layer2/loid/yor-status.js');
|
|
668
|
+
if (!deps.yorOrchestrator)
|
|
669
|
+
throw new Error('yorOrchestrator 未注入');
|
|
670
|
+
return yorStatus({ yorOrchestrator: deps.yorOrchestrator, logger: deps.logger });
|
|
671
|
+
}
|
|
672
|
+
case 'yor.rework': {
|
|
673
|
+
const { yorRework } = await import('./layer2/loid/yor-rework.js');
|
|
674
|
+
if (!deps.yorOrchestrator)
|
|
675
|
+
throw new Error('yorOrchestrator 未注入');
|
|
676
|
+
return yorRework({ yorOrchestrator: deps.yorOrchestrator, logger: deps.logger }, args);
|
|
677
|
+
}
|
|
678
|
+
case 'yor.approve': {
|
|
679
|
+
const { yorApprove } = await import('./layer2/loid/yor-approve.js');
|
|
680
|
+
if (!deps.yorOrchestrator)
|
|
681
|
+
throw new Error('yorOrchestrator 未注入');
|
|
682
|
+
return yorApprove({ yorOrchestrator: deps.yorOrchestrator, logger: deps.logger }, args);
|
|
683
|
+
}
|
|
684
|
+
case 'delivery.submit': {
|
|
685
|
+
const { deliverySubmit } = await import('./layer2/loid/delivery-submit.js');
|
|
686
|
+
return deliverySubmit({
|
|
687
|
+
db: deps.db,
|
|
688
|
+
logger: deps.logger,
|
|
689
|
+
getProjectConfig: deps.getProjectConfig,
|
|
690
|
+
}, args);
|
|
691
|
+
}
|
|
692
|
+
case 'delivery.upload': {
|
|
693
|
+
const { deliveryUpload } = await import('./layer2/loid/delivery-upload.js');
|
|
694
|
+
return deliveryUpload({
|
|
695
|
+
db: deps.db,
|
|
696
|
+
uploadDir: `${deps.workspacePath}/uploads`,
|
|
697
|
+
logger: deps.logger,
|
|
698
|
+
}, args);
|
|
699
|
+
}
|
|
700
|
+
case 'delivery.share': {
|
|
701
|
+
const { deliveryShare } = await import('./layer2/loid/delivery-share.js');
|
|
702
|
+
return deliveryShare(args);
|
|
703
|
+
}
|
|
704
|
+
// Layer 2: Loid 专属
|
|
705
|
+
case 'task.dispatch': {
|
|
706
|
+
const { taskDispatch } = await import('./layer2/loid/task-dispatch.js');
|
|
707
|
+
return taskDispatch({
|
|
708
|
+
db: deps.db,
|
|
709
|
+
workspacePath: deps.workspacePath,
|
|
710
|
+
logger: deps.logger,
|
|
711
|
+
getProjectConfig: deps.getProjectConfig,
|
|
712
|
+
}, args);
|
|
713
|
+
}
|
|
714
|
+
case 'task.lookup': {
|
|
715
|
+
const { taskLookup } = await import('./layer2/loid/task-lookup.js');
|
|
716
|
+
return taskLookup(deps.db, args);
|
|
717
|
+
}
|
|
718
|
+
case 'decision.log': {
|
|
719
|
+
const { decisionLog } = await import('./layer2/loid/decision-log.js');
|
|
720
|
+
return decisionLog(deps.db, args);
|
|
721
|
+
}
|
|
722
|
+
// Layer 2: Yor 专属 - 任务状态
|
|
723
|
+
case 'task.deliver': {
|
|
724
|
+
const { taskDeliver } = await import('./layer2/yor/task-deliver.js');
|
|
725
|
+
if (!deps.yorCollector)
|
|
726
|
+
throw new Error('yorCollector 未注入');
|
|
727
|
+
// 获取任务工作目录,用于 git 状态检查
|
|
728
|
+
let workingDir;
|
|
729
|
+
if (deps.currentTaskId) {
|
|
730
|
+
const { getTask } = await import('@team-anya/db');
|
|
731
|
+
const task = getTask(deps.db, deps.currentTaskId);
|
|
732
|
+
workingDir = task?.workspace_path ?? undefined;
|
|
733
|
+
}
|
|
734
|
+
return taskDeliver(deps.yorCollector, args, workingDir);
|
|
735
|
+
}
|
|
736
|
+
case 'task.block': {
|
|
737
|
+
const { taskBlock } = await import('./layer2/yor/task-block.js');
|
|
738
|
+
if (!deps.yorCollector)
|
|
739
|
+
throw new Error('yorCollector 未注入');
|
|
740
|
+
return taskBlock(deps.yorCollector, args);
|
|
741
|
+
}
|
|
742
|
+
case 'task.progress': {
|
|
743
|
+
const { taskProgress } = await import('./layer2/yor/task-progress.js');
|
|
744
|
+
return taskProgress(deps.db, deps.currentTaskId ?? '', args);
|
|
745
|
+
}
|
|
746
|
+
// Layer 3: 外部桥梁
|
|
747
|
+
case 'channel.send': {
|
|
748
|
+
const { channelSend } = await import('./layer3/channel-send.js');
|
|
749
|
+
if (!deps.channelRegistry)
|
|
750
|
+
throw new Error('channelRegistry 未注入');
|
|
751
|
+
return channelSend({
|
|
752
|
+
db: deps.db,
|
|
753
|
+
channelRegistry: deps.channelRegistry,
|
|
754
|
+
logger: deps.logger,
|
|
755
|
+
onMessageSent: deps.onMessageSent,
|
|
756
|
+
}, args);
|
|
757
|
+
}
|
|
758
|
+
case 'file.upload': {
|
|
759
|
+
const { fileUpload } = await import('./layer3/file-upload.js');
|
|
760
|
+
return fileUpload({
|
|
761
|
+
db: deps.db,
|
|
762
|
+
uploadDir: `${deps.workspacePath}/uploads`,
|
|
763
|
+
logger: deps.logger,
|
|
764
|
+
}, args);
|
|
765
|
+
}
|
|
766
|
+
case 'channel.receive': {
|
|
767
|
+
const { channelReceive } = await import('./layer3/channel-receive.js');
|
|
768
|
+
return channelReceive(args);
|
|
769
|
+
}
|
|
770
|
+
default:
|
|
771
|
+
throw new Error(`未知工具: ${toolName}`);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
return {
|
|
775
|
+
tools,
|
|
776
|
+
handleToolCall,
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
//# sourceMappingURL=registry.js.map
|