@tea-agent/loop-agent 0.27.1-beta.2 → 0.28.0

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 (48) hide show
  1. package/CHANGELOG.md +40 -1
  2. package/dist/application/task-lifecycle/observe.js +5 -0
  3. package/dist/application/task-lifecycle/plan-transitions.js +7 -2
  4. package/dist/cli/program.js +1 -1
  5. package/dist/commands/client-recovery.js +439 -20
  6. package/dist/commands/init.js +42 -6
  7. package/dist/executors/dag-pi-executor.js +165 -56
  8. package/dist/executors/pi-playwright-cli-tool.js +955 -0
  9. package/dist/executors/pi-sdk-executor.js +56 -0
  10. package/dist/executors/playwright-cli-launcher.js +63 -0
  11. package/dist/executors/shell-executor.js +128 -0
  12. package/dist/shared/playwright-cli-command-policy.js +41 -0
  13. package/dist/worker/observability/read-model.js +66 -8
  14. package/dist/worker/observe/static/dag-model.js +85 -13
  15. package/dist/workflows/dag/dynamic-runtime/loop-until.js +4 -0
  16. package/dist/workflows/dag/dynamic-runtime/map.js +13 -13
  17. package/dist/workflows/dag/frontend-implementation-contract.js +6 -124
  18. package/dist/workflows/dag/frontend-prewrite-gate.js +5 -35
  19. package/dist/workflows/dag/frontend-test-case-checklist.js +201 -8
  20. package/dist/workflows/dag/frontend-test-result-contract.js +52 -3
  21. package/dist/workflows/dag/init-hybrid.js +154 -95
  22. package/dist/workflows/dag/lifecycle.js +33 -2
  23. package/dist/workflows/dag/node-execution.js +11 -5
  24. package/dist/workflows/dag/output-protocol.js +25 -106
  25. package/dist/workflows/dag/report.js +9 -2
  26. package/dist/workflows/dag/rerun-run.js +62 -3
  27. package/dist/workflows/dag/run-store.js +6 -1
  28. package/dist/workflows/dag/runner.js +15 -3
  29. package/dist/workflows/dag/types.js +27 -0
  30. package/dist/workflows/dag/validate.js +121 -1
  31. package/docs/architecture/runtime-boundaries.md +13 -11
  32. package/docs/init-surface.manifest.json +6 -2
  33. package/docs/templates/README.md +9 -1
  34. package/docs/templates/frontend-implementation-contract.schema.json +2 -2
  35. package/docs/templates/frontend-test-dag.generate-cases.prompt.md +14 -7
  36. package/docs/templates/frontend-test-dag.json +55 -15
  37. package/docs/templates/frontend-test-dag.retrieve-context.prompt.md +7 -9
  38. package/docs/templates/frontend-test-dag.retrospect.prompt.md +1 -1
  39. package/docs/templates/frontend-test-dag.review-cases.prompt.md +1 -1
  40. package/docs/templates/frontend-test-dag.review-execution.prompt.md +1 -1
  41. package/harness.json +4 -4
  42. package/package.json +1 -1
  43. package/skills/loop-agent/SKILL.md +1 -1
  44. package/skills/loop-agent/references/command-reference.md +18 -6
  45. package/skills/playwright-cli/SKILL.md +69 -402
  46. package/skills/playwright-cli/references/tracing.md +3 -137
  47. package/skills/playwright-cli/references/video-recording.md +3 -141
  48. package/skills/playwright-cli-case-generator/SKILL.md +53 -46
@@ -1,143 +1,5 @@
1
- # Video Recording
1
+ # Video 输出边界
2
2
 
3
- Capture browser automation sessions as video for debugging, documentation, or verification. Produces WebM (VP8/VP9 codec).
3
+ 受治理的 `frontend-test` DAG 不提供 video 输出能力。
4
4
 
