@muggleai/works 4.9.2 → 4.10.1

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 (190) hide show
  1. package/README.md +3 -3
  2. package/dist/{chunk-6N7OIBAS.js → chunk-Q7WNEMN4.js} +109 -43
  3. package/dist/{chunk-4KQZLF56.js → chunk-ZKRHFTIC.js} +996 -91
  4. package/dist/cli.js +2 -2
  5. package/dist/index.js +2 -2
  6. package/dist/plugin/.claude-plugin/plugin.json +1 -1
  7. package/dist/plugin/.cursor-plugin/plugin.json +1 -1
  8. package/dist/plugin/README.md +4 -2
  9. package/dist/plugin/agents/acceptance-tester.md +24 -10
  10. package/dist/plugin/commands/m.md +7 -0
  11. package/dist/plugin/commands/mdo.md +7 -0
  12. package/dist/plugin/commands/mfeedback.md +7 -0
  13. package/dist/plugin/commands/mimport.md +7 -0
  14. package/dist/plugin/commands/mpr.md +7 -0
  15. package/dist/plugin/commands/mprefs.md +7 -0
  16. package/dist/plugin/commands/mregen.md +7 -0
  17. package/dist/plugin/commands/mrelease.md +7 -0
  18. package/dist/plugin/commands/mrepair.md +7 -0
  19. package/dist/plugin/commands/mstatus.md +7 -0
  20. package/dist/plugin/commands/mtest.md +7 -0
  21. package/dist/plugin/commands/mtestlocal.md +7 -0
  22. package/dist/plugin/commands/mtestprep.md +7 -0
  23. package/dist/plugin/commands/mupgrade.md +7 -0
  24. package/dist/plugin/scripts/ensure-electron-app.sh +56 -6
  25. package/dist/plugin/skills/_aliases.json +18 -0
  26. package/dist/plugin/skills/_shared/dev-server-readiness.md +231 -0
  27. package/dist/plugin/skills/_shared/failure-mode-handling.md +244 -0
  28. package/dist/plugin/skills/_shared/post-merge-cleanup.md +10 -0
  29. package/dist/plugin/skills/_shared/rebase-before-e2e.md +15 -0
  30. package/dist/plugin/skills/_shared/telemetry-emit.md +15 -0
  31. package/dist/plugin/skills/_shared/use-worktrees.md +53 -0
  32. package/dist/plugin/skills/do/e2e-acceptance.md +63 -18
  33. package/dist/plugin/skills/do/impact-analysis.md +45 -5
  34. package/dist/plugin/skills/do/open-prs.md +13 -4
  35. package/dist/plugin/skills/do/pr-followup.md +225 -0
  36. package/dist/plugin/skills/do/pre-flight.md +18 -11
  37. package/dist/plugin/skills/m/SKILL.md +8 -0
  38. package/dist/plugin/skills/mdo/SKILL.md +8 -0
  39. package/dist/plugin/skills/mfeedback/SKILL.md +8 -0
  40. package/dist/plugin/skills/mimport/SKILL.md +8 -0
  41. package/dist/plugin/skills/mpr/SKILL.md +8 -0
  42. package/dist/plugin/skills/mprefs/SKILL.md +8 -0
  43. package/dist/plugin/skills/mregen/SKILL.md +8 -0
  44. package/dist/plugin/skills/mrelease/SKILL.md +8 -0
  45. package/dist/plugin/skills/mrepair/SKILL.md +8 -0
  46. package/dist/plugin/skills/mstatus/SKILL.md +8 -0
  47. package/dist/plugin/skills/mtest/SKILL.md +8 -0
  48. package/dist/plugin/skills/mtestlocal/SKILL.md +8 -0
  49. package/dist/plugin/skills/mtestprep/SKILL.md +8 -0
  50. package/dist/plugin/skills/muggle/SKILL.md +11 -17
  51. package/dist/plugin/skills/muggle-do/SKILL.md +22 -4
  52. package/dist/plugin/skills/muggle-do-pr-followup/SKILL.md +37 -0
  53. package/dist/plugin/skills/muggle-do-task/SKILL.md +134 -0
  54. package/dist/plugin/skills/muggle-feedback/SKILL.md +38 -0
  55. package/dist/plugin/skills/muggle-feedback/ops/delete.md +49 -0
  56. package/dist/plugin/skills/muggle-feedback/ops/list.md +65 -0
  57. package/dist/plugin/skills/muggle-feedback/ops/submit.md +117 -0
  58. package/dist/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +73 -55
  59. package/dist/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
  60. package/dist/plugin/skills/muggle-preferences/SKILL.md +17 -68
  61. package/dist/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
  62. package/dist/plugin/skills/muggle-preferences/ops/configure.md +49 -0
  63. package/dist/plugin/skills/muggle-preferences/ops/list.md +9 -0
  64. package/dist/plugin/skills/muggle-preferences/ops/reset.md +6 -0
  65. package/dist/plugin/skills/muggle-preferences/ops/set.md +10 -0
  66. package/dist/plugin/skills/muggle-preferences/preference-gates/README.md +58 -0
  67. package/dist/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
  68. package/dist/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
  69. package/dist/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +11 -0
  70. package/dist/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
  71. package/dist/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +11 -0
  72. package/dist/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +11 -0
  73. package/dist/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
  74. package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
  75. package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +16 -0
  76. package/dist/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
  77. package/dist/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +11 -0
  78. package/dist/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +15 -0
  79. package/dist/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +11 -0
  80. package/dist/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +13 -0
  81. package/dist/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +11 -0
  82. package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +11 -0
  83. package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +11 -0
  84. package/dist/plugin/skills/muggle-preferences/preference-gates/verboseOutput.md +8 -0
  85. package/dist/plugin/skills/muggle-repair/SKILL.md +4 -2
  86. package/dist/plugin/skills/muggle-status/SKILL.md +14 -16
  87. package/dist/plugin/skills/muggle-test/SKILL.md +148 -123
  88. package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +92 -86
  89. package/dist/plugin/skills/muggle-test-import/SKILL.md +74 -35
  90. package/dist/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
  91. package/dist/plugin/skills/muggle-test-regenerate-missing/SKILL.md +49 -35
  92. package/dist/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
  93. package/dist/plugin/skills/muggle-upgrade/SKILL.md +4 -2
  94. package/dist/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
  95. package/dist/plugin/skills/mupgrade/SKILL.md +8 -0
  96. package/dist/release-manifest.json +4 -4
  97. package/dist/src-2G7ENRGI.js +1 -0
  98. package/package.json +10 -8
  99. package/plugin/.claude-plugin/plugin.json +1 -1
  100. package/plugin/.cursor-plugin/plugin.json +1 -1
  101. package/plugin/README.md +4 -2
  102. package/plugin/agents/acceptance-tester.md +24 -10
  103. package/plugin/commands/m.md +7 -0
  104. package/plugin/commands/mdo.md +7 -0
  105. package/plugin/commands/mfeedback.md +7 -0
  106. package/plugin/commands/mimport.md +7 -0
  107. package/plugin/commands/mpr.md +7 -0
  108. package/plugin/commands/mprefs.md +7 -0
  109. package/plugin/commands/mregen.md +7 -0
  110. package/plugin/commands/mrelease.md +7 -0
  111. package/plugin/commands/mrepair.md +7 -0
  112. package/plugin/commands/mstatus.md +7 -0
  113. package/plugin/commands/mtest.md +7 -0
  114. package/plugin/commands/mtestlocal.md +7 -0
  115. package/plugin/commands/mtestprep.md +7 -0
  116. package/plugin/commands/mupgrade.md +7 -0
  117. package/plugin/scripts/ensure-electron-app.sh +56 -6
  118. package/plugin/skills/_aliases.json +18 -0
  119. package/plugin/skills/_shared/dev-server-readiness.md +231 -0
  120. package/plugin/skills/_shared/failure-mode-handling.md +244 -0
  121. package/plugin/skills/_shared/post-merge-cleanup.md +10 -0
  122. package/plugin/skills/_shared/rebase-before-e2e.md +15 -0
  123. package/plugin/skills/_shared/telemetry-emit.md +15 -0
  124. package/plugin/skills/_shared/use-worktrees.md +53 -0
  125. package/plugin/skills/do/e2e-acceptance.md +63 -18
  126. package/plugin/skills/do/impact-analysis.md +45 -5
  127. package/plugin/skills/do/open-prs.md +13 -4
  128. package/plugin/skills/do/pr-followup.md +225 -0
  129. package/plugin/skills/do/pre-flight.md +18 -11
  130. package/plugin/skills/m/SKILL.md +8 -0
  131. package/plugin/skills/mdo/SKILL.md +8 -0
  132. package/plugin/skills/mfeedback/SKILL.md +8 -0
  133. package/plugin/skills/mimport/SKILL.md +8 -0
  134. package/plugin/skills/mpr/SKILL.md +8 -0
  135. package/plugin/skills/mprefs/SKILL.md +8 -0
  136. package/plugin/skills/mregen/SKILL.md +8 -0
  137. package/plugin/skills/mrelease/SKILL.md +8 -0
  138. package/plugin/skills/mrepair/SKILL.md +8 -0
  139. package/plugin/skills/mstatus/SKILL.md +8 -0
  140. package/plugin/skills/mtest/SKILL.md +8 -0
  141. package/plugin/skills/mtestlocal/SKILL.md +8 -0
  142. package/plugin/skills/mtestprep/SKILL.md +8 -0
  143. package/plugin/skills/muggle/SKILL.md +11 -17
  144. package/plugin/skills/muggle-do/SKILL.md +22 -4
  145. package/plugin/skills/muggle-do-pr-followup/SKILL.md +37 -0
  146. package/plugin/skills/muggle-do-task/SKILL.md +134 -0
  147. package/plugin/skills/muggle-feedback/SKILL.md +38 -0
  148. package/plugin/skills/muggle-feedback/ops/delete.md +49 -0
  149. package/plugin/skills/muggle-feedback/ops/list.md +65 -0
  150. package/plugin/skills/muggle-feedback/ops/submit.md +117 -0
  151. package/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +73 -55
  152. package/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
  153. package/plugin/skills/muggle-preferences/SKILL.md +17 -68
  154. package/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
  155. package/plugin/skills/muggle-preferences/ops/configure.md +49 -0
  156. package/plugin/skills/muggle-preferences/ops/list.md +9 -0
  157. package/plugin/skills/muggle-preferences/ops/reset.md +6 -0
  158. package/plugin/skills/muggle-preferences/ops/set.md +10 -0
  159. package/plugin/skills/muggle-preferences/preference-gates/README.md +58 -0
  160. package/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
  161. package/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
  162. package/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +11 -0
  163. package/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
  164. package/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +11 -0
  165. package/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +11 -0
  166. package/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
  167. package/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
  168. package/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +16 -0
  169. package/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
  170. package/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +11 -0
  171. package/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +15 -0
  172. package/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +11 -0
  173. package/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +13 -0
  174. package/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +11 -0
  175. package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +11 -0
  176. package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +11 -0
  177. package/plugin/skills/muggle-preferences/preference-gates/verboseOutput.md +8 -0
  178. package/plugin/skills/muggle-repair/SKILL.md +4 -2
  179. package/plugin/skills/muggle-status/SKILL.md +14 -16
  180. package/plugin/skills/muggle-test/SKILL.md +148 -123
  181. package/plugin/skills/muggle-test-feature-local/SKILL.md +92 -86
  182. package/plugin/skills/muggle-test-import/SKILL.md +74 -35
  183. package/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
  184. package/plugin/skills/muggle-test-regenerate-missing/SKILL.md +49 -35
  185. package/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
  186. package/plugin/skills/muggle-upgrade/SKILL.md +4 -2
  187. package/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
  188. package/plugin/skills/mupgrade/SKILL.md +8 -0
  189. package/scripts/postinstall.mjs +11 -1
  190. package/dist/src-7GB7WIFT.js +0 -1
