evolcore 0.0.32 → 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.
Files changed (150) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/bin/install-codex-managed-hooks.mjs +124 -37
  3. package/dist/agents/claude-runner.js +29 -2
  4. package/dist/agents/codex/app-server-client.js +3 -0
  5. package/dist/agents/codex/diagnostics.js +76 -44
  6. package/dist/agents/codex-runner.js +23 -19
  7. package/dist/agents/ecagent-runner.js +5 -13
  8. package/dist/aun/group/operations.js +0 -1
  9. package/dist/aun/msg/history.js +1 -0
  10. package/dist/aun/msg/p2p.js +0 -1
  11. package/dist/aun/outbox.js +50 -1
  12. package/dist/channels/aun.js +28 -2
  13. package/dist/channels/daemon.js +257 -2
  14. package/dist/cli/agent-command.js +58 -24
  15. package/dist/cli/agent.js +1 -1
  16. package/dist/cli/aun-commands.js +365 -29
  17. package/dist/cli/contact.js +8 -2
  18. package/dist/cli/daemon-commands.js +81 -12
  19. package/dist/cli/debug-mode.js +154 -0
  20. package/dist/cli/handoff-command.js +3 -0
  21. package/dist/cli/index.js +81 -64
  22. package/dist/cli/init.js +2 -2
  23. package/dist/cli/managed-command-guard.js +5 -0
  24. package/dist/cli/memory-command.js +8 -1
  25. package/dist/cli/queue-command.js +9 -4
  26. package/dist/cli/session-command.js +194 -0
  27. package/dist/cli/skill-command.js +78 -2
  28. package/dist/cli/task-context.js +1 -0
  29. package/dist/cli/thread-command.js +620 -0
  30. package/dist/cli/trigger-command.js +4 -2
  31. package/dist/config/builtin-roles.js +1 -0
  32. package/dist/config/config-field-policy.js +2 -3
  33. package/dist/config/config-manager.js +7 -2
  34. package/dist/config/resolved-config-op.js +3 -0
  35. package/dist/config-store.js +15 -0
  36. package/dist/core/auth/agent-delegation.js +25 -1
  37. package/dist/core/auth/debug-context.js +139 -0
  38. package/dist/core/auth/operation-authorizer.js +24 -1
  39. package/dist/core/auth/operation-catalog.js +33 -0
  40. package/dist/core/background-session/session-cleanup.js +212 -0
  41. package/dist/core/background-session/types.js +10 -0
  42. package/dist/core/bootstrap-messages.js +1 -1
  43. package/dist/core/bootstrap-service.js +6 -3
  44. package/dist/core/command/command-handler.js +60 -24
  45. package/dist/core/command/memory-slash.js +6 -2
  46. package/dist/core/command/menu-catalog.js +48 -1
  47. package/dist/core/command/menu-handler.js +92 -16
  48. package/dist/core/command/menu-protocol.js +24 -1
  49. package/dist/core/command/skill-slash.js +322 -0
  50. package/dist/core/command/slash-gate.js +6 -4
  51. package/dist/core/command/slash-handler.js +193 -13
  52. package/dist/core/command/topic-slash.js +528 -0
  53. package/dist/core/evolagent-registry.js +20 -5
  54. package/dist/core/handoff/runtime.js +5 -11
  55. package/dist/core/handoff/store.js +5 -0
  56. package/dist/core/ipc-registration.js +139 -2
  57. package/dist/core/memory/consolidation-context.js +49 -16
  58. package/dist/core/memory/consolidation-ops-records.js +35 -0
  59. package/dist/core/memory/consolidation-queue-format.js +21 -0
  60. package/dist/core/memory/consolidation.js +174 -180
  61. package/dist/core/message/aun-ipc-sender.js +161 -6
  62. package/dist/core/message/im-renderer.js +149 -6
  63. package/dist/core/message/message-bridge.js +13 -3
  64. package/dist/core/message/message-log.js +1 -0
  65. package/dist/core/message/peer-mode.js +6 -1
  66. package/dist/core/message/response-engine.js +349 -67
  67. package/dist/core/message/subtask-tool-projection.js +140 -0
  68. package/dist/core/model/catalog-service.js +17 -12
  69. package/dist/core/permission/ec-command-parser.js +126 -7
  70. package/dist/core/session/session-idle-monitor.js +249 -22
  71. package/dist/core/session/session-manager.js +54 -9
  72. package/dist/core/skill/command-parser.js +13 -0
  73. package/dist/core/skill/index-generator.js +4 -1
  74. package/dist/core/skill/startup.js +41 -0
  75. package/dist/core/skill/switch-resolver.js +55 -29
  76. package/dist/core/thread/command-parser.js +125 -0
  77. package/dist/core/thread/index.js +1 -0
  78. package/dist/core/thread/ipc-operation.js +95 -0
  79. package/dist/core/thread/thread-context-storage.js +131 -0
  80. package/dist/core/thread/thread-operation.js +258 -0
  81. package/dist/core/thread/thread-route.js +33 -0
  82. package/dist/core/thread/thread-service.js +777 -0
  83. package/dist/core/thread/types.js +1 -0
  84. package/dist/eck/message-renderer.js +35 -0
  85. package/dist/index.js +8 -5
  86. package/dist/ipc.js +89 -10
  87. package/dist/paths.js +23 -0
  88. package/dist/response-system/engines/v1/proactive-flow.js +169 -80
  89. package/dist/trigger/authorization.js +57 -28
  90. package/dist/trigger/feedback.js +7 -1
  91. package/dist/trigger/parser.js +63 -1
  92. package/dist/trigger/validation.js +14 -0
  93. package/dist/utils/error-utils.js +22 -1
  94. package/kits/docs/context-assembly.md +1 -0
  95. package/kits/docs/evolcore/INDEX.md +1 -0
  96. package/kits/docs/evolcore/agent-create.md +39 -28
  97. package/kits/docs/evolcore/agent.md +19 -4
  98. package/kits/docs/evolcore/ec-capabilities.md +4 -0
  99. package/kits/docs/evolcore/group-collaboration.md +3 -5
  100. package/kits/docs/evolcore/group.md +3 -4
  101. package/kits/docs/evolcore/memory-consolidation.md +1 -1
  102. package/kits/docs/evolcore/menu-exec-schema-commands.md +2 -2
  103. package/kits/docs/evolcore/menu-protocol.md +7 -0
  104. package/kits/docs/evolcore/msg.md +5 -8
  105. package/kits/docs/evolcore/thread-chain.md +267 -0
  106. package/kits/docs/prompt-loading-architecture.md +1 -0
  107. package/kits/eck_manifest.json +61 -26
  108. package/kits/eck_message_manifest.json +169 -10
  109. package/kits/rules/05-venue.md +1 -1
  110. package/kits/rules/07-memory-and-thread.md +202 -0
  111. package/kits/schemas/relation-config.schema.9.json +18 -3
  112. package/kits/schemas/role-config.schema.1.json +6 -6
  113. package/kits/schemas/single-session.schema.1.json +6 -6
  114. package/kits/schemas/single-session.schema.2.json +6 -6
  115. package/kits/schemas/single-session.schema.3.json +6 -6
  116. package/kits/skills/.switches.json +12 -1
  117. package/kits/skills/ec-group/SKILL.md +234 -0
  118. package/kits/skills/ec-skill/SKILL.md +10 -1
  119. package/kits/skills/ec-skill/scripts/cli.mjs +15 -1
  120. package/kits/skills/scrapling-article-fetch/SKILL.md +128 -0
  121. package/kits/skills/scrapling-article-fetch/scripts/check_python_env.py +54 -0
  122. package/kits/skills/scrapling-article-fetch/scripts/render_markdown_reply.py +35 -0
  123. package/kits/skills/scrapling-article-fetch/scripts/run_pipeline.sh +16 -0
  124. package/kits/skills/scrapling-article-fetch/scripts/scrapling_fetch.py +344 -0
  125. package/kits/skills/thread-ops/SKILL.md +492 -0
  126. package/kits/skills/wechat-article-media-download/SKILL.md +65 -0
  127. package/kits/skills/wechat-article-media-download/scripts/download.py +163 -0
  128. package/kits/skills/wechat-article-reader/SKILL.md +97 -0
  129. package/kits/skills/wechat-article-reader/scripts/fetch.mjs +256 -0
  130. package/kits/templates/bootstrap-welcome.md +7 -7
  131. package/kits/templates/memory-consolidation/forget.md +5 -0
  132. package/kits/templates/memory-consolidation/generalize.md +5 -0
  133. package/kits/templates/memory-consolidation/profile.md +5 -0
  134. package/kits/templates/memory-consolidation/promote.md +5 -0
  135. package/kits/templates/message-fragments/item.md +2 -1
  136. package/kits/templates/message-fragments/thread-context.md +6 -0
  137. package/kits/templates/message-fragments/trigger-session.md +2 -0
  138. package/kits/templates/message-fragments/trigger-thread-check.md +2 -0
  139. package/kits/templates/roles/member.json +2 -0
  140. package/kits/templates/roles/visitor.json +2 -0
  141. package/kits/templates/system-fragments/bootstrap.md +66 -72
  142. package/kits/templates/system-fragments/channel.md +3 -6
  143. package/kits/templates/system-fragments/commands.md +1 -0
  144. package/kits/templates/system-fragments/managed-runtime.md +15 -0
  145. package/kits/templates/system-fragments/reply.md +3 -2
  146. package/kits/templates/system-fragments/session.md +5 -14
  147. package/package.json +3 -1
  148. package/kits/docs/evolcore/group-fs.md +0 -17
  149. package/kits/docs/venues/aun-group.md +0 -45
  150. package/kits/docs/venues/group.md +0 -43