5
- ## Basic Recording
6
-
7
- ```bash
8
- # Open browser first
9
- playwright-cli open
10
-
11
- # Start recording
12
- playwright-cli video-start demo.webm
13
-
14
- # Add a chapter marker for section transitions
15
- playwright-cli video-chapter "Getting Started" --description="Opening the homepage" --duration=2000
16
-
17
- # Navigate and perform actions
18
- playwright-cli goto https://example.com
19
- playwright-cli snapshot
20
- playwright-cli click e1
21
-
22
- # Add another chapter
23
- playwright-cli video-chapter "Filling Form" --description="Entering test data" --duration=2000
24
- playwright-cli fill e2 "test input"
25
-
26
- # Stop and save
27
- playwright-cli video-stop
28
- ```
29
-
30
- ## Best Practices
31
-
32
- ### 1. Use Descriptive Filenames
33
-
34
- ```bash
35
- # Include context in filename
36
- playwright-cli video-start recordings/login-flow-2024-01-15.webm
37
- playwright-cli video-start recordings/checkout-test-run-42.webm
38
- ```
39
-
40
- ### 2. Record entire hero scripts.
41
-
42
- When recording a video for the user or as a proof of work, it is best to create a code snippet and execute it with run-code.
43
- It allows inserting appropriate pauses between the actions and annotating the video. There are new Playwright APIs for that.
44
-
45
- 1) Perform scenario using CLI and take note of all locators and actions. You'll need those locators to request their bounding boxes for highlight.
46
- 2) Create a file with the intended script for video (below). Use pressSequentially w/ delay for nice typing, make reasonable pauses.
47
- 3) Use playwright-cli run-code --filename your-script.js
48
-
49
- **Important**: Overlays are `pointer-events: none` — they do not interfere with page interactions. You can safely keep sticky overlays visible while clicking, filling, or performing any actions on the page.
50
-
51
- ```js
52
- async page => {
53
- await page.screencast.start({ path: 'video.webm', size: { width: 1280, height: 800 } });
54
- await page.goto('https://demo.playwright.dev/todomvc');
55
-
56
- // Show a chapter card — blurs the page and shows a dialog.
57
- // Blocks until duration expires, then auto-removes.
58
- // Use this for simple use cases, but always feel free to hand-craft your own beautiful
59
- // overlay via await page.screencast.showOverlay().
60
- await page.screencast.showChapter('Adding Todo Items', {
61
- description: 'We will add several items to the todo list.',
62
- duration: 2000,
63
- });
64
-
65
- // Perform action
66
- await page.getByRole('textbox', { name: 'What needs to be done?' }).pressSequentially('Walk the dog', { delay: 60 });
67
- await page.getByRole('textbox', { name: 'What needs to be done?' }).press('Enter');
68
- await page.waitForTimeout(1000);
69
-
70
- // Show next chapter
71
- await page.screencast.showChapter('Verifying Results', {
72
- description: 'Checking the item appeared in the list.',
73
- duration: 2000,
74
- });
75
-
76
- // Add a sticky annotation that stays while you perform actions.
77
- // Overlays are pointer-events: none, so they won't block clicks.
78
- const annotation = await page.screencast.showOverlay(`
79
- <div style="position: absolute; top: 8px; right: 8px;
80
- padding: 6px 12px; background: rgba(0,0,0,0.7);
81
- border-radius: 8px; font-size: 13px; color: white;">
82
- ✓ Item added successfully
83
- </div>
84
- `);
85
-
86
- // Perform more actions while the annotation is visible
87
- await page.getByRole('textbox', { name: 'What needs to be done?' }).pressSequentially('Buy groceries', { delay: 60 });
88
- await page.getByRole('textbox', { name: 'What needs to be done?' }).press('Enter');
89
- await page.waitForTimeout(1500);
90
-
91
- // Remove the annotation when done
92
- await annotation.dispose();
93
-
94
- // You can also highlight relevant locators and provide contextual annotations.
95
- const bounds = await page.getByText('Walk the dog').boundingBox();
96
- await page.screencast.showOverlay(`
97
- <div style="position: absolute;
98
- top: ${bounds.y}px;
99
- left: ${bounds.x}px;
100
- width: ${bounds.width}px;
101
- height: ${bounds.height}px;
102
- border: 1px solid red;">
103
- </div>
104
- <div style="position: absolute;
105
- top: ${bounds.y + bounds.height + 5}px;
106
- left: ${bounds.x + bounds.width / 2}px;
107
- transform: translateX(-50%);
108
- padding: 6px;
109
- background: #808080;
110
- border-radius: 10px;
111
- font-size: 14px;
112
- color: white;">Check it out, it is right above this text
113
- </div>
114
- `, { duration: 2000 });
115
-
116
- await page.screencast.stop();
117
- }
118
- ```
119
-
120
- Embrace creativity, overlays are powerful.
121
-
122
- ### Overlay API Summary
123
-
124
- | Method | Use Case |
125
- |--------|----------|
126
- | `page.screencast.showChapter(title, { description?, duration?, styleSheet? })` | Full-screen chapter card with blurred backdrop — ideal for section transitions |
127
- | `page.screencast.showOverlay(html, { duration? })` | Custom HTML overlay — use for callouts, labels, highlights |
128
- | `disposable.dispose()` | Remove a sticky overlay added without duration |
129
- | `page.screencast.hideOverlays()` / `page.screencast.showOverlays()` | Temporarily hide/show all overlays |
130
-
131
- ## Tracing vs Video
132
-
133
- | Feature | Video | Tracing |
134
- |---------|-------|---------|
135
- | Output | WebM file | Trace file (viewable in Trace Viewer) |
136
- | Shows | Visual recording | DOM snapshots, network, console, actions |
137
- | Use case | Demos, documentation | Debugging, analysis |
138
- | Size | Larger | Smaller |
139
-
140
- ## Limitations
141
-
142
- - Recording adds slight overhead to automation
143
- - Large recordings can consume significant disk space
5
+ DAG 的证据边界仅保留有界的 screenshot、pdf 和 snapshot evidence。需要记录的验证结论应以这些有界证据为准。
@@ -1,63 +1,72 @@
1
1
  ---