@@ -0,0 +1,134 @@
1
+ ---
2
+ name: muggle-do-task
3
+ description: Run a browser automation task on a website using natural language. Finds or creates the Muggle Test project, use case, test case, and script, then executes locally via the electron app. Use when the user wants to perform an action on a website (post, fill a form, click through a flow) rather than implement a code change.
4
+ ---
5
+
6
+ # Muggle Test Task Runner
7
+
8
+ > Telemetry first step: see [`_shared/telemetry-emit.md`](../_shared/telemetry-emit.md). Use `skillName: "muggle-do-task"`.
9
+
10
+ Runs a browser automation task described in plain English. Finds or creates the necessary Muggle Test entities automatically, then executes locally with mutation-driven step prediction.
11
+
12
+ ## Step 1 — Parse the prompt
13
+
14
+ From `$ARGUMENTS`, extract:
15
+
16
+ - **`domain`** — the target website domain (e.g., `x.com`, `amazon.com`, `localhost:3000`). Normalize: strip `www.`, strip `https://`, lowercase. Result: bare domain with no scheme, no trailing slash.
17
+ - **`useCaseName`** — the core action being performed, stripped of variable content (e.g., `"Publish a post"`, `"Add to cart"`, `"Submit a form"`).
18
+ - **`mutations`** — variable parameters as a `string[]` (JSON array of strings). Each string is either:
19
+ - A plain-English instruction describing what varies this run (e.g., `"The post content should be 'Hello world'"`)
20
+ - A local file path for uploads (e.g., `"Attach the image at C:\\Users\\stan4\\Pictures\\photo.jpg"`)
21
+
22
+ Examples: `["The post content should be 'Hello world'"]`, `["Attach the image at C:\\Users\\stan4\\photo.jpg", "Caption should be 'My photo'"]`
23
+ - **`localUrl`** — the full URL to test against (e.g., `https://x.com`, `http://localhost:3000`). For external sites, use `https://<domain>`. For local dev servers, use the port the user's app is running on.
24
+
25
+ If the prompt is ambiguous and you cannot confidently extract these, ask one clarifying question before proceeding.
26
+
27
+ ## Step 2 — Find or create Project
28
+
29
+ Load and call `muggle-remote-project-list`. Find a project whose URL contains `domain` (case-insensitive substring match).
30
+
31
+ **If found:** use it. Tell the user: `Found project: <name>`.
32
+
33
+ **If not found:** call `muggle-remote-project-create` with:
34
+ - `projectName`: `<domain>`
35
+ - `description`: `E2E acceptance testing project for <domain>`
36
+ - `url`: `https://<domain>`
37
+
38
+ Tell the user: `Created project: <name>`.
39
+
40
+ ## Step 3 — Find or create Use Case
41
+
42
+ Load and call `muggle-remote-use-case-list` filtered by `projectId`. Fuzzy-match against `useCaseName`:
43
+ - Case-insensitive
44
+ - Strip punctuation
45
+ - Match if either string is a substring of the other
46
+
47
+ If multiple candidates, pick the closest and tell the user which was selected.
48
+
49
+ **If not found:** call `muggle-remote-use-case-create-from-prompts` with:
50
+ - `projectId`: from Step 2
51
+ - `instructions`: `["<original prompt>"]`
52
+
53
+ Use the first result. Capture its `id` as `useCaseId`. If the result is empty or the call fails, stop and tell the user: "Could not create use case — try rephrasing the task description."
54
+
55
+ Tell the user: `Created use case: <title>`.
56
+
57
+ ## Step 4 — Find or create Test Case
58
+
59
+ Load and call `muggle-remote-test-case-list-by-use-case` with `useCaseId`. Filter for test cases where `status` equals `ACTIVE`.
60
+
61
+ **If not found:** call `muggle-remote-test-case-create` with:
62
+ - `projectId`: from Step 2
63
+ - `useCaseId`: from Step 3
64
+ - `title`: `<useCaseName>`
65
+ - `description`: `Test case for: <original prompt>`
66
+ - `goal`: `Successfully complete: <useCaseName>`
67
+ - `expectedResult`: `The action completes without error`
68
+ - `url`: `https://<domain>`
69
+
70
+ Tell the user: `Created test case: <id>`.
71
+
72
+ ## Step 5 — Find active Test Script
73
+
74
+ Load and call `muggle-remote-test-script-list` with:
75
+ - `projectId`: from Step 2
76
+ - `testCaseId`: from Step 4
77
+
78
+ Tell the user which mutations will be applied: `Mutations: <mutations[]>` (or "no mutations" if empty).
79
+
80
+ Filter for scripts where `status` equals `ACTIVE` or `PUBLISHED`. If all returned scripts have another status (`DRAFT`, `GENERATION_PENDING`, `FAILED`), treat as "no active script" and proceed to Phase 1.
81
+
82
+ ---
83
+
84
+ ### Phase 1 — No active script: generate locally
85
+
86
+ 1. Load and call `muggle-remote-test-case-get` with the test case ID from Step 4. This returns the full test case object needed by the local execution tool.
87
+
88
+ 2. Load and call `muggle-local-execute-test-generation` with:
89
+ - `testCase`: the full object from step 1 above
90
+ - `localUrl`: from Step 1
91
+ - `mutations`: the `mutations[]` array from Step 1 (omit if empty)
92
+
93
+ 3. Tell the user:
94
+ > Script generation is running in the Muggle Test window. Once complete, run `/muggle-do "<original prompt>"` again to execute the task.
95
+
96
+ Do not proceed further.
97
+
98
+ ---
99
+
100
+ ### Phase 2 — Active script found: replay with mutations
101
+
102
+ ## Step 6 — Fetch Action Script
103
+
104
+ 1. Load and call `muggle-remote-test-script-get` with the script ID from Step 5. Extract `actionScriptId`. If `actionScriptId` is missing or null, stop and tell the user: "The script record is incomplete — it may still be generating. Try again in a moment."
105
+
106
+ 2. Load and call `muggle-remote-action-script-get` with `actionScriptId`.
107
+
108
+ Tell the user: `Executing task...`
109
+
110
+ ## Step 7 — Execute locally
111
+
112
+ Load and call `muggle-local-execute-replay` with:
113
+ - `testScript`: the full object from Step 6 (from `muggle-remote-test-script-get`)
114
+ - `actionScript`: the content from Step 6 (from `muggle-remote-action-script-get`)
115
+ - `localUrl`: from Step 1
116
+ - `mutations`: the `mutations[]` array from Step 1 (omit if empty)
117
+
118
+ Tell the user:
119
+ > Running **[useCaseName]** on [domain]. Watch the Muggle Test window — it will execute the task with your parameters applied.
120
+
121
+ ## Step 8 — Route failures through the failure-mode handler
122
+
123
+ If Phase 1 generation or Phase 2 replay returns `failed` or any non-passing terminal state, follow [`_shared/failure-mode-handling.md`](../_shared/failure-mode-handling.md):
124
+
125
+ - **Phase 1 (generation) failure** → section C (buckets: `transient` / `infra` / `agent-course` / `product-uxux`).
126
+ - **Phase 2 (replay) failure** → section B (buckets: `infra` / `stale-script` / `product-defect`).
127
+
128
+ Steps:
129
+ 1. Read the run via `muggle-local-run-result-get` and extract signals per the heuristics in the shared doc.
130
+ 2. Emit `regen-failure-classified` or `replay-failure-classified` via `muggle-local-telemetry-event-emit` **before** asking the user.
131
+ 3. Present the recommended action via `AskUserQuestion` with the alternatives the shared doc lists for that bucket.
132
+ 4. After the user picks, emit the matching `*-resolved` event with `userAction`.
133
+
134
+ If the user picks `muggle-feedback` from any bucket's options, invoke the `muggle-feedback` skill via the `Skill` tool with the `runId`. Skip silently on clean success.
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: muggle-feedback
3
+ description: Capture feedback on a generated Muggle Test action script — either step-level or whole-script — and submit it so the system can analyze it and regenerate affected scripts. Use when the user has just run a Muggle Test (local or remote) and wants to flag what went wrong, when they paste a Muggle dashboard URL with a test script or run, or when they want to view or delete previously submitted feedback. Triggers on: '/muggle-feedback', 'give feedback on this run', 'the test was wrong', 'step N didn't work', 'the script clicked the wrong button', 'flag this run', 'the summary is wrong', 'show my feedback', 'list feedback', 'delete that feedback'. Skill auto-detects the run context from a recent local run, a remote run, or a Muggle dashboard URL in the prompt.
4
+ ---
5
+
6
+ # Muggle Test Feedback
7
+
8
+ > Telemetry first step: see [`_shared/telemetry-emit.md`](../_shared/telemetry-emit.md). Use `skillName: "muggle-feedback"`.
9
+
10
+ Capture user feedback on what a generated Muggle Test action script did wrong. The server uses each feedback row to find similar test cases via LLM and regenerate their scripts in the background.
11
+
12
+ ## Routing
13
+
14
+ Pick the operation, then read its op file for the procedure.
15
+
16
+ | Intent | Op file |
17
+ |---|---|
18
+ | "give feedback on this run" / "the test was wrong" / "step N didn't work" / a Muggle dashboard URL in the prompt / chained from another skill | [`ops/submit.md`](ops/submit.md) |
19
+ | "show my feedback" / "list feedback for this project" / "what feedback have I filed" | [`ops/list.md`](ops/list.md) |
20
+ | "delete that feedback" / "remove feedback for X" | [`ops/delete.md`](ops/delete.md) |
21
+
22
+ If intent is ambiguous, use `AskUserQuestion` once with options **Submit / List / Delete** — never ask the user to type a clarification in plain text.
23
+
24
+ ## Constraints (all ops)
25
+
26
+ - **Feedback attaches to a cloud action-script id.** A local run that has not yet been uploaded to the cloud has no such id. Submit must upload the run first if needed.
27
+ - **Feedback target is one of two shapes:**
28
+ - **Whole script** — `target.targetType = "actionScript"`, `target.targetId = <actionScriptId>`.
29
+ - **One specific step** — `target.targetType = "step"`, `target.targetId = "<actionScriptId>:<stepIndex>"` where `stepIndex` is **0-based** on the wire even though steps are shown to the user 1-based.
30
+ - **Project scope.** All ops scope to the user's last-used project (`muggle-local-last-project-get`). If unset, ask once and persist via `muggle-local-last-project-set` so subsequent ops in this session reuse it.
31
+ - **`feedbackText` must be non-empty.** Re-prompt the user if they leave it blank.
32
+
33
+ ## Non-negotiables (all ops)
34
+
35
+ - Use `AskUserQuestion` for every selection (project, test case, run, target type, confirm). Never ask the user to "reply with a number" in plain text.
36
+ - Convert step numbers between 1-based (rendered to user) and 0-based (wire format) at the boundary. Never expose 0-based indices to the user.
37
+ - One MCP submit/delete call per feedback piece — never batch into a single call.
38
+ - Surface the `feedbackAnalysisWorkflowRuntimeId` returned by submit so the user knows regeneration is running. Do not poll it from this skill.
@@ -0,0 +1,49 @@
1
+ # Delete feedback
2
+
3
+ Soft-delete a feedback entry. Always confirm with the user before deleting — this is a write the user cannot undo from this skill.
4
+
5
+ ## 1. Identify the feedback
6
+
7
+ Three paths:
8
+
9
+ - **Explicit id** — user named the feedback id (e.g. "delete feedback `abcd-1234-...`"). Use it.
10
+ - **Recently shown id** — the user is referring to a row from a list rendered earlier in the conversation. Resolve from that context.
11
+ - **No id given** — run [`list.md`](list.md) first to surface entries; offer "Delete one" as the next-action; the user picks.
12
+
13
+ ## 2. Show what will be deleted
14
+
15
+ Print:
16
+
17
+ ```
18
+ Feedback: <id>
19
+ Target: <Whole script | Step N>
20
+ Test case: <title>
21
+ Created: <human-readable>
22
+ Text:
23
+ <full feedbackText, indented>
24
+ ```
25
+
26
+ ## 3. Confirm
27
+
28
+ `AskUserQuestion`:
29
+
30
+ > "Delete this feedback?"
31
+ > - **Delete** — proceed
32
+ > - **Cancel** — abort
33
+
34
+ If the user cancels, print "Cancelled — feedback kept." and stop.
35
+
36
+ ## 4. Soft-delete
37
+
38
+ `muggle-remote-user-feedback-delete` with the feedback id.
39
+
40
+ ## 5. Report
41
+
42
+ On success: `✓ Deleted feedback <id>.`
43
+
44
+ On failure: print the error verbatim. If the error is "not found", inform the user the entry was likely already deleted and continue gracefully.
45
+
46
+ ## Non-negotiables
47
+
48
+ - Never delete without an explicit confirm step, even if the user said "delete X" in their original prompt — the confirm shows what they're actually deleting.
49
+ - One delete call per invocation. No bulk delete in v1.
@@ -0,0 +1,65 @@
1
+ # List feedback
2
+
3
+ Show feedback the user has filed. The user usually wants feedback on a specific test case (or test script, or use case) — not the whole project — so the skill picks a scope first.
4
+
5
+ ## 1. Scope to a project
6
+
7
+ Read `muggle-local-last-project-get`. If set, use it.
8
+
9
+ If unset: `muggle-remote-project-list` and pick via `AskUserQuestion` (top 5 by recency, plus "Show full list"). Persist with `muggle-local-last-project-set`.
10
+
11
+ ## 2. Pick a narrowing scope
12
+
13
+ Ask once via `AskUserQuestion` — the list tool accepts at most one narrowing filter:
14
+
15
+ > "What feedback do you want to see?"
16
+ > - **A specific test case** (most common)
17
+ > - **A specific test script**
18
+ > - **A specific use case**
19
+ > - **All in this project**
20
+
21
+ If the user came from a chained skill or from a recent run, default to the matching narrowing scope and skip this question.
22
+
23
+ ## 3. Resolve the filter id
24
+
25
+ - **Test case** → `muggle-remote-test-case-list` with `projectId`, `AskUserQuestion`. Pass picked id as `testCaseId`.
26
+ - **Test script** → first pick a test case (as above), then `muggle-remote-test-script-list` with `testCaseId`, `AskUserQuestion`. Pass as `testScriptId`.
27
+ - **Use case** → `muggle-remote-use-case-list` with `projectId`, `AskUserQuestion`. Pass as `useCaseId`.
28
+ - **All in project** → no narrowing param.
29
+
30
+ Use relevance-first filtering on each picker: top 3-5 most relevant to the user's stated goal, plus "Show full list".
31
+
32
+ ## 4. Fetch
33
+
34
+ `muggle-remote-user-feedback-list` with `projectId` and at most one of `actionScriptId` / `testScriptId` / `testCaseId` / `useCaseId`.
35
+
36
+ If the response has zero entries, print "No feedback yet for `<scope description>`." and offer `AskUserQuestion` with **Submit new feedback / Done**.
37
+
38
+ ## 5. Render
39
+
40
+ Markdown table sorted by `createdAt` (newest first):
41
+
42
+ | # | Target | Test case | Excerpt | Created | Id |
43
+ |---|---|---|---|---|---|
44
+
45
+ - **Target** — "Whole script" or "Step N" (convert wire 0-based index to 1-based for display).
46
+ - **Test case** — when the scope is `testCaseId` or `testScriptId`, all rows share the same test case (use the title from the picker). When the scope is `useCaseId` or project-wide, resolve per row by fetching `muggle-remote-test-script-list` once for each unique `actionScriptId` (cache in-memory) — or skip and show "Test case: …" if there are >20 unique scripts.
47
+ - **Excerpt** — first 80 chars of `feedbackText`, single line.
48
+ - **Created** — human-readable, e.g. `2 days ago`.
49
+ - **Id** — feedback id, truncated to first 8 chars in the table; full id shown in the detail view.
50
+
51
+ ## 6. Offer next action
52
+
53
+ `AskUserQuestion`:
54
+
55
+ > "What next?"
56
+ > - **View detail** — pick an entry, print full `feedbackText`, full ids, target, dashboard link if available.
57
+ > - **Delete one** — hand off to [`delete.md`](delete.md).
58
+ > - **Submit new feedback** — hand off to [`submit.md`](submit.md).
59
+ > - **Done**
60
+
61
+ ## Non-negotiables
62
+
63
+ - One narrowing filter only — never set more than one of `actionScriptId` / `testScriptId` / `testCaseId` / `useCaseId` in the same call.
64
+ - Convert wire 0-based step indices to 1-based when rendering to the user.
65
+ - Don't fetch test-case names per row eagerly past ~20 unique action scripts — make it opt-in.
@@ -0,0 +1,117 @@
1
+ # Submit feedback
2
+
3
+ Resolve the action script being commented on, render it for review, collect feedback against one or more steps and/or the whole script, then submit each piece as its own server-side row.
4
+
5
+ ## 1. Resolve the action script (the "anchor")
6
+
7
+ Pick the first applicable path. Stop at the first that yields an `actionScriptId`.
8
+
9
+ ### 1a. Dashboard URL in user's prompt
10
+
11
+ A Muggle dashboard URL looks like `https://app.muggle-ai.com/muggleTestV0/dashboard/projects/<projectId>/...`. Scan the user's recent message for any `https://app.muggle-ai.com/...` URL.
12
+
13
+ - Extract any UUID-shaped path segments. If `/projects/<uuid>` is present, capture as `projectId`. If `/test-scripts/<uuid>` is present, capture as `testScriptId`.
14
+ - If a `testScriptId` was captured: call `muggle-remote-test-script-get` to get the script and read `actionScriptId` off it. Done — proceed to step 2.
15
+ - If only a `projectId` was captured: use it as the project for path 1c and continue to picker.
16
+ - If parsing yields nothing actionable: fall through to 1b.
17
+
18
+ ### 1b. Recent local run (chained or just-finished)
19
+
20
+ If this skill was invoked by another skill (`muggle-test`, `muggle-test-feature-local`) the caller MUST pass the just-finished `runId` as context. If you have a `runId`:
21
+
22
+ 1. `muggle-local-run-result-get` with the `runId`.
23
+ 2. The result includes the test case context. If the run was already published (`muggle-local-publish-test-script` was called), the resulting `testScriptId` gives you the cloud `actionScriptId` via `muggle-remote-test-script-get`.
24
+ 3. **If the run was NOT published**, upload it first via `muggle-remote-local-run-upload` (passing the `runId`'s test case context and `actionScript` payload). Use the returned cloud `actionScriptId`.
25
+
26
+ If no `runId` was passed but the user is plausibly continuing from a recent test:
27
+
28
+ 1. `muggle-local-list-sessions` and pick sessions completed in the last 10 minutes for the current project.
29
+ 2. If exactly one fresh session exists, offer it as the default via `AskUserQuestion` ("Feedback on the run from <X> minutes ago?" with **Yes / Pick a different run**).
30
+ 3. If multiple, present the top 3 via `AskUserQuestion` (most recent first).
31
+ 4. Once picked, follow the publish-or-upload path above.
32
+
33
+ If neither chained nor recent fits, fall through to 1c.
34
+
35
+ ### 1c. Picker (project → test case → run)
36
+
37
+ 1. **Project.** Read `muggle-local-last-project-get`. If set, use it. Else `muggle-remote-project-list` with `AskUserQuestion` (top 5 by recency, plus "Show full list"). Persist the pick with `muggle-local-last-project-set`.
38
+ 2. **Test case.** `muggle-remote-test-case-list` with `projectId`, then `AskUserQuestion`. Top 5 by recency plus "Show full list". Rank by relevance if the user mentioned anything specific.
39
+ 3. **Run / script.** `muggle-remote-test-script-list` with `testCaseId`. Show via `AskUserQuestion` with: name + status + updatedAt. Top 5 by recency.
40
+ 4. `muggle-remote-test-script-get` on the picked one → note `actionScriptId`.
41
+
42
+ ## 2. Render the script for review
43
+
44
+ Always render before asking for feedback — the user must see the steps to reference them by index.
45
+
46
+ `muggle-remote-action-script-get` with the resolved `actionScriptId`.
47
+
48
+ Print:
49
+
50
+ - **Header** — project name, test case title, script name, status, run url (if available). For remote, include the dashboard link.
51
+ - **Steps** — numbered list, **1-based**, in order:
52
+ - `Step <n>: <action label> on <element text or id> — <briefExplanation>`
53
+ - If `screenshotPath` is present (local) or `screenshotUrl` (remote), append `[screenshot: <path>]` so the user can open it manually.
54
+ - **Summary** — print `summary` from the action script if present, else "No summary recorded".
55
+
56
+ ## 3. Collect feedback (batch)
57
+
58
+ Use `AskUserQuestion` to scope which targets:
59
+
60
+ > "Where is the problem?"
61
+ > - One specific step
62
+ > - Multiple steps
63
+ > - The whole script's outcome / summary
64
+ > - Multiple steps **and** the whole outcome
65
+
66
+ For each chosen target, prompt for the feedback paragraph in plain text. Keep prompts specific:
67
+
68
+ - For a step: "What should step `<n>` have done instead?"
69
+ - For the whole script: "What's wrong with the overall outcome?"
70
+
71
+ Validate each paragraph is non-empty (re-prompt if blank). Build an in-memory list of feedback pieces:
72
+
73
+ ```
74
+ [
75
+ { kind: "step", stepNumber: 3, text: "..." },
76
+ { kind: "step", stepNumber: 7, text: "..." },
77
+ { kind: "actionScript", text: "..." },
78
+ ]
79
+ ```
80
+
81
+ Before submitting, re-confirm the full set with the user via `AskUserQuestion`:
82
+
83
+ > "Submit these <N> feedback entries?" — **Submit / Edit / Cancel**.
84
+
85
+ ## 4. Submit
86
+
87
+ For each piece, call `muggle-remote-user-feedback-create` once. Map fields:
88
+
89
+ | Piece kind | `target.targetType` | `target.targetId` |
90
+ |---|---|---|
91
+ | Step `n` (1-based) | `"step"` | `` `${actionScriptId}:${n - 1}` `` (convert to 0-based) |
92
+ | Whole script | `"actionScript"` | `actionScriptId` |
93
+
94
+ Always pass `projectId` and `feedbackText`. Capture each response — note `feedback.id` and `feedbackAnalysisWorkflowRuntimeId` (may be undefined).
95
+
96
+ If a single create call fails, log the error, continue with the rest, and report the failure at the end. Do not abort the batch.
97
+
98
+ ## 5. Report
99
+
100
+ Print one line per submitted feedback in this shape:
101
+
102
+ ```
103
+ ✓ feedback <id> — <target description> [analysis runtime: <id>]
104
+ ```
105
+
106
+ End with a one-line note:
107
+
108
+ > "Regeneration runs in the background. Re-run this test case later to use the updated script."
109
+
110
+ If any pieces failed, list them under a `Failed:` header with the error.
111
+
112
+ ## Non-negotiables
113
+
114
+ - Always render the script (step 2) before collecting feedback.
115
+ - One create call per feedback piece — never concatenate paragraphs across targets.
116
+ - Convert step numbers from 1-based (UI) to 0-based (wire) at submit time.
117
+ - If the user came from a non-uploaded local run, do the upload silently before submit; do not ask for permission for the upload itself.
@@ -1,38 +1,34 @@
1
1
  ---
2
2
  name: muggle-pr-visual-walkthrough
3
- description: Renders and posts a visual walkthrough of Muggle AI E2E acceptance test results to a PR — per-test-case dashboard links, step-by-step screenshots, and pass/fail summary — using the `muggle build-pr-section` CLI for deterministic formatting with automatic fit-vs-overflow. Use at the end of any Muggle test run (local or remote) to give PR reviewers clickable visual evidence that user flows work. Triggers on 'post results to PR', 'attach walkthrough to PR', 'share E2E screenshots on the PR', 'add visual walkthrough to PR'.
3
+ description: Renders and posts a visual walkthrough of Muggle AI E2E acceptance test results to a PR — per-test-case dashboard links, step-by-step screenshots, and pass/fail summary — using the `muggle build-pr-section` CLI for deterministic formatting with automatic fit-vs-overflow. Use at the end of any Muggle Test test run (local or remote) to give PR reviewers clickable visual evidence that user flows work. Triggers on 'post results to PR', 'attach walkthrough to PR', 'share E2E screenshots on the PR', 'add visual walkthrough to PR'.
4
4
  ---
5
5
 
6
- # Muggle PR Visual Walkthrough
6
+ # Muggle Test PR Visual Walkthrough
7
+
8
+ > Telemetry first step: see [`_shared/telemetry-emit.md`](../_shared/telemetry-emit.md). Use `skillName: "muggle-pr-visual-walkthrough"`.
7
9
 
8
10
  Renders a visual walkthrough of Muggle AI E2E acceptance test results and posts it to a PR. Each test case is linked to its detail page on the Muggle AI dashboard, so PR reviewers can click through to see step-by-step screenshots and action scripts — not just a pass/fail flag.
9
11
 
10
- This is the **canonical PR-walkthrough workflow** shared across every Muggle entry point:
12
+ This is the **canonical PR-walkthrough workflow** shared across every Muggle Test entry point:
11
13
 
12
14
  | Caller | Mode | When to invoke |
13
15
  | :--- | :--- | :--- |
14
- | `muggle-test` | **Mode A** (post to existing PR) | After publishing results, user opts in via `AskQuestion` |
15
- | `muggle-test-feature-local` | **Mode A** (post to existing PR) | After publishing the run, user opts in via `AskQuestion` |
16
+ | `muggle-test` | **Mode A** (post to existing PR) | After publishing results, user opts in via `AskUserQuestion` |
17
+ | `muggle-test-feature-local` | **Mode A** (post to existing PR) | After publishing the run, user opts in via `AskUserQuestion` |
16
18
  | `muggle-do` / `open-prs.md` | **Mode B** (render-only for embedding) | During PR creation — caller embeds `body` in `gh pr create` and posts `comment` as follow-up |
19
+ | `muggle-test` Mode C / `acceptance-tester` agent | **Mode C** (embed in verdict comment) | Inside a open-PR sweep orchestrator — caller folds the rendered body into a single per-PR verdict comment instead of posting separately |
17
20
 
18
21
  Rendering is always done by `muggle build-pr-section`, a battle-tested CLI that handles deterministic markdown layout, per-step screenshots, and automatic fit-vs-overflow (oversized content spills into a follow-up comment). Never hand-write the walkthrough markdown.
19
22
 
20
23
  ## Preferences
21
24
 
22
- User preferences are available in the session context (injected at session start). Look for the line starting with `Muggle Preferences` — it contains key=value pairs like `autoLogin=ask showElectronBrowser=always ...`.
23
-
24
- If no preferences line is present, treat all preferences as `"ask"`.
25
+ This skill is invoked by callers (`muggle-test`, `muggle-test-feature-local`, `muggle-do`) **after** the caller has already consulted the `postPRVisualWalkthrough` gate and decided to post. Therefore **the gating happens upstream, not in this skill** — by the time this skill runs, the user has already approved posting (either via the saved gate value or by explicit pick).
25
26
 
26
- When you reach a decision gated by a preference:
27
- - **`always`** → proceed without asking the user
28
- - **`never`** → skip without asking the user
29
- - **`ask`** → ask the user, then offer: "Want me to remember this choice for future sessions?" If yes, call `muggle-local-preferences-set` with the key, their chosen value, and scope `global`.
27
+ | Preference | Where it's gated | Decision it gates |
28
+ |------------|------------------|-------------------|
29
+ | `postPRVisualWalkthrough` | Caller skill (e.g. `muggle-test` Step 9, `muggle-test-feature-local` Step 10) | Post visual walkthrough to PR |
30
30
 
31
- This skill uses these preferences:
32
-
33
- | Preference | Decision it gates |
34
- |------------|------------------|
35
- | `postPRVisualWalkthrough` | Post visual walkthrough to PR |
31
+ Per-key gate definitions live in `plugin/skills/muggle-preferences/preference-gates/`. This skill only renders and posts.
36
32
 
37
33
  ## Input contract: the `E2eReport` JSON
38
34
 
@@ -71,42 +67,48 @@ Every caller must build an `E2eReport` JSON object and have it in conversation c
71
67
  "failureStepIndex": 2,
72
68
  "error": "Element not found: Click checkout button",
73
69
  "artifactsDir": "/Users/.../~/.muggle-ai/sessions/<runId>"
70
+ },
71
+ {
72
+ "name": "Clear search input restores full list",
73
+ "description": "Verify clearing the search input restores all options.",
74
+ "useCaseName": "Filter Dropdowns",
75
+ "testCaseId": "<UUID>",
76
+ "runId": "<UUID>",
77
+ "viewUrl": "https://www.muggle-ai.com/...",
78
+ "status": "inconclusive",
79
+ "steps": [],
80
+ "reason": "No replayable script exists yet — needs first generation run."
74
81
  }
