@aiyiran/myclaw 1.1.185 → 1.1.187
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.
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
var cachedData = null;
|
|
32
32
|
var pollTimer = null;
|
|
33
33
|
var lastKnownClawName = null; // 统一从 /api/config 读取并缓存(本地与远程一致)
|
|
34
|
+
var lastKnownOpenclawRoot = null; // .openclaw 根目录绝对路径,从 /api/config 读取
|
|
34
35
|
var _preloadCache = {}; // url → Image 对象,防止重复预加载
|
|
35
36
|
var showHiddenArtifacts = false; // 是否显示被过滤掉的系统/模板内部文件
|
|
36
37
|
var MYCLAW_API_PORT = 18800;
|
|
@@ -74,6 +75,7 @@
|
|
|
74
75
|
})
|
|
75
76
|
.then(function (data) {
|
|
76
77
|
lastKnownClawName = data.claw;
|
|
78
|
+
lastKnownOpenclawRoot = data.root || null;
|
|
77
79
|
return data.claw;
|
|
78
80
|
})
|
|
79
81
|
.catch(function (err) {
|
|
@@ -449,6 +451,10 @@
|
|
|
449
451
|
// 1. 检查文件名是否包含在黑名单中
|
|
450
452
|
if (ARTIFACT_BLACKLIST.indexOf(basename) !== -1) return false;
|
|
451
453
|
|
|
454
|
+
// 1.5 约定前缀:文件名以 hide- 开头 = 内部/生成文件,默认不显示
|
|
455
|
+
// (Markdown 安全、shell 安全,供各流水线自命名用,无需维护清单)
|
|
456
|
+
if (basename.indexOf('hide-') === 0) return false;
|
|
457
|
+
|
|
452
458
|
// 2. 检查路径是否以黑名单目录开头
|
|
453
459
|
for (var i = 0; i < DIR_BLACKLIST.length; i++) {
|
|
454
460
|
if (path.indexOf(DIR_BLACKLIST[i]) === 0) {
|
|
@@ -537,8 +543,9 @@
|
|
|
537
543
|
copyPathBtn.onmouseleave = function () { copyPathBtn.style.background = '#2d2d4a'; };
|
|
538
544
|
copyPathBtn.onclick = function (e) {
|
|
539
545
|
e.stopPropagation();
|
|
540
|
-
var
|
|
541
|
-
|
|
546
|
+
var rel = getWorkspaceId() + '/' + (asset.path || '');
|
|
547
|
+
var pathToCopy = lastKnownOpenclawRoot ? lastKnownOpenclawRoot + '/' + rel : rel;
|
|
548
|
+
navigator.clipboard.writeText(pathToCopy).then(function () {
|
|
542
549
|
copyPathBtn.textContent = '✓';
|
|
543
550
|
copyPathBtn.style.color = '#10b981';
|
|
544
551
|
copyPathBtn.style.borderColor = '#10b981';
|
package/package.json
CHANGED
package/server/sync_workspace.py
CHANGED
|
@@ -1156,7 +1156,7 @@ class MyclawAPIHandler(BaseHTTPRequestHandler):
|
|
|
1156
1156
|
|
|
1157
1157
|
def _handle_config(self):
|
|
1158
1158
|
"""GET /api/config → 返回 claw 名称和 CDN base_url"""
|
|
1159
|
-
self._send_json({"claw": claw, "base_url": BASE_URL})
|
|
1159
|
+
self._send_json({"claw": claw, "base_url": BASE_URL, "root": get_openclaw_path()})
|
|
1160
1160
|
|
|
1161
1161
|
def _handle_artifacts(self, params):
|
|
1162
1162
|
"""GET /api/artifacts?workspace=xxx → 直接从磁盘读取 __MY_ARTIFACTS__.json"""
|
|
@@ -5,28 +5,23 @@ description: Extract and render chat history from OpenClaw session URLs. Use whe
|
|
|
5
5
|
|
|
6
6
|
# Chat History Extractor
|
|
7
7
|
|
|
8
|
-
##
|
|
9
|
-
|
|
10
|
-
- **单个 URL/key**:处理一个会话
|
|
11
|
-
- **逗号分隔**:`url1,url2,url3` 批量处理
|
|
12
|
-
- **JSON 数组**:`["url1","url2","url3"]` 批量处理
|
|
13
|
-
- **`--scan` 模式**:自动扫描所有 agent 的所有会话,统计表格
|
|
14
|
-
|
|
15
|
-
## 快速使用(推荐)
|
|
8
|
+
## 调用方式
|
|
16
9
|
|
|
17
10
|
```bash
|
|
18
|
-
#
|
|
19
|
-
python3 scripts/extract_chat.py
|
|
20
|
-
|
|
21
|
-
# 批量(逗号分隔)
|
|
22
|
-
python3 scripts/extract_chat.py "url1,url2,url3" <my-workspace>
|
|
11
|
+
# 只扫描:列出所有 agent 的所有会话,生成统计表格
|
|
12
|
+
python3 scripts/extract_chat.py <my-workspace>
|
|
23
13
|
|
|
24
|
-
#
|
|
25
|
-
python3 scripts/extract_chat.py
|
|
14
|
+
# 扫描 + 提取:在扫描基础上,额外提取指定会话的完整对话
|
|
15
|
+
python3 scripts/extract_chat.py <my-workspace> "<urls>"
|
|
26
16
|
```
|
|
27
17
|
|
|
28
|
-
`<my-workspace
|
|
29
|
-
|
|
18
|
+
- `<my-workspace>`:**必填**,执行命令的 agent 自己的 workspace 路径(不是被分析对话所在的 workspace)
|
|
19
|
+
- `<urls>`:可选,单个 URL/key、逗号分隔、或 JSON 数组
|
|
20
|
+
- 输出固定到 `<my-workspace>/chat-history/` 子目录
|
|
21
|
+
|
|
22
|
+
**两步执行逻辑**:
|
|
23
|
+
1. **始终先扫描**所有 agent → 生成 `作品扫描_<时间>.html`
|
|
24
|
+
2. 如果传了 `<urls>` → 再提取指定会话 → 生成 `index.js` + `index.html`
|
|
30
25
|
|
|
31
26
|
## 输出文件
|
|
32
27
|
|
|
@@ -113,21 +108,28 @@ URL 示例:`https://claw1.kekouen.cn/chat?session=agent%3Ac108-v1-1811%3Amain`
|
|
|
113
108
|
|
|
114
109
|
## 示例
|
|
115
110
|
|
|
116
|
-
###
|
|
111
|
+
### 只扫描
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
python3 scripts/extract_chat.py /root/.openclaw/workspace-teacher
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
输出:`chat-history/作品扫描_<时间>.html`
|
|
118
|
+
|
|
119
|
+
### 扫描 + 提取单个会话
|
|
117
120
|
|
|
118
121
|
```bash
|
|
119
|
-
python3 scripts/extract_chat.py
|
|
122
|
+
python3 scripts/extract_chat.py /root/.openclaw/workspace-teacher \
|
|
123
|
+
"https://claw1.kekouen.cn/chat?session=agent%3Ac108-v1-1811%3Amain"
|
|
120
124
|
```
|
|
121
125
|
|
|
122
|
-
###
|
|
126
|
+
### 扫描 + 提取多个会话
|
|
123
127
|
|
|
124
128
|
```bash
|
|
125
|
-
python3 scripts/extract_chat.py '[
|
|
129
|
+
python3 scripts/extract_chat.py /root/.openclaw/workspace-teacher '[
|
|
126
130
|
"https://claw6.kekouen.cn/chat?session=agent%3Axuexiji%3Amain",
|
|
127
|
-
"https://claw6.kekouen.cn/chat?session=agent%3Ausa%3Amain"
|
|
128
|
-
|
|
129
|
-
"https://claw6.kekouen.cn/chat?session=agent%3Ac108-v1-1810%3A..."
|
|
130
|
-
]' /root/.openclaw/workspace-teacher
|
|
131
|
+
"https://claw6.kekouen.cn/chat?session=agent%3Ausa%3Amain"
|
|
132
|
+
]'
|
|
131
133
|
```
|
|
132
134
|
|
|
133
|
-
|
|
135
|
+
输出:`chat-history/作品扫描_<时间>.html` + `chat-history/index.js` + `chat-history/index.html`
|
|
@@ -433,12 +433,9 @@ def run_scan(output_dir=None, host=None):
|
|
|
433
433
|
|
|
434
434
|
|
|
435
435
|
def main():
|
|
436
|
-
# Parse flags: --host HOST, --html, --scan
|
|
437
|
-
# Position: positional args (no --) come first, flags can be interleaved
|
|
438
436
|
args = sys.argv[1:]
|
|
439
437
|
|
|
440
438
|
host = detect_chat_host()
|
|
441
|
-
scan_mode = False
|
|
442
439
|
positional = []
|
|
443
440
|
|
|
444
441
|
i = 0
|
|
@@ -447,84 +444,69 @@ def main():
|
|
|
447
444
|
if a == '--host' and i + 1 < len(args):
|
|
448
445
|
host = args[i + 1]
|
|
449
446
|
i += 2
|
|
450
|
-
|
|
451
|
-
elif a == '--scan':
|
|
452
|
-
scan_mode = True
|
|
453
|
-
i += 1
|
|
454
447
|
else:
|
|
455
448
|
positional.append(a)
|
|
456
449
|
i += 1
|
|
457
450
|
|
|
458
|
-
if
|
|
451
|
+
if len(positional) == 0 or len(positional) > 2:
|
|
459
452
|
print("Usage:")
|
|
460
|
-
print(" python3 extract_chat.py <
|
|
461
|
-
print(" python3 extract_chat.py
|
|
462
|
-
print(
|
|
463
|
-
print("
|
|
464
|
-
print("
|
|
453
|
+
print(" python3 extract_chat.py <workspace> [--host HOST]")
|
|
454
|
+
print(" python3 extract_chat.py <workspace> '<urls>' [--host HOST]")
|
|
455
|
+
print("")
|
|
456
|
+
print(" <workspace> 执行命令的 agent 自己的 workspace 路径")
|
|
457
|
+
print(" <urls> 可选。单个 URL/key,逗号分隔,或 JSON 数组")
|
|
458
|
+
print(" 不传则只扫描;传了则扫描后再提取指定会话")
|
|
465
459
|
print(" 输出固定到: <workspace>/%s/" % REPORT_SUBDIR)
|
|
466
|
-
print("
|
|
467
|
-
print("
|
|
468
|
-
print(" --
|
|
460
|
+
print("")
|
|
461
|
+
print("Flags:")
|
|
462
|
+
print(" --host HOST Override chat host (default: auto-detect from config.json)")
|
|
469
463
|
sys.exit(1)
|
|
470
464
|
|
|
471
|
-
|
|
472
|
-
if scan_mode:
|
|
473
|
-
if len(positional) != 1:
|
|
474
|
-
print("ERROR: --scan takes exactly 1 argument: <workspace>")
|
|
475
|
-
print(" --scan auto-scans all agents, no scan path needed")
|
|
476
|
-
sys.exit(1)
|
|
477
|
-
workspace = positional[0]
|
|
478
|
-
output_dir = os.path.join(workspace, REPORT_SUBDIR)
|
|
479
|
-
run_scan(output_dir, host=host)
|
|
480
|
-
return
|
|
481
|
-
|
|
482
|
-
# Normal mode: first arg = urls, second arg = workspace
|
|
483
|
-
if len(positional) != 2:
|
|
484
|
-
print("ERROR: expected exactly 2 arguments: <urls> <workspace>")
|
|
485
|
-
sys.exit(1)
|
|
486
|
-
arg1 = positional[0]
|
|
487
|
-
workspace = positional[1]
|
|
465
|
+
workspace = positional[0]
|
|
488
466
|
output_dir = os.path.join(workspace, REPORT_SUBDIR)
|
|
489
|
-
items = parse_input(arg1)
|
|
490
|
-
print("Input: %d session(s)" % len(items))
|
|
491
|
-
print("Host: %s" % detect_chat_host())
|
|
492
|
-
|
|
493
467
|
os.makedirs(output_dir, exist_ok=True)
|
|
494
468
|
|
|
495
|
-
#
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
469
|
+
# Step 1: 始终扫描所有 agent
|
|
470
|
+
print("=== Step 1: 扫描所有 agent ===")
|
|
471
|
+
run_scan(output_dir, host=host)
|
|
472
|
+
|
|
473
|
+
# Step 2: 如果传了 urls,提取指定会话
|
|
474
|
+
if len(positional) == 2:
|
|
475
|
+
print("\n=== Step 2: 提取指定会话 ===")
|
|
476
|
+
urls = positional[1]
|
|
477
|
+
items = parse_input(urls)
|
|
478
|
+
print("Input: %d session(s)" % len(items))
|
|
479
|
+
print("Host: %s" % host)
|
|
480
|
+
|
|
481
|
+
# 清理旧产物
|
|
482
|
+
for old_f in os.listdir(output_dir):
|
|
483
|
+
if old_f.endswith('.js') or old_f == 'index.html':
|
|
484
|
+
try:
|
|
485
|
+
os.remove(os.path.join(output_dir, old_f))
|
|
486
|
+
except Exception:
|
|
487
|
+
pass
|
|
488
|
+
|
|
489
|
+
results = []
|
|
490
|
+
for i, item in enumerate(items, 1):
|
|
491
|
+
r = process_one(item, output_dir, i)
|
|
492
|
+
if r:
|
|
493
|
+
results.append(r)
|
|
494
|
+
|
|
495
|
+
if not results:
|
|
496
|
+
print("\nERROR: No sessions processed successfully.")
|
|
497
|
+
sys.exit(1)
|
|
515
498
|
|
|
516
|
-
|
|
517
|
-
import shutil
|
|
518
|
-
tpl_path = os.path.join(_get_script_dir(), '..', 'assets', 'chat-history-template.html')
|
|
519
|
-
if os.path.exists(tpl_path):
|
|
520
|
-
shutil.copy2(tpl_path, os.path.join(output_dir, 'index.html'))
|
|
521
|
-
print("View: %s" % os.path.join(output_dir, 'index.html'))
|
|
499
|
+
generate_index_js(results, output_dir)
|
|
522
500
|
|
|
523
|
-
|
|
524
|
-
|
|
501
|
+
import shutil
|
|
502
|
+
tpl_path = os.path.join(_get_script_dir(), '..', 'assets', 'chat-history-template.html')
|
|
503
|
+
if os.path.exists(tpl_path):
|
|
504
|
+
shutil.copy2(tpl_path, os.path.join(output_dir, 'index.html'))
|
|
505
|
+
print("View: %s" % os.path.join(output_dir, 'index.html'))
|
|
525
506
|
|
|
526
|
-
|
|
527
|
-
|
|
507
|
+
print_summary_table(results, host)
|
|
508
|
+
total_pairs = sum(r['total_pairs'] for r in results)
|
|
509
|
+
print("\n合计:%d 个会话,%d 对对话。" % (len(results), total_pairs))
|
|
528
510
|
|
|
529
511
|
|
|
530
512
|
if __name__ == '__main__':
|