2
2
  name: playwright-cli-case-generator
3
- description: 根据 FE-test RAG 知识包生成可由 playwright-cli 串行执行的前端功能测试用例、索引和 case manifest。
3
+ description: 根据 FE-test RAG 知识包生成可由受限 playwright_cli runtime 串行执行的前端功能测试用例、索引和 case manifest。
4
4
  ---
5
5
 
6
6
  # Playwright Test Generator
7
7
 
8
- 仅用于 FE-test DAG 的 `generate-frontend-functional-cases-pi`。本 skill
9
- 生成中文 Markdown 测试用例和 `manifest.json`,不执行浏览器、不生成
10
- Playwright/Pytest 源码,也不修改被测应用。
8
+ 仅用于 FE-test DAG 的 `generate-frontend-functional-cases-pi`。本 skill 生成中文 Markdown
9
+ 测试用例和 `manifest.json`,不执行浏览器、不生成测试源码,也不修改被测应用。
10
+
11
+ 生成的 case 步骤写成 `playwright-cli <command> ...` 行;执行阶段由 frontend-test browser child
12
+ 通过结构化 `playwright_cli` tool 消费。生成节点本身不获得 command capability。
11
13
 
12
14
  ## 输入与边界
13
15
 
14
- - 只读取 `testcase/frontend/rag/context.md`、`coverage-map.md` 与已有
15
- `testcase/frontend/cases/`。
16
+ - 只读取 `testcase/frontend/rag/context.md`、`coverage-map.md` 与已有 `testcase/frontend/cases/`。
16
17
  - 只写 `testcase/frontend/cases/**`;不得回读 PRD、读取 `.harness/`,或写
17
18
  `testcase/frontend/evidence/**`。