75
82
  ]
76
83
  }
77
84
  ```
78
85
 
79
- Required fields per test: `name`, `testCaseId`, `runId`, `viewUrl`, `status`, `steps[]` with `{stepIndex, action, screenshotUrl}`. Failed tests additionally require `failureStepIndex` and `error`.
86
+ Required fields per test: `name`, `testCaseId`, `runId`, `viewUrl`, `status`, `steps[]` with `{stepIndex, action, screenshotUrl}`.
80
87
 
81
- **Optional but recommended** per test:
82
- - `description` — a one-line summary of what the test case verifies. Shown in the collapsible header for each test and helps reviewers understand the test without expanding it. Pull from the test case's `title`/`description` via `muggle-remote-test-case-get`.
83
- - `useCaseName` — the parent use case title. When present on any test, the overview list is grouped by use case; otherwise it is rendered as a flat list. Pull from `muggle-remote-use-case-get` using the test case's parent use-case id.
84
- - `testScriptId` and `artifactsDir` are also optional.
88
+ - **Failed** tests additionally require `failureStepIndex` and `error`.
89
+ - **Inconclusive** tests additionally require `reason` (one short sentence on why the result is neither pass nor fail). `steps[]` may be empty — that's fine. Inconclusive is for runs that couldn't be classified pass/fail (no replayable script, environment precondition unmet, infra error blocked execution, agent stalled before reaching the assertion). **Never silently drop these — always emit them as `inconclusive`.** The CLI counts them in the overview and renders an `⚠️` row with the dashboard link so reviewers can click through. If you find yourself wanting to skip a test or hand-write a comment because the schema "doesn't fit," that is the schema fitting — use `inconclusive`.
85
90
 
86
- If any required field is missing, stop and tell the caller exactly what's missing. Never fabricate data.
87
-
88
- ## Step 1: Gather the `E2eReport`
91
+ ### Verdict
89
92
 
90
- How to assemble the JSON depends on which caller you are:
93
+ The renderer computes a verdict from the tests and emits a `**Verdict:** ✅ PASS | ❌ FAIL | ⚠️ INCONCLUSIVE` line at the top of the overview. The policy is strict:
91
94
 
92
- ### From `muggle-test` / `muggle-test-feature-local` (local mode)
95
+ - Any failed test → **FAIL** (regardless of how many passed or are inconclusive).
96
+ - No failures but any inconclusive → **INCONCLUSIVE**.
97
+ - All passed → **PASS**.
98
+ - Empty report → no verdict line.
93
99
 
94
- After `muggle-local-publish-test-script` returns `{testScriptId, viewUrl, ...}` for each run:
100
+ You do not compute or render the verdict yourself — the CLI does. Never write a "Verdict: PASS" line into a hand-edited summary; it will conflict with the CLI's computed verdict.
95
101
 
96
- 1. Call `muggle-remote-test-script-get` with `testScriptId` to fetch the published script.
97
- 2. Extract `steps[]` — for each step, build `{stepIndex: <index>, action: operation.action, screenshotUrl: operation.screenshotUrl}`.
98
- 3. Determine `status` from the local run result (`muggle-local-run-result-get`).
99
- 4. For failures, read `failureStepIndex`, `error`, and `artifactsDir` from the run result.
100
- 5. Assemble the `E2eReport` with `projectId` from the test run.
101
- 6. Populate `description` (test case title/description) and `useCaseName` (parent use case title) on each report entry — optional but strongly recommended; they drive the grouped overview and the per-test collapsible headers. Prefer values already in your conversation context from earlier steps (e.g. a test case you just created or selected, or a use case you confirmed); only call `muggle-remote-test-case-get` / `muggle-remote-use-case-get` for anything you don't already have.
102
-
103
- ### From `muggle-do` (`open-prs.md`)
102
+ **Optional but recommended** per test:
103
+ - `description` — a one-line summary of what the test case verifies. Shown in the collapsible header for each test and helps reviewers understand the test without expanding it. Pull from the test case's `title`/`description` via `muggle-remote-test-case-get`.
104
+ - `useCaseName` — the parent use case title. When present on any test, the overview list is grouped by use case; otherwise it is rendered as a flat list. Pull from `muggle-remote-use-case-get` using the test case's parent use-case id.
105
+ - `testScriptId` and `artifactsDir` are also optional.
104
106
 
105
- The `e2e-acceptance.md` stage already produces an `E2eReport` with the exact shape above — that is the report's native output format. Pass it through unchanged.
107
+ If any required field is missing, stop and tell the caller exactly what's missing. Never fabricate data.
106
108
 
107
- ### Direct invocation (user asked to post existing results)
109
+ ## Step 1: Assemble the `E2eReport`
108
110
 
109
- The caller must have already executed tests and published them. If the `E2eReport` is not in context, stop and tell the user to run `muggle-test` or `muggle-test-feature-local` first.
111
+ Read `plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md` for the full assembly guide.
110
112
 
111
113
  ## Step 2: Render via `muggle build-pr-section`
112
114
 
@@ -133,7 +135,7 @@ gh pr view --json number,url,title 2>/dev/null
133
135
  ```
