evolcore 0.0.32 → 0.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/bin/ec.js +3 -2
  3. package/bin/install-codex-managed-hooks.mjs +135 -37
  4. package/dist/agents/baseagent-availability.js +20 -36
  5. package/dist/agents/claude-runner.js +111 -15
  6. package/dist/agents/codex/app-server-client.js +3 -0
  7. package/dist/agents/codex/diagnostics.js +112 -54
  8. package/dist/agents/codex-runner.js +241 -63
  9. package/dist/agents/ecagent-runner.js +78 -33
  10. package/dist/agents/runner-types.js +5 -6
  11. package/dist/aun/aid/identity.js +1 -1
  12. package/dist/aun/group/operations.js +0 -1
  13. package/dist/aun/msg/history.js +1 -0
  14. package/dist/aun/msg/p2p.js +0 -1
  15. package/dist/aun/outbox.js +50 -1
  16. package/dist/channels/aun.js +44 -8
  17. package/dist/channels/daemon.js +261 -3
  18. package/dist/cli/agent-command.js +58 -24
  19. package/dist/cli/agent.js +1 -1
  20. package/dist/cli/aun-commands.js +368 -31
  21. package/dist/cli/contact.js +8 -2
  22. package/dist/cli/ctl-command.js +3 -1
  23. package/dist/cli/daemon-commands.js +197 -27
  24. package/dist/cli/debug-mode.js +154 -0
  25. package/dist/cli/fs-command.js +2 -1
  26. package/dist/cli/handoff-command.js +3 -0
  27. package/dist/cli/index.js +98 -67
  28. package/dist/cli/init.js +2 -2
  29. package/dist/cli/integrity-command.js +196 -0
  30. package/dist/cli/managed-command-guard.js +5 -0
  31. package/dist/cli/memory-command.js +166 -146
  32. package/dist/cli/queue-command.js +9 -4
  33. package/dist/cli/session-command.js +194 -0
  34. package/dist/cli/skill-command.js +78 -2
  35. package/dist/cli/task-context.js +1 -0
  36. package/dist/cli/thread-command.js +622 -0
  37. package/dist/cli/trigger-command.js +10 -3
  38. package/dist/config/builtin-roles.js +1 -0
  39. package/dist/config/config-field-policy.js +6 -3
  40. package/dist/config/config-manager.js +26 -2
  41. package/dist/config/contact-book-store.js +5 -0
  42. package/dist/config/resolved-config-op.js +3 -0
  43. package/dist/config/role-service.js +13 -0
  44. package/dist/config/runtime-env.js +16 -0
  45. package/dist/config-store.js +45 -0
  46. package/dist/core/audit/log-integrity.js +3 -1
  47. package/dist/core/auth/agent-delegation.js +133 -36
  48. package/dist/core/auth/debug-context.js +139 -0
  49. package/dist/core/auth/delegation-diagnostics.js +414 -0
  50. package/dist/core/auth/operation-authorizer.js +25 -2
  51. package/dist/core/auth/operation-catalog.js +49 -0
  52. package/dist/core/background-session/session-cleanup.js +212 -0
  53. package/dist/core/background-session/types.js +10 -0
  54. package/dist/core/bootstrap-messages.js +1 -1
  55. package/dist/core/bootstrap-service.js +6 -3
  56. package/dist/core/command/agent-control.js +18 -26
  57. package/dist/core/command/command-handler.js +197 -27
  58. package/dist/core/command/daemon-diagnostics.js +1 -0
  59. package/dist/core/command/memory-slash.js +6 -2
  60. package/dist/core/command/menu-catalog.js +51 -1
  61. package/dist/core/command/menu-handler.js +114 -23
  62. package/dist/core/command/menu-protocol.js +25 -1
  63. package/dist/core/command/skill-slash.js +322 -0
  64. package/dist/core/command/slash-gate.js +6 -4
  65. package/dist/core/command/slash-handler.js +195 -13
  66. package/dist/core/command/topic-slash.js +528 -0
  67. package/dist/core/daemon-bootstrap.js +4 -7
  68. package/dist/core/evolagent-registry.js +20 -5
  69. package/dist/core/file-integrity/read.js +61 -0
  70. package/dist/core/file-integrity/store.js +262 -0
  71. package/dist/core/handoff/runtime.js +5 -11
  72. package/dist/core/handoff/store.js +5 -0
  73. package/dist/core/ipc-registration.js +175 -3
  74. package/dist/core/memory/batch-meta.js +132 -0
  75. package/dist/core/memory/consolidation-context.js +83 -29
  76. package/dist/core/memory/consolidation-ops-records.js +49 -16
  77. package/dist/core/memory/consolidation-queue-format.js +21 -0
  78. package/dist/core/memory/consolidation.js +264 -205
  79. package/dist/core/memory/index-manager.js +19 -28
  80. package/dist/core/memory/memory-admin.js +19 -14
  81. package/dist/core/memory/memory-document.js +53 -9
  82. package/dist/core/memory/memory-writer.js +30 -15
  83. package/dist/core/message/aun-ipc-sender.js +161 -6
  84. package/dist/core/message/im-renderer.js +169 -10
  85. package/dist/core/message/message-bridge.js +15 -4
  86. package/dist/core/message/message-log.js +1 -0
  87. package/dist/core/message/peer-mode.js +6 -1
  88. package/dist/core/message/response-engine.js +929 -110
  89. package/dist/core/message/subtask-tool-projection.js +140 -0
  90. package/dist/core/model/catalog-service.js +17 -12
  91. package/dist/core/permission/ec-command-parser.js +217 -9
  92. package/dist/core/permission/protected-paths.js +5 -1
  93. package/dist/core/permission/readonly-shell-query.js +43 -5
  94. package/dist/core/permission/session-path-grants.js +334 -0
  95. package/dist/core/permission/tool-canonical.js +226 -0
  96. package/dist/core/permission/tool-policy.js +30 -62
  97. package/dist/core/role/runtime-policy.js +21 -10
  98. package/dist/core/session/session-fs-store.js +123 -8
  99. package/dist/core/session/session-idle-monitor.js +249 -22
  100. package/dist/core/session/session-manager.js +129 -14
  101. package/dist/core/skill/command-parser.js +13 -0
  102. package/dist/core/skill/index-generator.js +21 -4
  103. package/dist/core/skill/startup.js +41 -0
  104. package/dist/core/skill/switch-resolver.js +55 -29
  105. package/dist/core/system-session/grants.js +40 -0
  106. package/dist/core/system-session/memory.js +222 -0
  107. package/dist/core/system-session/registry.js +74 -0
  108. package/dist/core/system-session/types.js +14 -0
  109. package/dist/core/thread/command-parser.js +125 -0
  110. package/dist/core/thread/index.js +1 -0
  111. package/dist/core/thread/ipc-operation.js +95 -0
  112. package/dist/core/thread/thread-context-storage.js +131 -0
  113. package/dist/core/thread/thread-operation.js +258 -0
  114. package/dist/core/thread/thread-route.js +33 -0
  115. package/dist/core/thread/thread-service.js +770 -0
  116. package/dist/core/thread/types.js +1 -0
  117. package/dist/eck/kit-renderer.js +7 -2
  118. package/dist/eck/manifest-engine.js +24 -4
  119. package/dist/eck/message-renderer.js +35 -0
  120. package/dist/index.js +19 -7
  121. package/dist/ipc.js +140 -50
  122. package/dist/paths.js +93 -0
  123. package/dist/response-system/engines/v1/proactive-flow.js +169 -80
  124. package/dist/stats/billing.js +20 -8
  125. package/dist/trigger/authorization.js +57 -28
  126. package/dist/trigger/feedback.js +13 -2
  127. package/dist/trigger/parser.js +70 -1
  128. package/dist/trigger/system-definitions.js +3 -3
  129. package/dist/trigger/validation.js +14 -0
  130. package/dist/utils/cross-platform.js +11 -2
  131. package/dist/utils/error-dict.json +18 -4
  132. package/dist/utils/error-utils.js +143 -1
  133. package/dist/utils/instance-registry.js +13 -8
  134. package/dist/utils/log-writer.js +12 -0
  135. package/dist/utils/process-introspect.js +11 -0
  136. package/kits/docs/context-assembly.md +1 -1
  137. package/kits/docs/evolcore/INDEX.md +1 -0
  138. package/kits/docs/evolcore/agent-create.md +40 -28
  139. package/kits/docs/evolcore/agent.md +21 -6
  140. package/kits/docs/evolcore/config.md +2 -2
  141. package/kits/docs/evolcore/ctl.md +2 -2
  142. package/kits/docs/evolcore/ec-capabilities.md +5 -1
  143. package/kits/docs/evolcore/fs-architecture.md +4 -5
  144. package/kits/docs/evolcore/fs.md +1 -1
  145. package/kits/docs/evolcore/group-collaboration.md +4 -6
  146. package/kits/docs/evolcore/group.md +11 -12
  147. package/kits/docs/evolcore/memory-architecture.md +4 -5
  148. package/kits/docs/evolcore/memory-consolidation.md +19 -15
  149. package/kits/docs/evolcore/memory-tags.md +3 -1
  150. package/kits/docs/evolcore/memory.md +24 -12
  151. package/kits/docs/evolcore/menu-exec-schema-commands.md +2 -2
  152. package/kits/docs/evolcore/menu-protocol.md +7 -0
  153. package/kits/docs/evolcore/model.md +16 -0
  154. package/kits/docs/evolcore/msg.md +8 -11
  155. package/kits/docs/evolcore/thread-chain.md +267 -0
  156. package/kits/docs/prompt-loading-architecture.md +1 -1
  157. package/kits/eck_manifest.json +55 -40
  158. package/kits/eck_manifest.memory.json +0 -12
  159. package/kits/eck_message_manifest.json +169 -10
  160. package/kits/rules/01-overview.md +11 -0
  161. package/kits/rules/03-identity.md +6 -3
  162. package/kits/rules/05-venue.md +1 -1
  163. package/kits/rules/06-channel.md +1 -1
  164. package/kits/rules/07-memory-and-thread.md +199 -0
  165. package/kits/schemas/_meta.json +7 -1
  166. package/kits/schemas/agent-config.schema.13.json +1 -1
  167. package/kits/schemas/daemon.schema.7.json +140 -0
  168. package/kits/schemas/relation-config.schema.9.json +18 -3
  169. package/kits/schemas/role-config.schema.1.json +6 -6
  170. package/kits/schemas/single-session.schema.1.json +6 -6
  171. package/kits/schemas/single-session.schema.2.json +6 -6
  172. package/kits/schemas/single-session.schema.3.json +6 -6
  173. package/kits/skills/.switches.json +12 -1
  174. package/kits/skills/ec-group/SKILL.md +234 -0
  175. package/kits/skills/ec-skill/SKILL.md +10 -1
  176. package/kits/skills/ec-skill/scripts/cli.mjs +16 -2
  177. package/kits/skills/ec-skill/scripts/skill.mjs +1 -1
  178. package/kits/skills/scrapling-article-fetch/SKILL.md +128 -0
  179. package/kits/skills/scrapling-article-fetch/scripts/check_python_env.py +54 -0
  180. package/kits/skills/scrapling-article-fetch/scripts/render_markdown_reply.py +35 -0
  181. package/kits/skills/scrapling-article-fetch/scripts/run_pipeline.sh +16 -0
  182. package/kits/skills/scrapling-article-fetch/scripts/scrapling_fetch.py +344 -0
  183. package/kits/skills/thread-ops/SKILL.md +492 -0
  184. package/kits/skills/wechat-article-media-download/SKILL.md +65 -0
  185. package/kits/skills/wechat-article-media-download/scripts/download.py +163 -0
  186. package/kits/skills/wechat-article-reader/SKILL.md +97 -0
  187. package/kits/skills/wechat-article-reader/scripts/fetch.mjs +256 -0
  188. package/kits/templates/bootstrap-welcome.md +7 -7
  189. package/kits/templates/memory-consolidation/forget.md +7 -2
  190. package/kits/templates/memory-consolidation/generalize.md +9 -4
  191. package/kits/templates/memory-consolidation/notes.md +11 -11
  192. package/kits/templates/memory-consolidation/profile.md +8 -3
  193. package/kits/templates/memory-consolidation/promote.md +8 -3
  194. package/kits/templates/memory-consolidation/workflow.md +6 -6
  195. package/kits/templates/message-fragments/handoff-request-to-target.md +1 -1
  196. package/kits/templates/message-fragments/item.md +2 -1
  197. package/kits/templates/message-fragments/thread-context.md +6 -0
  198. package/kits/templates/message-fragments/trigger-session.md +2 -0
  199. package/kits/templates/message-fragments/trigger-thread-check.md +2 -0
  200. package/kits/templates/roles/member.json +2 -0
  201. package/kits/templates/roles/visitor.json +2 -0
  202. package/kits/templates/system-fragments/bootstrap.md +67 -72
  203. package/kits/templates/system-fragments/channel.md +3 -6
  204. package/kits/templates/system-fragments/commands.md +1 -0
  205. package/kits/templates/system-fragments/managed-runtime.md +15 -0
  206. package/kits/templates/system-fragments/memory.md +16 -9
  207. package/kits/templates/system-fragments/reply.md +7 -6
  208. package/kits/templates/system-fragments/session.md +5 -14
  209. package/package.json +6 -3
  210. package/dist/core/memory/memory-session-policy.js +0 -41
  211. package/dist/core/memory/memory-signature.js +0 -257
  212. package/kits/docs/evolcore/group-fs.md +0 -17
  213. package/kits/docs/venues/aun-group.md +0 -45
  214. package/kits/docs/venues/group.md +0 -43
