@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 relativePath = getWorkspaceId() + '/' + (asset.path || '');
541
- navigator.clipboard.writeText(relativePath).then(function () {
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiyiran/myclaw",
3
- "version": "1.1.185",
3
+ "version": "1.1.187",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -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 "<url>" <my-workspace>
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
- # 批量(JSON 数组)
25
- python3 scripts/extract_chat.py '["url1","url2","url3"]' <my-workspace>
14
+ # 扫描 + 提取:在扫描基础上,额外提取指定会话的完整对话
15
+ python3 scripts/extract_chat.py <my-workspace> "<urls>"
26
16
  ```
27
17
 
28
- `<my-workspace>` 是**执行命令的 agent 自己的 workspace 路径**(不是被分析的对话所在的 workspace)。
29
- 输出固定到 `<my-workspace>/chat-history/` 子目录。
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 "https://claw1.kekouen.cn/chat?session=agent%3Ac108-v1-1811%3Amain" /root/.openclaw/workspace-teacher
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
- "https://claw6.kekouen.cn/chat?session=agent%3Ac109-v3-1813%3A...",
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
- 输出在 `<workspace>/chat-history/` 下:`index.js` + `index.html`。
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 not positional and not scan_mode:
451
+ if len(positional) == 0 or len(positional) > 2:
459
452
  print("Usage:")
460
- print(" python3 extract_chat.py <url-or-key> <workspace> [--host HOST]")
461
- print(" python3 extract_chat.py 'url1,url2,url3' <workspace> [--host HOST]")
462
- print(' python3 extract_chat.py \'["url1","url2"]\' <workspace> [--host HOST]')
463
- print(" python3 extract_chat.py --scan <workspace> [--host HOST]")
464
- print("\n <workspace> 执行命令的 agent 自己的 workspace 路径")
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("\nFlags:")
467
- print(" --host HOST Override chat host (default: auto-detect from config.json)")
468
- print(" --scan Scan all agents")
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
- # --scan mode
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
- # 清理旧产物(含历史遗留的单会话 js)后再重新生成
496
- for old_f in os.listdir(output_dir):
497
- if old_f.endswith('.js') or old_f == 'index.html':
498
- try:
499
- os.remove(os.path.join(output_dir, old_f))
500
- except Exception:
501
- pass
502
-
503
- results = []
504
- for i, item in enumerate(items, 1):
505
- r = process_one(item, output_dir, i)
506
- if r:
507
- results.append(r)
508
-
509
- if not results:
510
- print("\nERROR: No sessions processed successfully.")
511
- sys.exit(1)
512
-
513
- # 唯一数据产物:index.js(chatIndex + chatAll)
514
- generate_index_js(results, output_dir)
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
- # Copy chat-history-template.html as index.html
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
- # Summary table
524
- print_summary_table(results, host)
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
- total_pairs = sum(r['total_pairs'] for r in results)
527
- print("\n合计:%d 个会话,%d 对对话。" % (len(results), total_pairs))
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__':