134
136
 
135
137
  - **PR exists** → continue to 3A.2
136
- - **No PR exists** → use `AskQuestion`:
138
+ - **No PR exists** → use `AskUserQuestion`:
137
139
  - "Create a new PR with the visual walkthrough in the body"
138
140
  - "Skip posting"
139
141
  - If the user chooses to create a new PR, switch to Mode B and return the rendered `body`/`comment` to the caller for embedding in `gh pr create`. Do not create the PR directly from this skill unless the caller has no better way to do it.
@@ -141,20 +143,16 @@ gh pr view --json number,url,title 2>/dev/null
141
143
 
142
144
  ### 3A.2: Post the body as a PR comment
143
145
 
146
+ Extract the `body` field with `jq -r` (not `sed`) so JSON escape sequences are properly decoded, then pipe to `--body-file -`:
147
+
144
148
  ```bash
145
- gh pr comment <pr-number> --body "$(cat <<'EOF'
146
- <contents of body field from CLI output>
147
- EOF
148
- )"
149
+ jq -r '.body' /tmp/muggle-pr-section.json | gh pr comment <pr-number> --body-file -
149
150
  ```
150
151
 
151
152
  ### 3A.3: Post the overflow comment only if the CLI emitted one
152
153
 
153
154
  ```bash
154
- gh pr comment <pr-number> --body "$(cat <<'EOF'
155
- <contents of comment field from CLI output>
156
- EOF
157
- )"
155
+ jq -r '.comment' /tmp/muggle-pr-section.json | gh pr comment <pr-number> --body-file -
158
156
  ```
