evolclaw 3.1.4 → 3.1.6

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 (99) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/dist/agents/claude-runner.js +398 -161
  3. package/dist/agents/kit-renderer.js +191 -25
  4. package/dist/aun/aid/agentmd.js +75 -103
  5. package/dist/aun/aid/client.js +1 -29
  6. package/dist/aun/aid/identity.js +105 -64
  7. package/dist/aun/aid/index.js +2 -1
  8. package/dist/aun/aid/store.js +74 -0
  9. package/dist/aun/msg/group.js +2 -2
  10. package/dist/aun/msg/p2p.js +26 -2
  11. package/dist/aun/rpc/connection.js +23 -30
  12. package/dist/channels/aun.js +174 -99
  13. package/dist/channels/dingtalk.js +2 -1
  14. package/dist/channels/feishu.js +301 -199
  15. package/dist/channels/qqbot.js +2 -1
  16. package/dist/channels/wechat.js +2 -1
  17. package/dist/channels/wecom.js +2 -1
  18. package/dist/cli/agent.js +21 -16
  19. package/dist/cli/bench.js +41 -28
  20. package/dist/cli/help.js +8 -0
  21. package/dist/cli/index.js +176 -87
  22. package/dist/cli/init-channel.js +5 -1
  23. package/dist/cli/init.js +37 -21
  24. package/dist/cli/link-rules.js +1 -7
  25. package/dist/cli/model.js +549 -0
  26. package/dist/cli/net-check.js +133 -50
  27. package/dist/cli/watch-msg.js +7 -7
  28. package/dist/cli/watch-web/debug-log.js +18 -0
  29. package/dist/cli/watch-web/server.js +306 -0
  30. package/dist/cli/watch-web/sources/aid.js +63 -0
  31. package/dist/cli/watch-web/sources/msg.js +70 -0
  32. package/dist/cli/watch-web/sources/session.js +638 -0
  33. package/dist/cli/watch-web/sources/types.js +10 -0
  34. package/dist/cli/watch-web/static/app.js +546 -0
  35. package/dist/cli/watch-web/static/index.html +54 -0
  36. package/dist/cli/watch-web/static/style.css +247 -0
  37. package/dist/config-store.js +1 -22
  38. package/dist/core/channel-loader.js +7 -4
  39. package/dist/core/command-handler.js +261 -133
  40. package/dist/core/evolagent-registry.js +1 -1
  41. package/dist/core/evolagent.js +4 -22
  42. package/dist/core/interaction-router.js +59 -0
  43. package/dist/core/message/im-renderer.js +9 -20
  44. package/dist/core/message/message-bridge.js +13 -9
  45. package/dist/core/message/message-log.js +2 -2
  46. package/dist/core/message/message-processor.js +211 -123
  47. package/dist/core/message/stream-idle-monitor.js +21 -0
  48. package/dist/core/model/model-catalog.js +215 -0
  49. package/dist/core/model/model-scope.js +250 -0
  50. package/dist/core/relation/peer-identity.js +58 -55
  51. package/dist/core/relation/peer-key.js +16 -0
  52. package/dist/core/session/session-fs-store.js +34 -55
  53. package/dist/core/session/session-key.js +24 -0
  54. package/dist/core/session/session-manager.js +308 -251
  55. package/dist/core/session/session-mapper.js +9 -4
  56. package/dist/core/trigger/manager.js +3 -3
  57. package/dist/core/trigger/parser.js +4 -4
  58. package/dist/core/trigger/scheduler.js +22 -7
  59. package/dist/index.js +61 -7
  60. package/dist/ipc.js +23 -1
  61. package/dist/utils/error-utils.js +6 -0
  62. package/dist/utils/process-introspect.js +7 -5
  63. package/kits/docs/GUIDE.md +2 -2
  64. package/kits/docs/INDEX.md +8 -8
  65. package/kits/docs/channels/aun.md +56 -17
  66. package/kits/docs/channels/feishu.md +41 -12
  67. package/kits/docs/context-assembly.md +182 -0
  68. package/kits/docs/evolclaw/INDEX.md +43 -0
  69. package/kits/docs/evolclaw/agent.md +49 -0
  70. package/kits/docs/evolclaw/aid.md +49 -0
  71. package/kits/docs/evolclaw/ctl.md +46 -0
  72. package/kits/docs/evolclaw/group.md +89 -0
  73. package/kits/docs/evolclaw/model.md +51 -0
  74. package/kits/docs/evolclaw/msg.md +91 -0
  75. package/kits/docs/evolclaw/rpc.md +35 -0
  76. package/kits/docs/evolclaw/storage.md +49 -0
  77. package/kits/docs/venues/aun-group.md +10 -0
  78. package/kits/docs/venues/aun-private.md +10 -0
  79. package/kits/docs/venues/client-desktop.md +10 -0
  80. package/kits/docs/venues/client-mobile.md +10 -0
  81. package/kits/docs/venues/feishu-group.md +13 -0
  82. package/kits/docs/venues/feishu-private.md +9 -0
  83. package/kits/docs/venues/group.md +23 -0
  84. package/kits/docs/venues/private.md +10 -0
  85. package/kits/eck_manifest.json +81 -36
  86. package/kits/rules/01-overview.md +20 -10
  87. package/kits/rules/06-channel.md +34 -27
  88. package/kits/templates/system-fragments/baseagent.md +7 -1
  89. package/kits/templates/system-fragments/channel.md +7 -5
  90. package/kits/templates/system-fragments/commands.md +19 -0
  91. package/kits/templates/system-fragments/session.md +19 -3
  92. package/kits/templates/system-fragments/venue.md +24 -0
  93. package/package.json +10 -5
  94. package/dist/aun/aid/lifecycle-log.js +0 -33
  95. package/dist/utils/aid-lifecycle-log.js +0 -33
  96. package/kits/docs/evolclaw/AGENT_CMD.md +0 -31
  97. package/kits/docs/evolclaw/MSG_GROUP.md +0 -30
  98. package/kits/docs/evolclaw/MSG_PRIVATE.md +0 -72
  99. package/kits/docs/evolclaw/tools.md +0 -25
