flower-trellis 0.4.0-beta.2 → 0.4.0-beta.4

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.
Files changed (65) hide show
  1. package/README.md +4 -0
  2. package/enhancements/MANIFEST.json +21 -3
  3. package/enhancements/common/.common/.claude/skills/craft-rpa/SKILL.md +377 -0
  4. package/enhancements/common/.common/.claude/skills/craft-rpa/recorder/dashboard.html +2102 -0
  5. package/enhancements/common/.common/.claude/skills/craft-rpa/recorder/inject.js +767 -0
  6. package/enhancements/common/.common/.claude/skills/craft-rpa/recorder/launch.js +255 -0
  7. package/enhancements/common/.common/.claude/skills/craft-rpa/recorder/logger.js +258 -0
  8. package/enhancements/common/.common/.claude/skills/craft-rpa/recorder/package-lock.json +59 -0
  9. package/enhancements/common/.common/.claude/skills/craft-rpa/recorder/package.json +13 -0
  10. package/enhancements/common/.common/.claude/skills/craft-rpa/scripts/jsonl-to-trace.js +722 -0
  11. package/enhancements/common/.common/.claude/skills/craft-rpa/scripts/run.sh +274 -0
  12. package/enhancements/common/.common/.claude/skills/craft-slides/SKILL.md +178 -0
  13. package/enhancements/common/.common/.claude/skills/craft-slides/reference/syntax.md +163 -0
  14. package/enhancements/common/.common/.claude/skills/craft-slides/scripts/slidev.sh +345 -0
  15. package/enhancements/common/.common/.claude/skills/craft-slides/templates/slides.apple-basic.md +113 -0
  16. package/enhancements/common/.common/.claude/skills/craft-slides/templates/slides.dracula.md +111 -0
  17. package/enhancements/common/.common/.claude/skills/craft-slides/templates/slides.geist.md +112 -0
  18. package/enhancements/common/.common/.claude/skills/craft-slides/templates/slides.md +103 -0
  19. package/enhancements/common/.common/.claude/skills/craft-slides/templates/slides.nord.md +123 -0
  20. package/enhancements/common/.common/.claude/skills/craft-slides/templates/slides.seriph.md +115 -0
  21. package/enhancements/common/.common/.claude/skills/humanize-writing/SKILL.md +628 -0
  22. package/enhancements/common/.common/.claude/skills/open-idea/SKILL.md +103 -0
  23. package/enhancements/common/.common/.claude/skills/open-idea/scripts/open_idea.py +657 -0
  24. package/enhancements/common/.common/.claude/skills/sub2api-account-json-fix/SKILL.md +47 -0
  25. package/enhancements/common/.common/.claude/skills/sub2api-account-json-fix/env/push.env.example +8 -0
  26. package/enhancements/common/.common/.claude/skills/sub2api-account-json-fix/scripts/run.sh +27 -0
  27. package/enhancements/common/.common/.claude/skills/torrent-analyze/SKILL.md +190 -0
  28. package/enhancements/common/.common/.claude/skills/torrent-analyze/config/default.env +39 -0
  29. package/enhancements/common/.common/.claude/skills/torrent-analyze/scripts/torrent_analyze.py +910 -0
  30. package/enhancements/common/.common/.codex/skills/craft-rpa/SKILL.md +377 -0
  31. package/enhancements/common/.common/.codex/skills/craft-rpa/recorder/dashboard.html +2102 -0
  32. package/enhancements/common/.common/.codex/skills/craft-rpa/recorder/inject.js +767 -0
  33. package/enhancements/common/.common/.codex/skills/craft-rpa/recorder/launch.js +255 -0
  34. package/enhancements/common/.common/.codex/skills/craft-rpa/recorder/logger.js +258 -0
  35. package/enhancements/common/.common/.codex/skills/craft-rpa/recorder/package-lock.json +59 -0
  36. package/enhancements/common/.common/.codex/skills/craft-rpa/recorder/package.json +13 -0
  37. package/enhancements/common/.common/.codex/skills/craft-rpa/scripts/jsonl-to-trace.js +722 -0
  38. package/enhancements/common/.common/.codex/skills/craft-rpa/scripts/run.sh +274 -0
  39. package/enhancements/common/.common/.codex/skills/craft-slides/SKILL.md +178 -0
  40. package/enhancements/common/.common/.codex/skills/craft-slides/reference/syntax.md +163 -0
  41. package/enhancements/common/.common/.codex/skills/craft-slides/scripts/slidev.sh +345 -0
  42. package/enhancements/common/.common/.codex/skills/craft-slides/templates/slides.apple-basic.md +113 -0
  43. package/enhancements/common/.common/.codex/skills/craft-slides/templates/slides.dracula.md +111 -0
  44. package/enhancements/common/.common/.codex/skills/craft-slides/templates/slides.geist.md +112 -0
  45. package/enhancements/common/.common/.codex/skills/craft-slides/templates/slides.md +103 -0
  46. package/enhancements/common/.common/.codex/skills/craft-slides/templates/slides.nord.md +123 -0
  47. package/enhancements/common/.common/.codex/skills/craft-slides/templates/slides.seriph.md +115 -0
  48. package/enhancements/common/.common/.codex/skills/humanize-writing/SKILL.md +628 -0
  49. package/enhancements/common/.common/.codex/skills/open-idea/SKILL.md +103 -0
  50. package/enhancements/common/.common/.codex/skills/open-idea/agents/openai.yaml +4 -0
  51. package/enhancements/common/.common/.codex/skills/open-idea/scripts/open_idea.py +657 -0
  52. package/enhancements/common/.common/.codex/skills/sub2api-account-json-fix/SKILL.md +126 -0
  53. package/enhancements/common/.common/.codex/skills/sub2api-account-json-fix/agents/openai.yaml +4 -0
  54. package/enhancements/common/.common/.codex/skills/sub2api-account-json-fix/env/push.env.example +8 -0
  55. package/enhancements/common/.common/.codex/skills/sub2api-account-json-fix/scripts/fix_exported_account_json.py +890 -0
  56. package/enhancements/common/.common/.codex/skills/sub2api-account-json-fix/scripts/run.sh +26 -0
  57. package/enhancements/common/.common/.codex/skills/torrent-analyze/SKILL.md +190 -0
  58. package/enhancements/common/.common/.codex/skills/torrent-analyze/config/default.env +39 -0
  59. package/enhancements/common/.common/.codex/skills/torrent-analyze/scripts/torrent_analyze.py +910 -0
  60. package/package.json +1 -1
  61. package/src/cli.js +5 -0
  62. package/src/commands/skill.js +261 -0
  63. package/src/lib/apply-enhancements.js +5 -23
  64. package/src/lib/enhancement-catalog.js +86 -0
  65. package/src/lib/skill-catalog.js +444 -0