159
157
 
160
158
  **Skip this step entirely if `comment` is `null`** — do not post a placeholder. The CLI decides fit-vs-overflow; never post the overflow comment speculatively.
@@ -176,16 +174,35 @@ Instead of posting, **return** the CLI output to the caller's context so they ca
176
174
  3. **Post `comment` as a follow-up only if the CLI emitted one:**
177
175
 
178
176
  ```bash
179
- gh pr comment <new-pr-number> --body "$(cat <<'EOF'
180
- <contents of comment field>
181
- EOF
182
- )"
177
+ jq -r '.comment' /tmp/muggle-pr-section.json | gh pr comment <new-pr-number> --body-file -
183
178
  ```
184
179
 
185
180
  Skip if `comment` is `null`.
186
181
 
187
182
  In Mode B, this skill does not call `gh pr comment` or `gh pr create` itself — the caller owns PR creation because it also owns branch pushing, title building (including `[E2E FAILING]` prefix on failures), and multi-repo orchestration.
188
183
 
184
+ ## Step 3 — Mode C: Embed mode for open-PR sweep orchestrators
185
+
186
+ Used when invoked as a sub-step of a open-PR sweep orchestrator (see `plugin/skills/muggle-test/SKILL.md` Mode C) rather than as a top-level user invocation. The orchestrator's `acceptance-tester` subagent (see `plugin/agents/acceptance-tester.md`) composes a **single per-PR verdict comment** and folds the walkthrough into it — posting separately would create 2–3 disparate comments per test cycle and clutter the PR.
187
+
188
+ ### 3C.1: Detect embed mode
189
+
190
+ The caller passes `mode: "embed"` as a skill argument. Default behavior (no `mode` passed, or `mode: "post"`) is Mode A — unchanged.
191
+
192
+ ### 3C.2: Render but do not post
193
+
194
+ Run `muggle build-pr-section` exactly as in Step 2. Then, **instead of calling `gh pr comment`**:
195
+
196
+ 1. **Return** the CLI output (`{ body, comment }`) to the caller as this skill's result.
197
+ 2. Do **not** find a PR, do **not** post a standalone comment, do **not** prompt the user.
198
+ 3. If `comment` is non-null (overflow case), return it alongside `body` — the orchestrator decides how to handle overflow (typically: inline `body` in the verdict comment, post `comment` as a follow-up).
199
+
200
+ ### 3C.3: Hand off
201
+
202
+ The orchestrator (`acceptance-tester`) concatenates the returned `body` into its verdict comment template alongside the verdict summary, change-list, and any other sections it owns, then posts a single `gh pr comment` itself. This skill's job ends at returning the rendered markdown.
203
+
204
+ In Mode C, the same fit-vs-overflow contract from Step 2 applies — never modify the CLI's output, never fabricate fields, never post anything. The caller owns posting.
205
+
189
206
  ## Tool Reference
