@muggleai/works 4.10.0 → 4.11.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 (197) hide show
  1. package/README.md +3 -3
  2. package/dist/{chunk-RK6XKSZK.js → chunk-Q7WNEMN4.js} +109 -43
  3. package/dist/{chunk-UVXOHXY2.js → chunk-ZKRHFTIC.js} +832 -89
  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 +35 -8
  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/pr-followup-helpers.md +150 -0
  30. package/dist/plugin/skills/_shared/rebase-before-e2e.md +15 -0
  31. package/dist/plugin/skills/_shared/telemetry-emit.md +15 -0
  32. package/dist/plugin/skills/_shared/use-worktrees.md +53 -0
  33. package/dist/plugin/skills/do/build.md +51 -0
  34. package/dist/plugin/skills/do/e2e-acceptance.md +64 -19
  35. package/dist/plugin/skills/do/impact-analysis.md +47 -7
  36. package/dist/plugin/skills/do/open-prs.md +72 -74
  37. package/dist/plugin/skills/do/pre-flight.md +21 -14
  38. package/dist/plugin/skills/do/requirements.md +2 -2
  39. package/dist/plugin/skills/do/unit-tests.md +2 -2
  40. package/dist/plugin/skills/m/SKILL.md +8 -0
  41. package/dist/plugin/skills/mdo/SKILL.md +8 -0
  42. package/dist/plugin/skills/mfeedback/SKILL.md +8 -0
  43. package/dist/plugin/skills/mimport/SKILL.md +8 -0
  44. package/dist/plugin/skills/mpr/SKILL.md +8 -0
  45. package/dist/plugin/skills/mprefs/SKILL.md +8 -0
  46. package/dist/plugin/skills/mregen/SKILL.md +8 -0
  47. package/dist/plugin/skills/mrelease/SKILL.md +8 -0
  48. package/dist/plugin/skills/mrepair/SKILL.md +8 -0
  49. package/dist/plugin/skills/mstatus/SKILL.md +8 -0
  50. package/dist/plugin/skills/mtest/SKILL.md +8 -0
  51. package/dist/plugin/skills/mtestlocal/SKILL.md +8 -0
  52. package/dist/plugin/skills/mtestprep/SKILL.md +8 -0
  53. package/dist/plugin/skills/muggle/SKILL.md +9 -6
  54. package/dist/plugin/skills/muggle-do/SKILL.md +36 -61
  55. package/dist/plugin/skills/muggle-do-task/SKILL.md +134 -0
  56. package/dist/plugin/skills/muggle-feedback/SKILL.md +39 -0
  57. package/dist/plugin/skills/muggle-feedback/ops/delete.md +49 -0
  58. package/dist/plugin/skills/muggle-feedback/ops/list.md +65 -0
  59. package/dist/plugin/skills/muggle-feedback/ops/submit.md +130 -0
  60. package/dist/plugin/skills/muggle-pr-followup/SKILL.md +59 -0
  61. package/dist/plugin/skills/muggle-pr-followup/contract.md +191 -0
  62. package/dist/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +68 -43
  63. package/dist/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
  64. package/dist/plugin/skills/muggle-preferences/SKILL.md +16 -108
  65. package/dist/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
  66. package/dist/plugin/skills/muggle-preferences/ops/configure.md +49 -0
  67. package/dist/plugin/skills/muggle-preferences/ops/list.md +9 -0
  68. package/dist/plugin/skills/muggle-preferences/ops/reset.md +6 -0
  69. package/dist/plugin/skills/muggle-preferences/ops/set.md +10 -0
  70. package/dist/plugin/skills/muggle-preferences/preference-gates/README.md +1 -1
  71. package/dist/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
  72. package/dist/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
  73. package/dist/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +3 -3
  74. package/dist/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
  75. package/dist/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +1 -1
  76. package/dist/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +2 -2
  77. package/dist/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
  78. package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
  79. package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +1 -2
  80. package/dist/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
  81. package/dist/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +4 -4
  82. package/dist/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +1 -1
  83. package/dist/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +1 -1
  84. package/dist/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +8 -25
  85. package/dist/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +1 -1
  86. package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +4 -4
  87. package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +4 -4
  88. package/dist/plugin/skills/muggle-repair/SKILL.md +4 -2
  89. package/dist/plugin/skills/muggle-status/SKILL.md +8 -5
  90. package/dist/plugin/skills/muggle-test/SKILL.md +110 -86
  91. package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +83 -62
  92. package/dist/plugin/skills/muggle-test-import/SKILL.md +28 -23
  93. package/dist/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
  94. package/dist/plugin/skills/muggle-test-regenerate-missing/SKILL.md +34 -18
  95. package/dist/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
  96. package/dist/plugin/skills/muggle-upgrade/SKILL.md +4 -2
  97. package/dist/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
  98. package/dist/plugin/skills/mupgrade/SKILL.md +8 -0
  99. package/dist/release-manifest.json +4 -4
  100. package/dist/{src-GD3YFCCW.js → src-2G7ENRGI.js} +1 -1
  101. package/package.json +9 -7
  102. package/plugin/.claude-plugin/plugin.json +1 -1
  103. package/plugin/.cursor-plugin/plugin.json +1 -1
  104. package/plugin/README.md +4 -2
  105. package/plugin/agents/acceptance-tester.md +24 -10
  106. package/plugin/commands/m.md +7 -0
  107. package/plugin/commands/mdo.md +7 -0
  108. package/plugin/commands/mfeedback.md +7 -0
  109. package/plugin/commands/mimport.md +7 -0
  110. package/plugin/commands/mpr.md +7 -0
  111. package/plugin/commands/mprefs.md +7 -0
  112. package/plugin/commands/mregen.md +7 -0
  113. package/plugin/commands/mrelease.md +7 -0
  114. package/plugin/commands/mrepair.md +7 -0
  115. package/plugin/commands/mstatus.md +7 -0
  116. package/plugin/commands/mtest.md +7 -0
  117. package/plugin/commands/mtestlocal.md +7 -0
  118. package/plugin/commands/mtestprep.md +7 -0
  119. package/plugin/commands/mupgrade.md +7 -0
  120. package/plugin/scripts/ensure-electron-app.sh +35 -8
  121. package/plugin/skills/_aliases.json +18 -0
  122. package/plugin/skills/_shared/dev-server-readiness.md +231 -0
  123. package/plugin/skills/_shared/failure-mode-handling.md +244 -0
  124. package/plugin/skills/_shared/post-merge-cleanup.md +10 -0
  125. package/plugin/skills/_shared/pr-followup-helpers.md +150 -0
  126. package/plugin/skills/_shared/rebase-before-e2e.md +15 -0
  127. package/plugin/skills/_shared/telemetry-emit.md +15 -0
  128. package/plugin/skills/_shared/use-worktrees.md +53 -0
  129. package/plugin/skills/do/build.md +51 -0
  130. package/plugin/skills/do/e2e-acceptance.md +64 -19
  131. package/plugin/skills/do/impact-analysis.md +47 -7
  132. package/plugin/skills/do/open-prs.md +72 -74
  133. package/plugin/skills/do/pre-flight.md +21 -14
  134. package/plugin/skills/do/requirements.md +2 -2
  135. package/plugin/skills/do/unit-tests.md +2 -2
  136. package/plugin/skills/m/SKILL.md +8 -0
  137. package/plugin/skills/mdo/SKILL.md +8 -0
  138. package/plugin/skills/mfeedback/SKILL.md +8 -0
  139. package/plugin/skills/mimport/SKILL.md +8 -0
  140. package/plugin/skills/mpr/SKILL.md +8 -0
  141. package/plugin/skills/mprefs/SKILL.md +8 -0
  142. package/plugin/skills/mregen/SKILL.md +8 -0
  143. package/plugin/skills/mrelease/SKILL.md +8 -0
  144. package/plugin/skills/mrepair/SKILL.md +8 -0
  145. package/plugin/skills/mstatus/SKILL.md +8 -0
  146. package/plugin/skills/mtest/SKILL.md +8 -0
  147. package/plugin/skills/mtestlocal/SKILL.md +8 -0
  148. package/plugin/skills/mtestprep/SKILL.md +8 -0
  149. package/plugin/skills/muggle/SKILL.md +9 -6
  150. package/plugin/skills/muggle-do/SKILL.md +36 -61
  151. package/plugin/skills/muggle-do-task/SKILL.md +134 -0
  152. package/plugin/skills/muggle-feedback/SKILL.md +39 -0
  153. package/plugin/skills/muggle-feedback/ops/delete.md +49 -0
  154. package/plugin/skills/muggle-feedback/ops/list.md +65 -0
  155. package/plugin/skills/muggle-feedback/ops/submit.md +130 -0
  156. package/plugin/skills/muggle-pr-followup/SKILL.md +59 -0
  157. package/plugin/skills/muggle-pr-followup/contract.md +191 -0
  158. package/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +68 -43
  159. package/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
  160. package/plugin/skills/muggle-preferences/SKILL.md +16 -108
  161. package/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
  162. package/plugin/skills/muggle-preferences/ops/configure.md +49 -0
  163. package/plugin/skills/muggle-preferences/ops/list.md +9 -0
  164. package/plugin/skills/muggle-preferences/ops/reset.md +6 -0
  165. package/plugin/skills/muggle-preferences/ops/set.md +10 -0
  166. package/plugin/skills/muggle-preferences/preference-gates/README.md +1 -1
  167. package/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
  168. package/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
  169. package/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +3 -3
  170. package/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
  171. package/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +1 -1
  172. package/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +2 -2
  173. package/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
  174. package/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
  175. package/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +1 -2
  176. package/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
  177. package/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +4 -4
  178. package/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +1 -1
  179. package/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +1 -1
  180. package/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +8 -25
  181. package/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +1 -1
  182. package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +4 -4
  183. package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +4 -4
  184. package/plugin/skills/muggle-repair/SKILL.md +4 -2
  185. package/plugin/skills/muggle-status/SKILL.md +8 -5
  186. package/plugin/skills/muggle-test/SKILL.md +110 -86
  187. package/plugin/skills/muggle-test-feature-local/SKILL.md +83 -62
  188. package/plugin/skills/muggle-test-import/SKILL.md +28 -23
  189. package/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
  190. package/plugin/skills/muggle-test-regenerate-missing/SKILL.md +34 -18
  191. package/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
  192. package/plugin/skills/muggle-upgrade/SKILL.md +4 -2
  193. package/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
  194. package/plugin/skills/mupgrade/SKILL.md +8 -0
  195. package/scripts/postinstall.mjs +11 -1
  196. package/dist/plugin/skills/do/validate-code.md +0 -38
  197. package/plugin/skills/do/validate-code.md +0 -38