@@ -0,0 +1,247 @@
1
+ :root {
2
+ --bg: #0d1117;
3
+ --bg2: #161b22;
4
+ --bg3: #21262d;
5
+ --border: #30363d;
6
+ --fg: #e6edf3;
7
+ --dim: #8b949e;
8
+ --accent: #58a6ff;
9
+ --green: #3fb950;
10
+ --red: #f85149;
11
+ --orange: #db8e3c;
12
+ --blue: #58a6ff;
13
+ --magenta: #bc8cff;
14
+ }
15
+
16
+ * { box-sizing: border-box; margin: 0; padding: 0; }
17
+
18
+ body {
19
+ font-family: -apple-system, "Segoe UI", "PingFang SC", "Microsoft YaHei", monospace;
20
+ background: var(--bg);
21
+ color: var(--fg);
22
+ font-size: 13px;
23
+ height: 100vh;
24
+ overflow: hidden;
25
+ }
26
+
27
+ /* ── 配对页 ── */
28
+ .pair-page {
29
+ display: flex; align-items: center; justify-content: center;
30
+ height: 100vh;
31
+ }
32
+ .pair-box {
33
+ background: var(--bg2);
34
+ border: 1px solid var(--border);
35
+ border-radius: 12px;
36
+ padding: 40px 48px;
37
+ text-align: center;
38
+ min-width: 320px;
39
+ }
40
+ .pair-box h1 { font-size: 22px; margin-bottom: 8px; }
41
+ .pair-hint { color: var(--dim); margin-bottom: 24px; }
42
+ .pair-box input {
43
+ width: 100%;
44
+ font-size: 28px;
45
+ letter-spacing: 12px;
46
+ text-align: center;
47
+ padding: 12px;
48
+ background: var(--bg);
49
+ border: 1px solid var(--border);
50
+ border-radius: 8px;
51
+ color: var(--fg);
52
+ margin-bottom: 16px;
53
+ }
54
+ .pair-box input:focus { outline: none; border-color: var(--accent); }
55
+ .pair-box button {
56
+ width: 100%;
57
+ padding: 12px;
58
+ font-size: 15px;
59
+ background: var(--accent);
60
+ color: #fff;
61
+ border: none;
62
+ border-radius: 8px;
63
+ cursor: pointer;
64
+ }
65
+ .pair-box button:hover { opacity: 0.9; }
66
+ .pair-error { color: var(--red); margin-top: 12px; min-height: 18px; }
67
+
68
+ /* ── 主面板布局 ── */
69
+ .app { display: flex; flex-direction: column; height: 100vh; }
70
+ .topbar {
71
+ display: flex; align-items: center; gap: 24px;
72
+ padding: 0 16px; height: 44px;
73
+ background: var(--bg2);
74
+ border-bottom: 1px solid var(--border);
75
+ flex-shrink: 0;
76
+ }
77
+ .brand { font-weight: 600; }
78
+ .tabs { display: flex; gap: 4px; }
79
+ .tab {
80
+ background: none; border: none; color: var(--dim);
81
+ padding: 6px 14px; cursor: pointer; border-radius: 6px;
82
+ font-size: 13px; font-family: inherit;
83
+ }
84
+ .tab:hover { color: var(--fg); background: var(--bg3); }
85
+ .tab.active { color: var(--accent); background: var(--bg3); }
86
+ .conn-status { margin-left: auto; color: var(--dim); font-size: 12px; }
87
+ .conn-status.ok { color: var(--green); }
88
+ .conn-status.err { color: var(--red); }
89
+
90
+ .content { flex: 1; overflow: hidden; position: relative; }
91
+ .view { display: none; height: 100%; overflow: auto; }
92
+ .view.active { display: block; }
93
+
94
+ /* ── AID 表格 ── */
95
+ table { width: 100%; border-collapse: collapse; font-size: 12px; }
96
+ th, td { text-align: left; padding: 7px 12px; border-bottom: 1px solid var(--border); white-space: nowrap; }
97
+ th { color: var(--dim); font-weight: 500; position: sticky; top: 0; background: var(--bg2); }
98
+ tr:hover td { background: var(--bg2); }
99
+ .dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; }
100
+ .dot.on { background: var(--green); }
101
+ .dot.off { background: var(--red); }
102
+ .dot.idle { background: var(--orange); }
103
+ .preview { color: var(--dim); max-width: 360px; overflow: hidden; text-overflow: ellipsis; }
104
+ .banner { padding: 10px 16px; background: #3d2a1a; color: var(--orange); border-bottom: 1px solid var(--border); }
105
+ .empty { padding: 40px; text-align: center; color: var(--dim); }
106
+
107
+ /* ── Messages 三栏 ── */
108
+ .msg-layout, .sess-layout { display: flex; height: 100%; }
109
+ .msg-col { overflow-y: auto; height: 100%; }
110
+ .msg-aids { width: 220px; border-right: 1px solid var(--border); flex-shrink: 0; }
111
+ .msg-peers { width: 240px; border-right: 1px solid var(--border); flex-shrink: 0; }
112
+ .msg-stream { flex: 1; padding: 12px; }
113
+ .list-item {
114
+ padding: 8px 12px; cursor: pointer; border-bottom: 1px solid var(--border);
115
+ }
116
+ .list-item:hover { background: var(--bg2); }
117
+ .list-item.sel { background: var(--bg3); border-left: 2px solid var(--accent); }
118
+ .list-item .name { font-weight: 500; }
119
+ .list-item .sub { color: var(--dim); font-size: 11px; margin-top: 2px; }
120
+ .col-title { padding: 8px 12px; color: var(--dim); font-size: 11px; text-transform: uppercase; position: sticky; top: 0; background: var(--bg); border-bottom: 1px solid var(--border); }
121
+
122
+ .bubble { margin-bottom: 12px; max-width: 80%; }
123
+ .bubble.in { margin-right: auto; }
124
+ .bubble.out { margin-left: auto; }
125
+ .bubble .meta { font-size: 11px; color: var(--dim); margin-bottom: 3px; }
126
+ .bubble .body {
127
+ padding: 8px 10px; border-radius: 8px; white-space: pre-wrap; word-break: break-word;
128
+ background: var(--bg2); border: 1px solid var(--border);
129
+ }
130
+ .bubble.in .body { border-left: 2px solid var(--green); }
131
+ .bubble.out .body { border-left: 2px solid var(--blue); }
132
+ .tag { display: inline-block; padding: 0 5px; border-radius: 3px; font-size: 10px; margin-left: 4px; background: var(--bg3); color: var(--magenta); }
133
+
134
+ /* ── Sessions ── */
135
+ .sess-list { width: 360px; border-right: 1px solid var(--border); flex-shrink: 0; display: flex; flex-direction: column; overflow: hidden; }
136
+ .sess-filter { padding: 10px; border-bottom: 1px solid var(--border); display: flex; flex-direction: column; gap: 8px; flex-shrink: 0; }
137
+ .sess-filter select, .sess-filter input {
138
+ width: 100%; padding: 6px 8px; background: var(--bg); color: var(--fg);
139
+ border: 1px solid var(--border); border-radius: 6px; font-size: 12px; font-family: inherit;
140
+ }
141
+ .sess-filter select:focus, .sess-filter input:focus { outline: none; border-color: var(--accent); }
142
+ .sess-count { font-size: 11px; color: var(--dim); }
143
+ .sess-items { flex: 1; overflow-y: auto; }
144
+
145
+ .sess-items .list-item .name { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
146
+ .sess-items .list-item .sub { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
147
+ .bind-badge { display: inline-flex; align-items: center; gap: 3px; padding: 0 5px; border-radius: 3px; background: var(--bg3); color: var(--accent); font-size: 10px; }
148
+ .bind-badge .dot { width: 6px; height: 6px; margin: 0; }
149
+ .msg-count { color: var(--dim); }
150
+
151
+ .sess-detail { flex: 1; padding: 0; overflow-y: auto; }
152
+
153
+ /* 会话头 */
154
+ .sess-header { position: sticky; top: 0; background: var(--bg2); border-bottom: 1px solid var(--border); padding: 12px 20px; z-index: 1; }
155
+ .sh-title { font-size: 15px; font-weight: 600; margin-bottom: 8px; }
156
+ .sh-stats { display: flex; flex-wrap: wrap; gap: 12px; font-size: 12px; color: var(--dim); }
157
+ .sh-stat { display: inline-flex; align-items: center; gap: 4px; }
158
+ .sh-stat .dot { width: 7px; height: 7px; margin: 0 2px; }
159
+ .sh-path { font-size: 11px; color: var(--dim); margin-top: 6px; font-family: ui-monospace, Consolas, monospace; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
160
+
161
+ /* 顶部 4 类分类条 */
162
+ .sh-cats { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
163
+ .cat-chip { display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; border-radius: 10px; font-size: 11px; background: var(--bg3); }
164
+ .cat-swatch { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
165
+ .cat-chip.cat-user_input .cat-swatch { background: var(--green); }
166
+ .cat-chip.cat-model_output .cat-swatch { background: var(--blue); }
167
+ .cat-chip.cat-tool_call .cat-swatch { background: var(--magenta); }
168
+ .cat-chip.cat-tool_result .cat-swatch { background: var(--orange); }
169
+ .cat-chip.cat-msg_send .cat-swatch { background: var(--cyan, #22d3a8); }
170
+
171
+ /* 视图切换工具条 */
172
+ .sess-toolbar { display: flex; align-items: center; gap: 12px; padding: 8px 20px; border-bottom: 1px solid var(--border); position: sticky; top: 0; background: var(--bg); z-index: 1; }
173
+ .view-toggle { padding: 4px 12px; border-radius: 14px; border: 1px solid var(--border); background: var(--bg3); color: var(--fg); cursor: pointer; font-size: 12px; font-family: inherit; }
174
+ .view-toggle.active { background: var(--accent); border-color: var(--accent); color: #fff; }
175
+ .toolbar-hint { font-size: 11px; color: var(--dim); }
176
+ .turn-list { padding-top: 8px; }
177
+
178
+ /* 对话视图:仿微信气泡 */
179
+ .chat-row { display: flex; flex-direction: column; margin: 10px 20px; max-width: 72%; }
180
+ .chat-row.in { align-items: flex-start; margin-right: auto; }
181
+ .chat-row.out { align-items: flex-end; margin-left: auto; }
182
+ .chat-bubble { padding: 9px 13px; border-radius: 12px; white-space: pre-wrap; word-break: break-word; line-height: 1.5; font-size: 13px; }
183
+ .chat-row.in .chat-bubble { background: var(--bg3); border-bottom-left-radius: 3px; }
184
+ .chat-row.out .chat-bubble { background: #2a6b3f; color: #eafff0; border-bottom-right-radius: 3px; }
185
+ .chat-time { font-size: 10px; color: var(--dim); margin-top: 3px; }
186
+
187
+ /* 处理过程折叠组 */
188
+ .proc-group { margin: 8px 20px; }
189
+ .proc-group > summary { cursor: pointer; color: var(--dim); font-size: 11px; padding: 4px 0; text-align: center; list-style: none; }
190
+ .proc-group > summary::-webkit-details-marker { display: none; }
191
+ .proc-group > summary:hover { color: var(--fg); }
192
+ .proc-body { border-left: 2px dashed var(--border); margin-left: 8px; padding-left: 4px; }
193
+ .proc-body .turn { margin: 8px 12px; }
194
+
195
+ /* 轮次:按 4 类着色(左色条 + 角色标签色)*/
196
+ .turn { margin: 0 20px 18px; border-left: 3px solid var(--border); padding-left: 12px; }
197
+ .turn:first-of-type { margin-top: 16px; }
198
+ .turn.cat-user_input { border-left-color: var(--green); }
199
+ .turn.cat-model_output { border-left-color: var(--blue); }
200
+ .turn.cat-tool_call { border-left-color: var(--magenta); }
201
+ .turn.cat-tool_result { border-left-color: var(--orange); }
202
+ .turn.cat-system { border-left-color: var(--dim); }
203
+
204
+ .turn-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; }
205
+ .turn-role { font-weight: 600; font-size: 12px; }
206
+ .turn.cat-user_input .turn-role { color: var(--green); }
207
+ .turn.cat-model_output .turn-role { color: var(--blue); }
208
+ .turn.cat-tool_call .turn-role { color: var(--magenta); }
209
+ .turn.cat-tool_result .turn-role { color: var(--orange); }
210
+ .turn.cat-system .turn-role { color: var(--dim); }
211
+ .turn-time { font-size: 11px; color: var(--dim); }
212
+ .turn-usage { font-size: 11px; color: var(--dim); margin-left: auto; }
213
+ .turn-blocks { display: flex; flex-direction: column; gap: 8px; }
214
+
215
+ /* 普通文本块 */
216
+ .blk-text { white-space: pre-wrap; word-break: break-word; line-height: 1.55; }
217
+
218
+ /* 思考块(折叠) */
219
+ .blk-thinking { font-size: 12px; }
220
+ .blk-thinking summary { cursor: pointer; color: var(--magenta); opacity: 0.8; }
221
+ .blk-thinking-body { white-space: pre-wrap; word-break: break-word; color: var(--dim); margin-top: 6px; padding-left: 12px; border-left: 2px solid var(--border); font-style: italic; }
222
+
223
+ /* 工具调用块 */
224
+ .blk-tool { background: var(--bg2); border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; }
225
+ .tool-head { font-size: 12px; margin-bottom: 4px; }
226
+ .tool-name { font-weight: 600; color: var(--accent); font-family: ui-monospace, "SF Mono", Consolas, monospace; }
227
+ .tool-param { display: flex; gap: 8px; margin-top: 3px; font-size: 12px; align-items: baseline; }
228
+ .tool-param .pk { color: var(--dim); flex-shrink: 0; min-width: 64px; }
229
+ .tool-param .pv {
230
+ font-family: ui-monospace, "SF Mono", Consolas, monospace; color: var(--fg);
231
+ background: var(--bg); padding: 1px 6px; border-radius: 4px; word-break: break-all;
232
+ white-space: pre-wrap; display: block; flex: 1;
233
+ }
234
+
235
+ /* 工具结果块(折叠,默认收起) */
236
+ .blk-result { font-size: 12px; }
237
+ .blk-result summary { cursor: pointer; color: var(--dim); }
238
+ .blk-result.err summary { color: var(--red); }
239
+ .result-body {
240
+ margin-top: 6px; padding: 8px 10px; background: var(--bg); border: 1px solid var(--border);
241
+ border-radius: 6px; white-space: pre-wrap; word-break: break-word; max-height: 280px; overflow-y: auto;
242
+ font-family: ui-monospace, "SF Mono", Consolas, monospace; font-size: 11.5px; line-height: 1.5;
243
+ }
244
+ .blk-result.err .result-body { border-color: var(--red); }
245
+
246
+
247
+
@@ -163,7 +163,7 @@ export function autoMigrateIfNeeded() {
163
163
  active_baseagent: oldConfig.agents?.defaultAgent || 'claude',
164
164
  baseagents: {},
165
165
  models: oldConfig.models,
166
- projects: oldConfig.projects ? { defaultPath: oldConfig.projects.defaultPath, list: oldConfig.projects.list, autoCreate: oldConfig.projects.autoCreate } : undefined,
166
+ projects: oldConfig.projects ? { defaultPath: oldConfig.projects.defaultPath } : undefined,
167
167
  chatmode: oldConfig.chatmode,
168
168
  show_activities: oldConfig.showActivities,
169
169
  flush_delay: oldConfig.flushDelay,
@@ -594,7 +594,6 @@ export async function migrateProject(oldPath, newPath) {
594
594
  claudeHistoryUpdated: false,
595
595
  codexUpdated: 0,
596
596
  evolclawDbUpdated: 0,
597
- evolclawConfigUpdated: false,
598
597
  directoryMoved: false,
599
598
  };
600
599
  const oldAbs = path.resolve(oldPath);
@@ -687,25 +686,5 @@ export async function migrateProject(oldPath, newPath) {
687
686
  }
688
687
  catch { /* fs not accessible */ }
689
688
  }
690
- // 7. 更新各 self-agent config.json 的 projects.list
691
- try {
692
- const { agents } = loadAllAgents();
693
- for (const cfg of agents) {
694
- if (!cfg.projects?.list)
695
- continue;
696
- let changed = false;
697
- for (const [k, v] of Object.entries(cfg.projects.list)) {
698
- if (v === oldAbs) {
699
- cfg.projects.list[k] = newAbs;
700
- changed = true;
701
- }
702
- }
703
- if (changed) {
704
- saveAgent(cfg);
705
- result.evolclawConfigUpdated = true;
706
- }
707
- }
708
- }
709
- catch { /* agents not accessible */ }
710
689
  return result;
711
690
  }
@@ -128,18 +128,21 @@ export class ChannelLoader {
128
128
  }
129
129
  const SEP = '#';
130
130
  export function formatChannelKey(k) {
131
- return `${k.type}${SEP}${encodeURIComponent(k.selfPeerId)}${SEP}${k.name}`;
131
+ if (k.selfAID.includes(SEP)) {
132
+ throw new Error(`Invalid selfAID (contains '#'): ${k.selfAID}`);
133
+ }
134
+ return `${k.type}${SEP}${k.selfAID}${SEP}${k.name}`;
132
135
  }
133
136
  export function parseChannelKey(key) {
134
137
  const parts = key.split(SEP);
135
138
  if (parts.length !== 3) {
136
139
  throw new Error(`Invalid channel key (expected 3 segments separated by '#'): ${key}`);
137
140
  }
138
- const [type, encodedSelfPeerId, name] = parts;
139
- if (!type || !encodedSelfPeerId || !name) {
141
+ const [type, selfAID, name] = parts;
142
+ if (!type || !selfAID || !name) {
140
143
  throw new Error(`Invalid channel key (empty segment): ${key}`);
141
144
  }
142
- return { type, selfPeerId: decodeURIComponent(encodedSelfPeerId), name };
145
+ return { type, selfAID, name };
143
146
  }
144
147
  export function tryParseChannelKey(key) {
145
148
  try {