18
- - 所有 API、字段限制、状态流转、数据来源、SLA、URL 与账号要求必须能在
19
- RAG 知识包中追溯。缺失信息标记 `blocked` 或“需人工确认”,不得猜测。
19
+ - 所有 API、字段限制、状态流转、数据来源、SLA、URL 与账号要求必须能在 RAG 知识包中追溯。
20
+ 缺失信息标记 `blocked` 或“需人工确认”,不得猜测。
20
21
 
21
22
  ## 输出
22
23
 
23
- - 写 `index.md`、`manifest.draft.json`(生成阶段;materialize 会写成
24
- `manifest.json`)与独立 case 文件
25
- `FE-<FEATURE>-<NNN>-<dimension>.md`;`dimension` 仅为 `core`、`boundary`、
26
- `flow` 或 `backend`。
24
+ - 写 `index.md`、`manifest.draft.json`(生成阶段;materialize 会写成 `manifest.json`)与独立 case 文件
25
+ `FE-<FEATURE>-<NNN>-<dimension>.md`;`dimension` 仅为 `core`、`boundary`、`flow` 或 `backend`。
27
26
  - **ID 契约(高频失败点,禁止混用)**:
28
27
  - `caseId` / 文件名 = **用例 ID**,形态 `FE-<FEATURE>-<NNN>-<dimension>`
29
- (例:`FE-LOGIN-001-core`)。**禁止**把验收标准写成 caseId
30
- (错误:`AC-FE-001.md` / `caseId: "AC-FE-001"`)。
28
+ (例:`FE-LOGIN-001-core`)。禁止把验收标准写成 caseId
31
29
  - `acIds` = **验收标准 ID 列表**,形态 `AC-FE-*` / `AC-*`
32
- (例:`["AC-FE-001"]`)。**禁止**把用例 ID 放进 acIds
33
- (错误:`acIds: ["FE-LOGIN-001-core"]`)。
30
+ (例:`["AC-FE-001"]`)。禁止把用例 ID 放进 acIds
34
31
  - `casePath` 必须等于 `testcase/frontend/cases/<caseId>.md`;
35
32
  `evidenceDir` 必须等于 `testcase/frontend/evidence/<caseId>/`。
36
- - `manifest` 使用 `schemaVersion: 1`,每项只含 `caseId`、`casePath`、
37
- `dimension`、`acIds`、`evidenceDir`。所有 ID、路径和 evidenceDir 必须唯一,
38
- 并位于 `testcase/frontend/` 内。
33
+ - `manifest` 使用 `schemaVersion: 1`,每项只含 `caseId`、`casePath`、`dimension`、`acIds`、
34
+ `evidenceDir`。所有 ID、路径和 evidenceDir 必须唯一,并位于 `testcase/frontend/` 内。
39
35
  - `index.md` 按功能点列出 case、维度、AC、数据依赖、API 映射和预期执行状态。
40
36
 
41
37
  每个 case 必须包含:
42
38
 
43
39
  1. 元信息:功能、CRUD 分类、维度、关联 AC、RAG 来源、API 映射状态与数据策略。
