@aiyiran/myclaw 1.1.154 → 1.1.158
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/assets/debug-collector.js +16 -31
- package/assets/debug-probe.js +20 -3
- package/assets/myclaw-inject.js +86 -58
- package/package.json +1 -1
|
@@ -120,39 +120,14 @@ function appendDebugEvent(probeEvent) {
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
/**
|
|
123
|
-
*
|
|
123
|
+
* 控制日志长度。
|
|
124
|
+
*
|
|
125
|
+
* 【当前阶段:全量,不做任何丢弃/折叠】
|
|
126
|
+
* 先采集完整真实的数据流以便观察。待看清真实形态后,再实现
|
|
127
|
+
* "错误锚点 + 重复折叠 + 丢弃留痕"的精简策略(届时恢复本函数)。
|
|
124
128
|
*/
|
|
125
129
|
function trimDebugEvents(events) {
|
|
126
|
-
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const importantTypes = new Set([
|
|
131
|
-
"runtime-error",
|
|
132
|
-
"unhandledrejection",
|
|
133
|
-
"resource-error"
|
|
134
|
-
]);
|
|
135
|
-
|
|
136
|
-
const importantEvents = events.filter((event) =>
|
|
137
|
-
importantTypes.has(event.type)
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
const latestEvents = events.slice(-MAX_EVENTS);
|
|
141
|
-
|
|
142
|
-
const merged = [...importantEvents, ...latestEvents];
|
|
143
|
-
|
|
144
|
-
const seen = new Set();
|
|
145
|
-
const deduped = [];
|
|
146
|
-
|
|
147
|
-
for (const event of merged) {
|
|
148
|
-
const key = event.seq || `${event.type}-${event.time}-${event.pageUrl}`;
|
|
149
|
-
if (seen.has(key)) continue;
|
|
150
|
-
seen.add(key);
|
|
151
|
-
deduped.push(event);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
events.length = 0;
|
|
155
|
-
events.push(...deduped.slice(-MAX_EVENTS));
|
|
130
|
+
return;
|
|
156
131
|
}
|
|
157
132
|
|
|
158
133
|
/**
|
|
@@ -317,6 +292,16 @@ function renderDebugRecordPreview(record) {
|
|
|
317
292
|
function formatEventForStudent(event) {
|
|
318
293
|
const time = event.time ? event.time.slice(11, 19) : "";
|
|
319
294
|
|
|
295
|
+
if (event.type === "probe-ready") {
|
|
296
|
+
const version = event.payload && event.payload.probeVersion;
|
|
297
|
+
return `${time} 调试探针启动${version ? "(" + version + ")" : ""}`;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (event.type === "console-truncated") {
|
|
301
|
+
const limit = event.payload && event.payload.limit;
|
|
302
|
+
return `${time} 程序输出过多,已截断${limit ? "(上限 " + limit + " 条)" : ""}`;
|
|
303
|
+
}
|
|
304
|
+
|
|
320
305
|
if (event.type === "page-enter") {
|
|
321
306
|
return `${time} 进入页面:${event.pageTitle || event.pagePath || event.pageUrl}`;
|
|
322
307
|
}
|
package/assets/debug-probe.js
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
window.__OPENCLAW_DEBUG_PROBE_INSTALLED__ = true;
|
|
21
21
|
|
|
22
|
-
const PROBE_VERSION = "
|
|
22
|
+
const PROBE_VERSION = "probe_005";
|
|
23
23
|
const MAX_TEXT_LENGTH = 1000;
|
|
24
24
|
const MAX_STACK_LENGTH = 3000;
|
|
25
25
|
const MAX_ELEMENT_TEXT_LENGTH = 80;
|
|
@@ -237,11 +237,21 @@
|
|
|
237
237
|
});
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
-
// 去重:避免 setTimeout 拦截 和 window.error 事件
|
|
240
|
+
// 去重:避免 setTimeout 拦截 和 window.error 事件 重复上报同一个错误。
|
|
241
|
+
// 两条路径拿到的 message 不一致:setTimeout 拦截器拿到原始 error.message
|
|
242
|
+
// (如 "Cannot read..."),window error 事件则带 "Uncaught TypeError: " 前缀。
|
|
243
|
+
// 归一化时剥掉这个前缀,确保同一个错误只上报一次。
|
|
241
244
|
const _reportedErrorKeys = new Set();
|
|
242
245
|
|
|
246
|
+
function normalizeErrorKey(message) {
|
|
247
|
+
return truncate(
|
|
248
|
+
String(message || "").replace(/^Uncaught\s+(\w*Error)?:?\s*/i, ""),
|
|
249
|
+
200
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
|
|
243
253
|
function reportRuntimeError(message, filename, lineno, colno, stack) {
|
|
244
|
-
const key =
|
|
254
|
+
const key = normalizeErrorKey(message);
|
|
245
255
|
if (_reportedErrorKeys.has(key)) return;
|
|
246
256
|
_reportedErrorKeys.add(key);
|
|
247
257
|
sendEvent("runtime-error", {
|
|
@@ -361,6 +371,13 @@
|
|
|
361
371
|
setupClickListener();
|
|
362
372
|
setupKeydownListener();
|
|
363
373
|
|
|
374
|
+
// 启动标记:版本号 + 时间。
|
|
375
|
+
// - 独立页面:直接打到控制台,方便人工确认 probe 已就位、是哪个版本。
|
|
376
|
+
// - iframe 模式:作为本轮记录的明确起点事件,便于排查"是否新一轮"。
|
|
377
|
+
const startedAt = now();
|
|
378
|
+
_nativeLog("[PROBE] " + PROBE_VERSION + " 已启动 @ " + startedAt);
|
|
379
|
+
sendEvent("probe-ready", { probeVersion: PROBE_VERSION, startedAt });
|
|
380
|
+
|
|
364
381
|
if (document.readyState === "loading") {
|
|
365
382
|
document.addEventListener("DOMContentLoaded", sendPageEnter);
|
|
366
383
|
} else {
|
package/assets/myclaw-inject.js
CHANGED
|
@@ -315,61 +315,66 @@
|
|
|
315
315
|
|
|
316
316
|
// ═══ 3. Debug 按钮 ═══
|
|
317
317
|
|
|
318
|
-
function
|
|
319
|
-
var
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
btn.innerHTML = [
|
|
325
|
-
'<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18"',
|
|
326
|
-
' viewBox="0 0 24 24" fill="none" stroke="currentColor"',
|
|
327
|
-
' stroke-width="2" stroke-linecap="round" stroke-linejoin="round">',
|
|
328
|
-
' <path d="m8 2 1.88 1.88"/>',
|
|
329
|
-
' <path d="M14.12 3.88 16 2"/>',
|
|
330
|
-
' <path d="M9 7.13v-1a3.003 3.003 0 1 1 6 0v1"/>',
|
|
331
|
-
' <path d="M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6"/>',
|
|
332
|
-
' <path d="M12 20v-9"/>',
|
|
333
|
-
' <path d="M6.53 9C4.6 9.43 3 11.3 3 13.5"/>',
|
|
334
|
-
' <path d="M20.97 13.5c0-2.2-1.6-4.07-3.53-4.5"/>',
|
|
335
|
-
' <path d="M4 19.5c0-2.2 1.8-4 4-4"/>',
|
|
336
|
-
' <path d="M20 19.5c0-2.2-1.8-4-4-4"/>',
|
|
337
|
-
'</svg>',
|
|
338
|
-
].join("");
|
|
318
|
+
function buildTestDonePrompt() {
|
|
319
|
+
var rec = window.myclawLastDebugRecord;
|
|
320
|
+
var lines = [
|
|
321
|
+
"我刚才已经完成了测试。",
|
|
322
|
+
"请你检查我的测试数据 debug/debug-record.html,重点查看里面的 JS 日志。",
|
|
323
|
+
];
|
|
339
324
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
325
|
+
if (rec && rec.debugRecordPath) {
|
|
326
|
+
lines.push("如果你能读取本地路径,也可以查看:" + rec.debugRecordPath);
|
|
327
|
+
}
|
|
328
|
+
if (rec && rec.entryFile) {
|
|
329
|
+
lines.push("我刚才测试的文件是:" + rec.entryFile);
|
|
330
|
+
}
|
|
344
331
|
|
|
345
|
-
|
|
332
|
+
lines.push("");
|
|
333
|
+
lines.push("请帮我判断:我们之前的问题是否已经修复。");
|
|
334
|
+
lines.push("如果已经修复,请简单说明你从日志里看到了什么证据。");
|
|
335
|
+
lines.push("如果还没有修复,请指出日志里最关键的问题,并建议下一步最小修改。");
|
|
336
|
+
|
|
337
|
+
return lines.join("\n");
|
|
346
338
|
}
|
|
347
339
|
|
|
348
|
-
function
|
|
340
|
+
function createProblemMenuButton() {
|
|
341
|
+
var wrap = document.createElement("div");
|
|
342
|
+
wrap.id = "myclaw-problem-menu";
|
|
343
|
+
|
|
349
344
|
var btn = document.createElement("button");
|
|
350
|
-
btn.id = "myclaw-
|
|
345
|
+
btn.id = "myclaw-problem-btn";
|
|
346
|
+
btn.type = "button";
|
|
351
347
|
btn.className = "agent-chat__input-btn";
|
|
352
|
-
btn.title = "
|
|
353
|
-
btn.setAttribute("aria-label", "
|
|
354
|
-
btn.
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
348
|
+
btn.title = "查问题";
|
|
349
|
+
btn.setAttribute("aria-label", "查问题");
|
|
350
|
+
btn.textContent = "查问题";
|
|
351
|
+
|
|
352
|
+
var menu = document.createElement("div");
|
|
353
|
+
menu.className = "myclaw-problem-menu-panel";
|
|
354
|
+
|
|
355
|
+
function makeItem(text, onClick) {
|
|
356
|
+
var item = document.createElement("button");
|
|
357
|
+
item.type = "button";
|
|
358
|
+
item.className = "myclaw-problem-menu-item";
|
|
359
|
+
item.textContent = text;
|
|
360
|
+
item.addEventListener("click", function (e) {
|
|
361
|
+
e.preventDefault();
|
|
362
|
+
e.stopPropagation();
|
|
363
|
+
onClick();
|
|
364
|
+
});
|
|
365
|
+
return item;
|
|
366
|
+
}
|
|
366
367
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
368
|
+
menu.appendChild(makeItem("查报错", showDebugModal));
|
|
369
|
+
menu.appendChild(makeItem("加日志", showLogModal));
|
|
370
|
+
menu.appendChild(makeItem("看结果", function () {
|
|
371
|
+
setTextareaValue(buildTestDonePrompt());
|
|
372
|
+
trySend();
|
|
373
|
+
}));
|
|
371
374
|
|
|
372
|
-
|
|
375
|
+
wrap.appendChild(btn);
|
|
376
|
+
wrap.appendChild(menu);
|
|
377
|
+
return wrap;
|
|
373
378
|
}
|
|
374
379
|
|
|
375
380
|
var debugVoiceDestroyers = [];
|
|
@@ -956,8 +961,7 @@ btn.addEventListener("click", function () {
|
|
|
956
961
|
var toolbar = document.querySelector(".agent-chat__toolbar-left");
|
|
957
962
|
if (!toolbar) return;
|
|
958
963
|
if (
|
|
959
|
-
toolbar.querySelector("#myclaw-
|
|
960
|
-
toolbar.querySelector("#myclaw-log-btn") &&
|
|
964
|
+
toolbar.querySelector("#myclaw-problem-menu") &&
|
|
961
965
|
toolbar.querySelector("#myclaw-prompt-btn") &&
|
|
962
966
|
toolbar.querySelector("#myclaw-voice-btn")
|
|
963
967
|
) {
|
|
@@ -969,19 +973,17 @@ btn.addEventListener("click", function () {
|
|
|
969
973
|
window.myclawIteration.init({ trySend: trySend });
|
|
970
974
|
}
|
|
971
975
|
|
|
972
|
-
var
|
|
973
|
-
var logBtn = document.querySelector("#myclaw-log-btn") || createLogButton();
|
|
976
|
+
var problemMenu = document.querySelector("#myclaw-problem-menu") || createProblemMenuButton();
|
|
974
977
|
var promptBtn = document.querySelector("#myclaw-prompt-btn") || createPromptButton();
|
|
975
978
|
var voiceBtn = document.querySelector("#myclaw-voice-btn") || createVoiceButton();
|
|
976
979
|
|
|
977
|
-
//
|
|
980
|
+
// 插入到工具栏最前面:语音、查问题、prompt 依次靠右
|
|
978
981
|
toolbar.insertBefore(promptBtn, toolbar.firstChild);
|
|
979
|
-
toolbar.insertBefore(
|
|
980
|
-
toolbar.insertBefore(
|
|
981
|
-
toolbar.insertBefore(voiceBtn, debugBtn);
|
|
982
|
+
toolbar.insertBefore(problemMenu, promptBtn);
|
|
983
|
+
toolbar.insertBefore(voiceBtn, problemMenu);
|
|
982
984
|
|
|
983
985
|
injected = true;
|
|
984
|
-
console.log("[myclaw-inject] \u2705 \u8bed\u97f3/
|
|
986
|
+
console.log("[myclaw-inject] \u2705 \u8bed\u97f3/\u67e5\u95ee\u9898/prompt\u6309\u94ae\u5df2\u6ce8\u5165");
|
|
985
987
|
}
|
|
986
988
|
|
|
987
989
|
// ═══ 注入录音态样式 ═══
|
|
@@ -1007,6 +1009,33 @@ btn.addEventListener("click", function () {
|
|
|
1007
1009
|
" animation: myclaw-ring 1.5s ease-out infinite;",
|
|
1008
1010
|
" pointer-events: none;",
|
|
1009
1011
|
"}",
|
|
1012
|
+
/* 查问题悬浮菜单 */
|
|
1013
|
+
"#myclaw-problem-menu {",
|
|
1014
|
+
" position: relative; display: inline-flex; align-items: center; flex-shrink: 0;",
|
|
1015
|
+
"}",
|
|
1016
|
+
"#myclaw-problem-btn {",
|
|
1017
|
+
" width: auto !important; min-width: 66px; padding: 0 12px !important;",
|
|
1018
|
+
" font-size: 13px; font-weight: 700; white-space: nowrap;",
|
|
1019
|
+
" border-radius: 8px;",
|
|
1020
|
+
"}",
|
|
1021
|
+
".myclaw-problem-menu-panel {",
|
|
1022
|
+
" display: none; position: absolute; left: 0; bottom: 100%;",
|
|
1023
|
+
" min-width: 92px; padding: 6px; border-radius: 10px;",
|
|
1024
|
+
" background: #1e1e2e; border: 1px solid #3d3d5c;",
|
|
1025
|
+
" box-shadow: 0 10px 32px rgba(0,0,0,0.35); z-index: 100000;",
|
|
1026
|
+
"}",
|
|
1027
|
+
"#myclaw-problem-menu:hover .myclaw-problem-menu-panel,",
|
|
1028
|
+
"#myclaw-problem-menu:focus-within .myclaw-problem-menu-panel {",
|
|
1029
|
+
" display: flex; flex-direction: column; gap: 4px;",
|
|
1030
|
+
"}",
|
|
1031
|
+
".myclaw-problem-menu-item {",
|
|
1032
|
+
" border: none; border-radius: 7px; background: transparent; color: #cdd6f4;",
|
|
1033
|
+
" padding: 8px 10px; text-align: left; cursor: pointer;",
|
|
1034
|
+
" font-size: 13px; font-weight: 600; font-family: -apple-system,sans-serif;",
|
|
1035
|
+
"}",
|
|
1036
|
+
".myclaw-problem-menu-item:hover, .myclaw-problem-menu-item:focus {",
|
|
1037
|
+
" background: #31314a; color: #fff; outline: none;",
|
|
1038
|
+
"}",
|
|
1010
1039
|
/* 按钮处理中态:半透明 + 2秒红圈收缩动画 */
|
|
1011
1040
|
".myclaw-voice-stopping {",
|
|
1012
1041
|
" opacity: 0.5 !important;",
|
|
@@ -2309,8 +2338,7 @@ btn.addEventListener("click", function () {
|
|
|
2309
2338
|
// 持续监听 DOM 变化,确保按钮始终在
|
|
2310
2339
|
new MutationObserver(function () {
|
|
2311
2340
|
if (
|
|
2312
|
-
!document.querySelector("#myclaw-
|
|
2313
|
-
!document.querySelector("#myclaw-log-btn") ||
|
|
2341
|
+
!document.querySelector("#myclaw-problem-menu") ||
|
|
2314
2342
|
!document.querySelector("#myclaw-prompt-btn") ||
|
|
2315
2343
|
!document.querySelector("#myclaw-voice-btn")
|
|
2316
2344
|
) {
|