evolcore 0.0.33 → 0.0.35-test.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/CHANGELOG.md +59 -0
- package/bin/ec.js +3 -2
- package/bin/install-codex-managed-hooks.mjs +38 -4
- package/dist/agents/baseagent-availability.js +20 -36
- package/dist/agents/claude-runner.js +93 -14
- package/dist/agents/codex/diagnostics.js +79 -22
- package/dist/agents/codex-runner.js +245 -47
- package/dist/agents/ecagent-runner.js +90 -27
- package/dist/agents/runner-types.js +5 -6
- package/dist/aun/aid/agentmd.js +13 -2
- package/dist/aun/aid/client.js +1 -1
- package/dist/aun/aid/identity.js +1 -1
- package/dist/aun/msg/managed-operation.js +16 -0
- package/dist/aun/msg/p2p.js +18 -2
- package/dist/channels/aun.js +123 -7
- package/dist/channels/daemon.js +6 -3
- package/dist/cli/aun-commands.js +39 -14
- package/dist/cli/ctl-command.js +3 -1
- package/dist/cli/daemon-commands.js +130 -23
- package/dist/cli/fs-command.js +2 -1
- package/dist/cli/getmeta-command.js +211 -0
- package/dist/cli/index.js +26 -6
- package/dist/cli/integrity-command.js +196 -0
- package/dist/cli/managed-command-guard.js +3 -0
- package/dist/cli/memory-command.js +200 -156
- package/dist/cli/thread-command.js +17 -7
- package/dist/cli/trigger-command.js +6 -1
- package/dist/config/config-field-policy.js +4 -0
- package/dist/config/config-manager.js +19 -0
- package/dist/config/contact-book-store.js +5 -0
- package/dist/config/resolved-config-op.js +25 -8
- package/dist/config/role-service.js +13 -0
- package/dist/config/runtime-env.js +16 -0
- package/dist/config-store.js +30 -0
- package/dist/core/audit/log-integrity.js +3 -1
- package/dist/core/auth/agent-delegation.js +108 -35
- package/dist/core/auth/delegation-diagnostics.js +414 -0
- package/dist/core/auth/operation-authorizer.js +22 -3
- package/dist/core/auth/operation-catalog.js +16 -0
- package/dist/core/channel-runtime.js +1 -1
- package/dist/core/command/agent-control.js +18 -26
- package/dist/core/command/command-handler.js +145 -5
- package/dist/core/command/daemon-diagnostics.js +1 -0
- package/dist/core/command/menu-catalog.js +3 -0
- package/dist/core/command/menu-handler.js +24 -7
- package/dist/core/command/menu-protocol.js +1 -0
- package/dist/core/command/slash-handler.js +2 -0
- package/dist/core/command/topic-slash.js +4 -7
- package/dist/core/daemon-bootstrap.js +4 -7
- package/dist/core/event-catalog.js +14 -0
- package/dist/core/file-integrity/read.js +61 -0
- package/dist/core/file-integrity/store.js +262 -0
- package/dist/core/ipc-registration.js +47 -2
- package/dist/core/memory/batch-meta.js +133 -0
- package/dist/core/memory/consolidation-context.js +132 -28
- package/dist/core/memory/consolidation-ops-records.js +14 -16
- package/dist/core/memory/consolidation-trigger.js +15 -7
- package/dist/core/memory/consolidation.js +146 -26
- package/dist/core/memory/index-manager.js +19 -28
- package/dist/core/memory/memory-admin.js +19 -14
- package/dist/core/memory/memory-document.js +53 -9
- package/dist/core/memory/memory-writer.js +50 -19
- package/dist/core/message/aun-ipc-sender.js +19 -1
- package/dist/core/message/im-renderer.js +20 -4
- package/dist/core/message/message-bridge.js +5 -4
- package/dist/core/message/message-log.js +1 -0
- package/dist/core/message/peer-mode.js +17 -0
- package/dist/core/message/response-engine.js +598 -50
- package/dist/core/permission/ec-command-parser.js +169 -44
- package/dist/core/permission/protected-paths.js +5 -1
- package/dist/core/permission/readonly-shell-query.js +43 -5
- package/dist/core/permission/session-path-grants.js +334 -0
- package/dist/core/permission/tool-canonical.js +226 -0
- package/dist/core/permission/tool-policy.js +60 -62
- package/dist/core/relation/peer-identity.js +87 -12
- package/dist/core/role/runtime-policy.js +21 -10
- package/dist/core/session/session-fs-store.js +123 -8
- package/dist/core/session/session-manager.js +131 -6
- package/dist/core/session/session-title.js +26 -1
- package/dist/core/skill/index-generator.js +17 -3
- package/dist/core/system-session/grants.js +40 -0
- package/dist/core/system-session/memory.js +289 -0
- package/dist/core/system-session/registry.js +74 -0
- package/dist/core/system-session/types.js +14 -0
- package/dist/core/thread/command-parser.js +6 -1
- package/dist/core/thread/ipc-operation.js +33 -16
- package/dist/core/thread/thread-operation.js +62 -24
- package/dist/core/thread/thread-service.js +258 -51
- package/dist/eck/kit-renderer.js +7 -2
- package/dist/eck/manifest-engine.js +24 -4
- package/dist/index.js +11 -2
- package/dist/ipc.js +51 -40
- package/dist/paths.js +70 -0
- package/dist/stats/billing.js +20 -8
- package/dist/trigger/feedback.js +6 -1
- package/dist/trigger/parser.js +8 -1
- package/dist/trigger/system-definitions.js +3 -3
- package/dist/utils/cross-platform.js +17 -5
- package/dist/utils/error-dict.json +18 -4
- package/dist/utils/error-utils.js +121 -0
- package/dist/utils/instance-registry.js +13 -8
- package/dist/utils/log-writer.js +12 -0
- package/dist/utils/process-introspect.js +11 -0
- package/kits/docs/context-assembly.md +0 -1
- package/kits/docs/evolcore/agent-create.md +5 -4
- package/kits/docs/evolcore/agent.md +2 -2
- package/kits/docs/evolcore/config.md +2 -2
- package/kits/docs/evolcore/ctl.md +2 -2
- package/kits/docs/evolcore/ec-capabilities.md +1 -1
- package/kits/docs/evolcore/fs-architecture.md +9 -10
- package/kits/docs/evolcore/fs.md +2 -2
- package/kits/docs/evolcore/group-collaboration.md +3 -3
- package/kits/docs/evolcore/group.md +14 -12
- package/kits/docs/evolcore/memory-architecture.md +4 -5
- package/kits/docs/evolcore/memory-consolidation.md +19 -16
- package/kits/docs/evolcore/memory-tags.md +3 -1
- package/kits/docs/evolcore/memory.md +24 -12
- package/kits/docs/evolcore/model.md +16 -0
- package/kits/docs/evolcore/msg.md +7 -7
- package/kits/docs/evolcore/stats.md +1 -1
- package/kits/docs/evolcore/thread-chain.md +30 -14
- package/kits/docs/prompt-loading-architecture.md +0 -1
- package/kits/eck_manifest.auxiliary.json +9 -0
- package/kits/eck_manifest.json +20 -20
- package/kits/eck_manifest.memory.json +20 -12
- package/kits/rules/01-overview.md +11 -0
- package/kits/rules/03-identity.md +6 -3
- package/kits/rules/06-channel.md +1 -1
- package/kits/rules/07-memory-and-thread.md +13 -16
- package/kits/schemas/_meta.json +7 -1
- package/kits/schemas/agent-config.schema.13.json +1 -1
- package/kits/schemas/daemon.schema.7.json +140 -0
- package/kits/skills/ec-group/SKILL.md +8 -5
- package/kits/skills/ec-skill/scripts/cli.mjs +1 -1
- package/kits/skills/ec-skill/scripts/skill.mjs +1 -1
- package/kits/skills/thread-ops/SKILL.md +18 -18
- package/kits/templates/memory-consolidation/forget.md +2 -2
- package/kits/templates/memory-consolidation/generalize.md +4 -4
- package/kits/templates/memory-consolidation/notes.md +12 -12
- package/kits/templates/memory-consolidation/profile.md +3 -3
- package/kits/templates/memory-consolidation/promote.md +3 -3
- package/kits/templates/memory-consolidation/workflow.md +42 -7
- package/kits/templates/message-fragments/handoff-request-to-target.md +1 -1
- package/kits/templates/system-fragments/bash-description.md +9 -0
- package/kits/templates/system-fragments/bootstrap.md +4 -3
- package/kits/templates/system-fragments/channel.md +2 -2
- package/kits/templates/system-fragments/memory.md +16 -9
- package/kits/templates/system-fragments/reply.md +6 -6
- package/kits/templates/system-fragments/session.md +1 -1
- package/package.json +4 -3
- package/dist/core/memory/memory-session-policy.js +0 -41
- package/dist/core/memory/memory-signature.js +0 -257
|
@@ -11,9 +11,10 @@
|
|
|
11
11
|
* 整理会话(sessionType=memory)另有 create / update / archive 三个写命令,
|
|
12
12
|
* 实现见 core/memory/memory-writer.ts,在这里只做 CLI 分发与权限委托。
|
|
13
13
|
*/
|
|
14
|
+
import fs from 'node:fs';
|
|
14
15
|
import { resolvePaths } from '../paths.js';
|
|
15
16
|
import { ipcQuery } from '../ipc.js';
|
|
16
|
-
import { isHelpFlag, wantsHelp } from './help.js';
|
|
17
|
+
import { isHelpFlag, wantsHelp, getArgValue } from './help.js';
|
|
17
18
|
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
18
19
|
import { canonicalizeEvolcoreCommandArgv } from '../core/permission/ec-command-parser.js';
|
|
19
20
|
import { formatQueueDetails } from '../core/memory/consolidation-queue-format.js';
|
|
@@ -28,20 +29,23 @@ const MEMORY_HELP = `用法: ec memory <command> [选项]
|
|
|
28
29
|
demote 把记忆降级回上一层(agent→relation,owner→agent)
|
|
29
30
|
consolidate 触发记忆整理(启动整理会话)
|
|
30
31
|
|
|
31
|
-
ec memory note --slug <slug> [--tags <tag1
|
|
32
|
+
ec memory note --slug <slug> [--tags '<tag1>,<tag2>'] '<content>'
|
|
32
33
|
|
|
33
34
|
选项:
|
|
34
35
|
--slug <slug> 文件名标识,字母/数字/连字符,长度 1-64(必填)
|
|
35
|
-
--tags <...>
|
|
36
|
+
--tags <...> 标签列表,单引号包住、逗号分隔;取值见 \$KITS_DOCS/evolcore/memory-tags.md
|
|
37
|
+
--speakers <...> 群聊专用:本条 note 涉及的发言人,单引号包住、逗号分隔,
|
|
38
|
+
如 --speakers '<aid1>,<aid2>';
|
|
39
|
+
整理会话据此把发言人信息分流写入各自的 relation 记忆
|
|
36
40
|
|
|
37
|
-
ec memory note update <slug> [--slug <新slug>] [--tags
|
|
41
|
+
ec memory note update <slug> [--slug <新slug>] [--tags '<tag1>,<tag2>'] ['<content>']
|
|
38
42
|
ec memory note drop <slug>
|
|
39
43
|
ec memory note list
|
|
40
44
|
|
|
41
|
-
ec memory create --scope <relation|agent|owner> --slug <slug> --desc <description> \\
|
|
42
|
-
--tags
|
|
45
|
+
ec memory create --scope <relation|agent|owner> --slug <slug> --desc '<description>' \\
|
|
46
|
+
--tags '<tag1>,<tag2>' [--keywords '<kw1>,<kw2>'] [--replaces '<path1>,<path2>'] '<content>'
|
|
43
47
|
|
|
44
|
-
ec memory update <path> [--tags
|
|
48
|
+
ec memory update <path> [--tags '<tag1>,<tag2>'] [--touch]
|
|
45
49
|
|
|
46
50
|
ec memory archive <path...>
|
|
47
51
|
|
|
@@ -51,18 +55,21 @@ ec memory consolidate [--mode <notes|generalize|promote|profile|forget>]
|
|
|
51
55
|
--mode 整理模式(默认 notes)
|
|
52
56
|
|
|
53
57
|
公共选项(所有子命令):
|
|
58
|
+
--format json 以 JSON 格式输出:成功时输出 daemon 返回的结果对象,
|
|
59
|
+
失败时输出 { ok: false, code, error },均写到 stdout
|
|
54
60
|
--debug <sessionId> 在宿主终端模拟该会话的托管环境(仅开发仓 daemon 支持);
|
|
55
61
|
会话没有运行中任务时,daemon 从会话文件重建运行时上下文
|
|
56
62
|
|
|
57
63
|
示例:
|
|
58
|
-
ec memory note --slug commit-convention --tags
|
|
59
|
-
ec memory note update commit-convention --tags
|
|
64
|
+
ec memory note --slug commit-convention --tags 'rule,long-term' 'commit 消息必须用中文'
|
|
65
|
+
ec memory note update commit-convention --tags 'rule,done' 'commit 消息必须用中文'
|
|
60
66
|
ec memory note drop commit-convention
|
|
61
67
|
ec memory note list
|
|
68
|
+
ec memory note list --format json
|
|
62
69
|
ec memory consolidate
|
|
63
70
|
ec memory consolidate --mode promote
|
|
64
|
-
ec memory create --scope relation --slug profile --desc
|
|
65
|
-
ec memory update consolidated/commit-convention.md --tags
|
|
71
|
+
ec memory create --scope relation --slug profile --desc '对端画像' --tags 'profile' --replaces consolidated/profile.md '(画像正文)'
|
|
72
|
+
ec memory update consolidated/commit-convention.md --tags 'rule,done'
|
|
66
73
|
ec memory archive consolidated/obsolete.md`;
|
|
67
74
|
export async function cmdMemory(args) {
|
|
68
75
|
args = canonicalizeEvolcoreCommandArgv(['ec', 'memory', ...args]).slice(2);
|
|
@@ -70,51 +77,69 @@ export async function cmdMemory(args) {
|
|
|
70
77
|
console.log(MEMORY_HELP);
|
|
71
78
|
return;
|
|
72
79
|
}
|
|
80
|
+
// --format 的取值先于一切校验:后续任何报错都要按它决定输出 JSON 还是文本
|
|
81
|
+
try {
|
|
82
|
+
assertFormatValues(args);
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
console.error(`❌ ${e.message}`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
const json = getArgValue(args, '--format') === 'json';
|
|
73
89
|
const sub = args[0];
|
|
74
90
|
if (sub === 'note') {
|
|
75
|
-
await cmdMemoryNote(args.slice(1));
|
|
91
|
+
await cmdMemoryNote(args.slice(1), json);
|
|
76
92
|
}
|
|
77
93
|
else if (sub === 'consolidate') {
|
|
78
|
-
await cmdMemoryConsolidate(args.slice(1));
|
|
94
|
+
await cmdMemoryConsolidate(args.slice(1), json);
|
|
79
95
|
}
|
|
80
96
|
else if (sub === 'create') {
|
|
81
|
-
await cmdMemoryCreate(args.slice(1));
|
|
97
|
+
await cmdMemoryCreate(args.slice(1), json);
|
|
82
98
|
}
|
|
83
99
|
else if (sub === 'update') {
|
|
84
|
-
await cmdMemoryConsolidatedUpdate(args.slice(1));
|
|
100
|
+
await cmdMemoryConsolidatedUpdate(args.slice(1), json);
|
|
85
101
|
}
|
|
86
102
|
else if (sub === 'archive') {
|
|
87
|
-
await cmdMemoryArchive(args.slice(1));
|
|
103
|
+
await cmdMemoryArchive(args.slice(1), json);
|
|
88
104
|
}
|
|
89
105
|
else if (sub === 'demote') {
|
|
90
|
-
await cmdMemoryDemote(args.slice(1));
|
|
91
|
-
}
|
|
92
|
-
else if (sub === 'feedback') {
|
|
93
|
-
await cmdMemoryFeedback(args.slice(1));
|
|
106
|
+
await cmdMemoryDemote(args.slice(1), json);
|
|
94
107
|
}
|
|
95
108
|
else {
|
|
96
|
-
|
|
97
|
-
console.error(MEMORY_HELP);
|
|
98
|
-
process.exit(1);
|
|
109
|
+
fail(json, 'INVALID_ARGUMENT', `未知子命令: ${sub}`, { text: `❌ 未知子命令: ${sub}\n${MEMORY_HELP}` });
|
|
99
110
|
}
|
|
100
111
|
}
|
|
112
|
+
/** 所有子命令都认的公共参数,不用每处声明。 */
|
|
113
|
+
const COMMON_FLAGS = ['--debug', '--format'];
|
|
114
|
+
/** `--format` 只支持 json;每次出现都检查,避免重复给出时 CLI 与 daemon 各取一个值。 */
|
|
115
|
+
function assertFormatValues(args) {
|
|
116
|
+
args.forEach((a, i) => {
|
|
117
|
+
if (a === '--format' && args[i + 1] !== 'json') {
|
|
118
|
+
throw new Error(`--format 仅支持 json: ${args[i + 1] ?? '(缺少取值)'}`);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
101
122
|
/**
|
|
102
|
-
* 解析 `--key value`
|
|
103
|
-
*
|
|
123
|
+
* 解析 `--key value` 与位置参数。
|
|
124
|
+
*
|
|
125
|
+
* flag 判定采用**精确匹配已知 flag 集合**,而非 `startsWith('--')`——正文是自由
|
|
126
|
+
* 文本,可能以 `--` 开头(如「--as-session 通道测试」),把它当未知参数拒绝会让
|
|
127
|
+
* 正文受命令行位置影响。不在已知集合里的 token 一律按正文处理。
|
|
128
|
+
*
|
|
129
|
+
* 另支持 POSIX `--` end-of-options:其后所有 token 无条件按正文。
|
|
104
130
|
*/
|
|
105
|
-
function parseArgs(args, known
|
|
131
|
+
function parseArgs(args, known) {
|
|
132
|
+
assertFormatValues(args);
|
|
106
133
|
const flags = new Map();
|
|
107
134
|
const positional = [];
|
|
108
135
|
for (let i = 0; i < args.length; i++) {
|
|
109
136
|
const a = args[i];
|
|
110
|
-
if (a
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
if (i + 1 >= args.length || args[i + 1].startsWith('--')) {
|
|
137
|
+
if (a === '--') {
|
|
138
|
+
positional.push(...args.slice(i + 1));
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
if (COMMON_FLAGS.includes(a) || known.includes(a)) {
|
|
142
|
+
if (i + 1 >= args.length || args[i + 1] === '--' || isKnownFlagToken(args[i + 1], known)) {
|
|
118
143
|
// --touch 这类布尔开关不带值
|
|
119
144
|
flags.set(a, '');
|
|
120
145
|
continue;
|
|
@@ -127,6 +152,9 @@ function parseArgs(args, known, throwOnUnknown = false) {
|
|
|
127
152
|
}
|
|
128
153
|
return { flags, positional };
|
|
129
154
|
}
|
|
155
|
+
function isKnownFlagToken(token, known) {
|
|
156
|
+
return COMMON_FLAGS.includes(token) || known.includes(token);
|
|
157
|
+
}
|
|
130
158
|
function parseTags(raw) {
|
|
131
159
|
if (raw === undefined)
|
|
132
160
|
return undefined;
|
|
@@ -141,11 +169,15 @@ export function resolveMemoryCommandArgv(argv) {
|
|
|
141
169
|
const known = {
|
|
142
170
|
note: ['--slug', '--tags', '--speakers'], 'note.update': ['--slug', '--tags'],
|
|
143
171
|
'note.drop': [], 'note.list': [], create: ['--scope', '--slug', '--desc', '--tags', '--keywords', '--replaces', '--peer'],
|
|
144
|
-
update: ['--tags', '--touch'], archive: [], demote: ['--scope'], consolidate: ['--mode'],
|
|
172
|
+
update: ['--tags', '--touch'], archive: [], demote: ['--scope'], consolidate: ['--mode'],
|
|
145
173
|
};
|
|
174
|
+
// feedback 已移除:旧会话/旧文档可能还在调用,给一句能照做的说明而不是泛化的非法命令。
|
|
175
|
+
if (kind === 'feedback') {
|
|
176
|
+
throw new Error('`ec memory feedback` 已移除:整理反馈由会话直接写入任务书给出的反馈文件');
|
|
177
|
+
}
|
|
146
178
|
if (!Object.prototype.hasOwnProperty.call(known, kind))
|
|
147
179
|
throw new Error('Invalid memory command');
|
|
148
|
-
const { flags, positional } = parseArgs(argv.slice(noteSub ? 3 : 2), known[kind]
|
|
180
|
+
const { flags, positional } = parseArgs(argv.slice(noteSub ? 3 : 2), known[kind]);
|
|
149
181
|
const required = (value, name) => {
|
|
150
182
|
if (!value)
|
|
151
183
|
throw new Error(`${name} is required`);
|
|
@@ -201,124 +233,162 @@ export function resolveMemoryCommandArgv(argv) {
|
|
|
201
233
|
throw new Error('Invalid consolidation mode');
|
|
202
234
|
return { type, mode };
|
|
203
235
|
}
|
|
204
|
-
|
|
236
|
+
throw new Error(`Unhandled memory command kind: ${kind}`);
|
|
205
237
|
}
|
|
206
238
|
/** 各子命令的一行完整用法:缺参报错时附上,模型照抄即可重试。 */
|
|
207
239
|
const USAGE = {
|
|
208
|
-
note:
|
|
209
|
-
noteUpdate:
|
|
240
|
+
note: "ec memory note --slug <slug> [--tags '<tag1>,<tag2>'] [--speakers '<aid1>,<aid2>'] '<正文>'",
|
|
241
|
+
noteUpdate: "ec memory note update <slug> [--slug <新slug>] [--tags '<tag1>,<tag2>'] ['<新正文>']",
|
|
210
242
|
noteDrop: 'ec memory note drop <slug>',
|
|
211
|
-
create:
|
|
212
|
-
update:
|
|
243
|
+
create: "ec memory create --scope <relation|agent|owner> --slug <slug> --desc '<描述>' --tags '<tag1>,<tag2>' [--keywords '<kw1>,<kw2>'] [--replaces '<路径1>,<路径2>'] [--peer <peerKey>] '<正文>'",
|
|
244
|
+
update: "ec memory update <路径> [--tags '<tag1>,<tag2>'] [--touch](至少给一项)",
|
|
213
245
|
archive: 'ec memory archive <路径...>',
|
|
214
246
|
};
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
247
|
+
/**
|
|
248
|
+
* 统一失败出口。JSON 模式与 `ec fs` / `ec response` 一致:stdout 输出 `{ ok: false, code, error }`;
|
|
249
|
+
* 文本模式默认输出 `❌ <message>`(有 usage 时再加一行用法);`text` 给出时整段原样输出,保留各处既有措辞。
|
|
250
|
+
*/
|
|
251
|
+
function fail(json, code, message, opts = {}) {
|
|
252
|
+
if (json) {
|
|
253
|
+
console.log(JSON.stringify({ ok: false, code, error: message, ...(opts.usage ? { usage: opts.usage } : {}) }, null, 2));
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
console.error(opts.text ?? (opts.usage ? `❌ ${message}\n用法: ${opts.usage}` : `❌ ${message}`));
|
|
257
|
+
}
|
|
218
258
|
process.exit(1);
|
|
219
259
|
}
|
|
260
|
+
function failWithUsage(json, message, usage) {
|
|
261
|
+
fail(json, 'INVALID_ARGUMENT', message, { usage });
|
|
262
|
+
}
|
|
263
|
+
/** CLI 侧解析:参数错误按输出格式报错退出。 */
|
|
264
|
+
function parseCliArgs(args, known, json) {
|
|
265
|
+
try {
|
|
266
|
+
return parseArgs(args, known);
|
|
267
|
+
}
|
|
268
|
+
catch (e) {
|
|
269
|
+
return fail(json, 'INVALID_ARGUMENT', e.message);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
220
272
|
/**
|
|
221
273
|
* 取当前会话。`--debug <sessionId>` 在宿主终端模拟托管环境(仅开发仓 daemon 认);
|
|
222
274
|
* 否则读 EVOLCORE_SESSION_ID。
|
|
223
275
|
*/
|
|
224
|
-
function requireManagedSession(cmd, flags) {
|
|
225
|
-
const
|
|
226
|
-
if (flags.has('--debug') && !
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
276
|
+
function requireManagedSession(cmd, flags, json) {
|
|
277
|
+
const explicitDebugSessionId = flags.get('--debug');
|
|
278
|
+
if (flags.has('--debug') && !explicitDebugSessionId) {
|
|
279
|
+
fail(json, 'INVALID_ARGUMENT', '--debug 需要提供 sessionId(如 --debug meta_20260910_1789013149542)');
|
|
280
|
+
}
|
|
281
|
+
// `ec … --as-session <id>` 由 debug-mode.ts 在进程启动时注入会话环境,
|
|
282
|
+
// 与 `--debug <id>` 是同一种调试身份。判据:注入了 delegation token、
|
|
283
|
+
// 但来自从属会话的 daemon runtime epoch,这是 debug-issue-token 的固定形态
|
|
284
|
+
// (真正的托管任务两者都有)。两者都必须走 daemon 的 debug 分支:
|
|
285
|
+
// 该分支只认本地 control token,不接受 task delegation。
|
|
286
|
+
const asSessionDebug = !explicitDebugSessionId
|
|
287
|
+
&& !!process.env.EVOLCORE_SESSION_ID
|
|
288
|
+
&& !!readDelegationCredential()
|
|
289
|
+
&& !process.env.EVOLCORE_DAEMON_RUNTIME_EPOCH;
|
|
290
|
+
const debugMode = !!explicitDebugSessionId || asSessionDebug;
|
|
291
|
+
const sessionId = explicitDebugSessionId || process.env.EVOLCORE_SESSION_ID;
|
|
231
292
|
if (!sessionId) {
|
|
232
|
-
|
|
233
|
-
|
|
293
|
+
const message = `EVOLCORE_SESSION_ID 未设置(${cmd} 仅在 evolcore 托管环境中可用;调试可加 --debug <sessionId> 或 --as-session <sessionId>)`;
|
|
294
|
+
fail(json, 'NO_SESSION', message, { text: `错误: ${message}` });
|
|
295
|
+
}
|
|
296
|
+
if (explicitDebugSessionId)
|
|
297
|
+
console.error(`[debug] 模拟会话 ${explicitDebugSessionId}`);
|
|
298
|
+
else if (asSessionDebug)
|
|
299
|
+
console.error(`[debug] --as-session 会话 ${sessionId}`);
|
|
300
|
+
let controlToken;
|
|
301
|
+
if (debugMode) {
|
|
302
|
+
try {
|
|
303
|
+
controlToken = fs.readFileSync(resolvePaths().controlToken, 'utf8').trim() || undefined;
|
|
304
|
+
}
|
|
305
|
+
catch { /* 交给 daemon 报错 */ }
|
|
234
306
|
}
|
|
235
|
-
if (debugSessionId)
|
|
236
|
-
console.error(`[debug] 模拟会话 ${debugSessionId}`);
|
|
237
307
|
return {
|
|
238
308
|
sessionId,
|
|
239
309
|
socketPath: resolvePaths().socket,
|
|
240
|
-
delegationToken
|
|
241
|
-
...(
|
|
310
|
+
// debug 身份必须用 control token;带 delegationToken 会被 daemon 直接拒绝
|
|
311
|
+
...(debugMode ? { controlToken, debug: true } : { delegationToken: readDelegationCredential() }),
|
|
242
312
|
};
|
|
243
313
|
}
|
|
244
314
|
// ── note ───────────────────────────────────────────────────────────────────
|
|
245
|
-
async function cmdMemoryNote(args) {
|
|
315
|
+
async function cmdMemoryNote(args, json) {
|
|
246
316
|
if (wantsHelp(args)) {
|
|
247
317
|
console.log(MEMORY_HELP);
|
|
248
318
|
return;
|
|
249
319
|
}
|
|
250
320
|
const sub = args[0];
|
|
251
321
|
if (sub === 'update')
|
|
252
|
-
return cmdMemoryNoteUpdate(args.slice(1));
|
|
322
|
+
return cmdMemoryNoteUpdate(args.slice(1), json);
|
|
253
323
|
if (sub === 'drop')
|
|
254
|
-
return cmdMemoryNoteDrop(args.slice(1));
|
|
324
|
+
return cmdMemoryNoteDrop(args.slice(1), json);
|
|
255
325
|
if (sub === 'list')
|
|
256
|
-
return cmdMemoryNoteList(args.slice(1));
|
|
257
|
-
return cmdMemoryNoteCreate(args);
|
|
326
|
+
return cmdMemoryNoteList(args.slice(1), json);
|
|
327
|
+
return cmdMemoryNoteCreate(args, json);
|
|
258
328
|
}
|
|
259
|
-
async function cmdMemoryNoteCreate(args) {
|
|
260
|
-
const { flags, positional } =
|
|
329
|
+
async function cmdMemoryNoteCreate(args, json) {
|
|
330
|
+
const { flags, positional } = parseCliArgs(args, ['--slug', '--tags', '--speakers'], json);
|
|
261
331
|
const content = positional.join(' ').trim();
|
|
262
332
|
const slug = flags.get('--slug');
|
|
263
333
|
const tags = parseTags(flags.get('--tags'));
|
|
264
334
|
const speakers = parseTags(flags.get('--speakers'));
|
|
265
335
|
if (!slug)
|
|
266
|
-
failWithUsage('必须提供 --slug', USAGE.note);
|
|
336
|
+
failWithUsage(json, '必须提供 --slug', USAGE.note);
|
|
267
337
|
if (!content)
|
|
268
|
-
failWithUsage('必须提供记忆内容(content)', USAGE.note);
|
|
269
|
-
const { socketPath, ...session } = requireManagedSession('ec memory note', flags);
|
|
338
|
+
failWithUsage(json, '必须提供记忆内容(content)', USAGE.note);
|
|
339
|
+
const { socketPath, ...session } = requireManagedSession('ec memory note', flags, json);
|
|
270
340
|
const result = await ipcQuery(socketPath, {
|
|
271
341
|
type: 'memory.note', argv: ['memory', 'note', ...args], ...session, slug, content, tags,
|
|
272
342
|
speakers: speakers && speakers.length > 0 ? speakers : undefined,
|
|
273
343
|
}, 15_000);
|
|
274
|
-
reportResult(result, (r) => {
|
|
344
|
+
reportResult(result, json, (r) => {
|
|
275
345
|
if (r.filePath)
|
|
276
346
|
console.log(r.filePath);
|
|
277
347
|
});
|
|
278
348
|
}
|
|
279
|
-
async function cmdMemoryNoteUpdate(args) {
|
|
280
|
-
const { flags, positional } =
|
|
349
|
+
async function cmdMemoryNoteUpdate(args, json) {
|
|
350
|
+
const { flags, positional } = parseCliArgs(args, ['--slug', '--tags'], json);
|
|
281
351
|
const slug = positional[0];
|
|
282
352
|
const content = positional.slice(1).join(' ').trim();
|
|
283
353
|
const newSlug = flags.get('--slug');
|
|
284
354
|
const tagsRaw = flags.get('--tags');
|
|
285
355
|
const tags = parseTags(tagsRaw);
|
|
286
356
|
if (!slug)
|
|
287
|
-
failWithUsage('必须提供要修改的 slug', USAGE.noteUpdate);
|
|
357
|
+
failWithUsage(json, '必须提供要修改的 slug', USAGE.noteUpdate);
|
|
288
358
|
if (!newSlug && tagsRaw === undefined && !content) {
|
|
289
|
-
failWithUsage('至少提供一项要改的内容(--slug / --tags / 正文)', USAGE.noteUpdate);
|
|
359
|
+
failWithUsage(json, '至少提供一项要改的内容(--slug / --tags / 正文)', USAGE.noteUpdate);
|
|
290
360
|
}
|
|
291
|
-
const { socketPath, ...session } = requireManagedSession('ec memory note update', flags);
|
|
361
|
+
const { socketPath, ...session } = requireManagedSession('ec memory note update', flags, json);
|
|
292
362
|
const result = await ipcQuery(socketPath, {
|
|
293
363
|
type: 'memory.note.update', argv: ['memory', 'note', 'update', ...args], ...session, slug,
|
|
294
364
|
newSlug, tags, tagsProvided: tagsRaw !== undefined,
|
|
295
365
|
content: content || undefined,
|
|
296
366
|
}, 15_000);
|
|
297
|
-
reportResult(result, (r) => {
|
|
367
|
+
reportResult(result, json, (r) => {
|
|
298
368
|
if (r.filePath)
|
|
299
369
|
console.log(r.filePath);
|
|
300
370
|
});
|
|
301
371
|
}
|
|
302
|
-
async function cmdMemoryNoteDrop(args) {
|
|
303
|
-
const { flags, positional } =
|
|
372
|
+
async function cmdMemoryNoteDrop(args, json) {
|
|
373
|
+
const { flags, positional } = parseCliArgs(args, [], json);
|
|
304
374
|
const slug = positional[0];
|
|
305
375
|
if (!slug)
|
|
306
|
-
failWithUsage('必须提供要撤销的 slug', USAGE.noteDrop);
|
|
307
|
-
const { socketPath, ...session } = requireManagedSession('ec memory note drop', flags);
|
|
376
|
+
failWithUsage(json, '必须提供要撤销的 slug', USAGE.noteDrop);
|
|
377
|
+
const { socketPath, ...session } = requireManagedSession('ec memory note drop', flags, json);
|
|
308
378
|
const result = await ipcQuery(socketPath, {
|
|
309
379
|
type: 'memory.note.drop', argv: ['memory', 'note', 'drop', ...args], ...session, slug,
|
|
310
380
|
}, 15_000);
|
|
311
|
-
reportResult(result, (r) => {
|
|
381
|
+
reportResult(result, json, (r) => {
|
|
312
382
|
console.log(`✓ 已撤销: ${r.filePath ?? slug}`);
|
|
313
383
|
});
|
|
314
384
|
}
|
|
315
|
-
async function cmdMemoryNoteList(args) {
|
|
316
|
-
const { flags } =
|
|
317
|
-
const { socketPath, ...session } = requireManagedSession('ec memory note list', flags);
|
|
385
|
+
async function cmdMemoryNoteList(args, json) {
|
|
386
|
+
const { flags } = parseCliArgs(args, [], json);
|
|
387
|
+
const { socketPath, ...session } = requireManagedSession('ec memory note list', flags, json);
|
|
318
388
|
const result = await ipcQuery(socketPath, {
|
|
319
389
|
type: 'memory.note.list', argv: ['memory', 'note', 'list', ...args], ...session,
|
|
320
390
|
}, 15_000);
|
|
321
|
-
reportResult(result, (r) => {
|
|
391
|
+
reportResult(result, json, (r) => {
|
|
322
392
|
const notes = r.notes ?? [];
|
|
323
393
|
if (notes.length === 0) {
|
|
324
394
|
console.log('(没有待整理的 note)');
|
|
@@ -333,10 +403,10 @@ async function cmdMemoryNoteList(args) {
|
|
|
333
403
|
});
|
|
334
404
|
}
|
|
335
405
|
// ── create / update / archive(仅整理会话) ─────────────────────────────────
|
|
336
|
-
async function cmdMemoryCreate(args) {
|
|
337
|
-
const { flags, positional } =
|
|
406
|
+
async function cmdMemoryCreate(args, json) {
|
|
407
|
+
const { flags, positional } = parseCliArgs(args, [
|
|
338
408
|
'--scope', '--slug', '--desc', '--tags', '--keywords', '--replaces', '--peer',
|
|
339
|
-
]);
|
|
409
|
+
], json);
|
|
340
410
|
const content = positional.join(' ').trim();
|
|
341
411
|
const scope = flags.get('--scope');
|
|
342
412
|
const slug = flags.get('--slug');
|
|
@@ -346,20 +416,20 @@ async function cmdMemoryCreate(args) {
|
|
|
346
416
|
const replacesRaw = flags.get('--replaces');
|
|
347
417
|
const targetPeerKey = flags.get('--peer');
|
|
348
418
|
if (!scope || !['agent', 'relation', 'owner'].includes(scope)) {
|
|
349
|
-
failWithUsage('--scope 必须是 agent / relation / owner 之一', USAGE.create);
|
|
419
|
+
failWithUsage(json, '--scope 必须是 agent / relation / owner 之一', USAGE.create);
|
|
350
420
|
}
|
|
351
421
|
if (!slug)
|
|
352
|
-
failWithUsage('必须提供 --slug', USAGE.create);
|
|
422
|
+
failWithUsage(json, '必须提供 --slug', USAGE.create);
|
|
353
423
|
if (!desc)
|
|
354
|
-
failWithUsage('必须提供 --desc', USAGE.create);
|
|
424
|
+
failWithUsage(json, '必须提供 --desc', USAGE.create);
|
|
355
425
|
if (tagsRaw === undefined)
|
|
356
|
-
failWithUsage('必须提供 --tags', USAGE.create);
|
|
426
|
+
failWithUsage(json, '必须提供 --tags', USAGE.create);
|
|
357
427
|
if (!content)
|
|
358
|
-
failWithUsage('必须提供记忆内容(content)', USAGE.create);
|
|
428
|
+
failWithUsage(json, '必须提供记忆内容(content)', USAGE.create);
|
|
359
429
|
if (targetPeerKey !== undefined && scope !== 'relation') {
|
|
360
|
-
failWithUsage('--peer 只在 --scope relation 时有效', USAGE.create);
|
|
430
|
+
failWithUsage(json, '--peer 只在 --scope relation 时有效', USAGE.create);
|
|
361
431
|
}
|
|
362
|
-
const { socketPath, ...session } = requireManagedSession('ec memory create', flags);
|
|
432
|
+
const { socketPath, ...session } = requireManagedSession('ec memory create', flags, json);
|
|
363
433
|
const result = await ipcQuery(socketPath, {
|
|
364
434
|
type: 'memory.create', argv: ['memory', 'create', ...args], ...session, scope, slug, description: desc,
|
|
365
435
|
content,
|
|
@@ -368,7 +438,7 @@ async function cmdMemoryCreate(args) {
|
|
|
368
438
|
replaces: replacesRaw ? replacesRaw.split(',').map(s => s.trim()).filter(Boolean) : undefined,
|
|
369
439
|
targetPeerKey: targetPeerKey ?? undefined,
|
|
370
440
|
}, 15_000);
|
|
371
|
-
reportResult(result, (r) => {
|
|
441
|
+
reportResult(result, json, (r) => {
|
|
372
442
|
if (r.filePath)
|
|
373
443
|
console.log(r.filePath);
|
|
374
444
|
if (Array.isArray(r.archived) && r.archived.length > 0) {
|
|
@@ -376,33 +446,33 @@ async function cmdMemoryCreate(args) {
|
|
|
376
446
|
}
|
|
377
447
|
});
|
|
378
448
|
}
|
|
379
|
-
async function cmdMemoryConsolidatedUpdate(args) {
|
|
380
|
-
const { flags, positional } =
|
|
449
|
+
async function cmdMemoryConsolidatedUpdate(args, json) {
|
|
450
|
+
const { flags, positional } = parseCliArgs(args, ['--tags', '--touch'], json);
|
|
381
451
|
const filePath = positional[0];
|
|
382
452
|
const tagsRaw = flags.get('--tags');
|
|
383
453
|
const touch = flags.has('--touch');
|
|
384
454
|
if (!filePath)
|
|
385
|
-
failWithUsage('必须提供要修改的记忆文件路径', USAGE.update);
|
|
455
|
+
failWithUsage(json, '必须提供要修改的记忆文件路径', USAGE.update);
|
|
386
456
|
if (tagsRaw === undefined && !touch)
|
|
387
|
-
failWithUsage('至少提供 --tags 或 --touch', USAGE.update);
|
|
388
|
-
const { socketPath, ...session } = requireManagedSession('ec memory update', flags);
|
|
457
|
+
failWithUsage(json, '至少提供 --tags 或 --touch', USAGE.update);
|
|
458
|
+
const { socketPath, ...session } = requireManagedSession('ec memory update', flags, json);
|
|
389
459
|
const result = await ipcQuery(socketPath, {
|
|
390
460
|
type: 'memory.update', argv: ['memory', 'update', ...args], ...session, filePath,
|
|
391
461
|
tags: parseTags(tagsRaw), touch,
|
|
392
462
|
}, 15_000);
|
|
393
|
-
reportResult(result, () => {
|
|
463
|
+
reportResult(result, json, () => {
|
|
394
464
|
console.log(`✓ 已更新: ${filePath}`);
|
|
395
465
|
});
|
|
396
466
|
}
|
|
397
|
-
async function cmdMemoryArchive(args) {
|
|
398
|
-
const { flags, positional } =
|
|
467
|
+
async function cmdMemoryArchive(args, json) {
|
|
468
|
+
const { flags, positional } = parseCliArgs(args, [], json);
|
|
399
469
|
if (positional.length === 0)
|
|
400
|
-
failWithUsage('必须提供至少一个要归档的文件路径', USAGE.archive);
|
|
401
|
-
const { socketPath, ...session } = requireManagedSession('ec memory archive', flags);
|
|
470
|
+
failWithUsage(json, '必须提供至少一个要归档的文件路径', USAGE.archive);
|
|
471
|
+
const { socketPath, ...session } = requireManagedSession('ec memory archive', flags, json);
|
|
402
472
|
const result = await ipcQuery(socketPath, {
|
|
403
473
|
type: 'memory.archive', argv: ['memory', 'archive', ...args], ...session, filePaths: positional,
|
|
404
474
|
}, 15_000);
|
|
405
|
-
reportResult(result, (r) => {
|
|
475
|
+
reportResult(result, json, (r) => {
|
|
406
476
|
const archived = r.archived ?? positional;
|
|
407
477
|
console.log(`✓ 已归档 ${archived.length} 个文件:`);
|
|
408
478
|
for (const f of archived)
|
|
@@ -410,27 +480,26 @@ async function cmdMemoryArchive(args) {
|
|
|
410
480
|
});
|
|
411
481
|
}
|
|
412
482
|
// ── consolidate ────────────────────────────────────────────────────────────
|
|
413
|
-
async function cmdMemoryDemote(args) {
|
|
483
|
+
async function cmdMemoryDemote(args, json) {
|
|
414
484
|
if (wantsHelp(args)) {
|
|
415
485
|
console.log(MEMORY_HELP);
|
|
416
486
|
return;
|
|
417
487
|
}
|
|
418
|
-
const { flags, positional } =
|
|
488
|
+
const { flags, positional } = parseCliArgs(args, ['--scope'], json);
|
|
419
489
|
const slug = positional[0];
|
|
420
490
|
if (!slug) {
|
|
421
|
-
|
|
422
|
-
|
|
491
|
+
const usage = 'ec memory demote <slug> [--scope agent|owner]';
|
|
492
|
+
fail(json, 'INVALID_ARGUMENT', '必须提供要降级的 slug', { usage, text: `用法: ${usage}` });
|
|
423
493
|
}
|
|
424
494
|
const scope = flags.get('--scope') ?? 'agent';
|
|
425
495
|
if (scope !== 'agent' && scope !== 'owner') {
|
|
426
|
-
|
|
427
|
-
process.exit(1);
|
|
496
|
+
fail(json, 'INVALID_ARGUMENT', '--scope 必须是 agent 或 owner', { text: '--scope 必须是 agent 或 owner' });
|
|
428
497
|
}
|
|
429
|
-
const { socketPath, ...session } = requireManagedSession('ec memory demote', flags);
|
|
498
|
+
const { socketPath, ...session } = requireManagedSession('ec memory demote', flags, json);
|
|
430
499
|
const result = await ipcQuery(socketPath, {
|
|
431
500
|
type: 'memory.demote', argv: ['memory', 'demote', ...args], ...session, slug, scope,
|
|
432
501
|
}, 15_000);
|
|
433
|
-
reportResult(result, (r) => {
|
|
502
|
+
reportResult(result, json, (r) => {
|
|
434
503
|
if (r.conflictArchived) {
|
|
435
504
|
console.log(`⚠ 目标层已有同名文件,当前记忆已归档至:`);
|
|
436
505
|
console.log(` ${r.conflictArchived}`);
|
|
@@ -441,28 +510,28 @@ async function cmdMemoryDemote(args) {
|
|
|
441
510
|
}
|
|
442
511
|
});
|
|
443
512
|
}
|
|
444
|
-
async function cmdMemoryConsolidate(args) {
|
|
513
|
+
async function cmdMemoryConsolidate(args, json) {
|
|
445
514
|
if (wantsHelp(args)) {
|
|
446
515
|
console.log(MEMORY_HELP);
|
|
447
516
|
return;
|
|
448
517
|
}
|
|
449
518
|
// 先于通用解析处理已废弃的 --scope,给出可操作的提示而不是「未知参数」
|
|
450
519
|
if (args.includes('--scope')) {
|
|
451
|
-
|
|
452
|
-
process.exit(1);
|
|
520
|
+
fail(json, 'INVALID_ARGUMENT', '`--scope` 已废弃。作用域由模式唯一决定,请改用 `--mode <notes|generalize|promote|profile|forget>`');
|
|
453
521
|
}
|
|
454
|
-
const { flags } =
|
|
522
|
+
const { flags } = parseCliArgs(args, ['--mode'], json);
|
|
455
523
|
const mode = (flags.get('--mode') ?? 'notes');
|
|
456
524
|
if (!MEMORY_MODES.includes(mode)) {
|
|
457
|
-
|
|
458
|
-
process.exit(1);
|
|
525
|
+
fail(json, 'INVALID_ARGUMENT', `--mode 必须是 ${MEMORY_MODES.join(' / ')} 之一`);
|
|
459
526
|
}
|
|
460
|
-
const { socketPath, ...session } = requireManagedSession('ec memory consolidate', flags);
|
|
461
|
-
|
|
527
|
+
const { socketPath, ...session } = requireManagedSession('ec memory consolidate', flags, json);
|
|
528
|
+
// JSON 模式下 stdout 只留结果对象
|
|
529
|
+
if (!json)
|
|
530
|
+
console.log(`正在触发记忆整理(mode=${mode})...`);
|
|
462
531
|
const result = await ipcQuery(socketPath, {
|
|
463
532
|
type: 'memory.consolidate', argv: ['memory', 'consolidate', ...args], ...session, mode,
|
|
464
533
|
}, 30_000);
|
|
465
|
-
reportResult(result, (r) => {
|
|
534
|
+
reportResult(result, json, (r) => {
|
|
466
535
|
if (r.queued) {
|
|
467
536
|
console.log(`⏳ 整理请求已入队(${mode} 模式),前一个整理会话结束后自动启动`);
|
|
468
537
|
for (const line of formatQueueDetails(r.queued))
|
|
@@ -480,43 +549,18 @@ async function cmdMemoryConsolidate(args) {
|
|
|
480
549
|
console.log('整理会话在后台继续运行。');
|
|
481
550
|
});
|
|
482
551
|
}
|
|
483
|
-
// ── feedback(整理会话反馈)─────────────────────────────────────────────────
|
|
484
|
-
/**
|
|
485
|
-
* 整理会话用 `ec memory feedback "<文本>"` 记录本次整理的反馈内容。
|
|
486
|
-
* 文本写入批次目录的 ops.jsonl(op=feedback-set),收尾时据此投递回发起会话。
|
|
487
|
-
* 未调用则不写,收尾回退到默认统计模板。
|
|
488
|
-
*/
|
|
489
|
-
async function cmdMemoryFeedback(args) {
|
|
490
|
-
if (wantsHelp(args)) {
|
|
491
|
-
console.log(MEMORY_HELP);
|
|
492
|
-
return;
|
|
493
|
-
}
|
|
494
|
-
const { flags, positional } = parseArgs(args, []);
|
|
495
|
-
const text = positional.join(' ').trim();
|
|
496
|
-
if (!text) {
|
|
497
|
-
console.error('用法: ec memory feedback "<反馈文本>"');
|
|
498
|
-
process.exit(1);
|
|
499
|
-
}
|
|
500
|
-
const { socketPath, ...session } = requireManagedSession('ec memory feedback', flags);
|
|
501
|
-
const result = await ipcQuery(socketPath, {
|
|
502
|
-
type: 'memory.feedback', argv: ['memory', 'feedback', ...args], ...session, text,
|
|
503
|
-
}, 15_000);
|
|
504
|
-
reportResult(result, () => {
|
|
505
|
-
console.log('✓ 已记录反馈内容');
|
|
506
|
-
});
|
|
507
|
-
}
|
|
508
552
|
// ── 结果输出 ───────────────────────────────────────────────────────────────
|
|
509
|
-
function reportResult(result, ok) {
|
|
553
|
+
function reportResult(result, json, ok) {
|
|
510
554
|
if (!result) {
|
|
511
|
-
|
|
512
|
-
process.exit(1);
|
|
555
|
+
fail(json, 'DAEMON_UNAVAILABLE', '无法连接 evolcore 服务', { text: '错误: 无法连接 evolcore 服务' });
|
|
513
556
|
}
|
|
514
557
|
const r = result;
|
|
515
|
-
if (r.ok) {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
else {
|
|
519
|
-
console.error(r.error || '操作失败');
|
|
520
|
-
process.exit(1);
|
|
558
|
+
if (!r.ok) {
|
|
559
|
+
const message = r.error || '操作失败';
|
|
560
|
+
fail(json, r.code || 'MEMORY_OPERATION_FAILED', message, { text: message });
|
|
521
561
|
}
|
|
562
|
+
if (json)
|
|
563
|
+
console.log(JSON.stringify(r, null, 2));
|
|
564
|
+
else
|
|
565
|
+
ok(r);
|
|
522
566
|
}
|