@@ -25,7 +25,7 @@ import { isNonAgentSessionChannel } from '../core/system-channels.js';
25
25
  import { printCodeStats } from './code-stats.js';
26
26
  import { getProcessStartTime, startTimeMatches } from '../utils/process-introspect.js';
27
27
  import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
28
- import { RUNTIME_HOME_ENV, WEB_CLI_BIN, WEB_PACKAGE_LATEST, WEB_PACKAGE_NAME } from '../product.js';
28
+ import { MAIN_CLI_BIN, RUNTIME_HOME_ENV, WEB_CLI_BIN, WEB_PACKAGE_LATEST, WEB_PACKAGE_NAME } from '../product.js';
29
29
  import { rotateStdoutLog } from '../utils/log-writer.js';
30
30
  import { inspectDataMigrationRequirement } from '../core/data-migration.js';
31
31
  import { isInitCancelledError, printInitCancelHint } from './init-cancel.js';
@@ -34,8 +34,34 @@ import { listCodexAppServerProcesses, unregisterCodexAppServerProcess } from '..
34
34
  import { DEFAULT_ECWEB_PORT, ecwebService, setEcwebEnabled } from '../config/daemon-services.js';
35
35
  import { checkCodexProjectPath, inspectCodexManagedHook, ensureCodexManagedHook, runCodexHookLaunchDiagnostic, } from '../agents/codex/diagnostics.js';