44
- 2. 前置条件:默认浏览器 session 中的登录状态、fixture/存量数据、清理责任;不得用 `-s=<case-id>` 建立 named session。
45
- 3. 可独立执行的命令序列:使用 RAG `context.md` 中已解析的绝对 `baseUrl`(优先来自任务源 `config.md`;缺失时默认 `http://localhost:5173`),必须以
46
- `playwright-cli open --browser=chrome --headed <resolved-base-url>` 开始,禁止保留 `<base-url>` 占位符,也不得使用 `-s=<case-id>` 或其他 named session;再按需登录/数据准备、
47
- `snapshot` 后优先使用元素引用、操作、UI 断言、可选 API 断言、cleanup、`close`。
48
- 4. 明确的 UI/API 预期与数据清理结果;无法满足的环境或数据依赖必须写为 `blocked`。
49
-
50
- 所有 snapshot、screenshot、trace video 命令必须指向执行节点提供的
51
- `testcase/frontend/evidence/<case-id>/` 工作目录。命令必须使用现有
52
- `playwright-cli` skill 已声明的接口;不要生成 `requests --clear`、
53
- `request-body` `response-body`。
40
+ 2. 前置条件:默认浏览器 session 中的登录状态、fixture/存量数据、清理责任;不得用
41
+ `-s=<case-id>` 建立 named session。
42
+ 3. 可独立执行的命令序列:使用 RAG `context.md` 中已解析的绝对 `baseUrl`(优先来自任务源
43
+ `config.md`;缺失时默认 `http://localhost:5173`),必须以
44
+ `playwright-cli open --browser=chrome --headed` 后接解析出的具体 base URL 开始;不得保留
45
+ base-url 占位符,也不得使用 `-s=<case-id>` 或其他 named session;再按需登录、数据准备、
46
+ `snapshot` 后优先使用元素引用和操作。每个拟通过场景必须在 `open` 后以成功的 `find` 作为
47
+ 唯一结构化 UI 语义断言,再由 controller 执行 post-execution cleanup。`snapshot`、`goto`、
48
+ `screenshot`、`requests`、`request` 和普通交互不能单独取得 passed authority。
49
+ 4. **动态元素 ref(硬约束)**:可执行的 `playwright-cli` 行绝不得包含尖括号 token,例如
50
+ `<fresh-ref>` 或描述性的 `<...>` 占位符。只能使用 shell-safe 文档占位符 `eX`、`eY` 等;每个
51
+ 占位符仅表示从紧邻其前、最新一次 `snapshot` 输出解析出的真实 `eNN` ref。生成的 case 必须在每次
52
+ 引用元素前写明 fresh snapshot;`eX`/`eY` 不是可传给 structured tool 的 literal ref,新的 snapshot
53
+ 会使旧 ref 失效,不得复用 stale ref。
54
+ 5. 明确的 UI/API 预期与数据清理结果;无法满足的环境或数据依赖必须写为 `blocked`。
55
+
56
+ 所有文件型输出均由 controller 绑定到执行节点提供的
57
+ `testcase/frontend/evidence/<case-id>/` 工作目录。截图一律使用 canonical 语法
58
+ `playwright-cli screenshot --filename final.png`;如确有从最新 snapshot 解析出的真实元素 ref,写为
59
+ `playwright-cli screenshot e5 --filename final.png`。`pdf` 必须写为
60
+ `playwright-cli pdf --filename final.pdf`。`snapshot` 无 filename 时仅返回响应;需要文件时使用
61
+ `playwright-cli snapshot --filename snapshot.txt`。不得生成 `playwright-cli screenshot <path>`,不得使用
62
+ `--path`、`--output` 或 `--file`,文件路径绝不能作为 screenshot 位置参数。命令只能使用
63
+ `playwright-cli` skill 已声明的 runtime allowlist;不要生成未声明的命令变体。
54
64
 
55
65
  ### playwright-cli-only(硬约束)
56
66
 
57
67
  - 用例步骤只能使用 `playwright-cli` skill 已声明的命令语法。
58
- - **禁止**裸 `playwright`、`npx playwright`、`playwright test`、`@playwright/test`、
59
- Node Playwright API 或生成 Playwright/Pytest 源码。
60
- - `playwright-cli` 不可用时不得降级到原生 Playwright;应写 blocked evidence,
68
+ - 不生成其他浏览器自动化调用、测试运行器调用或测试源码。
69
+ - `playwright-cli` 不可用时不得降级;应写 blocked evidence,
61
70
  `blockedReason: playwright-cli-unavailable`。
62
71
 
63
72
  ## 覆盖矩阵
@@ -69,35 +78,33 @@ Playwright/Pytest 源码,也不修改被测应用。
69
78
  | U-修改 | `core`、`boundary` | 有状态流转时 `flow`;有 API 映射时 `backend` |