package/dist/cli/index.js CHANGED
@@ -20,6 +20,7 @@ import { cmdStart, cmdStop, cmdRestart, cmdStatus, cmdLogs, cmdWatchCommand, cmd
20
20
  import { logCliCommand } from './command-log.js';
21
21
  import { isInitCancelledError, printInitCancelHint } from './init-cancel.js';
22
22
  import { assertManagedTopLevelCommandAllowed, ManagedCommandNotAllowedError } from './managed-command-guard.js';
23
+ import { resolveDebugContext, stripAsSessionArgs } from './debug-mode.js';
23
24
  const MAIN_HELP = `用法: ec <command> [选项]
24
25
 
25
26
  服务:
@@ -35,6 +36,7 @@ Agent 与会话:
35
36
  agent 管理 EvolAgent
36
37
  ctl 当前托管会话的控制命令
37
38
  queue 查询或操作 agent 消息队列
39
+ session 按 ec 会话 id 查询本地 session 存档(含 agentSessionId)
38
40
  task 恢复暂停或异常中断的会话任务
39
41
  trigger 管理定时与事件触发器
40
42
  handoff 查询和完成跨会话回流
@@ -76,7 +78,7 @@ AUN:
76
78
  EVENT_LOG 事件日志(默认: true)`;
77
79
  function printLifecycleHelp(command) {
78
80
  const help = {
79
- start: `用法: ec start [--foreground] [--diagnose|-d]\n\n --foreground 前台运行,适合 systemd 或容器直接管理\n --diagnose, -d 以诊断模式启动 daemon`,
81
+ start: `用法: ec start [--foreground] [--diagnose|-d] [--debug] [--as-mode dev|install]\n\n --foreground 前台运行,适合 systemd 或容器直接管理\n --diagnose, -d 以诊断模式启动 daemon\n --debug 调试模式:注册调试 IPC,可在宿主终端以任意 session 身份发命令\n --as-mode 覆盖运行模式判定(仅本次启动生效,不写配置):\n install = 按安装模式(校验随包文件完整性,篡改自动恢复)\n dev = 按开发模式(不校验随包文件)`,
80
82
  stop: '用法: ec stop\n\n停止当前 EVOLCORE_HOME 下运行的 EvolCore 服务。',
81
83
  restart: `用法: ec restart [--clear] [--diagnose|-d]\n\n --clear 同时清理跨 HOME 残留的 EvolCore 主进程\n --diagnose, -d 以诊断模式启动新 daemon`,
82
84
  status: '用法: ec status\n\n查看 daemon、agent、渠道与会话运行状态。',
@@ -102,8 +104,12 @@ export async function main(args) {
102
104
  return;
103
105
  }
104
106
  const cmd = args[0] || 'start';
107
+ // 调试路径:--as-session <sessionId> 注入托管会话身份,必须在白名单检查之前
108
+ await resolveDebugContext(args);
109
+ // 注入完成后剥除 --as-session <sessionId> 两个参数,避免子命令把它们当作未知参数
110
+ const strippedArgs = stripAsSessionArgs(args);
105
111
  try {
106
- assertManagedTopLevelCommandAllowed(cmd, args);
112
+ assertManagedTopLevelCommandAllowed(cmd, strippedArgs);
107
113
  }
108
114
  catch (error) {
109
115
  if (!(error instanceof ManagedCommandNotAllowedError))
@@ -112,7 +118,7 @@ export async function main(args) {
112
118
  process.exitCode = 1;
113
119
  return;
114
120
  }
115
- logCliCommand(cmd, args);
121
+ logCliCommand(cmd, strippedArgs);
116
122
  if (cmd === '--version' || cmd === '-v' || cmd === '-V') {
117
123
  const pkg = JSON.parse(fs.readFileSync(path.join(getPackageRoot(), 'package.json'), 'utf-8'));
118
124
  console.log(pkg.version);
@@ -125,7 +131,7 @@ export async function main(args) {
125
131
  switch (cmd) {
126
132
  case 'init': {
127
133
  try {
128
- if (wantsHelp(args.slice(1))) {
134
+ if (wantsHelp(strippedArgs.slice(1))) {
129
135
  console.log(`用法: ec init [渠道] [选项]
130
136
 
131
137
  仅初始化 defaults.json:
@@ -155,49 +161,49 @@ export async function main(args) {
155
161
  ec init wecom 企业微信 AI Bot 扫码创建/手工配置`);
156
162
  }
157
163
  else {
158
- const hasChannelTarget = Boolean(args[1] && !args[1].startsWith('-'));
164
+ const hasChannelTarget = Boolean(strippedArgs[1] && !strippedArgs[1].startsWith('-'));
159
165
  if (hasChannelTarget)
160
166
  printInitCancelHint();
161
- if (args[1] === 'aun') {
167
+ if (strippedArgs[1] === 'aun') {
162
168
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
163
169
  suppressSdkLogs();
164
170
  await cmdInitAun();
165
171
  }
166
- else if (args[1] === 'wechat') {
172
+ else if (strippedArgs[1] === 'wechat') {
167
173
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
168
174
  suppressSdkLogs();
169
175
  await cmdInitWechat();
170
176
  }
171
- else if (args[1] === 'feishu') {
177
+ else if (strippedArgs[1] === 'feishu') {
172
178
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
173
179
  suppressSdkLogs();
174
180
  await cmdInitFeishu();
175
181
  }
176
- else if (args[1] === 'dingtalk') {
182
+ else if (strippedArgs[1] === 'dingtalk') {
177
183
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
178
184
  suppressSdkLogs();
179
185
  await cmdInitDingtalk();
180
186
  }
181
- else if (args[1] === 'qqbot') {
187
+ else if (strippedArgs[1] === 'qqbot') {
182
188
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
183
189
  suppressSdkLogs();
184
190
  await cmdInitQQBot();
185
191
  }
186
- else if (args[1] === 'wecom') {
192
+ else if (strippedArgs[1] === 'wecom') {
187
193
  await cmdInitWecom();
188
194
  }
189
- else if (args[1] && !args[1].startsWith('-')) {
195
+ else if (strippedArgs[1] && !strippedArgs[1].startsWith('-')) {
190
196
  const supported = ['feishu', 'wechat', 'aun', 'dingtalk', 'qqbot', 'wecom'];
191
- console.error(`❌ 不支持的渠道: ${args[1]}`);
197
+ console.error(`❌ 不支持的渠道: ${strippedArgs[1]}`);
192
198
  console.error(` 支持的渠道: ${supported.join(', ')}`);
193
199
  process.exit(1);
194
200
  }
195
201
  else {
196
202
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
197
203
  suppressSdkLogs();
198
- const nonInteractive = args.includes('--non-interactive');
199
- const wantsAutoStart = args.includes('--auto-start');
200
- const wantsNoAutoStart = args.includes('--no-auto-start');
204
+ const nonInteractive = strippedArgs.includes('--non-interactive');
205
+ const wantsAutoStart = strippedArgs.includes('--auto-start');
206
+ const wantsNoAutoStart = strippedArgs.includes('--no-auto-start');
201
207
  if (wantsAutoStart && wantsNoAutoStart) {
202
208
  console.error('❌ --auto-start 与 --no-auto-start 不能同时使用');
203
209
  process.exitCode = 1;
@@ -205,12 +211,12 @@ export async function main(args) {
205
211
  }
206
212
  const initialized = await cmdInit({
207
213
  nonInteractive,
208
- baseagent: getArgValue(args, '--baseagent'),
209
- force: args.includes('--force'),
210
- owner: getArgValue(args, '--owner'),
211
- projectpath: getArgValue(args, '--projectpath'),
212
- ecweb: args.includes('--ecweb') ? true : undefined,
213
- format: getArgValue(args, '--format'),
214
+ baseagent: getArgValue(strippedArgs, '--baseagent'),
215
+ force: strippedArgs.includes('--force'),
216
+ owner: getArgValue(strippedArgs, '--owner'),
217
+ projectpath: getArgValue(strippedArgs, '--projectpath'),
218
+ ecweb: strippedArgs.includes('--ecweb') ? true : undefined,
219
+ format: getArgValue(strippedArgs, '--format'),
214
220
  autoStart: wantsAutoStart ? true : wantsNoAutoStart ? false : undefined,
215
221
  });
216
222
  if (!initialized && process.exitCode == null)
@@ -227,31 +233,41 @@ export async function main(args) {
227
233
  break;
228
234
  }
229
235
  case 'start':
230
- if (wantsHelp(args.slice(1))) {
236
+ if (wantsHelp(strippedArgs.slice(1))) {
231
237
  printLifecycleHelp('start');
232
238
  break;
233
239
  }
234
- await cmdStart({
235
- diagnose: args.includes('--diagnose') || args.includes('-d'),
236
- foreground: args.includes('--foreground'),
237
- });
240
+ {
241
+ const asModeRaw = getArgValue(strippedArgs, '--as-mode');
242
+ if (asModeRaw !== undefined && asModeRaw !== 'dev' && asModeRaw !== 'install') {
243
+ console.error(`❌ --as-mode 只接受 dev 或 install,收到: ${asModeRaw}`);
244
+ process.exitCode = 1;
245
+ break;
246
+ }
247
+ await cmdStart({
248
+ diagnose: strippedArgs.includes('--diagnose') || strippedArgs.includes('-d'),
249
+ foreground: strippedArgs.includes('--foreground'),
250
+ debug: strippedArgs.includes('--debug'),
251
+ asMode: asModeRaw,
252
+ });
253
+ }
238
254
  break;
239
255
  case 'stop':
240
- if (wantsHelp(args.slice(1))) {
256
+ if (wantsHelp(strippedArgs.slice(1))) {
241
257
  printLifecycleHelp('stop');
242
258
  break;
243
259
  }
244
260
  await cmdStop();
245
261
  break;
246
262
  case 'restart':
247
- if (wantsHelp(args.slice(1))) {
263
+ if (wantsHelp(strippedArgs.slice(1))) {
248
264
  printLifecycleHelp('restart');
249
265
  break;
250
266
  }
251
- await cmdRestart({ clear: args.includes('--clear'), diagnose: args.includes('--diagnose') || args.includes('-d') });
267
+ await cmdRestart({ clear: strippedArgs.includes('--clear'), diagnose: strippedArgs.includes('--diagnose') || strippedArgs.includes('-d') });
252
268
  break;
253
269
  case 'status':
254
- if (wantsHelp(args.slice(1))) {
270
+ if (wantsHelp(strippedArgs.slice(1))) {
255
271
  printLifecycleHelp('status');
256
272
  break;
257
273
  }
@@ -273,21 +289,21 @@ export async function main(args) {
273
289
  }
274
290
  break;
275
291
  case 'logs':
276
- if (wantsHelp(args.slice(1))) {
292
+ if (wantsHelp(strippedArgs.slice(1))) {
277
293
  printLifecycleHelp('logs');
278
294
  break;
279
295
  }
280
- cmdLogs(args.slice(1));
296
+ cmdLogs(strippedArgs.slice(1));
281
297
  break;
282
298
  case 'watch':
283
- if (wantsHelp(args.slice(1))) {
299
+ if (wantsHelp(strippedArgs.slice(1))) {
284
300
  printLifecycleHelp('watch');
285
301
  break;
286
302
  }
287
- await cmdWatchCommand(args.slice(1));
303
+ await cmdWatchCommand(strippedArgs.slice(1));
288
304
  break;
289
305
  case 'restart-monitor':
290
- if (wantsHelp(args.slice(1))) {
306
+ if (wantsHelp(strippedArgs.slice(1))) {
291
307
  printLifecycleHelp('restart-monitor');
292
308
  break;
293
309
  }
@@ -297,7 +313,7 @@ export async function main(args) {
297
313
  try {
298
314
  // 开发源码仓可提供 mode.js;正式 npm 包可以不携带该内部命令。
299
315
  const { cmdMode } = await import('./mode.js');
300
- await cmdMode(args.slice(1));
316
+ await cmdMode(strippedArgs.slice(1));
301
317
  }
302
318
  catch (error) {
303
319
  if (error?.code === 'ERR_MODULE_NOT_FOUND' && /(?:^|[\\/])mode\.js(?:$|')/.test(String(error?.message ?? ''))) {
@@ -309,70 +325,75 @@ export async function main(args) {
309
325
  }
310
326
  break;
311
327
  case 'mv':
312
- if (wantsHelp(args.slice(1))) {
328
+ if (wantsHelp(strippedArgs.slice(1))) {
313
329
  printLifecycleHelp('mv');
314
330
  break;
315
331
  }
316
- await cmdMv(args[1], args[2]);
332
+ await cmdMv(strippedArgs[1], strippedArgs[2]);
317
333
  break;
318
334
  case 'diagnose':
319
- if (wantsHelp(args.slice(1))) {
335
+ if (wantsHelp(strippedArgs.slice(1))) {
320
336
  printLifecycleHelp('diagnose');
321
337
  break;
322
338
  }
323
- await cmdDiagnose(args.slice(1));
339
+ await cmdDiagnose(strippedArgs.slice(1));
324
340
  break;
325
341
  case 'data': {
326
342
  const { cmdData } = await import('./data-command.js');
327
- await cmdData(args.slice(1));
343
+ await cmdData(strippedArgs.slice(1));
328
344
  break;
329
345
  }
330
346
  case 'net': {
331
347
  const { cmdNet } = await import('./net-check.js');
332
- await cmdNet(args.slice(1));
348
+ await cmdNet(strippedArgs.slice(1));
349
+ break;
350
+ }
351
+ case 'integrity': {
352
+ const { cmdIntegrity } = await import('./integrity-command.js');
353
+ await cmdIntegrity(strippedArgs.slice(1));
333
354
  break;
334
355
  }
335
356
  case 'ctl':
336
- await cmdCtl(args.slice(1));
357
+ await cmdCtl(strippedArgs.slice(1));
337
358
  break;
338
359
  case 'memory':
339
- await cmdMemory(args.slice(1));
360
+ await cmdMemory(strippedArgs.slice(1));
340
361
  break;
341
362
  case 'queue':
342
- await cmdQueue(args.slice(1));
363
+ await cmdQueue(strippedArgs.slice(1));
343
364
  break;
344
365
  case 'task': {
345
366
  const { cmdTask } = await import('./task-command.js');
346
- await cmdTask(args.slice(1));
367
+ await cmdTask(strippedArgs.slice(1));
347
368
  break;
348
369
  }
349
370
  case 'trigger':
350
371
  {
351
372
  const { cmdTrigger } = await import('./trigger-command.js');
352
- await cmdTrigger(args.slice(1));
373
+ await cmdTrigger(strippedArgs.slice(1));
353
374
  }
354
375
  break;
355
376
  case 'agent': {
356
377
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
357
378
  suppressSdkLogs();
358
- await cmdAgent(args.slice(1));
379
+ await cmdAgent(strippedArgs.slice(1));
359
380
  break;
360
381
  }
361
382
  case 'aid': {
362
383
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
363
384
  suppressSdkLogs();
364
- await cmdAid(args.slice(1));
385
+ await cmdAid(strippedArgs.slice(1));
365
386
  break;
366
387
  }
367
388
  case 'rpc': {
368
389
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
369
390
  suppressSdkLogs();
370
- await cmdRpc(args.slice(1));
391
+ await cmdRpc(strippedArgs.slice(1));
371
392
  break;
372
393
  }
373
394
  case 'diag': {
374
395
  const { cmdDiag } = await import('./diag.js');
375
- await cmdDiag(args.slice(1));
396
+ await cmdDiag(strippedArgs.slice(1));
376
397
  break;
377
398
  }
378
399
  case 'menu-client': {
@@ -380,7 +401,7 @@ export async function main(args) {
380
401
  suppressSdkLogs();
381
402
  const { cmdMenuClient } = await import('./menu-client.js');
382
403
  try {
383
- await cmdMenuClient(args.slice(1));
404
+ await cmdMenuClient(strippedArgs.slice(1));
384
405
  }
385
406
  catch (error) {
386
407
  const payload = {
@@ -397,80 +418,90 @@ export async function main(args) {
397
418
  case 'storage': {
398
419
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
399
420
  suppressSdkLogs();
400
- await cmdStorage(args.slice(1));
421
+ await cmdStorage(strippedArgs.slice(1));
401
422
  break;
402
423
  }
403
424
  case 'fs': {
404
425
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
405
426
  suppressSdkLogs();
406
427
  const { cmdFs } = await import('./fs-command.js');
407
- await cmdFs(args.slice(1));
428
+ await cmdFs(strippedArgs.slice(1));
408
429
  break;
409
430
  }
410
431
  case 'msg': {
411
432
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
412
433
  suppressSdkLogs();
413
- await cmdMsg(args.slice(1));
434
+ await cmdMsg(strippedArgs.slice(1));
414
435
  break;
415
436
  }
416
437
  case 'handoff': {
417
438
  const { cmdHandoff } = await import('./handoff-command.js');
418
- await cmdHandoff(args.slice(1));
439
+ await cmdHandoff(strippedArgs.slice(1));
440
+ break;
441
+ }
442
+ case 'thread': {
443
+ const { runThreadCommand } = await import('./thread-command.js');
444
+ await runThreadCommand(strippedArgs.slice(1));
445
+ break;
446
+ }
447
+ case 'session': {
448
+ const { runSessionCommand } = await import('./session-command.js');
449
+ await runSessionCommand(strippedArgs.slice(1));
419
450
  break;
420
451
  }
421
452
  case 'group': {
422
453
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
423
454
  suppressSdkLogs();
424
- await cmdGroup(args.slice(1));
455
+ await cmdGroup(strippedArgs.slice(1));
425
456
  break;
426
457
  }
427
458
  case 'model': {
428
459
  const { cmdModel } = await import('./model.js');
429
- await cmdModel(args.slice(1));
460
+ await cmdModel(strippedArgs.slice(1));
430
461
  break;
431
462
  }
432
463
  case 'skill': {
433
464
  const { cmdSkill } = await import('./skill-command.js');
434
- await cmdSkill(args.slice(1));
465
+ await cmdSkill(strippedArgs.slice(1));
435
466
  break;
436
467
  }
437
468
  case 'response': {
438
469
  const { cmdResponse } = await import('./response.js');
439
- await cmdResponse(args.slice(1));
470
+ await cmdResponse(strippedArgs.slice(1));
440
471
  break;
441
472
  }
442
473
  case 'config': {
443
474
  const { cmdConfig } = await import('./config.js');
444
- await cmdConfig(args.slice(1));
475
+ await cmdConfig(strippedArgs.slice(1));
445
476
  break;
446
477
  }
447
478
  case 'contact': {
448
479
  const { cmdContact } = await import('./contact.js');
449
- await cmdContact(args.slice(1));
480
+ await cmdContact(strippedArgs.slice(1));
450
481
  break;
451
482
  }
452
483
  case 'stats': {
453
484
  const { handleStats } = await import('./stats.js');
454
- await handleStats(args.slice(1));
485
+ await handleStats(strippedArgs.slice(1));
455
486
  break;
456
487
  }
457
488
  case 'version':
458
489
  case '-v':
459
490
  case '--version': {
460
491
  const { handleVersion } = await import('./version.js');
461
- handleVersion(args.slice(1));
492
+ handleVersion(strippedArgs.slice(1));
462
493
  break;
463
494
  }
464
495
  case 'bench': {
465
496
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
466
497
  suppressSdkLogs();
467
498
  const { cmdBench } = await import('./bench.js');
468
- await cmdBench(args.slice(1));
499
+ await cmdBench(strippedArgs.slice(1));
469
500
  break;
470
501
  }
471
502
  case 'link-rules': {
472
503
  const { cmdLinkRules } = await import('./link-rules.js');
473
- cmdLinkRules(args.slice(1));
504
+ cmdLinkRules(strippedArgs.slice(1));
474
505
  break;
475
506
  }
476
507
  default:
package/dist/cli/init.js CHANGED
@@ -561,8 +561,8 @@ export async function initTail(options = {}) {
561
561
  async function handleOwnersPrompt(rl) {
562
562
  const daemonConfigForOwners = loadDaemonConfig();
563
563
  if (daemonConfigForOwners.aid && (!daemonConfigForOwners.owners || daemonConfigForOwners.owners.length === 0)) {
564
- const needOwner = (await ask(rl, '\n是否配置进程级管理者(Owner AID)?[y/N] ')).trim().toLowerCase();
565
- if (needOwner === 'y' || needOwner === 'yes') {
564
+ const needOwner = (await ask(rl, '\n是否配置进程级管理者(Owner AID)?[Y/n] ')).trim().toLowerCase();
565
+ if (!needOwner || needOwner === 'y' || needOwner === 'yes') {
566
566
  console.log('\n📡 进程级管理者绑定 — 请用 evol app 扫描二维码\n');
567
567
  // QR 绑定流程需要暂时关闭 rl,因为它会创建自己的输入监听
568
568
  rl.pause();
@@ -0,0 +1,196 @@
1
+ /**
2
+ * integrity-command.ts — `ec integrity` 子命令
3
+ *
4
+ * 子命令:
5
+ * ec integrity check <path> — 检查单个文件的台账状态(不修改,不恢复)
6
+ * ec integrity seal <path> — 把当前磁盘内容作为新基线登记(确认一次合法的带外修改)
7
+ * ec integrity query <path> — 打印台账记录(sha256、时间、登记方)
8
+ * ec integrity list — 列出所有已登记文件的状态摘要
9
+ *
10
+ * 所有操作都是本地 CLI,不经过 daemon IPC。
11
+ * 注意:ec integrity 不在 managed 白名单里,agent 会话内执行会被拒绝。
12
+ */
13
+ import { createRequire } from 'module';
14
+ import { checkFile, queryRecord, registerFile } from '../core/file-integrity/store.js';
15
+ import { integrityDbPath, resolveRoot } from '../paths.js';
16
+ import fs from 'fs';
17
+ import path from 'path';
18
+ const requireFromHere = createRequire(import.meta.url);
19
+ const HELP = `用法: ec integrity <subcommand> [path]
20
+
21
+ 子命令:
22
+ check <path> 检查文件台账状态(不修改,不恢复文件)
23
+ seal <path> 把当前磁盘内容登记为新基线(确认合法的带外修改)
24
+ query <path> 查看台账记录(hash、时间、登记方)
25
+ list 列出所有已登记文件的摘要状态
26
+
27
+ 说明:
28
+ 台账库位于 $EVOLCORE_HOME/data/integrity/file-integrity.db
29
+ "seal" 操作相当于手动确认一次合法修改,使其成为新的校验基线。
30
+ 在开发模式下(非 node_modules 安装),系统文件不会自动校验,
31
+ 但可以用 seal 主动建立基线,便于后续对比。
32
+ `;
33
+ function fmtTime(unix) {
34
+ if (!unix)
35
+ return '—';
36
+ return new Date(unix * 1000).toLocaleString('zh-CN', {
37
+ year: 'numeric', month: '2-digit', day: '2-digit',
38
+ hour: '2-digit', minute: '2-digit', second: '2-digit',
39
+ hour12: false,
40
+ });
41
+ }
42
+ function fmtHash(h) {
43
+ return h.slice(0, 16) + '…';
44
+ }
45
+ function resolveTarget(arg) {
46
+ return path.isAbsolute(arg) ? arg : path.resolve(process.cwd(), arg);
47
+ }
48
+ function cmdCheck(target) {
49
+ const result = checkFile(target);
50
+ const rel = path.relative(resolveRoot(), target) || path.basename(target);
51
+ switch (result.status) {
52
+ case 'missing':
53
+ console.log(`❓ 文件不存在: ${rel}`);
54
+ process.exitCode = 1;
55
+ break;
56
+ case 'unregistered':
57
+ console.log(`🆕 未登记(使用 seal 建立基线): ${rel}`);
58
+ process.exitCode = 1;
59
+ break;
60
+ case 'verified':
61
+ console.log(`✅ 校验通过: ${rel}`);
62
+ console.log(` sha256: ${fmtHash(result.actual)}`);
63
+ break;
64
+ case 'tampered':
65
+ console.log(`❌ 已被修改: ${rel}`);
66
+ console.log(` 预期: ${fmtHash(result.expected)}`);
67
+ console.log(` 实际: ${fmtHash(result.actual)}`);
68
+ console.log(` 可恢复: ${result.restorable ? '是(快照完好)' : '否(快照已损坏)'}`);
69
+ process.exitCode = 1;
70
+ break;
71
+ }
72
+ }
73
+ function cmdSeal(target) {
74
+ if (!fs.existsSync(target)) {
75
+ console.error(`❌ 文件不存在: ${target}`);
76
+ process.exitCode = 1;
77
+ return;
78
+ }
79
+ registerFile(target);
80
+ const rel = path.relative(resolveRoot(), target) || path.basename(target);
81
+ console.log(`✅ 已登记为新基线: ${rel}`);
82
+ }
83
+ function cmdQuery(target) {
84
+ const rec = queryRecord(target);
85
+ const rel = path.relative(resolveRoot(), target) || path.basename(target);
86
+ if (!rec) {
87
+ console.log(`🆕 台账无记录: ${rel}`);
88
+ return;
89
+ }
90
+ console.log(`文件: ${rel}`);
91
+ console.log(` sha256: ${rec.sha256}`);
92
+ console.log(` 登记时间: ${fmtTime(rec.registered_at)}`);
93
+ console.log(` 最后校验: ${fmtTime(rec.last_verified_at)}`);
94
+ console.log(` 登记方: ${rec.registrar_aid ?? '(系统)'}`);
95
+ }
96
+ function cmdList() {
97
+ if (!fs.existsSync(integrityDbPath())) {
98
+ console.log('台账库尚未创建(还没有任何文件被登记过)');
99
+ return;
100
+ }
101
+ let DatabaseSync;
102
+ try {
103
+ ({ DatabaseSync } = requireFromHere('node:sqlite'));
104
+ }
105
+ catch {
106
+ console.error('❌ node:sqlite 不可用(需要 Node.js 22.5+)');
107
+ process.exitCode = 1;
108
+ return;
109
+ }
110
+ const db = new DatabaseSync(integrityDbPath(), { readonly: true });
111
+ const rows = db.prepare('SELECT file_path, sha256, registered_at, last_verified_at FROM file_integrity ORDER BY file_path').all();
112
+ if (rows.length === 0) {
113
+ console.log('台账为空');
114
+ return;
115
+ }
116
+ // 台账主键在 Windows 下是小写,root 也要按同样规则归一化才能前缀匹配
117
+ const rootSlash = resolveRoot().replace(/\\/g, '/');
118
+ const root = (process.platform === 'win32' ? rootSlash.toLowerCase() : rootSlash) + '/';
119
+ let ok = 0, tampered = 0, missing = 0;
120
+ console.log(`台账共 ${rows.length} 条记录(${integrityDbPath()})\n`);
121
+ for (const row of rows) {
122
+ const rel = row.file_path.replace(/\\/g, '/').startsWith(root)
123
+ ? row.file_path.replace(/\\/g, '/').slice(root.length)
124
+ : row.file_path;
125
+ const chk = checkFile(row.file_path);
126
+ let icon;
127
+ switch (chk.status) {
128
+ case 'verified':
129
+ icon = '✅';
130
+ ok++;
131
+ break;
132
+ case 'tampered':
133
+ icon = '❌';
134
+ tampered++;
135
+ break;
136
+ case 'missing':
137
+ icon = '❓';
138
+ missing++;
139
+ break;
140
+ case 'unregistered':
141
+ icon = '🆕';
142
+ break;
143
+ default: icon = ' ';
144
+ }
145
+ console.log(`${icon} ${rel}`);
146
+ if (chk.status === 'tampered') {
147
+ console.log(` 预期: ${fmtHash(row.sha256)} 实际: ${fmtHash(chk.actual)}`);
148
+ }
149
+ }
150
+ console.log(`\n摘要:通过 ${ok},已改 ${tampered},不存在 ${missing}`);
151
+ if (tampered > 0 || missing > 0)
152
+ process.exitCode = 1;
153
+ }
154
+ export async function cmdIntegrity(args) {
155
+ const sub = args[0];
156
+ if (!sub || sub === '--help' || sub === '-h') {
157
+ console.log(HELP);
158
+ return;
159
+ }
160
+ switch (sub) {
161
+ case 'check': {
162
+ if (!args[1]) {
163
+ console.error('用法: ec integrity check <path>');
164
+ process.exitCode = 1;
165
+ return;
166
+ }
167
+ cmdCheck(resolveTarget(args[1]));
168
+ break;
169
+ }
170
+ case 'seal': {
171
+ if (!args[1]) {
172
+ console.error('用法: ec integrity seal <path>');
173
+ process.exitCode = 1;
174
+ return;
175
+ }
176
+ cmdSeal(resolveTarget(args[1]));
177
+ break;
178
+ }
179
+ case 'query': {
180
+ if (!args[1]) {
181
+ console.error('用法: ec integrity query <path>');
182
+ process.exitCode = 1;
183
+ return;
184
+ }
185
+ cmdQuery(resolveTarget(args[1]));
186
+ break;
187
+ }
188
+ case 'list':
189
+ cmdList();
190
+ break;
191
+ default:
192
+ console.error(`未知子命令: ${sub}`);
193
+ console.log(HELP);
194
+ process.exitCode = 1;
195
+ }
196
+ }
@@ -18,8 +18,13 @@ const MANAGED_TASK_COMMANDS = new Set([
18
18
  'msg',
19
19
  'queue',
20
20
  'response',
21
+ // `session` 按 ec 会话 id 只读查询本地 session 存档(meta 文件尾行的
22
+ // agentSessionId 等),不触碰 daemon 与进程生命周期。
23
+ 'session',
21
24
  // `skill` 管理 EC 技能(安装/开关/校验)。它的主要使用者就是 agent 自己——
22
25
  // ec-skill 技能的 SKILL.md 明确指导 agent 调用它。脚本只读写
26
+ // `thread` 提供话题链操作,通过 thread.op IPC 鉴权
27
+ 'thread',
23
28
  // $EVOLCORE_HOME/skills/ 与 kits/skills/ 下的技能文件,不触碰进程生命周期。
24
29
  // 本白名单只负责让它进到脚本;具体某一级的读写权限由 skill.mjs 的
25
30
  // assertPermission() 按会话上下文判定(群聊一律拒,Agent 级要 owner,