190
207
 
191
208
  | Phase | Tool |
@@ -195,14 +212,15 @@ In Mode B, this skill does not call `gh pr comment` or `gh pr create` itself —
195
212
  | Find existing PR (Mode A) | `gh pr view` |
196
213
  | Post comment(s) (Mode A) | `gh pr comment` |
197
214
  | Create new PR (Mode B, caller handles) | `gh pr create` |
198
- | User confirmation (Mode A no-PR branch) | `AskQuestion` |
215
+ | User confirmation (Mode A no-PR branch) | `AskUserQuestion` |
199
216
 
200
217
  ## Guardrails
201
218
 
202
- - **Never hand-write the walkthrough markdown** — always call `muggle build-pr-section`. The CLI is the single source of truth for formatting.
219
+ - **Never hand-write the walkthrough markdown** — always call `muggle build-pr-section`. The CLI is the single source of truth for formatting. If a test outcome doesn't fit `passed | failed`, that's what `inconclusive` is for — never fall back to a hand-written summary, a custom table, a "Verdict: PASS" header, a `Tested on:`/`Project:` footer, or any other freeform text. The CLI already emits per-test-case dashboard links (no project-level link), uses `https://www.muggle-ai.com/...` URLs (never the test target's `localhost` URL), and computes the verdict — anything you would manually add is wrong by construction.
203
220
  - **Never modify the CLI's output** — post `body` and (if present) `comment` verbatim. Any reformatting defeats the fit-vs-overflow budget math.
204
221
  - **Never invent report fields** — if `projectId`, a per-test `viewUrl`, or per-step `screenshotUrl` is missing, stop and report what's missing. Do not fabricate URLs or fill in placeholders.
205
222
  - **Never post the overflow comment when `comment` is `null`** — the CLI decides fit-vs-overflow.
206
223
  - **Never create a PR without confirmation in Mode A** — if no PR exists, ask the user or switch to Mode B and hand back to the caller.
207
224
  - **Don't run tests** — this skill only renders and posts existing results. If the `E2eReport` is not in context, redirect the caller to `muggle-test`, `muggle-test-feature-local`, or `muggle-do`.
208
- - **Mode A vs Mode B is chosen by the caller, not the user** — `muggle-test` always uses Mode A; `muggle-do` always uses Mode B. Don't ask the user which mode to use.
225
+ - **Mode is chosen by the caller, not the user** — `muggle-test` top-level uses Mode A; `muggle-do` uses Mode B; open-PR sweep orchestrators (`muggle-test` Mode C / `acceptance-tester`) pass `mode: "embed"` for Mode C. Don't ask the user which mode to use.
226
+ - **Never post in Mode C** — when `mode: "embed"` is passed, return the rendered body to the caller and stop. The orchestrator owns the single verdict comment.