package/README.md CHANGED
@@ -52,6 +52,9 @@ flower-trellis init -u <your-name> -y
52
52
  # 升级 Trellis 并按新版本重新叠加强化包
53
53
  flower-trellis update
54
54
 
55
+ # 交互管理通用技能,并查看工作流强化包
56
+ flower-trellis skill
57
+
55
58
  # 卸载:移除 Trellis 本体并清理强化包残留
56
59
  flower-trellis uninstall
57
60
 
@@ -67,6 +70,7 @@ flower-trellis -v
67
70
  |------|------|
68
71
  | `init` | 安装 Trellis 并叠加强化包(默认命令,裸跑等同 `init`) |
69
72
  | `update` | 升级 Trellis,并按新版本重新叠加强化包 |
73
+ | `skill` | 打开交互菜单:启用或停用通用技能,只读查看工作流强化包 |
70
74
  | `uninstall` | 移除 Trellis 本体并清理强化包残留(支持 `-y` / `--dry-run`) |
71
75
  | `<其它命令>` | 原样透传给 Trellis,覆盖其现有及未来子命令 |
72
76
  | `-v` / `-h` | 打印版本 / 帮助 |
@@ -1,7 +1,25 @@
1
1
  {
2
- "syncedAt": "2026-06-30T00:30:48.425Z",
3
- "syncedFrom": "vendor/skill-garden/.trellis",
4
- "sourceCommit": "44b5b31a0c0346f4d615ad6f3f58af860cc3983d",
2
+ "syncedAt": "2026-07-01T04:27:03.524Z",
3
+ "syncedFrom": "vendor/skill-garden",
4
+ "sourceCommit": "7a9b882db76500b49b38cf423be682fb06effe1a",
5
+ "common": {
6
+ "codexSkills": [
7
+ "craft-rpa",
8
+ "craft-slides",
9
+ "humanize-writing",
10
+ "open-idea",
11
+ "sub2api-account-json-fix",
12
+ "torrent-analyze"
13
+ ],
14
+ "claudeSkills": [
15
+ "craft-rpa",
16
+ "craft-slides",
17
+ "humanize-writing",
18
+ "open-idea",
19
+ "sub2api-account-json-fix",
20
+ "torrent-analyze"
21
+ ]
22
+ },
5
23
  "variants": {
6
24
  "old": {
7
25
  "claudeSkills": [],
@@ -0,0 +1,377 @@
1
+ ---
2
+ name: craft-rpa
3
+ description: "录制真实浏览器流程为按会话保存的 JSONL,并转换成 RPA 改造参考用的 markdown trace。适用于录制浏览器流程、生成 RPA 流程参考、session.jsonl 转 trace、Dashboard 反向控浏览器、craft rpa、record browser flow;不用于 CI 测试、并行录制或反爬绕过。"
4
+ ---
5
+
6
+ # Craft RPA
7
+
8
+ > 自包含的"录制 → 多会话留档 → 机械翻译成 markdown 流程参考"端到端工具,服务于**人工/半自动 RPA 改造**(不是自动 e2e 测试)。
9
+ > skill 内自带 `recorder/`(launch.js / logger.js / inject.js / dashboard.html)、`scripts/run.sh`(生命周期管理)、`scripts/jsonl-to-trace.js`(转换输出)。
10
+
11
+ ---
12
+
13
+ ## 适用场景
14
+
15
+ - 录制业务流程作为 RPA / 自动化脚本的**改造素材**(UiPath / Power Automate / Selenium / Playwright)
16
+ - 复盘第三方系统的真实交互(尤其严 CSP 站点,如 oracle.com)
17
+ - 同一目标多次录制,每次会话独立留档,便于横向对照
18
+ - 通过 Dashboard 在另一台机器上观察 + 控制 WSL/Linux 里的录制会话
19
+ - 抓 SPA / 复杂前端应用的真实运行轨迹
20
+
21
+ ## 不适用场景
22
+
23
+ - 无人值守的 CI 集成测试 → 用 Playwright test runner
24
+ - 跨机器并行录制 / 集群压测
25
+ - 反爬绕过 / 反检测自动化
26
+ - 仅前端 lint / 单测 / spec 验证
27
+ - 期望"录完就能跑"的自动重放 —— trace.md 是人/AI 改造素材,不是可执行脚本
28
+
29
+ ---
30
+
31
+ ## 前置条件
32
+
33
+ - Node ≥ 18(LTS 推荐)
34
+ - 系统装 Chrome(默认),或 `npx playwright install chromium` + 把 `recorder/launch.js` 里的 `USE_SYSTEM_CHROME` 改成 `false`
35
+ - WSL2 必须有 WSLg(`echo $DISPLAY` 应非空)
36
+ - 端口 `7777` 未被占用(否则改三处常量,见 Hard Constraints #2)
37
+
38
+ ---
39
+
40
+ ## 首次安装
41
+
42
+ skill 推荐装到用户全局,任意仓库自动可用:
43
+
44
+ ```bash
45
+ cp -r <source>/.claude/skills/craft-rpa ~/.claude/skills/
46
+ # 首次 start 时 run.sh 会自动 npm install,无需手装
47
+ ```
48
+
49
+ 或每个仓库装一份:
50
+
51
+ ```bash
52
+ cp -r <source>/.claude/skills/craft-rpa <repo>/.claude/skills/
53
+ ```
54
+
55
+ 后文 `$SKILL_DIR` 统一指 `~/.claude/skills/craft-rpa` 或 `<repo>/.claude/skills/craft-rpa`。
56
+
57
+ ---
58
+
59
+ ## 自动模式(AI 代跑)
60
+
61
+ 想让 AI 替你跑录制 / 停止 / 转换,**不要手 cd 进 recorder/**,改用脚本封装:
62
+
63
+ ```bash
64
+ bash "$SKILL_DIR/scripts/run.sh" start [URL] # 新会话目录 + 后台起;无 URL:TTY 下 prompt,非 TTY 直接 about:blank
65
+ bash "$SKILL_DIR/scripts/run.sh" status # 看是否在跑 + 当前会话 + 历史数 + Dashboard URL
66
+ bash "$SKILL_DIR/scripts/run.sh" sessions # 列所有历史会话(* 标当前)
67
+ bash "$SKILL_DIR/scripts/run.sh" logs [N] # tail 最近 N 行(默认 50)
68
+ bash "$SKILL_DIR/scripts/run.sh" stop # SIGINT 优雅停止,3s 未退再 SIGTERM
69
+ bash "$SKILL_DIR/scripts/run.sh" craft [--session <ts>] [OUT]
70
+ # 转 jsonl → trace.md;--session 默认 = 当前/最新;OUT 默认 ./trace.md
71
+ ```
72
+
73
+ 运行时状态 / sessions / profile 全部在 `$(pwd)/.craft-rpa/`(可用 `CRAFT_RPA_HOME` env 覆盖到任意路径)。首次 `start` 自动 `npm install`(跳浏览器下载,~10s)。
74
+
75
+ **AI 行为约定**(看到下列触发就跑对应子命令,不要手敲底层 cd / nohup):
76
+
77
+ | 用户说 | AI 跑 |
78
+ |--------|-------|
79
+ | "开始录" / "录浏览器 [URL]" / "start" | `run.sh start [URL]`,把返回的会话 ts + Dashboard URL 贴给用户 |
80
+ | "停" / "结束录制" / "stop" | `run.sh stop`,贴出本会话事件数 |
81
+ | "转换" / "生成参考" / "craft" | `run.sh craft`(输出 trace.md),贴出输出路径 + 行数 + 会话 ts |
82
+ | "转上一次的" / "转 <ts>" | `run.sh craft --session <ts>` |
83
+ | "看 log" / "看日志" | `run.sh logs` |
84
+ | "在跑吗" / "status" / "看下当前" | `run.sh status` |
85
+ | "列会话" / "看历史" | `run.sh sessions` |
86
+
87
+ **AI 不要做**:
88
+
89
+ - 浏览器窗口里的鼠标 / 键盘操作 —— 这是 GUI 部分,只能由用户本人完成
90
+ - 修改 `recorder/` 里的代码 —— 它是 skill 独立资产(仅 `REDACT_SENSITIVE` 常量允许调)
91
+ - 跳过 `run.sh` 直接 `nohup node launch.js` —— 会绕过会话目录管理和 PID 管理
92
+ - 自己尝试合并语义步骤 / 命名 step / 删事件 —— 这是 AI 精修阶段的事(下一段),`craft` 输出已经包含全部原始信息
93
+
94
+ ---
95
+
96
+ ## 数据位置与多会话约定
97
+
98
+ 录制产物与运行时状态**写入项目根**(与 skill 代码解耦),默认 `<cwd>/.craft-rpa/`,可用环境变量 `CRAFT_RPA_HOME` 覆盖。
99
+
100
+ ```
101
+ <repo>/.craft-rpa/ ← 项目根,建议仓库根 .gitignore 豁免整目录
102
+ ├── sessions/
103
+ │ ├── 2026-05-18_10-30-00/ ← 每次 start 创建时间戳目录,不覆盖历史
104
+ │ │ ├── session.jsonl
105
+ │ │ └── trace.md ← 可选,craft 输出可指定到此
106
+ │ ├── 2026-05-18_14-22-15/
107
+ │ └── legacy-2026-05-17_... ← 老版本遗留 / 升级时自动归档
108
+ ├── profile/ ← Chrome 持久 profile(登录态,项目独立)
109
+ ├── .launch.pid / .launch.log ← 进程管理 + 日志
110
+ └── .current-session ← 最近一次 start 的会话 ts
111
+
112
+ .claude/skills/craft-rpa/recorder/ ← skill 内仅代码资产;start 时建两个软链 → 数据根:
113
+ ├── session.jsonl → <repo>/.craft-rpa/sessions/<latest>/session.jsonl
114
+ └── profile → <repo>/.craft-rpa/profile
115
+ ```
116
+
117
+ **为什么这样**:
118
+ - 录制 jsonl 是**项目业务数据**,跟着仓库走(每个仓库独立 session 池,不串)
119
+ - skill 代码可装 `~/.claude/skills/craft-rpa/` 全局,所有仓库共用同一份代码
120
+ - launch.js / logger.js 用 `__dirname` 解析 session.jsonl / profile,通过 recorder/ 内软链自动落到项目根 —— **录制器代码不用改**
121
+
122
+ **关键性质**:
123
+
124
+ - 每次 `run.sh start` 创建新时间戳目录,**不覆盖**历史
125
+ - `recorder/session.jsonl` / `recorder/profile` 始终是软链,随当前会话切换目标
126
+ - 老版本遗留的 `recorder/session.jsonl`(普通文件)在新版第一次 start 时自动归档到 `sessions/legacy-<ts>/`;`recorder/profile/`(普通目录)归档到 `.craft-rpa/profile-legacy-<ts>/`
127
+ - `run.sh craft` 默认转最新;`--session <ts>` 可转任意历史
128
+ - 删历史:手动 `rm -rf .craft-rpa/sessions/<ts>/`,run.sh 不管删
129
+
130
+ **`CRAFT_RPA_HOME` env 用法**:
131
+
132
+ ```bash
133
+ # 默认:cwd 是 oracle-register 时,数据写在 oracle-register/.craft-rpa/
134
+ cd <your-repo> && bash $SKILL_DIR/scripts/run.sh start
135
+
136
+ # 想统一集中存(比如 home 下中央位置):
137
+ export CRAFT_RPA_HOME=~/rpa-recordings
138
+ bash $SKILL_DIR/scripts/run.sh start
139
+ ```
140
+
141
+ ---
142
+
143
+ ## AI 精修阶段做什么(关键)
144
+
145
+ `jsonl-to-trace.js` 输出是**机械翻译,不删信息**:每个事件平铺一段,字段全保留。这意味着 trace.md 里没有"业务步骤"概念,只有原始事件。
146
+
147
+ **AI 拿到 trace.md 后应该做的事**(用户没明说时也要主动做):
148
+
149
+ 1. **识别业务步骤**:把多条相邻事件合并成"用户在做一件事"
150
+ 例:`input(email)` + `input(password)` + `click(登录)` + `network(POST /api/login → 200)` + `pageload(/dashboard)` = "Step 1 — 用户登录"
151
+ 2. **给步骤起业务命名**:基于元素 accessibleName / URL / 上下文推断(登录 / 下单 / 创建实例 / 退订),不要叫 "Step 1 — Click button"
152
+ 3. **标注噪音但不删原文**:对明显无业务意义的事件(高频 mousemove、纯 focus / blur、统计埋点 xhr)在产出里灰显或归类到"噪音观察"段,**但 trace.md 原文不动**
153
+
154
+ ⚠ **关键警示**:trace.md 速览表中 `[BUSINESS-IN-NOISE]` 标记的事件**永远不能当噪音过滤**——它们是被埋在 fingerprint frames 噪音段里的业务 click(典型场景:支付 modal 内的 Credit Card / Close 按钮,被前后大量 ThreatMetrix fingerprint frame 包围)。AI 看到此标记必须**反向验证**该 interaction 是否对应一个业务步骤,并在 rpa-draft.md 中显式覆盖。`[NOISE?]` 仅是参考标记不是真值,但 `[BUSINESS-IN-NOISE]` 是"已经发现的反例",优先级最高。
155
+ 4. **保留选择器全集**:RPA 改造时不同工具偏好不同选择器(UiPath 喜欢 ID,Selenium 偏 XPath,Playwright 喜欢 role+name),不要只挑一个
156
+ 5. **保留敏感字段原值**:RPA 流程通常需要固定填值,直接呈现,不要替换为占位
157
+ 6. **输出 RPA 改造草案**:推荐结构
158
+
159
+ ```markdown
160
+ # RPA 流程草案 - <场景名>
161
+
162
+ ## 整体流程
163
+ <3-5 句业务描述>
164
+
165
+ ## 关键步骤
166
+
167
+ ### Step 1 — <业务命名>
168
+ - 触发: <用户什么动作>
169
+ - 元素: <accessibleName> (selector: <最稳的两三个>)
170
+ - 输入值: <如有>
171
+ - 触发请求: <如有>
172
+ - 完成判定: <pageload / 元素出现 / network status>
173
+
174
+ ### Step 2 — ...
175
+
176
+ ## 噪音观察(供改造时跳过)
177
+ - 事件 #15-#18:鼠标 hover 触发 tooltip,无业务意义
178
+ - 事件 #34:百度统计埋点,可忽略
179
+
180
+ ## RPA 工具适配建议
181
+ - UiPath:用 attribute 选 testId / id
182
+ - Power Automate:用 role+name
183
+ - Selenium:用 XPath 兜底
184
+ ```
185
+
186
+ 7. **保留可追溯性**:每个 Step 标注覆盖的原始事件 # 区间,方便用户回查
187
+
188
+ ### 产物落盘约定
189
+
190
+ | 项 | 约定 |
191
+ |----|------|
192
+ | **文件名** | `rpa-draft.md`(固定,不带场景名后缀;场景名写在文档标题里) |
193
+ | **位置** | `$CRAFT_RPA_HOME/sessions/<ts>/rpa-draft.md`,与 `trace.md` 同目录,可追溯性最强 |
194
+ | **触发关键词** | 用户说"精修" / "RPA 草案" / "改造草案" / "draft" / "进入精修阶段" / "输出草案" 时,AI 主动生成 |
195
+ | **不落对话** | 草案体量通常数 KB ~ 数十 KB,写文件后只给用户:**路径 + 关键发现摘要(3-5 点)**,不在对话里贴正文 |
196
+ | **重生成** | 重新精修同一会话 → 覆盖 `rpa-draft.md`(不加时间戳后缀,会话隔离已由父目录 `<ts>/` 完成) |
197
+ | **跨会话对照** | 不合并 jsonl;由 AI 在精修时读多个 `sessions/<ts>/trace.md`,产出独立的"对照"草案(用户显式要求时) |
198
+
199
+ ---
200
+
201
+ ## RPA 实施模板(撞 → 修循环)
202
+
203
+ > 本段沉淀自 `oracle-register` 等实战任务的撞坑经验:rpa-draft.md 给出的 selector 表 **绝不是 ground truth**,实施期默认会撞 2-3 次;不内置失败回路就只能盯眼看,几小时排错变成几分钟。
204
+
205
+ ### rpa-draft 不是 ground truth
206
+
207
+ trace.md 是机械翻译;rpa-draft.md 是 AI 基于 trace 的**推断**——它没看过真实 DOM,只看到了选择器集合 + 文本 + 祖先链。对 react-select / 自定义 radio / 隐藏 checkbox 等第三方深度定制 SPA(典型:oracle.com / cybersource 支付),selector 表只能当 **first guess**:
208
+
209
+ - 真实跑起来 `getByRole('option')` 找不到、`getByLabel(/X/)` 命中错的元素、提交按钮一直 disabled —— 都是预期内的
210
+ - 默认会撞 2-3 次,撞了不是 rpa-draft 写错,是 selector 推断本质上的不确定性
211
+ - 撞了**不要硬猜下一个选择器**——dump DOM 看真实结构,再回头改
212
+
213
+ ### 必备四件套
214
+
215
+ 实施 RPA 脚本时必须内置(任一缺失都让排错时长 ×5):
216
+
217
+ 1. **dumpFailure** —— 失败时落:
218
+ - `screenshot.png`(fullPage)
219
+ - `url.txt`(失败时的 URL,SPA 单 URL 时也要)
220
+ - `dom.html`(主 frame `page.content()`)
221
+ - `frame_N_<url>.html`(所有非主 frame 的 `f.content()`)—— iframe 支付 / 跨域 widget 唯一能看到真实 DOM 的方式
222
+ - `error.json`(step / message / stack)
223
+ 2. **Playwright tracing** —— `ctx.tracing.start({snapshots: true, sources: true})` / `ctx.tracing.stop({path: 'trace.zip'})`,失败后用 `npx playwright show-trace trace.zip` 回放可视化排查
224
+ 3. **Atomic status machine** —— `pending → running → succeeded / dead`;
225
+ - 退出 hook(SIGINT / SIGTERM / uncaughtException)把 `running` 回写 `pending` 避免账户被悬挂
226
+ - `accounts.json.tmp` + rename 原子写,避免半成品状态
227
+ 4. **noise / business hint 参考但自验** —— 看到 trace.md 里 `[BUSINESS-IN-NOISE]` 标记的 interaction 当作 **"必须验证是否漏点"的提示**,不直接信任 AI 的噪音过滤结论。被埋在 fingerprint frame 噪音里的支付按钮(Credit Card / Close)是这个标记的典型对象
228
+
229
+ ### 7 类 Playwright stubborn elements 速查
230
+
231
+ 撞 `Timeout` / `intercepts pointer events` / `not visible` / `outside of the viewport` / `getByRole 命中错元素` / Submit 永远 disabled / 等不到 URL 跳转 时,先对照 `<repo>/.trellis/spec/guides/playwright-stubborn-elements-guide.md` 的 7 类速查表 + Click 三层 actionability 跳过参考(.click → force:true → evaluate(el => el.click))。该 guide 含 oracle-register 实战的具体修法和 selector 优先级修订版。
232
+
233
+ > 注:guide 路径以 `<repo>` 占位,因为 craft-rpa skill 可装到全局 home(`~/.claude/skills/`),而 spec 通常在具体项目仓库。
234
+
235
+ ### 何时升级 timing 应对
236
+
237
+ 实施期撞到下面任一现象,**立刻升级 timing 策略**,不要硬调 selector:
238
+
239
+ - onBlur validation 不触发(Continue 按钮永远 disabled)→ 字段内 `pressSequentially(value, {delay: 80-150})` + `press('Tab')` 主动 blur,而非一次性 `fill()`
240
+ - 后端风控 ban / step 间瞬时切换被检测 → step 间加 500-2000ms `humanPause` 随机停顿
241
+ - 字段完全无鼠标移动被 fingerprint(很少需要)→ `page.mouse.move` 加少量随机轨迹
242
+
243
+ 不是所有 input 都要逐字符——**只在校验逻辑挂在 onBlur 或 Continue 一直 disabled 的字段**上加。
244
+
245
+ ### 已知限制(写进 SKILL.md 避免反复踩)
246
+
247
+ - **Shadow DOM 内 outerHTML 提取**:浏览器 API 限制,跨 shadow root 拿不到,inject.js 的 `target.contextHTML` 字段在 shadow root 元素上会缺失;只能用 selectors / accessibleName 推断
248
+ - **跨域 iframe 元素**:同源策略限制,inject.js 在跨域 iframe 内单独运行但无法跨域访问父 frame 上下文;`target.contextHTML` 在跨域 iframe 内取自当前 frame 上下文(不含父 frame)
249
+
250
+ ---
251
+
252
+ ## 工作流
253
+
254
+ ### Step 1: 启动录制
255
+
256
+ ```bash
257
+ bash "$SKILL_DIR/scripts/run.sh" start https://target.com
258
+ # 或
259
+ bash "$SKILL_DIR/scripts/run.sh" start # 起 about:blank
260
+ ```
261
+
262
+ 启动成功标志:
263
+
264
+ - run.sh 返回 `[craft-rpa] started (pid=..., url=...)` + 会话 ts + Dashboard URL
265
+ - 浏览器窗口弹出(每个新页面 Console 会打 `[inject] boot at <url>`)
266
+ - `<cwd>/.craft-rpa/sessions/<ts>/session.jsonl` 已创建(空文件,等事件)
267
+
268
+ ### Step 2: 用 Dashboard 实时验证
269
+
270
+ 打开 `http://localhost:7777/dashboard`:
271
+
272
+ - 顶部 4 计数器(int / net / nav / err)随你的操作上跳
273
+ - 没数:`run.sh logs` 看 launch / logger 报错;最常见根因是 `7777` 端口被占
274
+
275
+ **快捷键**:
276
+
277
+ | 键 | 动作 |
278
+ |----|------|
279
+ | `T` | 切主题 |
280
+ | `Space` | 暂停 / 恢复事件流 |
281
+ | `Ctrl/⌘ + F` | 聚焦搜索 |
282
+ | `Esc` | 关闭详情面板 |
283
+
284
+ **反向控浏览器**(走 `logger.js` 的 `/control/*` 接口):
285
+
286
+ - Dashboard 顶部 URL 栏输地址回车 → 当前 tab 打开;勾"新标签"则 newTab
287
+ - 底部 tabs 区域可点切换 / 关闭 / 刷新 / 前进后退
288
+
289
+ ### Step 3: 录完停止
290
+
291
+ ```bash
292
+ bash "$SKILL_DIR/scripts/run.sh" stop
293
+ # 输出: [craft-rpa] stopped (session=2026-05-18_10-30-00, 187 events)
294
+ ```
295
+
296
+ 或直接关浏览器窗口(launch.js 自动检测 context.on('close') 关闭 logger,run.sh 的 PID 文件会留着但 status 会发现进程已死自动清掉)。
297
+
298
+ ### Step 4: 生成 RPA 流程参考(trace.md)
299
+
300
+ ```bash
301
+ bash "$SKILL_DIR/scripts/run.sh" craft
302
+ # 默认 --session=最新 → 写 ./trace.md
303
+ ```
304
+
305
+ **trace.md 内容结构**:
306
+
307
+ 1. **头部元数据**:起止时间 / 时长 / 事件总数 / URL 覆盖 / kind.type 分布 / 超长 URL 截断统计
308
+ 2. **速览表**:每事件一行(`#/jsonl#/t+s/kind.type/简述/最稳selector/value 或 URL`),方便整体把握
309
+ 3. **事件详情**:每事件一段,字段全保留(target.selectors 全集 / accessibleName / state / boundingBox / 网络字段 / 祖先链 / formFields ...)
310
+
311
+ **关键性质**:
312
+
313
+ - 机械翻译,**不过滤任何事件**(信息零损失)
314
+ - **不命名业务 step**(js 不知道业务语义,留给 AI 精修)
315
+ - **不脱敏**(`recorder/inject.js` 已默认 `REDACT_SENSITIVE=false`,value 全是原值)
316
+ - 超长 URL(>800 chars 默认)截断 + 标注 `jsonlLine: <N>` 反查;原文取法 `sed -n '<N>p' session.jsonl | jq .url`
317
+
318
+ **AI 拿到 trace.md 后**:走"AI 精修阶段做什么"段的 7 步,输出 RPA 改造草案给用户。
319
+
320
+ ### Step 5: 转给 RPA 工具实施
321
+
322
+ 把 trace.md(原始素材) + AI 精修后的草案(产出) 给到 RPA 工程师,他们对照 selector 全集 + 输入值 + 网络断言 + 业务命名,在 UiPath / Power Automate / 自研 RPA 里搭出可视化流程。
323
+
324
+ ---
325
+
326
+ ## Hard Constraints(违反破坏核心功能)
327
+
328
+ 1. **`bypassCSP: true` 不能关** —— 否则严 CSP 站点(如 oracle.com)的 fetch 全部被拦,inject.js 一条事件都送不出。位置:`recorder/launch.js` 的 `launchOptions`
329
+ 2. **端口 `7777` 改动必须三处同步**:`recorder/logger.js` 默认端口 / `recorder/inject.js` 的 `LOGGER` 常量 / `recorder/dashboard.html` 的所有 `/control/*` fetch
330
+ 3. **`recorder/inject.js` 保持单文件 / 无依赖 / 不抛错到业务页面** —— Playwright `addInitScript({ path })` 注入约束;一旦抛错会污染目标站
331
+ 4. **HTML 注入点必须 `escapeHtml`** —— Dashboard 渲染的事件 target 来自任意目标站,XSS 高危。位置:`recorder/dashboard.html`
332
+ 5. **CORS 必须回显 `Origin` 不能用 `*`** —— `sendBeacon` + cookie 场景要求。位置:`recorder/logger.js`
333
+ 6. **敏感字段默认 NOT 脱敏(`REDACT_SENSITIVE = false`)** —— RPA 流程参考需要原值;`target.sensitive` 标记仍保留供人工识别。**唯独**当 trace.md 产物要外传或归档时,自行评估是否手动脱敏对应 value 行。要重新启用源头脱敏,改 `recorder/inject.js` 的 `REDACT_SENSITIVE = true`(整次会话内对所有命中字段生效)
334
+
335
+ ---
336
+
337
+ ## 排错快查
338
+
339
+ | 症状 | 根因 | 修复 |
340
+ |------|------|------|
341
+ | 浏览器拉不起 / 找不到 display | WSL2 无 WSLg / Linux 无图形 | 升 Win11 自带 WSLg / 装 X server / 或改 `headless: true`(无 GUI 重放) |
342
+ | `Executable doesn't exist at .../chrome-linux/chrome` | `USE_SYSTEM_CHROME=false` 但没装 Chromium | `npx playwright install chromium` 或把常量改回 `true` |
343
+ | `channel 'chrome' is not installed` | `USE_SYSTEM_CHROME=true` 但系统没装 Chrome | `apt install google-chrome-stable` 或下载 Chromium |
344
+ | 端口 `7777` 被占 | 其他进程占用 | 改 `recorder/logger.js` 默认端口 + `recorder/inject.js` 的 `LOGGER`;或 `startLogger({ port: 8888 })` |
345
+ | Dashboard 一直 0 事件 | inject.js 没注入 / fetch 被拦 | `run.sh logs` 看有没有 `[inject] boot at ...`;确认 `bypassCSP` 没关 |
346
+ | 跨源 iframe 内事件丢失 | 浏览器同源策略 | 已知限制,无解;改用顶层窗口操作 |
347
+ | `run.sh start` 报"already running" 但你没跑 | `.launch.pid` 残留 | `rm .craft-rpa/.launch.pid` 后重试 |
348
+ | `craft` 报"no session found" | sessions 目录空 / 没录过 | 先 `run.sh start` 录一段 |
349
+ | trace.md 速览表表格错位 | 字段含 `|` 或换行未转义 | js 已转义,如仍有问题报具体 # 事件 |
350
+ | 整页跳转后 sessionId 变了对不上 | 这是正常的 —— 每页注入是新会话(jsonl 内的 sessionId,与 run.sh 的会话 ts 是不同概念) | 分析时按 `url` 分组,不依赖 jsonl 内 sessionId 跨页对齐 |
351
+ | 历史 sessions 太多占空间 | 手动清理 | `ls .craft-rpa/sessions/` 看,`rm -rf .craft-rpa/sessions/<ts>/` 删 |
352
+
353
+ ---
354
+
355
+ ## 反模式
356
+
357
+ ### 脚本生成 / 解读层面
358
+
359
+ - 让 `jsonl-to-trace.js` 做语义合并 / step 命名 / 噪音判断 —— 这些需要业务上下文,js 不知道;**留给 AI 精修阶段**
360
+ - 在转换器里默认过滤事件 —— 信息丢失不可逆;噪音判断由 AI 在精修阶段标注(但不删原文)
361
+ - 用 `xpath` 作为首选 selector —— xpath 是兜底,DOM 一调全断;按 testId → role+name → id → name → ariaLabel → text 顺序找
362
+ - 把多次 `run.sh start` 的事件混在一个 trace.md 里 —— 每会话独立,跨会话对照应该是 AI 在精修阶段做,不是合并 jsonl
363
+
364
+ ### 工具使用层面
365
+
366
+ - 在 `recorder/inject.js` 引入 npm 依赖 —— `addInitScript` 注入约束,只能用浏览器原生 API
367
+ - 把端口 / Dashboard 暴露公网 —— logger 监听 `0.0.0.0:7777` 且无鉴权,仅本地开发
368
+ - 并行起多个 `launch.js` 共用同一 `.craft-rpa/profile/` —— Chrome 单实例锁,会启动失败或损坏 profile
369
+ - 改了 `inject.js` 的 `LOGGER` 端口但没改 `logger.js` / `dashboard.html` —— 三处必须同步(Hard Constraints #2)
370
+ - 录制时 `Ctrl+C` 强杀 launch.js —— 优先 `run.sh stop`,让 SIGINT 走完优雅关闭路径,profile 才能正确落盘
371
+ - 把 `.craft-rpa/` 提交进 git —— 该目录全是业务数据 + 运行时,装 skill 到新仓库时在仓库根 `.gitignore` 加一行 `.craft-rpa/`
372
+
373
+ ### Skill 使用层面
374
+
375
+ - 不要为"跑一次 launch.js"创建 trellis task —— 这是工具调用,不是工程任务
376
+ - 不要把 `trace.md` 写回 `recorder/` —— recorder 只负责录制,产出应放消费方仓库或 `.craft-rpa/sessions/<ts>/`
377
+ - skill 内 `recorder/` 是 skill 自带的独立资产,跟项目根的 oracle-register 代码无关 —— 改 skill 内的代码不会影响项目根,反之亦然(`REDACT_SENSITIVE` 切换属 skill 内本地配置)