36
36
  const execFileAsync = promisify(execFile);
37
+ export async function confirmCodexHookRebind(state, packageRoot) {
38
+ console.log('⚠️ Codex 受管 Hook 绑定的另一套 EvolCore/Node 路径仍存在,需确认是否切换:');
39
+ console.log(` 现有包: ${state.managedPackageRoot}`);
40
+ console.log(` 现有 Node: ${state.managedNodePath}`);
41
+ console.log(` 当前包: ${packageRoot}`);
42
+ console.log(` 当前 Node: ${process.execPath}`);
43
+ console.log(' 切换会更新机器级 Hook,影响共享此策略的 Codex 会话;不会执行数据迁移。');
44
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
45
+ console.warn(` 非交互模式不自动选择。请在交互式终端运行 ${MAIN_CLI_BIN} start 确认;也可使用现有安装的 CLI。`);
46
+ return false;
47
+ }
48
+ const terminal = readline.createInterface({ input: process.stdin, output: process.stdout });
49
+ return new Promise(resolve => {
50
+ let settled = false;
51
+ const finish = (confirmed) => {
52
+ if (settled)
53
+ return;
54
+ settled = true;
55
+ terminal.close();
56
+ resolve(confirmed);
57
+ };
58
+ terminal.once('close', () => finish(false));
59
+ terminal.once('SIGINT', () => finish(false));
60
+ terminal.question(' [1] 切换到当前包/Node 并修复 [2] 保留原绑定并取消本次启动 [1/2,默认 2]: ', answer => finish(answer.trim() === '1'));
61
+ });
62
+ }
37
63
  /** Run before launch, and before restart stops any existing daemon. */
