wezard 2.0.0 → 2.0.2
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CLAUDE.md +7 -8
- package/README.md +20 -32
- package/cli/wezard.sh +0 -62
- package/config.example.jsonc +3 -9
- package/dist/cli/init.js +12 -21
- package/dist/cli/init.js.map +1 -1
- package/dist/daemon/approval.js +2 -4
- package/dist/daemon/approval.js.map +1 -1
- package/dist/daemon/cc-session.js +136 -0
- package/dist/daemon/cc-session.js.map +1 -0
- package/dist/daemon/detail.js +2 -3
- package/dist/daemon/detail.js.map +1 -1
- package/dist/daemon/inbound.js +90 -110
- package/dist/daemon/inbound.js.map +1 -1
- package/dist/daemon/index.js +130 -111
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/memory-steward.js +82 -0
- package/dist/daemon/memory-steward.js.map +1 -0
- package/dist/daemon/mirror-bridge.js +201 -62
- package/dist/daemon/mirror-bridge.js.map +1 -1
- package/dist/daemon/session-name.js +4 -27
- package/dist/daemon/session-name.js.map +1 -1
- package/dist/daemon/spawn-tmux.js +35 -13
- package/dist/daemon/spawn-tmux.js.map +1 -1
- package/dist/daemon/wizard-memory.js +21 -26
- package/dist/daemon/wizard-memory.js.map +1 -1
- package/dist/daemon/wizard.js +54 -11
- package/dist/daemon/wizard.js.map +1 -1
- package/dist/mcp/server.js +63 -153
- package/dist/mcp/server.js.map +1 -1
- package/dist/shared/chat-http.js +44 -16
- package/dist/shared/chat-http.js.map +1 -1
- package/dist/shared/chat-render.js +10 -8
- package/dist/shared/chat-render.js.map +1 -1
- package/dist/shared/cli-backends.js +2 -7
- package/dist/shared/cli-backends.js.map +1 -1
- package/dist/shared/config.js +10 -12
- package/dist/shared/config.js.map +1 -1
- package/dist/shared/detail-render.js +35 -16
- package/dist/shared/detail-render.js.map +1 -1
- package/dist/shared/detail-store.js +14 -3
- package/dist/shared/detail-store.js.map +1 -1
- package/dist/shared/role-render.js +4 -1
- package/dist/shared/role-render.js.map +1 -1
- package/dist/shared/role-view.js +49 -11
- package/dist/shared/role-view.js.map +1 -1
- package/dist/shared/world.js +11 -1
- package/dist/shared/world.js.map +1 -1
- package/hooks/pre-tool-use.sh +4 -4
- package/package.json +1 -2
- package/web/chat.css +103 -58
- package/web/chat.js +153 -82
- package/commands/wrc.md +0 -7
- package/dist/daemon/cc-bridge.js +0 -183
- package/dist/daemon/cc-bridge.js.map +0 -1
- package/dist/daemon/sessions.js +0 -4
- package/dist/daemon/sessions.js.map +0 -1
package/web/chat.js
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
// at / recvAt: 服务端快照时刻与本地收到时刻。所有"现在几点"的判断都换算到
|
|
24
24
|
// 服务端时钟, 否则客户端时钟偏几分钟就会把运行中的会话判成已结束。
|
|
25
|
-
var R = { at: 0, recvAt: 0, role: null, sessions: [], convs: [], relations: false, schedules: 0, stats: null };
|
|
25
|
+
var R = { at: 0, recvAt: 0, role: null, sessions: [], convs: [], relations: false, schedules: 0, stats: null, winStats: null };
|
|
26
26
|
// frags: 当前窗口的原始片段 (id → 片段)。片段不带方向, 换视角时拿它就地重包左右。
|
|
27
27
|
var S = { es: null, pinned: true, gen: 0, frags: {} };
|
|
28
28
|
// 关系/日程两栏共用的世界快照。sel = 当前聚焦的节点, kinds = 边类型开关。
|
|
@@ -41,7 +41,6 @@
|
|
|
41
41
|
var VIEW = 'msgs';
|
|
42
42
|
var $ = function (s) { return document.querySelector(s); };
|
|
43
43
|
var app = $('#app'), thread = $('#thread'), inner = $('#thread-in'), convsEl = $('#convs');
|
|
44
|
-
var connEl = $('#conn');
|
|
45
44
|
var wmapEl = $('#wmap'), wscrollEl = $('#wscroll'), wtoolsEl = $('#wtools'), planEl = $('#plan-in');
|
|
46
45
|
|
|
47
46
|
var srvNow = function () { return R.at ? R.at + (Date.now() - R.recvAt) : Date.now(); };
|
|
@@ -115,7 +114,7 @@
|
|
|
115
114
|
var names = {};
|
|
116
115
|
var learn = function (id, name, label) { if (id && name) names[id] = { name: name, label: label || '' }; };
|
|
117
116
|
var kindOf = function (id) {
|
|
118
|
-
return /^task:/.test(id) ? 'task' : /^human:/.test(id) ? 'human' : 'wizard';
|
|
117
|
+
return /^task:/.test(id) ? 'task' : id === 'system:' ? 'system' : /^human:/.test(id) ? 'human' : 'wizard';
|
|
119
118
|
};
|
|
120
119
|
var nodeOf = function (target) {
|
|
121
120
|
return W.nodes.filter(function (n) { return n.target === target; })[0];
|
|
@@ -126,14 +125,14 @@
|
|
|
126
125
|
};
|
|
127
126
|
var roleLabel = function (id) {
|
|
128
127
|
var k = names[id] || {}, n = nodeOf(id);
|
|
129
|
-
return k.label || (n && n.label) || (
|
|
128
|
+
return k.label || (n && n.label) || ({ human: '👤', task: '⏰', system: '🧙' })[kindOf(id)] || '🧙';
|
|
130
129
|
};
|
|
131
130
|
// `.name` 的点由 CSS 画 —— 人与定时任务没有地址, 不画点。
|
|
132
131
|
var nm = function (id, name) {
|
|
133
132
|
return '<span class="nm ' + kindOf(id) + '">' + esc(name || roleName(id)) + '</span>';
|
|
134
133
|
};
|
|
135
134
|
var nameOf = function (id) { return (kindOf(id) === 'wizard' ? '.' : '') + roleName(id); };
|
|
136
|
-
var canSwitch = function (id) { return !!id && kindOf(id) !== 'task' && id !== 'human:'; };
|
|
135
|
+
var canSwitch = function (id) { return !!id && kindOf(id) !== 'task' && kindOf(id) !== 'system' && id !== 'human:'; };
|
|
137
136
|
|
|
138
137
|
// ── markdown 渲染 (只对未渲染过的节点做, 复用节点不重绘) ──
|
|
139
138
|
var md = null;
|
|
@@ -208,10 +207,35 @@
|
|
|
208
207
|
var d = document.createElement('div'); d.innerHTML = html; return d;
|
|
209
208
|
};
|
|
210
209
|
|
|
210
|
+
// ── 工具调用正文: 第二级数据, 展开那一刻才取 ──
|
|
211
|
+
// 片段里的 .tool-body 是个空壳 (data-lazy-turn / data-lazy-use), 首屏只带摘要行。
|
|
212
|
+
// toggle 不冒泡, 所以在线程根上用捕获听 —— 用户点开, 和 reconcile 换了新节点后
|
|
213
|
+
// restoreOpen 回填展开态, 走的是同一个事件: 后者正好把「展开着等结果」的那次调用
|
|
214
|
+
// 重取成带结果的正文。取到之后正文就留在节点上, 收起再展开不会重取。
|
|
215
|
+
var loadTool = function (d) {
|
|
216
|
+
var body = childBy(d, 'tool-body');
|
|
217
|
+
if (!body || !body.hasAttribute('data-lazy-turn') || body._busy || body.firstChild) return;
|
|
218
|
+
body._busy = true; body.removeAttribute('data-err');
|
|
219
|
+
api('api/tool', { turn: body.getAttribute('data-lazy-turn'), use: body.getAttribute('data-lazy-use') })
|
|
220
|
+
.then(function (r) {
|
|
221
|
+
if (!r.ok) throw new Error(r.error);
|
|
222
|
+
var stick = S.pinned;
|
|
223
|
+
body.innerHTML = r.html;
|
|
224
|
+
if (stick) toBottom(true);
|
|
225
|
+
})
|
|
226
|
+
// 失败留着空壳 (CSS 给出提示), 再展开一次就是重试。
|
|
227
|
+
.catch(function () { body.setAttribute('data-err', '1'); })
|
|
228
|
+
.then(function () { body._busy = false; });
|
|
229
|
+
};
|
|
230
|
+
|
|
211
231
|
// ── 滚动: 默认到底; 用户手动上翻后解除吸附, 回到底部再吸附 ──
|
|
212
232
|
var atBottom = function () { return thread.scrollHeight - thread.scrollTop - thread.clientHeight < 80; };
|
|
213
233
|
var toBottom = function (force) { if (force || S.pinned) thread.scrollTop = thread.scrollHeight; };
|
|
214
234
|
thread.addEventListener('scroll', function () { S.pinned = atBottom(); });
|
|
235
|
+
inner.addEventListener('toggle', function (e) {
|
|
236
|
+
var d = e.target;
|
|
237
|
+
if (d.open && d.classList && d.classList.contains('tool-call')) loadTool(d);
|
|
238
|
+
}, true);
|
|
215
239
|
|
|
216
240
|
// ── 左栏: 当前 role 的名片 + 会话列表 ──
|
|
217
241
|
var convOf = function (key) { return R.convs.filter(function (c) { return c.key === key; })[0]; };
|
|
@@ -224,45 +248,82 @@
|
|
|
224
248
|
});
|
|
225
249
|
return out;
|
|
226
250
|
};
|
|
227
|
-
|
|
228
|
-
|
|
251
|
+
// ── 状态: wizard 是否在执行中 ──
|
|
252
|
+
// 服务端只给事实 (busy / alive / runningUntil), 亮不亮在这里按本地时钟判 ——
|
|
253
|
+
// 到点没有新写入就自己熄 (同 expireRows), 不必等下一次推送。
|
|
254
|
+
var ST = { run: '执行中', idle: '空闲', off: '已关闭' };
|
|
255
|
+
var stateOf = function (s) { return wRunning(s) ? 'run' : s.alive ? 'idle' : 'off'; };
|
|
256
|
+
// 侧栏只在执行中时点一盏灯: 列表里安静是常态, 亮着的才值得看一眼。
|
|
257
|
+
var lampOf = function (s) {
|
|
258
|
+
return s && wRunning(s) ? '<i class="live" title="' + ST.run + '"></i>' : '';
|
|
259
|
+
};
|
|
260
|
+
var paintStatus = function () {
|
|
261
|
+
var el = $('#rb-st'), r = R.role;
|
|
262
|
+
if (!el || !r) return;
|
|
263
|
+
var k = stateOf(r);
|
|
264
|
+
el.className = 'st ' + k; el.textContent = ST[k];
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
var avatarOf = function (c, extra) {
|
|
268
|
+
if (c.kind !== 'group') return '<span class="av">' + esc(c.label) + (extra || '') + '</span>';
|
|
229
269
|
var ms = membersOf(c).slice(0, 4);
|
|
230
270
|
return '<span class="av mosaic n' + ms.length + '" aria-hidden="true">' +
|
|
231
271
|
ms.map(function (m) { return '<i>' + esc(m.label || roleLabel(m.role)) + '</i>'; }).join('') + '</span>';
|
|
232
272
|
};
|
|
233
273
|
|
|
274
|
+
// 选中的那一项若是个 role (私聊对端 / 群里的某人), 行内给一个换视角的开关。
|
|
275
|
+
// 不能是 <button>: 它嵌在整行那颗按钮里。
|
|
276
|
+
var SWAP = '<svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"><path d="M3 5.5h9M9.5 3l2.5 2.5L9.5 8M13 10.5H4M6.5 8 4 10.5 6.5 13" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>';
|
|
277
|
+
var swapOf = function (role) {
|
|
278
|
+
return canSwitch(role) && role !== ROLE
|
|
279
|
+
? '<span class="sw" role="button" tabindex="0" data-sw="' + esc(role) + '" title="' + esc('切到 ' + nameOf(role) + ' 的视角') + '">' + SWAP + '</span>'
|
|
280
|
+
: '';
|
|
281
|
+
};
|
|
282
|
+
var line = function (title, sw, ts, pv) {
|
|
283
|
+
return '<span class="b"><span class="l1"><span class="t">' + title + '</span>' + sw +
|
|
284
|
+
'<span class="ts">' + esc(fmtAgo(ts)) + '</span></span>' +
|
|
285
|
+
'<span class="pv">' + esc(pv) + '</span></span>';
|
|
286
|
+
};
|
|
287
|
+
|
|
234
288
|
var convItem = function (c) {
|
|
235
289
|
var on = c.key === CONV;
|
|
236
290
|
var title = c.kind === 'wizard' ? nm(c.peer, c.name) : '<span class="nm chat">' + esc(c.name) + '</span>';
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
291
|
+
// 只列与我有往来的: 在群里但没和我说过话的人, 点进去也是空的。
|
|
292
|
+
var talked = on ? c.subs.filter(function (s) { return s.count; }) : [];
|
|
293
|
+
var subs = talked.length
|
|
294
|
+
? '<div class="subs">' + talked.map(function (s) {
|
|
295
|
+
var sel = s.role === WITH;
|
|
296
|
+
return '<button class="si' + (sel ? ' on' : '') + '" data-conv="' + esc(c.key) + '" data-with="' + esc(s.role) + '" ' +
|
|
297
|
+
'title="' + esc('我与 ' + nameOf(s.role) + ' 在这里的 ' + s.count + ' 条往来') + '">' +
|
|
298
|
+
'<span class="av">' + esc(s.label) + lampOf(s.status) + '</span>' +
|
|
299
|
+
line(nm(s.role, s.name), sel ? swapOf(s.role) : '', s.lastTs, s.preview) + '</button>';
|
|
243
300
|
}).join('') + '</div>'
|
|
244
301
|
: '';
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
'<span class="ts">' + esc(fmtAgo(c.lastTs)) + '</span></span>' +
|
|
249
|
-
'<span class="pv">' + esc(c.preview) + '</span></span>' +
|
|
302
|
+
var sel = on && !WITH;
|
|
303
|
+
return '<button class="ci' + (sel ? ' on' : '') + '" data-conv="' + esc(c.key) + '">' +
|
|
304
|
+
avatarOf(c, lampOf(c.status)) + line(title, sel && c.kind === 'wizard' ? swapOf(c.peer) : '', c.lastTs, c.preview) +
|
|
250
305
|
'</button>' + subs;
|
|
251
306
|
};
|
|
252
307
|
|
|
253
308
|
var renderConvs = function () {
|
|
254
309
|
var groups = R.convs.filter(function (c) { return c.kind === 'group'; });
|
|
255
310
|
var dms = R.convs.filter(function (c) { return c.kind !== 'group'; });
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
311
|
+
// 空着的那一栏不画 —— 对谁都一样: 人没有私聊只是这条规则的一个特例。
|
|
312
|
+
var sec = function (title, list) {
|
|
313
|
+
return list.length ? '<h2>' + title + '<span>' + list.length + '</span></h2>' + list.map(convItem).join('') : '';
|
|
259
314
|
};
|
|
260
|
-
//
|
|
261
|
-
|
|
262
|
-
|
|
315
|
+
// 没变就不碰 DOM: 心跳每 3s 来一次, 重建会把列表的滚动与焦点蹭掉。
|
|
316
|
+
var html = sec('群聊', groups) + sec('私聊', dms);
|
|
317
|
+
if (convsEl._html === html) return;
|
|
318
|
+
convsEl._html = html; convsEl.innerHTML = html;
|
|
263
319
|
convsEl.querySelectorAll('[data-conv]').forEach(function (b) {
|
|
264
320
|
b.onclick = function () { selectConv(b.getAttribute('data-conv'), b.getAttribute('data-with') || ''); };
|
|
265
321
|
});
|
|
322
|
+
convsEl.querySelectorAll('[data-sw]').forEach(function (x) {
|
|
323
|
+
var go = function (e) { e.stopPropagation(); switchRole(x.getAttribute('data-sw')); };
|
|
324
|
+
x.onclick = go;
|
|
325
|
+
x.onkeydown = function (e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); go(e); } };
|
|
326
|
+
});
|
|
266
327
|
};
|
|
267
328
|
|
|
268
329
|
var shortCwd = function (p) {
|
|
@@ -321,16 +382,19 @@
|
|
|
321
382
|
var renderRole = function () {
|
|
322
383
|
var r = R.role;
|
|
323
384
|
if (!r) return;
|
|
385
|
+
// 名字下面那一行就是出身 —— 有父亲的直接写成「谁的什么」(可点过去), 不再另起一条重复。
|
|
324
386
|
// 分身 = 从父亲某个 session 节点 fork 出来的 (带着那一刻的上下文);
|
|
325
387
|
// 子 wizard = 父亲 spawn 的白板, 只有出身、没有继承。
|
|
326
|
-
var kind =
|
|
327
|
-
|
|
388
|
+
var kind = !r.parent
|
|
389
|
+
? esc(r.kind === 'human' ? '人' : 'wizard')
|
|
390
|
+
: r.forkedFrom
|
|
391
|
+
? '<span class="go" data-r="' + esc(r.parent.id) + '" title="从它的 session ' + esc(r.forkedFrom) + ' fork, 开局带着那一刻的上下文">⧉ .' + esc(r.parent.name) + ' 的分身 · @' + esc(r.forkedFrom.slice(0, 8)) + '</span>'
|
|
392
|
+
: '<span class="go" data-r="' + esc(r.parent.id) + '" title="它 spawn 的白板, 没有继承上下文">↳ .' + esc(r.parent.name) + ' 的子 wizard</span>';
|
|
328
393
|
var facts = [];
|
|
329
394
|
if (r.cwd) facts.push('<span title="' + esc(r.cwd) + '">📁 ' + esc(shortCwd(r.cwd)) + '</span>');
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
: '<span class="go" data-r="' + esc(r.parent.id) + '" title="它 spawn 的白板, 没有继承上下文">↳ .' + esc(r.parent.name) + ' 的子 wizard</span>');
|
|
395
|
+
// 生在哪个群、什么时候 —— 一件事, 一行。
|
|
396
|
+
var born = [r.chat, r.bornAt ? fmtAgo(r.bornAt) : ''].filter(Boolean);
|
|
397
|
+
if (born.length) facts.push('<span title="' + esc('创建于' + (r.chat ? ' ' + r.chat : '') + (r.bornAt ? ' · ' + fmtDay(r.bornAt) : '')) + '">🐣 ' + esc(born.join(' · ')) + '</span>');
|
|
334
398
|
var kin = function (xs, what) {
|
|
335
399
|
return xs.length ? '<span title="' + esc(xs.map(function (x) { return '.' + x.name; }).join(' ')) + '">' + xs.length + ' 个' + what + '</span>' : '';
|
|
336
400
|
};
|
|
@@ -338,80 +402,86 @@
|
|
|
338
402
|
$('#rb-who').innerHTML =
|
|
339
403
|
'<div class="id"><span class="av">' + esc(r.label) + '</span>' +
|
|
340
404
|
'<span class="l">' + nm(r.id, r.name) +
|
|
341
|
-
'<span class="k">' +
|
|
405
|
+
'<span class="k">' + kind + (r.kind === 'wizard' ? '<span class="st" id="rb-st"></span>' : '') + '</span></span></div>' +
|
|
342
406
|
(r.description ? '<p class="job">' + esc(r.description) + '</p>' : '') +
|
|
343
407
|
'<div class="facts">' + facts.join('') + '</div>';
|
|
408
|
+
paintStatus();
|
|
344
409
|
$('#rb-who').querySelectorAll('.go').forEach(function (g) {
|
|
345
410
|
g.onclick = function () { switchRole(g.getAttribute('data-r')); };
|
|
346
411
|
});
|
|
347
412
|
$('#rb-sess').innerHTML = R.sessions.length > 1 ? sessPicker() : '';
|
|
413
|
+
$('#rb-foot').hidden = R.sessions.length < 2;
|
|
348
414
|
bindSessPicker();
|
|
349
|
-
syncFoot();
|
|
350
415
|
var acts = [];
|
|
351
|
-
|
|
352
|
-
if (
|
|
416
|
+
// 入口只在有东西可看时出现, 且只是一枚徽标 —— 名片的主角是身份, 不是按钮。
|
|
417
|
+
if (R.relations) acts.push('<button class="bd' + (VIEW === 'world' ? ' on' : '') + '" data-view="world">关系图</button>');
|
|
418
|
+
if (R.schedules) acts.push('<button class="bd' + (VIEW === 'plan' ? ' on' : '') + '" data-view="plan">日程<b>' + R.schedules + '</b></button>');
|
|
353
419
|
$('#rb-acts').innerHTML = acts.join('');
|
|
354
|
-
$('#rb-acts').querySelectorAll('.
|
|
420
|
+
$('#rb-acts').querySelectorAll('.bd').forEach(function (b) {
|
|
355
421
|
b.onclick = function () { setView(VIEW === b.getAttribute('data-view') ? 'msgs' : b.getAttribute('data-view')); };
|
|
356
422
|
});
|
|
357
423
|
// 标题就是这一页的主张: 你此刻站在谁的位置上。换视角 → 标题跟着换。
|
|
358
424
|
document.title = nameOf(r.id) + ' 的视角';
|
|
359
425
|
};
|
|
360
426
|
|
|
361
|
-
//
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
var COLORS = { input: '#0a7d6b', cacheRead: '#8250df', cacheWrite: '#953800', output: '#1a7f37' };
|
|
427
|
+
// ── 用量条: 一组轮次的总账 ──
|
|
428
|
+
// usageHTML 只管「一本账长什么样」(TagSummary → 一条), 账是谁的、挂在哪由 renderUsage 定。
|
|
429
|
+
var SEGS = [
|
|
430
|
+
['input', '输入', '#0a7d6b'], ['cacheRead', '缓存读', '#8250df'],
|
|
431
|
+
['cacheWrite', '缓存写', '#953800'], ['output', '输出', '#1a7f37'],
|
|
432
|
+
];
|
|
368
433
|
var TIP = {
|
|
369
434
|
turns: '对话轮数', tools: '工具调用次数', api: 'API 请求次数',
|
|
370
|
-
ctx: '上下文峰值 — 单次请求送入的 input + 缓存 的最高值',
|
|
371
|
-
out: '累计输出 token', cache: '累计缓存 token (读 + 写)', time: '累计耗时',
|
|
435
|
+
ctx: '上下文峰值 — 单次请求送入的 input + 缓存 的最高值', time: '累计耗时',
|
|
372
436
|
};
|
|
373
437
|
var liveDur = function (t) {
|
|
374
438
|
var d = (t.usage && t.usage.durationMs) || 0;
|
|
375
439
|
if (!t.runningUntil) return d;
|
|
376
440
|
return d + Math.max(0, Math.min(srvNow(), t.runningUntil) - R.at);
|
|
377
441
|
};
|
|
378
|
-
var
|
|
379
|
-
var el = $('#rb-prof');
|
|
380
|
-
var t = R.stats;
|
|
381
|
-
if (!t) { el.innerHTML = ''; syncFoot(); return; }
|
|
442
|
+
var usageHTML = function (t) {
|
|
382
443
|
var u = t.usage || {};
|
|
383
|
-
var segs =
|
|
384
|
-
.filter(function (s) { return u[s[0]] > 0; });
|
|
444
|
+
var segs = SEGS.filter(function (s) { return u[s[0]] > 0; });
|
|
385
445
|
var total = segs.reduce(function (a, s) { return a + u[s[0]]; }, 0);
|
|
446
|
+
// 值为 0 = 该指标没有数据 (老记录 / 网关不报 usage), 不占位置。
|
|
447
|
+
var kv = function (k, n, text) {
|
|
448
|
+
return n ? '<span class="kv" title="' + esc(TIP[k] || k) + '"><b>' + esc(text) + '</b>' + k + '</span>' : '';
|
|
449
|
+
};
|
|
450
|
+
// 输出 / 缓存不再单列成指标 —— 它们就是 I/O 图例里的那几格。
|
|
386
451
|
var io = total > 0
|
|
387
|
-
? '<
|
|
452
|
+
? '<span class="u-io" title="累计 token I/O · 共 ' + fmtTok(total) + '">' +
|
|
388
453
|
'<span class="bar">' + segs.map(function (s) {
|
|
389
454
|
return '<span class="seg" style="width:' + (u[s[0]] / total * 100).toFixed(2) + '%;background:' +
|
|
390
|
-
|
|
455
|
+
s[2] + '" title="' + s[1] + ': ' + fmtTok(u[s[0]]) + '"></span>';
|
|
391
456
|
}).join('') + '</span>' +
|
|
392
457
|
'<span class="leg">' + segs.map(function (s) {
|
|
393
|
-
return '<span class="lg"><i style="background:' +
|
|
458
|
+
return '<span class="lg"><i style="background:' + s[2] + '"></i>' + s[1] +
|
|
394
459
|
'<b>' + fmtTok(u[s[0]]) + '</b></span>';
|
|
395
460
|
}).join('') + '</span>' +
|
|
396
|
-
'</
|
|
461
|
+
'</span>'
|
|
397
462
|
: '';
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
'
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
463
|
+
return '<span class="u-lb">用量</span>' +
|
|
464
|
+
'<span class="u-kvs">' +
|
|
465
|
+
kv('turns', t.turns, t.turns) + kv('tools', u.tools, u.tools) + kv('api', u.calls, u.calls) +
|
|
466
|
+
kv('ctx', u.ctxPeak, fmtTok(u.ctxPeak)) + kv('time', liveDur(t), fmtDur(liveDur(t))) +
|
|
467
|
+
'</span>' + io +
|
|
468
|
+
(t.model ? '<span class="u-model" title="' + esc(t.model) + '">' + esc(t.model.replace(/^claude-/, '')) + '</span>' : '');
|
|
469
|
+
};
|
|
470
|
+
// 没变就不碰 DOM: 心跳每 3s 来一次, 重建会把悬停中的 tooltip 蹭掉。
|
|
471
|
+
var putUsage = function (el, t) {
|
|
472
|
+
var html = t ? usageHTML(t) : '';
|
|
473
|
+
// !el: web/ 是热更的, 外壳 HTML 要等 daemon 重启 —— 新脚本可能先遇上没有挂载点的旧外壳。
|
|
474
|
+
if (!el || el._html === html) return;
|
|
475
|
+
el._html = html; el.innerHTML = html; el.hidden = !html;
|
|
476
|
+
// 条的高度挤的是消息区 —— 原本贴底的继续贴底。
|
|
477
|
+
toBottom();
|
|
478
|
+
};
|
|
479
|
+
// wizard: 整页页脚, 它自己跑过的全部轮次 (选了 session 就只算那一段)。
|
|
480
|
+
// 人: 自己不跑轮次 —— 在群里点开某个 wizard 之后, 窗口底下是这段往来的账。
|
|
481
|
+
var renderUsage = function () {
|
|
482
|
+
var wiz = !!R.role && R.role.kind === 'wizard';
|
|
483
|
+
putUsage($('#pg-usage'), wiz ? R.stats : null);
|
|
484
|
+
putUsage($('#ch-usage'), !wiz && WITH && VIEW === 'msgs' ? R.winStats : null);
|
|
415
485
|
};
|
|
416
486
|
|
|
417
487
|
// ── 右栏头: 这个群聊 / 私聊是什么 (关系 / 日程视图时是视图名) ──
|
|
@@ -471,8 +541,7 @@
|
|
|
471
541
|
var av = mine ? '' : '<button class="av' + (canSwitch(m.from) ? ' go' : '') + '" data-r="' + esc(m.from) + '" title="' + esc(nameOf(m.from)) + '"' + (canSwitch(m.from) ? '' : ' disabled') + '>' + esc(m.fromLabel || roleLabel(m.from)) + '</button>';
|
|
472
542
|
return '<div class="mrow ' + (mine ? 'mine' : 'them') + '" data-id="' + esc(m.id) + '" data-turn="' + esc(m.turnId || m.id) + '" data-ts="' + m.ts + '"' +
|
|
473
543
|
(m.ping ? ' data-ping="1"' : '') + ' data-sig="' + esc(m.sig) + '" data-stale-at="' + (m.staleAt || 0) + '">' +
|
|
474
|
-
av +
|
|
475
|
-
'<div class="mcol"><div class="mwho">' + who + '</div><div class="mb">' + m.html + '</div></div>' +
|
|
544
|
+
'<div class="mcol"><div class="mwho">' + av + who + '</div><div class="mb">' + m.html + '</div></div>' +
|
|
476
545
|
flip +
|
|
477
546
|
'</div>';
|
|
478
547
|
};
|
|
@@ -605,7 +674,8 @@
|
|
|
605
674
|
var applyRole = function (d) {
|
|
606
675
|
R.at = d.at || Date.now(); R.recvAt = Date.now();
|
|
607
676
|
R.role = d.role; R.sessions = d.sessions || []; R.convs = d.convs || [];
|
|
608
|
-
R.relations = !!d.relations; R.schedules = d.schedules || 0;
|
|
677
|
+
R.relations = !!d.relations; R.schedules = d.schedules || 0;
|
|
678
|
+
R.stats = d.stats || null; R.winStats = d.winStats || null;
|
|
609
679
|
ROLE = d.role.id;
|
|
610
680
|
learn(d.role.id, d.role.name, d.role.label);
|
|
611
681
|
R.convs.forEach(function (c) {
|
|
@@ -613,7 +683,7 @@
|
|
|
613
683
|
c.subs.forEach(function (s) { learn(s.role, s.name, s.label); });
|
|
614
684
|
});
|
|
615
685
|
if (!CONV || !convOf(CONV)) { CONV = d.conv || ''; WITH = ''; }
|
|
616
|
-
renderRole();
|
|
686
|
+
renderRole(); renderUsage(); renderConvs(); renderHead();
|
|
617
687
|
};
|
|
618
688
|
|
|
619
689
|
// ── SSE: role 摘要 + 当前窗口的消息增量。断线指数退避重连。 ──
|
|
@@ -625,9 +695,8 @@
|
|
|
625
695
|
S.es = es;
|
|
626
696
|
es.addEventListener('role', function (e) { try { applyRole(JSON.parse(e.data)); } catch (err) { } });
|
|
627
697
|
es.addEventListener('msg', function (e) { try { upsertMsg(JSON.parse(e.data)); } catch (err) { } });
|
|
628
|
-
es.onopen = function () { backoff = 1000;
|
|
698
|
+
es.onopen = function () { backoff = 1000; };
|
|
629
699
|
es.onerror = function () {
|
|
630
|
-
connEl.className = 'conn off'; connEl.title = '连接断开, 重连中';
|
|
631
700
|
es.close(); if (S.es === es) S.es = null;
|
|
632
701
|
setTimeout(function () { if (!S.es) connect(); }, backoff);
|
|
633
702
|
backoff = Math.min(backoff * 2, 15000);
|
|
@@ -655,7 +724,9 @@
|
|
|
655
724
|
CONV = key; WITH = withRole || '';
|
|
656
725
|
if (VIEW !== 'msgs') setView('msgs');
|
|
657
726
|
app.classList.add('reading');
|
|
658
|
-
|
|
727
|
+
// 上一个窗口的账不属于这个窗口 —— 先收起, 新的随 SSE 的首个 role 事件到。
|
|
728
|
+
R.winStats = null;
|
|
729
|
+
renderConvs(); renderHead(); renderUsage();
|
|
659
730
|
S.gen++;
|
|
660
731
|
syncUrl();
|
|
661
732
|
inner.innerHTML = '<div class="empty">加载中…</div>';
|
|
@@ -1444,7 +1515,7 @@
|
|
|
1444
1515
|
app.classList.toggle('outer', v !== 'msgs');
|
|
1445
1516
|
// 手机上关系/日程占满主区 —— 进入即阅读态。
|
|
1446
1517
|
if (v !== 'msgs') app.classList.add('reading');
|
|
1447
|
-
renderRole(); renderHead();
|
|
1518
|
+
renderRole(); renderHead(); renderUsage();
|
|
1448
1519
|
if (v === 'msgs') { fxStop(); toBottom(true); }
|
|
1449
1520
|
else {
|
|
1450
1521
|
// 关系图一打开就聚焦在当前 role 身上: 它的邻居亮着, 其余压暗。
|
|
@@ -1465,13 +1536,13 @@
|
|
|
1465
1536
|
// 本地心跳: 相对时间、运行中判定、耗时都随时间变化, 但服务端没有新事件可推。
|
|
1466
1537
|
setInterval(function () {
|
|
1467
1538
|
if (!R.role) return;
|
|
1468
|
-
|
|
1539
|
+
renderUsage();
|
|
1469
1540
|
expireRows();
|
|
1541
|
+
// 侧栏的「几分钟前」与状态灯: 内容没变时 renderConvs 不碰 DOM。
|
|
1542
|
+
paintStatus(); renderConvs();
|
|
1470
1543
|
if (VIEW === 'world') tickWorld();
|
|
1471
1544
|
else if (VIEW === 'plan') renderPlan();
|
|
1472
1545
|
}, TICK_MS);
|
|
1473
|
-
// 侧栏的「几分钟前」一分钟刷一次就够 —— 每 3s 重建会把列表的滚动与焦点蹭掉。
|
|
1474
|
-
setInterval(function () { if (R.role && VIEW === 'msgs') renderConvs(); }, 60000);
|
|
1475
1546
|
|
|
1476
1547
|
// ── boot ──
|
|
1477
1548
|
// 带着 role / conv 来的链接直接进阅读态 (手机上不先落在会话列表)。
|
package/commands/wrc.md
DELETED
package/dist/daemon/cc-bridge.js
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
// Headless Claude Code bridge. Spawns `claude -p` per WeCom message, streams
|
|
2
|
-
// stdout (stream-json) back via WeCom replyStream. One in-flight subprocess
|
|
3
|
-
// per principal; subsequent messages queue.
|
|
4
|
-
import { spawn } from "node:child_process";
|
|
5
|
-
import { createInterface } from "node:readline";
|
|
6
|
-
import { expandHome } from "../shared/paths.js";
|
|
7
|
-
import { augmentedPath } from "../shared/exec-path.js";
|
|
8
|
-
import { resolveCliBackend } from "../shared/cli-backends.js";
|
|
9
|
-
const FLUSH_INTERVAL_MS = 250;
|
|
10
|
-
const deltaText = (line) => {
|
|
11
|
-
if (line.type === "stream_event" &&
|
|
12
|
-
line.event?.type === "content_block_delta" &&
|
|
13
|
-
line.event.delta?.type === "text_delta") {
|
|
14
|
-
return line.event.delta.text ?? "";
|
|
15
|
-
}
|
|
16
|
-
return undefined;
|
|
17
|
-
};
|
|
18
|
-
const assistantText = (line) => {
|
|
19
|
-
if (line.type === "assistant" && line.message?.content) {
|
|
20
|
-
return line.message.content
|
|
21
|
-
.filter((b) => b.type === "text" && typeof b.text === "string")
|
|
22
|
-
.map((b) => b.text)
|
|
23
|
-
.join("");
|
|
24
|
-
}
|
|
25
|
-
return undefined;
|
|
26
|
-
};
|
|
27
|
-
const runOne = async (args) => {
|
|
28
|
-
const { text, resumeSid, cfg, log, client, frame, streamId, principal, onSession } = args;
|
|
29
|
-
const cliArgs = [
|
|
30
|
-
"-p",
|
|
31
|
-
text,
|
|
32
|
-
"--output-format",
|
|
33
|
-
"stream-json",
|
|
34
|
-
...resolveCliBackend(cfg.wrc).headlessStreamingArgs,
|
|
35
|
-
...cfg.wrc.extraArgs,
|
|
36
|
-
];
|
|
37
|
-
if (resumeSid)
|
|
38
|
-
cliArgs.push("--resume", resumeSid);
|
|
39
|
-
log.info({ resumeSid, claudeBin: cfg.wrc.claudeBin }, "spawn claude");
|
|
40
|
-
const proc = spawn(cfg.wrc.claudeBin, cliArgs, {
|
|
41
|
-
cwd: expandHome(cfg.wrc.cwd),
|
|
42
|
-
env: { ...process.env, PATH: augmentedPath(process.env.PATH) },
|
|
43
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
44
|
-
});
|
|
45
|
-
let acc = "";
|
|
46
|
-
let lastSent = "";
|
|
47
|
-
let sawDelta = false; // gate assistant-event fallback (see deltaText/assistantText comment)
|
|
48
|
-
let flushTimer;
|
|
49
|
-
let stderrTail = "";
|
|
50
|
-
const sendFlush = async (finish) => {
|
|
51
|
-
if (acc === lastSent && !finish)
|
|
52
|
-
return;
|
|
53
|
-
lastSent = acc;
|
|
54
|
-
try {
|
|
55
|
-
await client.replyStream(frame, streamId, acc || " ", finish);
|
|
56
|
-
}
|
|
57
|
-
catch (e) {
|
|
58
|
-
log.warn({ err: e.message, finish }, "replyStream failed");
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
const scheduleFlush = () => {
|
|
62
|
-
if (flushTimer)
|
|
63
|
-
return;
|
|
64
|
-
flushTimer = setTimeout(() => {
|
|
65
|
-
flushTimer = undefined;
|
|
66
|
-
void sendFlush(false);
|
|
67
|
-
}, FLUSH_INTERVAL_MS);
|
|
68
|
-
};
|
|
69
|
-
const stdout = proc.stdout;
|
|
70
|
-
const stderr = proc.stderr;
|
|
71
|
-
if (!stdout || !stderr) {
|
|
72
|
-
throw new Error("claude subprocess missing stdio pipes");
|
|
73
|
-
}
|
|
74
|
-
// ENOENT / EACCES 等 spawn 失败走 'error' 事件,不监听会 crash 整个 daemon。
|
|
75
|
-
let spawnError;
|
|
76
|
-
proc.on("error", (err) => {
|
|
77
|
-
spawnError = err;
|
|
78
|
-
log.error({ err: err.message, code: err.code }, "spawn error");
|
|
79
|
-
});
|
|
80
|
-
const rl = createInterface({ input: stdout });
|
|
81
|
-
rl.on("line", (raw) => {
|
|
82
|
-
if (!raw.trim())
|
|
83
|
-
return;
|
|
84
|
-
let line;
|
|
85
|
-
try {
|
|
86
|
-
line = JSON.parse(raw);
|
|
87
|
-
}
|
|
88
|
-
catch {
|
|
89
|
-
log.debug({ raw: raw.slice(0, 200) }, "non-JSON stdout line");
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
if (line.type === "system" && line.subtype === "init" && line.session_id) {
|
|
93
|
-
onSession(line.session_id);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
const delta = deltaText(line);
|
|
97
|
-
if (delta) {
|
|
98
|
-
sawDelta = true;
|
|
99
|
-
acc += delta;
|
|
100
|
-
scheduleFlush();
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
const whole = assistantText(line);
|
|
104
|
-
// Fallback only if we never saw any delta (e.g. cached / non-streaming response).
|
|
105
|
-
if (whole && !sawDelta) {
|
|
106
|
-
acc += whole;
|
|
107
|
-
scheduleFlush();
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
if (line.type === "result") {
|
|
111
|
-
// result.result is the final assistant text in cases where no assistant event was emitted (e.g. no_response).
|
|
112
|
-
if (!acc && typeof line.result === "string")
|
|
113
|
-
acc = line.result;
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
proc.stderr?.on("data", (chunk) => {
|
|
117
|
-
const s = chunk.toString("utf8");
|
|
118
|
-
stderrTail = (stderrTail + s).slice(-2000);
|
|
119
|
-
});
|
|
120
|
-
await new Promise((resolve) => {
|
|
121
|
-
proc.on("close", async (code) => {
|
|
122
|
-
if (flushTimer) {
|
|
123
|
-
clearTimeout(flushTimer);
|
|
124
|
-
flushTimer = undefined;
|
|
125
|
-
}
|
|
126
|
-
if (spawnError || code !== 0) {
|
|
127
|
-
const reason = spawnError
|
|
128
|
-
? `spawn ${cfg.wrc.claudeBin}: ${spawnError.message}`
|
|
129
|
-
: `claude exited ${code}`;
|
|
130
|
-
log.error({ code, spawnErr: spawnError?.message, stderrTail: stderrTail.slice(-500) }, "claude failure");
|
|
131
|
-
const fallback = acc
|
|
132
|
-
? `${acc}\n\n[${reason}]`
|
|
133
|
-
: `[wezard] ${reason}\n${stderrTail.slice(-500)}`;
|
|
134
|
-
acc = fallback;
|
|
135
|
-
}
|
|
136
|
-
await sendFlush(true);
|
|
137
|
-
// WeCom 列表对 stream 消息硬编码 "…" 预览,唯一覆盖方式是在 stream 终止后补发一条普通消息。
|
|
138
|
-
// 取 acc 按空行切分的最后一段——对应"最后一段话",多段冗长输出不会全压进列表。
|
|
139
|
-
const tail = acc.split(/\n{2,}/).filter((s) => s.trim()).pop();
|
|
140
|
-
if (tail) {
|
|
141
|
-
const chatId = principal.includes(":") ? principal.slice(principal.indexOf(":") + 1) : principal;
|
|
142
|
-
try {
|
|
143
|
-
await client.sendMessage(chatId, { msgtype: "markdown", markdown: { content: tail } });
|
|
144
|
-
}
|
|
145
|
-
catch (e) {
|
|
146
|
-
log.warn({ err: e.message }, "preview push failed");
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
log.info({ code, chars: acc.length }, "claude done");
|
|
150
|
-
resolve();
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
};
|
|
154
|
-
const queues = new Map();
|
|
155
|
-
const enqueue = (key, job) => {
|
|
156
|
-
const prev = queues.get(key) ?? Promise.resolve();
|
|
157
|
-
const next = prev.then(job, job).catch(() => undefined);
|
|
158
|
-
queues.set(key, next.finally(() => {
|
|
159
|
-
if (queues.get(key) === next)
|
|
160
|
-
queues.delete(key);
|
|
161
|
-
}));
|
|
162
|
-
return next;
|
|
163
|
-
};
|
|
164
|
-
export const makeBridge = (deps) => {
|
|
165
|
-
return {
|
|
166
|
-
dispatch: ({ principal, text, images, frame, streamId }) => enqueue(principal, () => {
|
|
167
|
-
const refs = (images ?? []).map((p) => `@${p}`).join("\n");
|
|
168
|
-
const finalText = refs ? (text ? `${refs}\n${text}` : refs) : text;
|
|
169
|
-
return runOne({
|
|
170
|
-
text: finalText,
|
|
171
|
-
resumeSid: deps.sessions.get(principal),
|
|
172
|
-
cfg: deps.cfg,
|
|
173
|
-
log: deps.log.child({ principal }),
|
|
174
|
-
client: deps.client,
|
|
175
|
-
frame,
|
|
176
|
-
streamId,
|
|
177
|
-
principal,
|
|
178
|
-
onSession: (sid) => deps.sessions.set(principal, sid),
|
|
179
|
-
});
|
|
180
|
-
}),
|
|
181
|
-
};
|
|
182
|
-
};
|
|
183
|
-
//# sourceMappingURL=cc-bridge.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cc-bridge.js","sourceRoot":"","sources":["../../daemon/cc-bridge.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon/sessions.js
DELETED