@@ -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,39 @@
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, which step(s), confirm). Step selection must be a clickable picker built from the rendered steps (see [`ops/submit.md`](ops/submit.md) §3b) — never ask the user to type a number.
36
+ - Always render the run's steps and summary (§2) **before** collecting feedback — users can only point at what they can see.
37
+ - 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.
38
+ - One MCP submit/delete call per feedback piece — never batch into a single call.
39
+ - 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,130 @@
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
+ ### 3a. Pick the scope (entity type)
59
+
60
+ Use `AskUserQuestion` to scope which targets:
61
+
62
+ > "Where is the problem?"
63
+ > - One specific step
64
+ > - Multiple steps
65
+ > - The whole script's outcome / summary
66
+ > - Multiple steps **and** the whole outcome
67
+
68
+ ### 3b. Pick the step(s) — clickable picker
69
+
70
+ When 3a includes any step-level scope, present the rendered steps as a **clickable `AskUserQuestion` picker** — never as a typed number.
71
+
72
+ - **Option format** — Label: `Step <n>: <action label> on <element text or id>` (≤80 chars). Description: the step's `briefExplanation` (≤120 chars).
73
+ - **Multi-select** — `multiSelect: true` for "Multiple steps" or "Multiple steps and the whole outcome"; `multiSelect: false` for "One specific step".
74
+ - **Long scripts (>10 steps)** — rank by keyword overlap with the user's prompt (label or briefExplanation); fall back to the first 10 if no match. Append **"Show all steps"** as a final option that re-asks with the full list — never silently truncate.
75
+
76
+ For each selected step, prompt in plain text:
77
+
78
+ > "What should step `<n>` have done instead?"
79
+
80
+ For the whole-script scope, prompt:
81
+
82
+ > "What's wrong with the overall outcome?"
83
+
84
+ Validate each paragraph is non-empty (re-prompt if blank). Build an in-memory list of feedback pieces:
85
+
86
+ ```
87
+ [
88
+ { kind: "step", stepNumber: 3, text: "..." },
89
+ { kind: "step", stepNumber: 7, text: "..." },
90
+ { kind: "actionScript", text: "..." },
91
+ ]
92
+ ```
93
+
94
+ Before submitting, re-confirm the full set with the user via `AskUserQuestion`:
95
+
96
+ > "Submit these <N> feedback entries?" — **Submit / Edit / Cancel**.
97
+
98
+ ## 4. Submit
99
+
100
+ For each piece, call `muggle-remote-user-feedback-create` once. Map fields:
101
+
102
+ | Piece kind | `target.targetType` | `target.targetId` |
103
+ |---|---|---|
104
+ | Step `n` (1-based) | `"step"` | `` `${actionScriptId}:${n - 1}` `` (convert to 0-based) |
105
+ | Whole script | `"actionScript"` | `actionScriptId` |
106
+
107
+ Always pass `projectId` and `feedbackText`. Capture each response — note `feedback.id` and `feedbackAnalysisWorkflowRuntimeId` (may be undefined).
108
+
109
+ 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.
110
+
111
+ ## 5. Report
112
+
113
+ Print one line per submitted feedback in this shape:
114
+
115
+ ```
116
+ ✓ feedback <id> — <target description> [analysis runtime: <id>]
117
+ ```
118
+
119
+ End with a one-line note:
120
+
121
+ > "Regeneration runs in the background. Re-run this test case later to use the updated script."
122
+
123
+ If any pieces failed, list them under a `Failed:` header with the error.
124
+
125
+ ## Non-negotiables
126
+
127
+ - Always render the script (step 2) before collecting feedback.
128
+ - One create call per feedback piece — never concatenate paragraphs across targets.
129
+ - Convert step numbers from 1-based (UI) to 0-based (wire) at submit time.
130
+ - 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.
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: muggle-pr-followup
3
+ description: Generic per-PR follow-up loop. One polling tick per dispatch. Watches one PR for new submitted reviews; when an actionable review lands, invokes the caller's implementation cycle (build/test/walkthrough/push handler the caller declares), then resumes polling. Use as `/loop 1m /muggle:muggle-pr-followup <session-slug> <pr-number>`. Caller-agnostic — `muggle-do` is the first caller but not the last.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # Muggle PR Follow-up
8
+
9
+ > Telemetry first step: see [`_shared/telemetry-emit.md`](../_shared/telemetry-emit.md). Use `skillName: "muggle-pr-followup"`.
10
+
11
+ A generic loop that babysits one open PR until it's merged or closed. Polls for submitted reviews; on an actionable review, dispatches the caller's implementation cycle to re-build, re-test, refresh the walkthrough, and push.
12
+
13
+ **Per-PR isolation.** One dispatch per PR, not per session. Multi-PR work runs N independent loops.
14
+
15
+ ## Input
16
+
17
+ `$ARGUMENTS = <session-slug> <pr-number>`. The session-slug is the directory basename under `.muggle-<caller>/sessions/` (e.g. `.muggle-do/sessions/`) that this loop reads its state from. The pr-number identifies which PR in that session's manifest this loop watches.
18
+
19
+ - Empty / `help` / `?` → list active `(slug, pr-number)` pairs across known callers, exit.
20
+ - One argument → ambiguous; list PRs under that slug, exit.
21
+ - Two arguments → resolve and run one tick.
22
+
23
+ ## Contract
24
+
25
+ The per-tick contract — termination check, allow-list resolution, review polling, classify, cycle dispatch, escalation, telemetry — lives in [`contract.md`](contract.md). Read it before driving a tick.
26
+
27
+ ## Caller-supplied implementation cycle
28
+
29
+ The skill itself is caller-agnostic. When an actionable review lands, it invokes the **implementation cycle** declared by the caller in the session's `cycle.json`:
30
+
31
+ ```json
32
+ {
33
+ "cycleName": "muggle-do dev cycle",
34
+ "steps": [
35
+ { "stage": 3, "file": "../do/build.md" },
36
+ { "stage": 4, "file": "../do/impact-analysis.md" },
37
+ { "stage": 5, "file": "../do/unit-tests.md" },
38
+ { "stage": 6, "file": "../do/e2e-acceptance.md" },
39
+ { "name": "post-walkthrough", "skill": "muggle-pr-visual-walkthrough", "mode": "A" }
40
+ ],
41
+ "pushHandler": "git push origin <branch>"
42
+ }
43
+ ```
44
+
45
+ The cycle's job: read the amended `requirements.md`, run each declared step, push to the existing branch. The cycle returns one of `pushed | escalated | failed`. The skill doesn't care what's inside the steps — it just iterates them, captures the outcome, and writes a reply summary referencing the new SHA.
46
+
47
+ Callers without a `cycle.json` are rejected with `no cycle declared — caller must seed cycle.json at dispatch time`.
48
+
49
+ ## Subagent dispatch (optional)
50
+
51
+ A caller may declare `"useSubagent": true` in `cycle.json`. When set, the implementation cycle runs as a separate Claude subagent rather than inline in the loop's tick — gives stronger isolation per PR but adds overhead per cycle. Default is inline (which is itself isolated per-tick via `/loop`).
52
+
53
+ ## Design adjustment escalation
54
+
55
+ When the implementation cycle reports back that the review requires not just code change but a **design adjustment** beyond what the current requirements support (e.g. the build stage discovers the requested change conflicts with a load-bearing assumption), the cycle returns `failed: design-adjustment`. The loop treats this like an ambiguous escalation but with a different terminal message that points at the design conflict and asks the user to decide.
56
+
57
+ ## Why a separate skill (and not e.g. inside the caller's own skill folder)
58
+
59
+ `/loop` dispatches via slash command; slash commands resolve to top-level skills under `plugin/skills/`. A per-tick loop driven by `/loop` therefore has to live as a top-level skill. Putting the loop's content directly inside a caller-specific folder would make `/loop`-dispatch impossible (or fragile via shell-only entry points). Keeping the loop generic and caller-agnostic is what lets `/loop` dispatch into it cleanly.