38
- export function ensureCodexHookBeforeLifecycle(onRepaired) {
64
+ export async function ensureCodexHookBeforeLifecycle(onRepaired) {
39
65
  if (!platform.isWindows)
40
66
  return true;
41
67
  try {
@@ -53,19 +79,31 @@ export function ensureCodexHookBeforeLifecycle(onRepaired) {
53
79
  });
54
80
  if (!usesCodex)
55
81
  return true;
56
- const result = ensureCodexManagedHook({
57
- packageRoot: getPackageRoot(),
58
- onInstallRequired: () => console.log('🔧 Codex 运行组件缺失,正在自动安装;Windows 提示管理员授权时请选择“是”。'),
82
+ const packageRoot = getPackageRoot();
83
+ const result = await ensureCodexManagedHook({
84
+ packageRoot,
85
+ repairDecision: state => confirmCodexHookRebind(state, packageRoot),
86
+ onInstallRequired: state => console.log(state.status === 'stale'
87
+ ? '🔧 Codex 受管 Hook 路径已过期,正在修复;Windows 提示管理员授权时请选择“是”。'
88
+ : '🔧 Codex 运行组件缺失,正在自动安装;Windows 提示管理员授权时请选择“是”。'),
59
89
  });
60
90
  if (result.status === 'installed') {
61
91
  if (result.repaired) {
62
- console.log('✅ Codex Windows managed hook 已自动安装并验证');
92
+ console.log('✅ Codex Windows managed hook 已修复并验证');
63
93
  onRepaired?.();
64
94
  }
65
95
  return true;
66
96
  }
67
- console.error(`❌ Codex Windows managed hook 未就绪:${result.error || result.reason || result.status}`);
68
- if (result.status === 'missing') {
97
+ if (result.cancelled) {
98
+ console.warn('ℹ 未确认切换 Codex 受管 Hook,保留原绑定;本次启动/重启已取消,现有服务未停止。');
99
+ process.exitCode = 1;
100
+ return false;
101
+ }
102
+ console.error(`❌ Codex Windows managed hook 启动检查未通过:${result.error || result.reason || result.status}`);
103
+ if (result.status === 'stale') {
104
+ console.error(` 本次操作已停止,现有服务未停止。请在交互式终端运行 ${MAIN_CLI_BIN} start 确认修复,或使用原安装的 CLI。`);
105
+ }
106
+ else if (result.status === 'missing') {
69
107
  console.error(' 本次操作已停止。下次启动或重启会再次自动尝试安装,需要允许 Windows 管理员授权。');
70
108
  }
71
109
  else {
@@ -192,6 +230,7 @@ function buildDaemonEnv(p, opts) {
192
230
  EVENT_LOG: process.env.EVENT_LOG || 'true',
193
231
  ...(opts.diagnose ? { EVOLCORE_DIAGNOSE: '1' } : {}),
194
232
  ...(opts.bindBootstrap ? { EVOLCORE_BIND_BOOTSTRAP: '1' } : {}),
233
+ ...(opts.debug ? { EVOLCORE_DEBUG_MODE: '1' } : {}),
195
234
  };
196
235
  }
197
236
  function latestSourceMtime(dir) {
@@ -474,10 +513,10 @@ export async function cmdStart(opts = {}) {
474
513
  const existingDaemon = await probeDaemon(p.socket);
475
514
  if (existingDaemon) {
476
515
  let hookRepaired = false;
477
- if (!ensureCodexHookBeforeLifecycle(() => { hookRepaired = true; }))
516
+ if (!await ensureCodexHookBeforeLifecycle(() => { hookRepaired = true; }))
478
517
  return;
479
518
  if (hookRepaired) {
480
- console.log('🔄 Codex 运行组件已补齐,正在自动重启服务以加载策略...');
519
+ console.log('🔄 Codex 运行组件已修复,正在自动重启服务以加载策略...');
481
520
  await cmdRestart({ diagnose: opts.diagnose });
482
521
  return;
483
522
  }
@@ -524,7 +563,7 @@ export async function cmdStart(opts = {}) {
524
563
  // The initialization path can create the first Codex agent, so perform the
525
564
  // machine-hook check after config migration/auto-init and before any daemon
526
565
  // process is launched.
527
- if (!ensureCodexHookBeforeLifecycle())
566
+ if (!await ensureCodexHookBeforeLifecycle())
528
567
  return;
529
568
  // 控制 AID 门禁:缺 aid 且交互式 → 只补全控制 AID + owners(不重走 baseagent 向导)。
530
569
  // 非 TTY(restart-monitor/systemd/管道)不补全(无法交互),只提示后继续启动,daemon 侧 warn 兜底。
@@ -666,6 +705,21 @@ export async function cmdStart(opts = {}) {
666
705
  console.log(` EVOLCORE_HOME: ${resolveRoot()}`);
667
706
  console.log(` Logs: ${p.logs}/`);
668
707
  console.log(`⏱ ready in ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s`);
708
+ if (opts.debug) {
709
+ console.log('');
710
+ console.log('🔧 调试模式已启用(EVOLCORE_DEBUG_MODE=1)');
711
+ console.log(' 在宿主终端以任意 session 身份执行命令:');
712
+ console.log('');
713
+ console.log(' ec msg send "消息内容" --as-session <sessionId>');
714
+ console.log(' ec trigger list --as-session <sessionId>');
715
+ console.log(' ec memory list --as-session <sessionId>');
716
+ console.log('');
717
+ console.log(' 查看可用会话(运行后将在此处列出):');
718
+ console.log(' ec msg send "test" --as-session # 不带 sessionId 自动列出');
719
+ console.log('');
720
+ console.log(' 注意:重启 daemon(ec restart)会清除调试模式,');
721
+ console.log(' 需重新执行 ec start --debug 才能恢复。');
722
+ }
669
723
  void waitForExistingEcweb(p).then((ecweb) => {
670
724
  if (shouldPrintNoSelfAgentHints) {
671
725
  printNoSelfAgentHints({ daemonConfig: loadDaemonConfig(), ecwebStarted: ecweb !== null, skipped });
@@ -769,6 +823,21 @@ export async function cmdStart(opts = {}) {
769
823
  printCodeStats(getPackageRoot(), p.logs);
770
824
  }
771
825
  console.log(`⏱ done in ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s`);
826
+ if (opts.debug) {
827
+ console.log('');
828
+ console.log('🔧 调试模式已启用(EVOLCORE_DEBUG_MODE=1)');
829
+ console.log(' 在宿主终端以任意 session 身份执行命令:');
830
+ console.log('');
831
+ console.log(' ec msg send "消息内容" --as-session <sessionId>');
832
+ console.log(' ec trigger list --as-session <sessionId>');
833
+ console.log(' ec memory list --as-session <sessionId>');
834
+ console.log('');
835
+ console.log(' 查看可用会话(运行后将在此处列出):');
836
+ console.log(' ec msg send "test" --as-session # 不带 sessionId 自动列出');
837
+ console.log('');
838
+ console.log(' 注意:重启 daemon(ec restart)会清除调试模式,');
839
+ console.log(' 需重新执行 ec start --debug 才能恢复。');
840
+ }
772
841
  // ECWeb lifecycle belongs to the daemon; the CLI only reports whether
773
842
  // the supervised instance became healthy.
774
843
  const ecwebStarted = await waitForExistingEcweb(p) !== null;
@@ -904,7 +973,7 @@ export async function cmdStop() {
904
973
  export async function cmdRestart(opts = {}) {
905
974
  const cmdStartedAt = Date.now();
906
975
  console.log('🔄 Restarting EvolCore...');
907
- if (!ensureCodexHookBeforeLifecycle())
976
+ if (!await ensureCodexHookBeforeLifecycle())
908
977
  return;
909
978
  const initialStatus = scanInstances();
910
979
  const socketPath = resolvePaths().socket;
@@ -0,0 +1,154 @@
1
+ /**
2
+ * debug-mode.ts — `--as-session <sessionId>` 调试路径
3
+ *
4
+ * 在外部终端(宿主 CC 终端)以任意 agent 身份执行托管命令。
5
+ * 调用方在检查 EVOLCORE_SESSION_ID 之前先调用 resolveDebugContext(args);
6
+ * 注入完成后 process.env.EVOLCORE_SESSION_ID 已设好,后续走统一托管路径。
7
+ */
8
+ import fs from 'fs';
9
+ import path from 'path';
10
+ import { resolvePaths, debugSessionsDir } from '../paths.js';
11
+ import { ipcQuery } from '../ipc.js';
12
+ import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
13
+ import { buildTaskRuntimeEnv } from './task-context.js';
14
+ const AS_SESSION_FLAG = '--as-session';
15
+ function formatTimeAgo(ms) {
16
+ const s = Math.floor(ms / 1000);
17
+ if (s < 60)
18
+ return `${s}秒前`;
19
+ const m = Math.floor(s / 60);
20
+ if (m < 60)
21
+ return `${m}分钟前`;
22
+ const h = Math.floor(m / 60);
23
+ if (h < 24)
24
+ return `${h}小时前`;
25
+ return `${Math.floor(h / 24)}天前`;
26
+ }
27
+ function listAvailableSessions() {
28
+ const dir = debugSessionsDir();
29
+ if (!fs.existsSync(dir))
30
+ return { sessions: [], dirExists: false };
31
+ try {
32
+ const sessions = fs.readdirSync(dir)
33
+ .filter(f => f.endsWith('.json'))
34
+ .map(f => {
35
+ try {
36
+ return JSON.parse(fs.readFileSync(path.join(dir, f), 'utf-8'));
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ })
42
+ .filter((s) => s !== null && !!s.sessionId)
43
+ .sort((a, b) => b.writtenAt - a.writtenAt)
44
+ .slice(0, 20);
45
+ return { sessions, dirExists: true };
46
+ }
47
+ catch {
48
+ return { sessions: [], dirExists: true };
49
+ }
50
+ }
51
+ function printSessionList(result) {
52
+ const { sessions, dirExists } = result;
53
+ if (!dirExists) {
54
+ console.error('❌ 调试模式未启用。请先执行:ec start --debug');
55
+ return;
56
+ }
57
+ if (sessions.length === 0) {
58
+ console.error('ℹ️ 调试模式已启用,但暂无可用会话。');
59
+ console.error(' 请等待 agent 收到至少一条消息后再试。');
60
+ return;
61
+ }
62
+ console.error('\n可用会话(最近 20 个):');
63
+ for (const s of sessions) {
64
+ const age = formatTimeAgo(Date.now() - s.writtenAt);
65
+ console.error(` ${s.sessionId} ${s.selfAid} → ${s.channelId} ${age}`);
66
+ }
67
+ }
68
+ /**
69
+ * 检测命令行参数中是否包含 --as-session,若有则执行调试路径:
70
+ * 1. 互斥检查(托管会话中拒绝)
71
+ * 2. 读临时文件
72
+ * 3. 调 debug-issue-token IPC 现取 token
73
+ * 4. 注入 process.env,后续命令走统一托管路径
74
+ *
75
+ * 不带 --as-session 时直接返回,不做任何事。
76
+ */
77
+ export async function resolveDebugContext(args) {
78
+ const flagIdx = args.indexOf(AS_SESSION_FLAG);
79
+ if (flagIdx === -1)
80
+ return;
81
+ // 互斥检查:托管会话里不允许 --as-session
82
+ if (process.env.EVOLCORE_SESSION_ID) {
83
+ console.error('❌ --as-session 仅限外部终端使用,托管会话中不可用');
84
+ process.exit(1);
85
+ }
86
+ const sessionId = args[flagIdx + 1];
87
+ // 不带 sessionId 或 sessionId 以 - 开头(下一个 flag)
88
+ if (!sessionId || sessionId.startsWith('-')) {
89
+ console.error('❌ --as-session 需要指定 sessionId\n');
90
+ console.error(`使用:ec <命令> --as-session <sessionId>`);
91
+ printSessionList(listAvailableSessions());
92
+ process.exit(1);
93
+ }
94
+ if (!/^[A-Za-z0-9][A-Za-z0-9_.-]*$/.test(sessionId)) {
95
+ console.error('❌ 无效 sessionId');
96
+ process.exit(1);
97
+ }
98
+ // 读临时文件(session bind 时已写入)
99
+ const snapshotPath = path.join(debugSessionsDir(), `${sessionId}.json`);
100
+ if (!fs.existsSync(snapshotPath)) {
101
+ const result = listAvailableSessions();
102
+ if (!result.dirExists) {
103
+ console.error('❌ 调试模式未启用。请先执行:ec start --debug');
104
+ }
105
+ else {
106
+ console.error(`❌ 调试会话不存在:${sessionId}\n`);
107
+ printSessionList(result);
108
+ }
109
+ process.exit(1);
110
+ }
111
+ // 调 debug-issue-token IPC 现取 token
112
+ let response;
113
+ try {
114
+ response = await ipcQuery(resolvePaths().socket, { type: 'debug-issue-token', sessionId }, 5000);
115
+ }
116
+ catch (err) {
117
+ console.error(`❌ 无法连接 daemon:${err instanceof Error ? err.message : String(err)}`);
118
+ console.error('请确认 daemon 正在以 debug 模式运行:ec start --debug');
119
+ process.exit(1);
120
+ }
121
+ if (!response) {
122
+ console.error('❌ daemon 无响应,请确认 daemon 正在以 debug 模式运行:ec start --debug');
123
+ process.exit(1);
124
+ }
125
+ if (!response.ok) {
126
+ console.error(`❌ 无法获取调试 token:${response.error}`);
127
+ process.exit(1);
128
+ }
129
+ const { token, runtimeContext } = response;
130
+ // 注入 process.env,后续代码走统一托管路径
131
+ // 注意:去掉 daemonRuntimeEpoch——debug session 不是真实任务,
132
+ // 不应该受 ipc.ts 里的 daemon epoch 检查约束,否则 msg send --thread 后续命令会报
133
+ // "The task delegation token belongs to a previous daemon runtime"
134
+ const ctxWithoutEpoch = { ...runtimeContext, daemonRuntimeEpoch: undefined };
135
+ Object.assign(process.env, buildTaskRuntimeEnv(ctxWithoutEpoch));
136
+ process.env[AGENT_DELEGATION_TOKEN_ENV] = token;
137
+ // thread 命令从 EVOLCORE_SELF_AID 读 selfAid(不走 taskRuntimeContext),单独注入
138
+ if (runtimeContext.selfAid)
139
+ process.env.EVOLCORE_SELF_AID = runtimeContext.selfAid;
140
+ }
141
+ /** 从 args 中去掉 --as-session <sessionId> 两个元素,返回净化后的参数列表 */
142
+ export function stripAsSessionArgs(args) {
143
+ const result = [];
144
+ let i = 0;
145
+ while (i < args.length) {
146
+ if (args[i] === AS_SESSION_FLAG) {
147
+ i += 2; // 跳过 flag 和 sessionId
148
+ }
149
+ else {
150
+ result.push(args[i++]);
151
+ }
152
+ }
153
+ return result;
154
+ }
@@ -162,6 +162,9 @@ export async function cmdHandoff(args) {
162
162
  if (!sub || isHelpFlag(sub) || wantsHelp(args)) {
163
163
  console.log(`用法: ec handoff <command> [args]
164
164
 
165
+ ⚠ ec handoff 已废弃,请改用话题链(ec thread + ec msg send --thread)。
166
+ 本命令保留以兼容现有脚本,将在 P2 后续版本中移除。
167
+
165
168
  Commands:
166
169
  return [handoff-id] [content] 提交一个回流结果;required 可用同一 ID 追加多个结果
167
170
  return [handoff-id] --text-from-file <path>