@aiyiran/myclaw 1.1.141 → 1.1.143
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/myclaw-inject.js +59 -69
- package/index.js +4 -0
- package/package.json +1 -1
- package/server/debug_record.py +4 -34
package/assets/myclaw-inject.js
CHANGED
|
@@ -371,7 +371,7 @@
|
|
|
371
371
|
].join(";");
|
|
372
372
|
|
|
373
373
|
var input = document.createElement("textarea");
|
|
374
|
-
input.rows =
|
|
374
|
+
input.rows = 4;
|
|
375
375
|
input.maxLength = maxLength || 180;
|
|
376
376
|
input.placeholder = placeholder || "";
|
|
377
377
|
input.spellcheck = false;
|
|
@@ -554,58 +554,38 @@
|
|
|
554
554
|
scroll.className = "myclaw-debug-scroll";
|
|
555
555
|
|
|
556
556
|
var guide = document.createElement("div");
|
|
557
|
-
guide.className = "myclaw-debug-
|
|
558
|
-
["我做了什么", "发生了什么", "我的预期是什么"].forEach(function (text) {
|
|
559
|
-
var item = document.createElement("
|
|
560
|
-
item.
|
|
557
|
+
guide.className = "myclaw-debug-steps";
|
|
558
|
+
["我做了什么", "发生了什么", "我的预期是什么"].forEach(function (text, index) {
|
|
559
|
+
var item = document.createElement("div");
|
|
560
|
+
item.className = "myclaw-debug-step";
|
|
561
|
+
var num = document.createElement("span");
|
|
562
|
+
num.className = "myclaw-debug-step-num";
|
|
563
|
+
num.textContent = String(index + 1) + ".";
|
|
564
|
+
var label = document.createElement("span");
|
|
565
|
+
label.textContent = text;
|
|
566
|
+
item.appendChild(num);
|
|
567
|
+
item.appendChild(label);
|
|
561
568
|
guide.appendChild(item);
|
|
562
569
|
});
|
|
563
570
|
|
|
564
571
|
var inputSection = document.createElement("div");
|
|
565
|
-
inputSection.appendChild(makeDebugLabel("
|
|
566
|
-
var descriptionField = makeDebugVoiceInputField("
|
|
572
|
+
inputSection.appendChild(makeDebugLabel("按 1、2、3 的顺序说"));
|
|
573
|
+
var descriptionField = makeDebugVoiceInputField("1. 我点了开始按钮\n2. 页面没有反应\n3. 我希望角色开始移动", 220, function (val) {
|
|
567
574
|
state.description = val;
|
|
568
575
|
refresh();
|
|
569
576
|
});
|
|
570
577
|
inputSection.appendChild(descriptionField.el);
|
|
571
578
|
debugVoiceDestroyers.push(descriptionField.destroy);
|
|
572
579
|
|
|
573
|
-
var previewWrap = document.createElement("div");
|
|
574
|
-
previewWrap.className = "myclaw-debug-preview";
|
|
575
|
-
var previewLabel = document.createElement("div");
|
|
576
|
-
previewLabel.className = "myclaw-debug-preview-label";
|
|
577
|
-
previewLabel.textContent = "将要发给 AI 的内容:";
|
|
578
|
-
var previewEl = document.createElement("div");
|
|
579
|
-
previewEl.className = "myclaw-debug-preview-text";
|
|
580
|
-
previewWrap.appendChild(previewLabel);
|
|
581
|
-
previewWrap.appendChild(previewEl);
|
|
582
|
-
|
|
583
580
|
scroll.appendChild(guide);
|
|
584
581
|
scroll.appendChild(inputSection);
|
|
585
|
-
scroll.appendChild(previewWrap);
|
|
586
582
|
|
|
587
583
|
var footer = document.createElement("div");
|
|
588
584
|
footer.className = "myclaw-debug-footer";
|
|
589
585
|
|
|
590
|
-
var cancelBtn = document.createElement("button");
|
|
591
|
-
cancelBtn.className = "myclaw-debug-cancel";
|
|
592
|
-
cancelBtn.textContent = "取消";
|
|
593
|
-
cancelBtn.addEventListener("click", function () {
|
|
594
|
-
closeDebugModal();
|
|
595
|
-
});
|
|
596
|
-
|
|
597
|
-
var insertBtn = document.createElement("button");
|
|
598
|
-
insertBtn.className = "myclaw-debug-insert";
|
|
599
|
-
insertBtn.textContent = "⬇ 先放到聊天框";
|
|
600
|
-
insertBtn.addEventListener("click", function () {
|
|
601
|
-
if (!hasDebugInput()) return;
|
|
602
|
-
setTextareaValue(buildDebugPrompt());
|
|
603
|
-
closeDebugModal();
|
|
604
|
-
});
|
|
605
|
-
|
|
606
586
|
var submitBtn = document.createElement("button");
|
|
607
587
|
submitBtn.className = "myclaw-debug-submit";
|
|
608
|
-
submitBtn.textContent = "➤
|
|
588
|
+
submitBtn.textContent = "➤ 发给 AI 帮我查";
|
|
609
589
|
submitBtn.addEventListener("click", function () {
|
|
610
590
|
if (!hasDebugInput()) return;
|
|
611
591
|
setTextareaValue(buildDebugPrompt());
|
|
@@ -619,18 +599,11 @@
|
|
|
619
599
|
|
|
620
600
|
function refresh() {
|
|
621
601
|
var ready = hasDebugInput();
|
|
622
|
-
previewEl.textContent = ready ? buildDebugPrompt() : "先写一项,这里会自动整理成要发给 AI 的内容。";
|
|
623
|
-
previewEl.style.color = ready ? "#cdd6f4" : "#555";
|
|
624
602
|
submitBtn.disabled = !ready;
|
|
625
|
-
insertBtn.disabled = !ready;
|
|
626
603
|
submitBtn.style.opacity = ready ? "1" : "0.4";
|
|
627
|
-
insertBtn.style.opacity = ready ? "1" : "0.4";
|
|
628
604
|
submitBtn.style.cursor = ready ? "pointer" : "not-allowed";
|
|
629
|
-
insertBtn.style.cursor = ready ? "pointer" : "not-allowed";
|
|
630
605
|
}
|
|
631
606
|
|
|
632
|
-
footer.appendChild(cancelBtn);
|
|
633
|
-
footer.appendChild(insertBtn);
|
|
634
607
|
footer.appendChild(submitBtn);
|
|
635
608
|
box.appendChild(header);
|
|
636
609
|
box.appendChild(scroll);
|
|
@@ -638,10 +611,6 @@
|
|
|
638
611
|
overlay.appendChild(box);
|
|
639
612
|
document.body.appendChild(overlay);
|
|
640
613
|
|
|
641
|
-
overlay.addEventListener("click", function (e) {
|
|
642
|
-
if (e.target === overlay) closeDebugModal();
|
|
643
|
-
});
|
|
644
|
-
|
|
645
614
|
refresh();
|
|
646
615
|
descriptionField.focus();
|
|
647
616
|
}
|
|
@@ -948,37 +917,58 @@ btn.addEventListener("click", function () {
|
|
|
948
917
|
" animation: myclaw-fade-in 0.15s ease;",
|
|
949
918
|
"}",
|
|
950
919
|
".myclaw-debug-box {",
|
|
951
|
-
"
|
|
952
|
-
"
|
|
953
|
-
" box-shadow: 0
|
|
954
|
-
" display: flex; flex-direction: column;
|
|
920
|
+
" width: 560px; max-width: 96vw; max-height: 92vh;",
|
|
921
|
+
" background: #1e1e2e; border-radius: 12px; overflow: hidden;",
|
|
922
|
+
" box-shadow: 0 12px 48px rgba(0,0,0,0.6);",
|
|
923
|
+
" display: flex; flex-direction: column;",
|
|
955
924
|
"}",
|
|
956
|
-
".myclaw-debug-
|
|
957
|
-
"
|
|
925
|
+
".myclaw-debug-header {",
|
|
926
|
+
" display: flex; align-items: center; justify-content: space-between;",
|
|
927
|
+
" padding: 13px 18px;",
|
|
928
|
+
" background: linear-gradient(135deg,#ef4444,#f59e0b);",
|
|
929
|
+
" color: #fff; font-size: 15px; font-weight: bold;",
|
|
930
|
+
" font-family: -apple-system,sans-serif; user-select: none; flex-shrink: 0;",
|
|
958
931
|
"}",
|
|
959
|
-
".myclaw-debug-
|
|
960
|
-
"
|
|
932
|
+
".myclaw-debug-close {",
|
|
933
|
+
" cursor: pointer; padding: 2px 8px; border-radius: 4px; font-size: 15px;",
|
|
961
934
|
"}",
|
|
962
|
-
".myclaw-debug-
|
|
963
|
-
"
|
|
964
|
-
"
|
|
965
|
-
"
|
|
966
|
-
" resize: vertical; outline: none; font-family: inherit; color: #333;",
|
|
935
|
+
".myclaw-debug-close:hover { background: rgba(255,255,255,0.2); }",
|
|
936
|
+
".myclaw-debug-scroll {",
|
|
937
|
+
" flex: 1; overflow-y: auto; padding: 20px 20px 8px;",
|
|
938
|
+
" display: flex; flex-direction: column; gap: 18px;",
|
|
967
939
|
"}",
|
|
968
|
-
".myclaw-debug-
|
|
969
|
-
"
|
|
970
|
-
"
|
|
940
|
+
".myclaw-debug-label {",
|
|
941
|
+
" font-size: 12px; color: #f59e0b; font-weight: bold;",
|
|
942
|
+
" margin-bottom: 8px; font-family: -apple-system,sans-serif;",
|
|
943
|
+
"}",
|
|
944
|
+
".myclaw-debug-steps {",
|
|
945
|
+
" display: flex; flex-direction: column; gap: 8px;",
|
|
946
|
+
" padding: 12px 14px; background: #252536; border-radius: 8px;",
|
|
947
|
+
" border-left: 3px solid #f59e0b;",
|
|
971
948
|
"}",
|
|
972
|
-
".myclaw-debug-
|
|
973
|
-
"
|
|
974
|
-
"
|
|
949
|
+
".myclaw-debug-step {",
|
|
950
|
+
" display: flex; align-items: center; gap: 9px;",
|
|
951
|
+
" color: #cdd6f4; font-size: 13px; font-family: -apple-system,sans-serif;",
|
|
952
|
+
"}",
|
|
953
|
+
".myclaw-debug-step-num {",
|
|
954
|
+
" width: 24px; height: 20px; border-radius: 999px; flex-shrink: 0;",
|
|
955
|
+
" display: inline-flex; align-items: center; justify-content: center;",
|
|
956
|
+
" background: #f59e0b; color: #1e1e2e; font-weight: bold; font-size: 12px;",
|
|
957
|
+
"}",
|
|
958
|
+
".myclaw-debug-footer {",
|
|
959
|
+
" display: flex; gap: 10px; padding: 14px 20px;",
|
|
960
|
+
" border-top: 1px solid #2d2d3f; flex-shrink: 0; background: #1e1e2e;",
|
|
975
961
|
"}",
|
|
976
962
|
".myclaw-debug-submit {",
|
|
977
|
-
" padding:
|
|
978
|
-
"
|
|
979
|
-
" font-
|
|
963
|
+
" flex: 1; padding: 11px 0; border: none; border-radius: 8px;",
|
|
964
|
+
" color: #fff; font-size: 14px; font-weight: bold;",
|
|
965
|
+
" font-family: -apple-system,sans-serif; cursor: pointer; transition: all 0.15s;",
|
|
966
|
+
"}",
|
|
967
|
+
".myclaw-debug-submit { background: #10b981; }",
|
|
968
|
+
".myclaw-debug-submit:hover:not(:disabled) { background: #059669; }",
|
|
969
|
+
".myclaw-debug-submit:disabled {",
|
|
970
|
+
" cursor: not-allowed;",
|
|
980
971
|
"}",
|
|
981
|
-
".myclaw-debug-submit:hover { background: #3a58d6; }",
|
|
982
972
|
].join("\n");
|
|
983
973
|
document.head.appendChild(style);
|
|
984
974
|
}
|
package/index.js
CHANGED
|
@@ -2101,6 +2101,10 @@ async function runServer(name) {
|
|
|
2101
2101
|
// 2. 覆盖 py 文件 & guard 脚本(确保最新)
|
|
2102
2102
|
fs.copyFileSync(sourcePyPath, targetPyPath);
|
|
2103
2103
|
fs.copyFileSync(sourceSchemaPath, path.join(targetDir, 'artifacts_schema.py'));
|
|
2104
|
+
const sourceDebugRecordPath = path.join(__dirname, 'server', 'debug_record.py');
|
|
2105
|
+
if (fs.existsSync(sourceDebugRecordPath)) {
|
|
2106
|
+
fs.copyFileSync(sourceDebugRecordPath, path.join(targetDir, 'debug_record.py'));
|
|
2107
|
+
}
|
|
2104
2108
|
console.log('[Server] 同步脚本: ' + targetPyPath);
|
|
2105
2109
|
fs.copyFileSync(sourceGuardPath, targetGuardPath);
|
|
2106
2110
|
fs.chmodSync(targetGuardPath, 0o755);
|
package/package.json
CHANGED
package/server/debug_record.py
CHANGED
|
@@ -128,48 +128,18 @@ def render_debug_record_html(input_record: Dict[str, Any]) -> str:
|
|
|
128
128
|
|
|
129
129
|
|
|
130
130
|
# =============================================================================
|
|
131
|
-
# 3. 保存层:写入 debug-record.html
|
|
131
|
+
# 3. 保存层:写入 debug-record.html
|
|
132
132
|
# =============================================================================
|
|
133
133
|
|
|
134
134
|
|
|
135
135
|
def save_debug_record(record: Dict[str, Any], debug_dir: Path) -> Dict[str, str]:
|
|
136
|
-
"""
|
|
137
|
-
保存调试记录。
|
|
138
|
-
|
|
139
|
-
会保存两个文件:
|
|
140
|
-
1. debug-record.json:完整结构化数据,方便 AI / 后续系统读取
|
|
141
|
-
2. debug-record.html:学生、老师、AI 都可以打开看的运行回放页面
|
|
142
|
-
|
|
143
|
-
参数:
|
|
144
|
-
record:
|
|
145
|
-
前端提交的调试记录。
|
|
146
|
-
debug_dir:
|
|
147
|
-
服务端已经计算好的 debug 目录。
|
|
148
|
-
不要直接使用前端传来的路径。
|
|
149
|
-
|
|
150
|
-
返回:
|
|
151
|
-
{
|
|
152
|
-
"json_path": "...",
|
|
153
|
-
"html_path": "..."
|
|
154
|
-
}
|
|
155
|
-
"""
|
|
156
136
|
debug_dir.mkdir(parents=True, exist_ok=True)
|
|
157
137
|
|
|
158
138
|
normalized_record = normalize_record(record)
|
|
159
|
-
|
|
160
|
-
json_path = debug_dir / "debug-record.json"
|
|
161
139
|
html_path = debug_dir / "debug-record.html"
|
|
140
|
+
write_text_atomic(html_path, render_debug_record_html(normalized_record))
|
|
162
141
|
|
|
163
|
-
|
|
164
|
-
html_content = render_debug_record_html(normalized_record)
|
|
165
|
-
|
|
166
|
-
write_text_atomic(json_path, json_content)
|
|
167
|
-
write_text_atomic(html_path, html_content)
|
|
168
|
-
|
|
169
|
-
return {
|
|
170
|
-
"json_path": str(json_path),
|
|
171
|
-
"html_path": str(html_path),
|
|
172
|
-
}
|
|
142
|
+
return {"html_path": str(html_path)}
|
|
173
143
|
|
|
174
144
|
|
|
175
145
|
def write_text_atomic(file_path: Path, content: str) -> None:
|
|
@@ -279,7 +249,7 @@ def handle_save_request(body: Dict[str, Any], openclaw_root: str, server_claw: s
|
|
|
279
249
|
"ok": True,
|
|
280
250
|
"traceId": record["traceId"],
|
|
281
251
|
"debugRecordPath": paths["html_path"],
|
|
282
|
-
|
|
252
|
+
|
|
283
253
|
"debugRecordUrl": debug_record_url,
|
|
284
254
|
}
|
|
285
255
|
|