70
79
  | D-删除 | `core` | 有 API 映射时 `backend` |
71
80
 
72
- - `boundary` 只从已知必填、长度、范围、精度、枚举或字符规则推导;无约束时
73
- 不伪造边界值。
81
+ - `boundary` 只从已知必填、长度、范围、精度、枚举或字符规则推导;无约束时不伪造边界值。
74
82
  - `flow` 是自包含的多步状态旅程;每个关键步骤都有 UI 与已知数据一致性断言,
75
83
  不依赖其他 case 创建的数据。
76
- - `backend` 只在 API 映射存在时使用 `requests` / `request <id>`,或在精确时序
77
- 下使用 `run-code`。错误、空态或超时使用 `route`,并在 cleanup 中 `unroute`。
78
- 响应字段和性能阈值必须来自 RAG
84
+ - `backend` 只在 API 映射存在时使用 `requests` / `request <id>` 记录已观察到的后端证据;
85
+ 响应字段和性能阈值必须来自 RAG。时序、异常、响应内容、数据准备或环境条件无法由 runtime
86
+ allowlist RAG 证明时,必须生成 `blocked` case/evidence,并说明原因。
79
87
 
80
88
  ## 数据策略
81
89
 
82
- - C-新增优先使用需求中给出的测试数据;仅在已授权 API 映射存在时才描述临时构造
83
- 与清理。
90
+ - C-新增优先使用需求中给出的测试数据;仅在已授权 API 映射存在时才描述临时构造与清理。
84
91
  - R 查询优先使用知识包登记的 fixture 或当前用户可见数据。
85
92
  - **U/D 修改删除归属顺序(硬约束)**:
86
93
  1. 仅操作可由**当前登录用户身份**与 UI/API 可观测归属字段共同证明的数据;
87
94
  禁止只凭名称、猜测 ID 或列表顺序认定归属。
88
- 2. 当前用户无可用数据时,优先在当前用户上下文创建带 run/case 可追踪标记、
89
- 可清理的数据,再执行 U/D,并在 cleanup 中验证清理。
95
+ 2. 当前用户无可用数据时,优先在当前用户上下文创建带 run/case 可追踪标记、可清理的数据,
96
+ 再执行 U/D,并在 cleanup 中验证清理。
90
97
  3. 无法安全创建时,仅可使用任务源/RAG 已确认且受路径/环境约束的 Mock,
91
98
  并明确标注为 Mock(不得声称真实后端验证)。
92
99
  4. 既无法证明归属、也无法安全创建或 Mock 时,写 `blocked` evidence,
93
100
  `blockedReason` 使用:`current-user-data-unavailable` |
94
101
  `data-ownership-unverifiable` | `safe-test-data-setup-unavailable`,不执行 U/D。
95
102
  5. 禁止修改/删除其他用户数据、共享 fixture、生产数据或无法确认可清理的数据。
96
- - 禁止使用生产 URL、真实用户凭据或不可清理的数据写入。无法证明隔离与清理时,
97
- case 必须为 `blocked`。
103
+ - 禁止使用生产 URL、真实用户凭据或不可清理的数据写入。无法证明隔离与清理时,case 必须为
104
+ `blocked`。
98
105
 
99
106
  ## 交接
100
107
 
101
- 生成结束时仅返回紧凑 JSON 摘要:case 总数、各维度数量、manifest 相对路径、
102
- blocked case ID 与原因。详细内容保留在 case 文件,供后续 manifest/map 子节点
103
- 逐 case 读取,避免把完整用例塞进上游上下文。
108
+ 生成结束时仅返回紧凑 JSON 摘要:case 总数、各维度数量、manifest 相对路径、blocked case ID
109
+ 与原因。详细内容保留在 case 文件,供后续 manifest/map 子节点逐 case 读取,避免把完整用例塞进
110
+ 上游上下文。