evolcore 0.0.31 → 0.0.33
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/CHANGELOG.md +35 -0
- package/bin/install-codex-managed-hooks.mjs +124 -37
- package/dist/agents/claude-runner.js +29 -2
- package/dist/agents/codex/app-server-client.js +3 -0
- package/dist/agents/codex/diagnostics.js +76 -44
- package/dist/agents/codex-runner.js +51 -24
- package/dist/agents/ecagent-runner.js +9 -13
- package/dist/agents/gemini-runner.js +4 -0
- package/dist/aun/aid/store.js +0 -81
- package/dist/aun/group/fs-download.js +1 -10
- package/dist/aun/group/operations.js +0 -1
- package/dist/aun/msg/history.js +1 -0
- package/dist/aun/msg/managed-operation.js +130 -32
- package/dist/aun/msg/p2p.js +0 -1
- package/dist/aun/outbox.js +50 -1
- package/dist/aun/service-proxy.js +12 -18
- package/dist/aun/storage/index.js +29 -0
- package/dist/channels/aun.js +38 -137
- package/dist/channels/daemon.js +257 -2
- package/dist/cli/agent-command.js +64 -31
- package/dist/cli/agent-create.js +43 -24
- package/dist/cli/agent.js +16 -70
- package/dist/cli/aun-commands.js +512 -32
- package/dist/cli/contact.js +8 -2
- package/dist/cli/ctl-command.js +1 -2
- package/dist/cli/daemon-commands.js +82 -13
- package/dist/cli/debug-mode.js +154 -0
- package/dist/cli/diag.js +2 -2
- package/dist/cli/handoff-command.js +18 -5
- package/dist/cli/index.js +81 -64
- package/dist/cli/init.js +2 -2
- package/dist/cli/managed-command-guard.js +5 -0
- package/dist/cli/memory-command.js +93 -12
- package/dist/cli/model.js +14 -138
- package/dist/cli/queue-command.js +51 -0
- package/dist/cli/response.js +5 -54
- package/dist/cli/session-command.js +194 -0
- package/dist/cli/skill-command.js +85 -3
- package/dist/cli/stats.js +10 -4
- package/dist/cli/task-command.js +1 -0
- package/dist/cli/task-context.js +16 -0
- package/dist/cli/thread-command.js +620 -0
- package/dist/cli/trigger-command.js +76 -50
- package/dist/config/builtin-roles.js +9 -7
- package/dist/config/config-field-policy.js +2 -3
- package/dist/config/config-manager.js +7 -2
- package/dist/config/resolved-config-op.js +3 -0
- package/dist/config-store.js +15 -0
- package/dist/core/agent-ipc-registration.js +65 -22
- package/dist/core/auth/agent-delegation.js +42 -2
- package/dist/core/auth/debug-context.js +139 -0
- package/dist/core/auth/delegation-authorization.js +1 -0
- package/dist/core/auth/operation-authorizer.js +24 -1
- package/dist/core/auth/operation-catalog.js +44 -3
- package/dist/core/background-session/session-cleanup.js +212 -0
- package/dist/core/background-session/types.js +10 -0
- package/dist/core/bootstrap-messages.js +1 -1
- package/dist/core/bootstrap-service.js +6 -3
- package/dist/core/command/command-handler.js +224 -45
- package/dist/core/command/diag-service.js +5 -1
- package/dist/core/command/memory-slash.js +6 -2
- package/dist/core/command/menu-catalog.js +48 -1
- package/dist/core/command/menu-handler.js +92 -16
- package/dist/core/command/menu-protocol.js +24 -1
- package/dist/core/command/skill-slash.js +322 -0
- package/dist/core/command/slash-gate.js +6 -4
- package/dist/core/command/slash-handler.js +193 -13
- package/dist/core/command/topic-slash.js +528 -0
- package/dist/core/evolagent-registry.js +20 -5
- package/dist/core/handoff/ipc-registration.js +38 -0
- package/dist/core/handoff/runtime.js +5 -11
- package/dist/core/handoff/store.js +5 -0
- package/dist/core/ipc-registration.js +210 -9
- package/dist/core/memory/consolidation-context.js +49 -16
- package/dist/core/memory/consolidation-ops-records.js +35 -0
- package/dist/core/memory/consolidation-queue-format.js +21 -0
- package/dist/core/memory/consolidation.js +174 -180
- package/dist/core/message/aun-ipc-sender.js +207 -8
- package/dist/core/message/im-renderer.js +149 -6
- package/dist/core/message/message-bridge.js +13 -3
- package/dist/core/message/message-log.js +1 -0
- package/dist/core/message/message-queue.js +131 -3
- package/dist/core/message/peer-mode.js +6 -1
- package/dist/core/message/response-engine.js +379 -69
- package/dist/core/message/subtask-tool-projection.js +140 -0
- package/dist/core/model/catalog-service.js +17 -12
- package/dist/core/permission/ec-command-parser.js +126 -7
- package/dist/core/permission/sandbox-runtime.js +14 -1
- package/dist/core/session/session-idle-monitor.js +249 -22
- package/dist/core/session/session-manager.js +54 -9
- package/dist/core/skill/command-parser.js +13 -0
- package/dist/core/skill/index-generator.js +4 -1
- package/dist/core/skill/startup.js +41 -0
- package/dist/core/skill/switch-resolver.js +55 -29
- package/dist/core/task/task-recovery-service.js +2 -0
- package/dist/core/task/task-resume-operation.js +11 -0
- package/dist/core/thread/command-parser.js +125 -0
- package/dist/core/thread/index.js +1 -0
- package/dist/core/thread/ipc-operation.js +95 -0
- package/dist/core/thread/thread-context-storage.js +131 -0
- package/dist/core/thread/thread-operation.js +258 -0
- package/dist/core/thread/thread-route.js +33 -0
- package/dist/core/thread/thread-service.js +777 -0
- package/dist/core/thread/types.js +1 -0
- package/dist/eck/message-renderer.js +35 -0
- package/dist/index.js +10 -7
- package/dist/ipc.js +234 -17
- package/dist/paths.js +23 -0
- package/dist/response-system/engines/v1/proactive-flow.js +169 -80
- package/dist/trigger/authorization.js +59 -29
- package/dist/trigger/feedback.js +7 -1
- package/dist/trigger/ipc-service.js +49 -35
- package/dist/trigger/parser.js +63 -1
- package/dist/trigger/script-sandbox.js +58 -77
- package/dist/trigger/validation.js +14 -0
- package/dist/utils/error-utils.js +22 -1
- package/kits/docs/AUTHORING.md +1 -1
- package/kits/docs/channels/aun.md +8 -0
- package/kits/docs/context-assembly.md +1 -0
- package/kits/docs/evolcore/INDEX.md +3 -2
- package/kits/docs/evolcore/agent-create.md +39 -28
- package/kits/docs/evolcore/agent.md +19 -4
- package/kits/docs/evolcore/ec-capabilities.md +4 -0
- package/kits/docs/evolcore/group-collaboration.md +3 -5
- package/kits/docs/evolcore/group.md +3 -4
- package/kits/docs/evolcore/memory-consolidation.md +1 -1
- package/kits/docs/evolcore/menu-exec-schema-commands.md +2 -2
- package/kits/docs/evolcore/menu-protocol.md +7 -0
- package/kits/docs/evolcore/msg.md +5 -8
- package/kits/docs/evolcore/task.md +2 -0
- package/kits/docs/evolcore/thread-chain.md +267 -0
- package/kits/docs/evolcore/trigger.md +2 -2
- package/kits/docs/prompt-loading-architecture.md +1 -0
- package/kits/eck_manifest.json +61 -26
- package/kits/eck_message_manifest.json +169 -10
- package/kits/rules/01-overview.md +0 -9
- package/kits/rules/05-venue.md +1 -1
- package/kits/rules/06-channel.md +7 -1
- package/kits/rules/07-memory-and-thread.md +202 -0
- package/kits/schemas/relation-config.schema.9.json +18 -3
- package/kits/schemas/role-config.schema.1.json +6 -6
- package/kits/schemas/single-session.schema.1.json +6 -6
- package/kits/schemas/single-session.schema.2.json +6 -6
- package/kits/schemas/single-session.schema.3.json +6 -6
- package/kits/skills/.switches.json +12 -1
- package/kits/skills/ec-group/SKILL.md +234 -0
- package/kits/skills/ec-skill/SKILL.md +10 -1
- package/kits/skills/ec-skill/scripts/cli.mjs +15 -1
- package/kits/skills/scrapling-article-fetch/SKILL.md +128 -0
- package/kits/skills/scrapling-article-fetch/scripts/check_python_env.py +54 -0
- package/kits/skills/scrapling-article-fetch/scripts/render_markdown_reply.py +35 -0
- package/kits/skills/scrapling-article-fetch/scripts/run_pipeline.sh +16 -0
- package/kits/skills/scrapling-article-fetch/scripts/scrapling_fetch.py +344 -0
- package/kits/skills/thread-ops/SKILL.md +492 -0
- package/kits/skills/wechat-article-media-download/SKILL.md +65 -0
- package/kits/skills/wechat-article-media-download/scripts/download.py +163 -0
- package/kits/skills/wechat-article-reader/SKILL.md +97 -0
- package/kits/skills/wechat-article-reader/scripts/fetch.mjs +256 -0
- package/kits/templates/bootstrap-welcome.md +7 -7
- package/kits/templates/memory-consolidation/forget.md +5 -0
- package/kits/templates/memory-consolidation/generalize.md +5 -0
- package/kits/templates/memory-consolidation/profile.md +5 -0
- package/kits/templates/memory-consolidation/promote.md +5 -0
- package/kits/templates/message-fragments/item.md +2 -1
- package/kits/templates/message-fragments/thread-context.md +6 -0
- package/kits/templates/message-fragments/trigger-session.md +2 -0
- package/kits/templates/message-fragments/trigger-thread-check.md +2 -0
- package/kits/templates/roles/member.json +2 -0
- package/kits/templates/roles/visitor.json +2 -0
- package/kits/templates/system-fragments/bootstrap.md +66 -72
- package/kits/templates/system-fragments/channel.md +3 -6
- package/kits/templates/system-fragments/commands.md +2 -1
- package/kits/templates/system-fragments/managed-runtime.md +15 -0
- package/kits/templates/system-fragments/reply.md +3 -2
- package/kits/templates/system-fragments/session.md +5 -14
- package/package.json +3 -1
- package/kits/docs/evolcore/group-fs.md +0 -17
- package/kits/docs/venues/aun-group.md +0 -45
- package/kits/docs/venues/group.md +0 -43
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { normalizeThreadPeer } from './thread-service.js';
|
|
2
|
+
export function executeThreadOperation(request, threadService, sendSystemMsg) {
|
|
3
|
+
return _executeThreadOperation(request, threadService, sendSystemMsg);
|
|
4
|
+
}
|
|
5
|
+
async function _executeThreadOperation(request, threadService, sendSystemMsg) {
|
|
6
|
+
const op = String(request.op);
|
|
7
|
+
const selfAid = typeof request.selfAid === 'string' ? request.selfAid : '';
|
|
8
|
+
if (!selfAid)
|
|
9
|
+
return { ok: false, code: 'MISSING_SELF_AID', error: 'selfAid is required' };
|
|
10
|
+
// 入口归一:调用方可能传入裸 ID 或带渠道前缀的写法,统一成索引里存储的形态。
|
|
11
|
+
// 归一失败(解析不出)时保留原值,由下游按"无此对端"处理,不改变 arg 缺失的语义。
|
|
12
|
+
request = { ...request, peer: normalizeThreadPeer(request.peer) ?? request.peer };
|
|
13
|
+
try {
|
|
14
|
+
switch (op) {
|
|
15
|
+
case 'list': {
|
|
16
|
+
const result = threadService.listThreads({
|
|
17
|
+
selfAid,
|
|
18
|
+
peer: request.peer,
|
|
19
|
+
status: request.status,
|
|
20
|
+
label: request.label ?? undefined,
|
|
21
|
+
unlabeled: request.unlabeled,
|
|
22
|
+
sort: request.sort,
|
|
23
|
+
page: request.page,
|
|
24
|
+
limit: request.limit,
|
|
25
|
+
});
|
|
26
|
+
const threads = result.threads.map(t => ({
|
|
27
|
+
...t,
|
|
28
|
+
running: false,
|
|
29
|
+
peerName: t.peerName ?? t.peer,
|
|
30
|
+
}));
|
|
31
|
+
return { ok: true, result: { ...result, threads } };
|
|
32
|
+
}
|
|
33
|
+
case 'list-peers': {
|
|
34
|
+
const peers = threadService.listPeers(selfAid);
|
|
35
|
+
return { ok: true, result: { peers } };
|
|
36
|
+
}
|
|
37
|
+
case 'show': {
|
|
38
|
+
let peer = request.peer;
|
|
39
|
+
let threadId = request.threadId;
|
|
40
|
+
if ((!peer || !threadId) && request.sessionId) {
|
|
41
|
+
const resolved = threadService.resolveCurrentThread(selfAid, request.sessionId);
|
|
42
|
+
if (resolved) {
|
|
43
|
+
peer = resolved.peer;
|
|
44
|
+
threadId = resolved.threadId;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (!peer)
|
|
48
|
+
return { ok: false, code: 'MISSING_ARGS', error: 'peer is required' };
|
|
49
|
+
// peer-only ref (no threadId) → show main session
|
|
50
|
+
if (!threadId) {
|
|
51
|
+
const result = await threadService.showMainSession(selfAid, peer);
|
|
52
|
+
if (!result)
|
|
53
|
+
return { ok: false, code: 'NOT_FOUND', error: `与 ${peer} 无活跃主会话` };
|
|
54
|
+
return { ok: true, result };
|
|
55
|
+
}
|
|
56
|
+
const result = await threadService.showThread({ selfAid, peer, threadId });
|
|
57
|
+
// 索引健康检查:检测 session 文件是否存在
|
|
58
|
+
const indexWarning = result._indexWarning;
|
|
59
|
+
const resp = { ok: true, result };
|
|
60
|
+
if (indexWarning)
|
|
61
|
+
resp.indexWarning = indexWarning;
|
|
62
|
+
return resp;
|
|
63
|
+
}
|
|
64
|
+
case 'check-index': {
|
|
65
|
+
const result = threadService.checkIndex(selfAid);
|
|
66
|
+
let warning;
|
|
67
|
+
if (result.missing > 0 && result.stale > 0) {
|
|
68
|
+
warning = `索引异常:${result.missing} 条 session 文件缺失(数据问题),${result.stale} 条属性与文件不一致(写盘时序)`;
|
|
69
|
+
}
|
|
70
|
+
else if (result.missing > 0) {
|
|
71
|
+
warning = `索引异常:${result.missing} 条 session 文件缺失,rebuild-index 后相关话题的 rename/label/status 改动将回退`;
|
|
72
|
+
}
|
|
73
|
+
else if (result.stale > 0) {
|
|
74
|
+
warning = `索引轻微不一致:${result.stale} 条话题属性(name/label/status)与 session 文件最后一行不同步,rebuild-index 可修复`;
|
|
75
|
+
}
|
|
76
|
+
return { ok: true, result, indexWarning: warning };
|
|
77
|
+
}
|
|
78
|
+
case 'history': {
|
|
79
|
+
let peer = request.peer;
|
|
80
|
+
let threadId = request.threadId;
|
|
81
|
+
if (!peer && request.sessionId) {
|
|
82
|
+
const resolved = threadService.resolveCurrentThread(selfAid, request.sessionId);
|
|
83
|
+
if (resolved) {
|
|
84
|
+
peer = resolved.peer;
|
|
85
|
+
threadId = resolved.threadId;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// threadId 可选:不传时读主会话(threadId=null)消息
|
|
89
|
+
if (!peer)
|
|
90
|
+
return { ok: false, code: 'MISSING_ARGS', error: 'peer is required' };
|
|
91
|
+
const result = await threadService.historyThread({
|
|
92
|
+
selfAid,
|
|
93
|
+
peer,
|
|
94
|
+
threadId,
|
|
95
|
+
limit: request.limit,
|
|
96
|
+
before: request.before,
|
|
97
|
+
after: request.after,
|
|
98
|
+
direction: request.direction,
|
|
99
|
+
});
|
|
100
|
+
return { ok: true, result };
|
|
101
|
+
}
|
|
102
|
+
case 'create': {
|
|
103
|
+
if (!request.peer || !request.name)
|
|
104
|
+
return { ok: false, code: 'MISSING_ARGS', error: 'peer and name required' };
|
|
105
|
+
const result = await threadService.createThread({
|
|
106
|
+
selfAid,
|
|
107
|
+
peer: request.peer,
|
|
108
|
+
peerKind: request.peerKind ?? 'private',
|
|
109
|
+
name: request.name,
|
|
110
|
+
label: request.label ?? undefined,
|
|
111
|
+
topicStatus: request.topicStatus,
|
|
112
|
+
});
|
|
113
|
+
if (sendSystemMsg) {
|
|
114
|
+
try {
|
|
115
|
+
await sendSystemMsg({
|
|
116
|
+
from: selfAid,
|
|
117
|
+
to: request.peer,
|
|
118
|
+
threadId: result.threadId,
|
|
119
|
+
topicName: result.name,
|
|
120
|
+
peerKind: request.peerKind ?? 'private',
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// 系统消息发送失败不影响本地创建
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return { ok: true, result };
|
|
128
|
+
}
|
|
129
|
+
case 'rename': {
|
|
130
|
+
let peer = request.peer;
|
|
131
|
+
let threadId = request.threadId;
|
|
132
|
+
if ((!peer || !threadId) && request.sessionId) {
|
|
133
|
+
const resolved = threadService.resolveCurrentThread(selfAid, request.sessionId);
|
|
134
|
+
if (resolved) {
|
|
135
|
+
peer = resolved.peer;
|
|
136
|
+
threadId = resolved.threadId;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (!peer || !threadId || !request.name)
|
|
140
|
+
return { ok: false, code: 'MISSING_ARGS', error: 'peer, threadId and name required' };
|
|
141
|
+
const result = await threadService.renameThread({ selfAid, peer, threadId, name: request.name });
|
|
142
|
+
return { ok: true, result };
|
|
143
|
+
}
|
|
144
|
+
case 'label': {
|
|
145
|
+
let peer = request.peer;
|
|
146
|
+
let threadId = request.threadId;
|
|
147
|
+
if ((!peer || !threadId) && request.sessionId) {
|
|
148
|
+
const resolved = threadService.resolveCurrentThread(selfAid, request.sessionId);
|
|
149
|
+
if (resolved) {
|
|
150
|
+
peer = resolved.peer;
|
|
151
|
+
threadId = resolved.threadId;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (!peer || !threadId)
|
|
155
|
+
return { ok: false, code: 'MISSING_ARGS', error: 'peer and threadId required' };
|
|
156
|
+
await threadService.labelThread({ selfAid, peer, threadId, label: request.label ?? null });
|
|
157
|
+
return { ok: true };
|
|
158
|
+
}
|
|
159
|
+
case 'status': {
|
|
160
|
+
let peer = request.peer;
|
|
161
|
+
let threadId = request.threadId;
|
|
162
|
+
if ((!peer || !threadId) && request.sessionId) {
|
|
163
|
+
const resolved = threadService.resolveCurrentThread(selfAid, request.sessionId);
|
|
164
|
+
if (resolved) {
|
|
165
|
+
peer = resolved.peer;
|
|
166
|
+
threadId = resolved.threadId;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (!peer || !threadId || !request.topicStatus)
|
|
170
|
+
return { ok: false, code: 'MISSING_ARGS', error: 'peer, threadId and topicStatus required' };
|
|
171
|
+
await threadService.statusThread({ selfAid, peer, threadId, topicStatus: request.topicStatus });
|
|
172
|
+
return { ok: true };
|
|
173
|
+
}
|
|
174
|
+
case 'rebuild-index': {
|
|
175
|
+
const dryRun = request.dryRun === true;
|
|
176
|
+
const result = await threadService.rebuildIndex(selfAid, dryRun);
|
|
177
|
+
if (dryRun) {
|
|
178
|
+
const { rebuilt } = result;
|
|
179
|
+
const check = threadService.checkIndex(selfAid);
|
|
180
|
+
return { ok: true, result: { rebuilt, missing: check.missing, missingIds: check.missingIds, dryRun: true } };
|
|
181
|
+
}
|
|
182
|
+
return { ok: true, result };
|
|
183
|
+
}
|
|
184
|
+
case 'delete': {
|
|
185
|
+
let peer = request.peer;
|
|
186
|
+
let threadId = request.threadId;
|
|
187
|
+
if ((!peer || !threadId) && request.sessionId) {
|
|
188
|
+
const resolved = threadService.resolveCurrentThread(selfAid, request.sessionId);
|
|
189
|
+
if (resolved) {
|
|
190
|
+
peer = resolved.peer;
|
|
191
|
+
threadId = resolved.threadId;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (!peer || !threadId)
|
|
195
|
+
return { ok: false, code: 'MISSING_ARGS', error: 'peer and threadId required' };
|
|
196
|
+
await threadService.deleteThread(selfAid, peer, threadId);
|
|
197
|
+
return { ok: true };
|
|
198
|
+
}
|
|
199
|
+
case 'summary-show': {
|
|
200
|
+
if (!request.sessionId)
|
|
201
|
+
return { ok: false, code: 'MISSING_ARGS', error: 'sessionId required' };
|
|
202
|
+
const result = threadService.showSummary(selfAid, request.sessionId);
|
|
203
|
+
return { ok: true, result: result ?? null };
|
|
204
|
+
}
|
|
205
|
+
case 'summary-set': {
|
|
206
|
+
if (!request.sessionId || !request.content)
|
|
207
|
+
return { ok: false, code: 'MISSING_ARGS', error: 'sessionId and content required' };
|
|
208
|
+
// 覆盖游标由 service 自动记录(写入时刻话题最后一条消息的 ts),调用方不用传。
|
|
209
|
+
const result = threadService.setSummary(selfAid, request.sessionId, request.content, request.ifRev);
|
|
210
|
+
// 顺带改名:总结时往往正好把话题主题想清楚了,一次命令写完更省事。
|
|
211
|
+
// 调用方(CLI / slash)保证 name 一定存在;`-` 表示"保持原标题不改"。
|
|
212
|
+
// 主会话没有话题名可改(threadId 为空),忽略该参数而不是报错。
|
|
213
|
+
const rawName = typeof request.name === 'string' ? request.name.trim() : '';
|
|
214
|
+
let name = rawName && rawName !== '-' ? rawName : undefined;
|
|
215
|
+
let threadId = request.threadId;
|
|
216
|
+
if (name && !threadId) {
|
|
217
|
+
const resolved = threadService.resolveCurrentThread(selfAid, request.sessionId);
|
|
218
|
+
threadId = resolved?.threadId;
|
|
219
|
+
}
|
|
220
|
+
let peer = request.peer;
|
|
221
|
+
if (name && threadId && !peer) {
|
|
222
|
+
peer = threadService.readThreadIndex(selfAid).threads.find(t => t.threadId === threadId)?.peer;
|
|
223
|
+
}
|
|
224
|
+
if (name && threadId && peer) {
|
|
225
|
+
try {
|
|
226
|
+
const renamed = await threadService.renameThread({ selfAid, peer, threadId, name });
|
|
227
|
+
return { ok: true, result: { ...result, renamedTo: renamed.name, renamedChanged: renamed.changed } };
|
|
228
|
+
}
|
|
229
|
+
catch (e) {
|
|
230
|
+
// 摘要已写入,改名失败不回滚——如实返回,让调用方知道只有改名这步没成
|
|
231
|
+
return {
|
|
232
|
+
ok: true,
|
|
233
|
+
result: { ...result, renameError: e?.message ?? String(e) },
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return { ok: true, result };
|
|
238
|
+
}
|
|
239
|
+
case 'summary-log': {
|
|
240
|
+
if (!request.sessionId)
|
|
241
|
+
return { ok: false, code: 'MISSING_ARGS', error: 'sessionId required' };
|
|
242
|
+
const result = threadService.logSummary(selfAid, request.sessionId);
|
|
243
|
+
return { ok: true, result };
|
|
244
|
+
}
|
|
245
|
+
case 'summary-clear': {
|
|
246
|
+
if (!request.sessionId)
|
|
247
|
+
return { ok: false, code: 'MISSING_ARGS', error: 'sessionId required' };
|
|
248
|
+
threadService.clearSummary(selfAid, request.sessionId);
|
|
249
|
+
return { ok: true };
|
|
250
|
+
}
|
|
251
|
+
default:
|
|
252
|
+
return { ok: false, code: 'UNKNOWN_OP', error: `Unknown op: ${op}` };
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
return { ok: false, code: error.code ?? 'ERROR', error: error.message ?? String(error) };
|
|
257
|
+
}
|
|
258
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { sameGroupAid } from '../../aun/group/identity.js';
|
|
2
|
+
import { ThreadService } from './thread-service.js';
|
|
3
|
+
/**
|
|
4
|
+
* 解析 `--thread` 跨话题发送的目标话题。
|
|
5
|
+
*
|
|
6
|
+
* 话题必须存在于发送方本端索引、属于 AUN 渠道、peerKind 与发送 scope 一致;
|
|
7
|
+
* 给出 target 时还必须与话题 peer 相同(群按群 AID 规范化比较)。
|
|
8
|
+
* 返回 undefined 表示该 thread 不能作为跨话题路由依据。
|
|
9
|
+
*/
|
|
10
|
+
export function resolveThreadRouteTarget(selfAid, threadId, scope, target) {
|
|
11
|
+
if (!selfAid || !threadId)
|
|
12
|
+
return undefined;
|
|
13
|
+
let entry;
|
|
14
|
+
try {
|
|
15
|
+
entry = ThreadService.findThreadById(selfAid.replace(/^@/, ''), threadId);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
if (!entry)
|
|
21
|
+
return undefined;
|
|
22
|
+
if ((entry.channelType ?? 'aun') !== 'aun')
|
|
23
|
+
return undefined;
|
|
24
|
+
if (entry.peerKind !== (scope === 'group' ? 'group' : 'private'))
|
|
25
|
+
return undefined;
|
|
26
|
+
if (target === undefined)
|
|
27
|
+
return entry;
|
|
28
|
+
const normalizedTarget = target.replace(/^@/, '');
|
|
29
|
+
const matches = scope === 'group'
|
|
30
|
+
? sameGroupAid(entry.peer, normalizedTarget)
|
|
31
|
+
: entry.peer === normalizedTarget;
|
|
32
|
+
return matches ? entry : undefined;
|
|
33
|
+
}
|