@muggleai/works 5.31.0-staging.275 → 5.31.0-staging.277
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.
- package/.claude-plugin/marketplace.json +1 -1
- package/README.md +4 -3
- package/dist/{chunk-HK7XCCNT.js → chunk-FVG7CYB7.js} +2 -2
- package/dist/{chunk-7J7DS4SA.js → chunk-NTEBYUCA.js} +1 -1
- package/dist/cli.js +2 -2
- package/dist/index.js +2 -2
- package/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/.codex-mcp.json +1 -1
- package/dist/plugin/.codex-plugin/plugin.json +1 -1
- package/dist/plugin/.cursor-plugin/plugin.json +1 -1
- package/dist/plugin/.mcp.json +1 -1
- package/dist/plugin/scripts/guardrails.mjs +5 -3
- package/dist/plugin/skills/do/background-e2e.md +3 -3
- package/dist/plugin/skills/do/build.md +1 -1
- package/dist/plugin/skills/do/e2e-acceptance.md +3 -2
- package/dist/plugin/skills/do/input-routing.md +1 -1
- package/dist/plugin/skills/do/open-prs/forward.md +126 -102
- package/dist/plugin/skills/do/open-prs.md +2 -2
- package/dist/plugin/skills/do/unit-tests.md +1 -1
- package/dist/plugin/skills/do/wave-e2e.md +14 -8
- package/dist/plugin/skills/muggle-do/SKILL.md +13 -6
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoRouteBuildToMuggleDo.md +1 -1
- package/dist/release-manifest.json +3 -3
- package/dist/{src-QA7TWQ2M.js → src-LYOBYPFZ.js} +1 -1
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-mcp.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/.mcp.json +1 -1
- package/plugin/scripts/guardrails.mjs +5 -3
- package/plugin/skills/do/background-e2e.md +3 -3
- package/plugin/skills/do/build.md +1 -1
- package/plugin/skills/do/e2e-acceptance.md +3 -2
- package/plugin/skills/do/input-routing.md +1 -1
- package/plugin/skills/do/open-prs/forward.md +126 -102
- package/plugin/skills/do/open-prs.md +2 -2
- package/plugin/skills/do/unit-tests.md +1 -1
- package/plugin/skills/do/wave-e2e.md +14 -8
- package/plugin/skills/muggle-do/SKILL.md +13 -6
- package/plugin/skills/muggle-preferences/preference-gates/autoRouteBuildToMuggleDo.md +1 -1
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"name": "muggleai",
|
|
10
10
|
"source": "./plugin",
|
|
11
11
|
"description": "Real-browser E2E acceptance for your coding agent: test the flows you changed and open the PR with screenshots. Built for flows other tools can't reach: managed test identities with live inboxes (magic links, email OTP and 2FA, verification mail, password resets), an encrypted secret store for login and test credentials, and a test graph that runs prerequisite flows first. Plain-English tests become replayable scripts on localhost or preview URLs.",
|
|
12
|
-
"version": "5.31.0-staging.
|
|
12
|
+
"version": "5.31.0-staging.277"
|
|
13
13
|
}
|
|
14
14
|
]
|
|
15
15
|
}
|
package/README.md
CHANGED
|
@@ -40,12 +40,13 @@ Works in Claude Code, Cursor, Codex, Windsurf, and any MCP client. Powered by [M
|
|
|
40
40
|
| 3 | Build | Delegates real design surface to a design → plan → subagent build, then commits (signed) | Conventional commits |
|
|
41
41
|
| 4 | Impact analysis | Maps the diff to the user flows it can break | Affected-flow list |
|
|
42
42
|
| 5 | Unit tests | Runs the suite authored in stage 3 | Exit code |
|
|
43
|
-
|
|
|
44
|
-
|
|
|
43
|
+
| 5.5 | Pull request | Opens the PR/MR before the browser run, its walkthrough check red until stage 7 | PR URL |
|
|
44
|
+
| 6 | Acceptance | Drives a real browser through the affected flows, its progress showing on the PR | Verdict + `runId` + per-step screenshots |
|
|
45
|
+
| 7 | Walkthrough | Settles the PR's walkthrough comment with the run's evidence | Walkthrough comment |
|
|
45
46
|
| 7.5 | Repair | Investigates and fixes acceptance failures, up to 3 iterations | Repair log |
|
|
46
47
|
| 8 | Watcher | Polls reviews, CI, and base-branch drift; re-enters the cycle on each | `followup.log` |
|
|
47
48
|
|
|
48
|
-
Stage
|
|
49
|
+
Stage 5.5 refuses to open the PR until build and unit tests meet the Definition of Done, and stage 7 refuses to settle its walkthrough without an E2E verdict. Stage 8 is dispatched only once stage 7.5 clears — a cycle with unrepaired failures never reaches a watcher.
|
|
49
50
|
|
|
50
51
|
---
|
|
51
52
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __export, getLogger, TelemetryEnvironment, getConfig, createChildLogger, buildElectronAppReleaseAssetUrl, getActiveRuntimeTarget, getAuthService, hasApiKey, getElectronAppVersion, getElectronAppDir, getPlatformKey, reconcileProjectPreferences, getDataDir2, PREFERENCES_FILE_NAME, isFirstRun, writePreferences, DEFAULT_PREFERENCES, isElectronAppInstalled, getElectronAppChecksums, getChecksumForPlatform, getElectronAppSignedFromVersion, getReleaseSignerIdentityUri, verifyFileChecksum, resolveElectronAppExecutablePath, calculateFileChecksum, initTelemetry, Surface, ServiceName, track, EventName, getQaTools, getLocalQaTools, performLogout, assertDeviceCodeClientProvisioned, performLogin, getActiveElectronAppReleaseStream, buildToolInputJsonSchema, toolRequiresAuth, getCallerCredentials, parseElectronAppDirName, getElectronAppReleaseTagPrefix, hasShownDisclosure, markDisclosureShown, getBundledElectronAppVersion, getElectronAppVersionSource, getCredentialsFilePath, ElectronAppReleaseStream, buildElectronAppChecksumsUrl, __require, getDisclosureCopy, buildOnboardingPlan, applyOnboardingAnswers, needsOnboarding, buildLlmSourcePlan, describeLlmSourceStatus, resolveLlmSourceStatus, readRunView, RunViewError, renderRunViewText, writeRunViewHtml, openBrowserUrl, evaluateCheckoutFreshness, runGitCommand, BLOCKING_FRESHNESS_VERDICTS, claimServiceStack, BUSY_EXIT_CODE, checkServiceStack, releaseServiceStack, readServiceStackStatus, resolvePreferences, OnboardingBlanketChoice, PreferenceKey, LlmSource, applyLlmSourceSelection, describeStackMismatch, getDataDir, DEFAULT_LOCAL_LLM_BASE_URL, isValidLocalBaseUrl, local_exports } from './chunk-
|
|
1
|
+
import { __export, getLogger, TelemetryEnvironment, getConfig, createChildLogger, buildElectronAppReleaseAssetUrl, getActiveRuntimeTarget, getAuthService, hasApiKey, getElectronAppVersion, getElectronAppDir, getPlatformKey, reconcileProjectPreferences, getDataDir2, PREFERENCES_FILE_NAME, isFirstRun, writePreferences, DEFAULT_PREFERENCES, isElectronAppInstalled, getElectronAppChecksums, getChecksumForPlatform, getElectronAppSignedFromVersion, getReleaseSignerIdentityUri, verifyFileChecksum, resolveElectronAppExecutablePath, calculateFileChecksum, initTelemetry, Surface, ServiceName, track, EventName, getQaTools, getLocalQaTools, performLogout, assertDeviceCodeClientProvisioned, performLogin, getActiveElectronAppReleaseStream, buildToolInputJsonSchema, toolRequiresAuth, getCallerCredentials, parseElectronAppDirName, getElectronAppReleaseTagPrefix, hasShownDisclosure, markDisclosureShown, getBundledElectronAppVersion, getElectronAppVersionSource, getCredentialsFilePath, ElectronAppReleaseStream, buildElectronAppChecksumsUrl, __require, getDisclosureCopy, buildOnboardingPlan, applyOnboardingAnswers, needsOnboarding, buildLlmSourcePlan, describeLlmSourceStatus, resolveLlmSourceStatus, readRunView, RunViewError, renderRunViewText, writeRunViewHtml, openBrowserUrl, evaluateCheckoutFreshness, runGitCommand, BLOCKING_FRESHNESS_VERDICTS, claimServiceStack, BUSY_EXIT_CODE, checkServiceStack, releaseServiceStack, readServiceStackStatus, resolvePreferences, OnboardingBlanketChoice, PreferenceKey, LlmSource, applyLlmSourceSelection, describeStackMismatch, getDataDir, DEFAULT_LOCAL_LLM_BASE_URL, isValidLocalBaseUrl, local_exports } from './chunk-NTEBYUCA.js';
|
|
2
2
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
3
|
import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
4
4
|
import { v4 } from 'uuid';
|
|
@@ -1165,7 +1165,7 @@ async function resolveGsScreenshotUrls(report, opts) {
|
|
|
1165
1165
|
if (gsUrls.length === 0) {
|
|
1166
1166
|
return report;
|
|
1167
1167
|
}
|
|
1168
|
-
const mcps = await import('./src-
|
|
1168
|
+
const mcps = await import('./src-LYOBYPFZ.js');
|
|
1169
1169
|
const credentials = await mcps.getCallerCredentialsAsync();
|
|
1170
1170
|
if (!credentials.bearerToken && !credentials.apiKey) {
|
|
1171
1171
|
stderrWrite(
|
|
@@ -2858,7 +2858,7 @@ var PREFERENCES_SCHEMA = {
|
|
|
2858
2858
|
description: "When a prior session left an E2E validation context for this working tree, reuse it instead of re-asking the validation questions"
|
|
2859
2859
|
},
|
|
2860
2860
|
["autoRouteBuildToMuggleDo" /* AutoRouteBuildToMuggleDo */]: {
|
|
2861
|
-
description: "When a prompt looks like a build/implement/fix request, route it through the /muggle-do pipeline (requirements \u2192 build \u2192 impact \u2192 tests \u2192
|
|
2861
|
+
description: "When a prompt looks like a build/implement/fix request, route it through the /muggle-do pipeline (requirements \u2192 build \u2192 impact \u2192 tests \u2192 PR \u2192 E2E \u2192 watcher)"
|
|
2862
2862
|
},
|
|
2863
2863
|
["autoWatchPR" /* AutoWatchPR */]: {
|
|
2864
2864
|
description: "After a test run opens a PR, start a muggle-pr-followup watcher that polls for new reviews and hands them to /muggle-do"
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { src_exports as commands, createUnifiedMcpServer, server_exports as server } from './chunk-
|
|
2
|
-
export { createChildLogger, e2e_exports as e2e, getConfig, getLocalQaTools, getLogger, getQaTools, local_exports as localQa, mcp_exports as mcp, e2e_exports as qa, src_exports as shared } from './chunk-
|
|
1
|
+
export { src_exports as commands, createUnifiedMcpServer, server_exports as server } from './chunk-FVG7CYB7.js';
|
|
2
|
+
export { createChildLogger, e2e_exports as e2e, getConfig, getLocalQaTools, getLogger, getQaTools, local_exports as localQa, mcp_exports as mcp, e2e_exports as qa, src_exports as shared } from './chunk-NTEBYUCA.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "muggle",
|
|
3
3
|
"description": "Real-browser E2E acceptance for your coding agent: test the flows you changed and open the PR with screenshots. Built for flows other tools can't reach: managed test identities with live inboxes (magic links, email OTP and 2FA, verification mail, password resets), an encrypted secret store for login and test credentials, and a test graph that runs prerequisite flows first. Plain-English tests become replayable scripts on localhost or preview URLs.",
|
|
4
|
-
"version": "5.31.0-staging.
|
|
4
|
+
"version": "5.31.0-staging.277",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Muggle AI",
|
|
7
7
|
"email": "support@muggle-ai.com"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "muggle",
|
|
3
|
-
"version": "5.31.0-staging.
|
|
3
|
+
"version": "5.31.0-staging.277",
|
|
4
4
|
"description": "Real-browser E2E acceptance for your coding agent: test the flows you changed and open the PR with screenshots. Built for flows other tools can't reach: managed test identities with live inboxes (magic links, email OTP and 2FA, verification mail, password resets), an encrypted secret store for login and test credentials, and a test graph that runs prerequisite flows first. Plain-English tests become replayable scripts on localhost or preview URLs.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Muggle AI",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "muggle",
|
|
3
3
|
"displayName": "Muggle AI",
|
|
4
4
|
"description": "Real-browser E2E acceptance for your coding agent: test the flows you changed and open the PR with screenshots. Built for flows other tools can't reach: managed test identities with live inboxes (magic links, email OTP and 2FA, verification mail, password resets), an encrypted secret store for login and test credentials, and a test graph that runs prerequisite flows first. Plain-English tests become replayable scripts on localhost or preview URLs.",
|
|
5
|
-
"version": "5.31.0-staging.
|
|
5
|
+
"version": "5.31.0-staging.277",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Muggle AI",
|
|
8
8
|
"email": "support@muggle-ai.com"
|
package/dist/plugin/.mcp.json
CHANGED
|
@@ -137,6 +137,7 @@ var RECONCILE_REPLAY_TIMEOUT_MS = 15e3;
|
|
|
137
137
|
var GUARDRAIL_SUBCOMMAND_ASSIGNMENT = /^GUARDRAIL_SUBCOMMAND="([\w-]+)"/m;
|
|
138
138
|
var HOOK_COMMAND_SCRIPTS = /^set -- ([^;]+);/;
|
|
139
139
|
var GUARDRAIL_DISPATCH_SCRIPT = "guardrail-dispatch.sh";
|
|
140
|
+
var MUGGLE_DO_STAGES_AFTER_BUILD = "impact \u2192 unit tests \u2192 PR \u2192 E2E \u2192 watcher";
|
|
140
141
|
|
|
141
142
|
// src/guardrails/store/fileLock.ts
|
|
142
143
|
function isProcessAlive(pid) {
|
|
@@ -3305,7 +3306,8 @@ function watchGate() {
|
|
|
3305
3306
|
if (state.watchSkipped !== true && prsAwaitingStateScan(unwatchedPrUrls, state, prStateScan).length > 0) {
|
|
3306
3307
|
startBackgroundJob("scan-watch-pr-states" /* ScanWatchPrStates */, [sessionId]);
|
|
3307
3308
|
}
|
|
3308
|
-
const
|
|
3309
|
+
const owedWatchPrUrls = resolveOwedWatchPrs(withoutDelegatedPrs(unwatchedPrUrls, state, Date.now()), state, prStateScan);
|
|
3310
|
+
const decision = watchGateDecision(state, owedWatchPrUrls);
|
|
3309
3311
|
if (decision.action === "release" /* Release */) return releaseGate("watchReleased");
|
|
3310
3312
|
if (decision.action === "none" /* None */) return "{}";
|
|
3311
3313
|
recordGateBlock("watchBlockCount", decision.blockCount);
|
|
@@ -3359,7 +3361,7 @@ function buildFollowthroughGate() {
|
|
|
3359
3361
|
if (decision.action === "release" /* Release */) return releaseGate("buildSkipped");
|
|
3360
3362
|
if (decision.action === "none" /* None */) return "{}";
|
|
3361
3363
|
recordGateBlock("buildBlockCount", decision.blockCount);
|
|
3362
|
-
const reason = decision.blockCount === 1 ? `Do not end the turn yet. This session took a build/implement/fix request but no PR was opened. A root cause written into the transcript ships nothing \u2014 once the session ends it is gone, and the watcher gate never fires because it only looks at PRs that exist. Carry the work to a PR via ${muggleSkill("/muggle-do")}, which runs requirements \u2192 build \u2192
|
|
3364
|
+
const reason = decision.blockCount === 1 ? `Do not end the turn yet. This session took a build/implement/fix request but no PR was opened. A root cause written into the transcript ships nothing \u2014 once the session ends it is gone, and the watcher gate never fires because it only looks at PRs that exist. Carry the work to a PR via ${muggleSkill("/muggle-do")}, which runs requirements \u2192 build \u2192 ${MUGGLE_DO_STAGES_AFTER_BUILD}. If no PR is owed here (the user changed their mind, the fix landed in another repo, the answer was advice rather than a change), tell the user why and run \`echo "MUGGLE_BUILD_SKIP: <reason>"\` \u2014 that records the skip and keeps this gate quiet for the rest of the session.` : `Build request still unanswered \u2014 no PR opened (reminder ${decision.blockCount}/${MAX_BUILD_BLOCKS}): carry it to a PR via ${muggleSkill("/muggle-do")}, or record a legitimate skip via \`echo "MUGGLE_BUILD_SKIP: <reason>"\`.`;
|
|
3363
3365
|
return blockStop(reason, host);
|
|
3364
3366
|
}
|
|
3365
3367
|
function walkthroughGate() {
|
|
@@ -3482,7 +3484,7 @@ function buildRouter() {
|
|
|
3482
3484
|
if (readState(sessionId).buildIntentRouted) return "{}";
|
|
3483
3485
|
commitStateMutation(sessionId, { kind: "fields" /* Fields */, fields: { buildIntentRouted: true } });
|
|
3484
3486
|
if (isMuggleDoInvoked) return "{}";
|
|
3485
|
-
const ctx = `This looks like a build/implement/fix request. Per the autoRouteBuildToMuggleDo preference, route it through ${muggleSkill("/muggle-do")} \u2014 which runs requirements \u2192 build (delegated to superpowers' design\u2192plan\u2192review) \u2192
|
|
3487
|
+
const ctx = `This looks like a build/implement/fix request. Per the autoRouteBuildToMuggleDo preference, route it through ${muggleSkill("/muggle-do")} \u2014 which runs requirements \u2192 build (delegated to superpowers' design\u2192plan\u2192review) \u2192 ${MUGGLE_DO_STAGES_AFTER_BUILD}. If autoRouteBuildToMuggleDo=always, enter that flow; if =ask, offer it; if =never, proceed normally.`;
|
|
3486
3488
|
return envelope("UserPromptSubmit", ctx, host);
|
|
3487
3489
|
}
|
|
3488
3490
|
function closingAssistantText() {
|
|
@@ -34,7 +34,7 @@ The agent knows only its brief. Pass every value itself, never a pointer to the
|
|
|
34
34
|
|
|
35
35
|
- The change's slug and absolute session directory.
|
|
36
36
|
- Repo, worktree path, branch, base branch, and the head SHA under test — for a wave, one entry per member, from its `Wave members` block.
|
|
37
|
-
- The PR URL
|
|
37
|
+
- The change's PR URL — for a wave, every member's. Stage 5.5 opened it before this run; only an `autoCreatePR` skip leaves none. Muggle reads PR URLs from the brief to know which PR's walkthrough is waiting on this run, so leave none out and add none that belong to another change.
|
|
38
38
|
- `Validation`, `localUrl`, `projectId`, and test-credential status from `state.md`.
|
|
39
39
|
- The `e2eScope` from impact analysis, verbatim; a Stage 7.5 re-run passes only its affected test cases.
|
|
40
40
|
- The acceptance criteria from `requirements.md`.
|
|
@@ -63,7 +63,7 @@ On the agent's completion notification, the main session:
|
|
|
63
63
|
|
|
64
64
|
1. **Checks freshness.** Every `Tested:` line must name its branch's current head. A branch that moved since dispatch — any member's, for a wave — makes the report stale: queue the change again and post nothing.
|
|
65
65
|
2. **Records it** — `E2E dispatch: reported — …` in `state.md`.
|
|
66
|
-
3. **Continues that change from Stage 7**, in its worktree. [`open-prs/forward.md`](open-prs/forward.md)
|
|
66
|
+
3. **Continues that change from Stage 7**, in its worktree. [`open-prs/forward.md`](open-prs/forward.md) settles the walkthrough of the PR Stage 5.5 opened with this report — every member's PR for a wave, per [`wave-e2e.md`](wave-e2e.md) Stage 7 — through Mode A with its number and repo passed explicitly, never from the current branch, since the session's cwd may be another change's worktree.
|
|
67
67
|
4. **Runs Stage 7.5** inline. A repair pass's re-run returns to this lane, behind any local run in flight.
|
|
68
68
|
5. **Arms the change's watcher** once 7.5 clears (Stage 8).
|
|
69
69
|
6. **Dispatches the next queued change.**
|
|
@@ -76,7 +76,7 @@ A session that fixed bugs by hand and opened each PR itself follows the same lan
|
|
|
76
76
|
|
|
77
77
|
## Enforcement
|
|
78
78
|
|
|
79
|
-
- Dispatching a background acceptance-tester holds the E2E and debug-path Stop gates off for a bounded window, and for that window the walkthrough
|
|
79
|
+
- Dispatching a background acceptance-tester holds the E2E and debug-path Stop gates off for a bounded window, and for that window the walkthrough and watch gates set aside the PRs its brief names — the session is never steered into a second browser run alongside the agent's, nor into arming a watch on a PR whose run has not come back.
|
|
80
80
|
- A walkthrough posted to one PR settles that PR only; every other PR the session opened is still checked for its own.
|
|
81
81
|
- A skip declaration settles only the PRs of the change it is declared in — the working tree's repo and branch: the PRs opened for that branch and its branch's PR, never another change's, wherever the session's directory sat when a PR was opened.
|
|
82
82
|
- Every PR's walkthrough check stays red until its slot is settled, so a change whose run never came back cannot pass as tested.
|
|
@@ -33,7 +33,7 @@ For each affected repo:
|
|
|
33
33
|
|
|
34
34
|
## Delegation
|
|
35
35
|
|
|
36
|
-
For a non-trivial change — multiple files, real design surface, or anything you would otherwise brainstorm before coding — run the implementation through superpowers' design → plan → subagent-driven build, then return to this stage's Output. That is a runtime hand-off (an action), not a doc dependency; do not encode superpowers' internals here. Routing a build request into this pipeline (the `autoRouteBuildToMuggleDo` front-door guardrail) exists to combine superpowers' design rigor with this pipeline's impact analysis,
|
|
36
|
+
For a non-trivial change — multiple files, real design surface, or anything you would otherwise brainstorm before coding — run the implementation through superpowers' design → plan → subagent-driven build, then return to this stage's Output. That is a runtime hand-off (an action), not a doc dependency; do not encode superpowers' internals here. Routing a build request into this pipeline (the `autoRouteBuildToMuggleDo` front-door guardrail) exists to combine superpowers' design rigor with this pipeline's impact analysis, PR, E2E, and watcher — neither delivers both alone.
|
|
37
37
|
|
|
38
38
|
## Output
|
|
39
39
|
|
|
@@ -50,6 +50,7 @@ You receive everything from `state.md` already — pre-flight resolved it:
|
|
|
50
50
|
- The list of changed repos, files, and a summary of changes
|
|
51
51
|
- The requirements goal
|
|
52
52
|
- The `e2eScope` from impact analysis — the impacted, retired, and new use cases and test cases this stage runs
|
|
53
|
+
- In a forward run, the PR Stage 5.5 opened from the working tree — the run's [PR progress](../_shared/dev-loop/run.md#pr-progress) shows on it, and Stage 7 settles its walkthrough
|
|
53
54
|
|
|
54
55
|
## Your Job
|
|
55
56
|
|
|
@@ -79,9 +80,9 @@ A scope with deliverable checks and no browser case runs none of these and goes
|
|
|
79
80
|
2. **Auth** — `muggle-remote-auth-status` must be `authenticated`; else escalate.
|
|
80
81
|
3. **Identity tenant/domain match** — if test credentials were marked `existing`, confirm the repo's configured identity tenant/domain matches the recorded tenant/domain. Mismatch → halt.
|
|
81
82
|
|
|
82
|
-
**Readiness halt.** The cycle planned a browser run and still owes it, so an app that cannot be brought up halts the cycle and is never a `SKIPPED` exit: declare no skip code, write no waiver, run nothing downstream. Report the URL probed, what `muggle-test-prepare` tried (the start command and how it failed), and that
|
|
83
|
+
**Readiness halt.** The cycle planned a browser run and still owes it, so an app that cannot be brought up halts the cycle and is never a `SKIPPED` exit: declare no skip code, write no waiver, run nothing downstream. Report the URL probed, what `muggle-test-prepare` tried (the start command and how it failed), and that the PR's walkthrough is unsettled; then end the turn and wait for the user. This holds for unattended runs and for a request that asked for the PR. A forward cycle leaves its PR open with the walkthrough unsettled, so its walkthrough check stays red: it posts no walkthrough, runs no Stage 7.5 and arms no watcher. Nothing more is owed that PR until the app answers, so run `echo "MUGGLE_WALKTHROUGH_SKIP: readiness halt — <PR URL>"` and `echo "MUGGLE_WATCH_SKIP: readiness halt — <PR URL>"`, which keep the Stop gates from pressing for a walkthrough or watch the halt withholds. A watcher cycle pushes nothing and escalates through its own path, which keeps the watcher running. A run that failed because the app never answered (connection refused, page never loaded) returns to item 1, and still down is this halt. A Stop-hook reminder that E2E is still owed does not lift it.
|
|
83
84
|
|
|
84
|
-
Only the app not answering is this halt. A run the runner itself lost while readiness passes — an Electron or MCP crash, a Studio abort before the first step — is a failing run, however often it repeats: record it in the Failed block and go on to Stage 7, which
|
|
85
|
+
Only the app not answering is this halt. A run the runner itself lost while readiness passes — an Electron or MCP crash, a Studio abort before the first step — is a failing run, however often it repeats: record it in the Failed block and go on to Stage 7, which retitles the PR `[E2E FAILING]` for Stage 7.5 to classify.
|
|
85
86
|
|
|
86
87
|
### Step 1: Authentication already verified
|
|
87
88
|
|
|
@@ -6,7 +6,7 @@ How `/muggle-do` resolves `$ARGUMENTS` to a mode. Modes 1–4 are programmatic
|
|
|
6
6
|
2. **Fix-CI** — a PR/MR URL **and** a `fix ci` / `fix-ci` directive with failing check names (no review/discussion ids) → [`fix-ci.md`](fix-ci.md).
|
|
7
7
|
3. **Rebase** — a PR/MR URL **and** a `rebase` directive (or legacy `resolve conflicts` / `resolve-conflicts`; no review/discussion ids, no check names) → [`resolve-conflicts.md`](resolve-conflicts.md). Rebases the branch onto its base whether it's merely behind or actually conflicting.
|
|
8
8
|
4. **Post-merge cleanup** — a `cleanup` token and `slug=<slug>` (no PR URL, no review ids), optionally `state=<merged|closed>` (default `merged`) → [`cleanup.md`](cleanup.md).
|
|
9
|
-
5. **Empty / `help` / `menu` / `?`** → menu + session selector.
|
|
9
|
+
5. **Empty / `help` / `menu` / `?`** → menu + session selector, answered from this file alone: open no stage file. The menu offers describing a task to start the forward pipeline, plus `/muggle-status`, `/muggle-repair`, and `/muggle-upgrade`. The session selector lists each directory under `~/.muggle-ai/muggle-do/sessions/` with the PRs and states in its `prs.json`; picking one resumes that session.
|
|
10
10
|
6. **Task automation** (perform an action on a website) → `muggle:muggle-browser-task`.
|
|
11
11
|
7. **Otherwise** → forward pipeline at Stage 1.
|
|
12
12
|
|
|
@@ -1,102 +1,126 @@
|
|
|
1
|
-
# Open PR — forward mode
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
##
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
1
|
+
# Open PR — forward mode
|
|
2
|
+
|
|
3
|
+
The forward pipeline's PR stages, which run on either side of Stage 6. **Stage 5.5** opens the change — a PR on GitHub (`gh pr create`) or an MR on GitLab (`glab mr create`), provider resolved in Step 5 — as soon as unit tests pass, before any browser run. **Stage 7** settles that run's result on it, then seeds session state and arms the first watch.
|
|
4
|
+
|
|
5
|
+
The PR goes up first because opening it needs nothing from the run: CI and reviewers start on the diff while E2E runs, and the run's [PR progress](../../_shared/dev-loop/run.md#pr-progress) fills the PR's walkthrough comment case by case. The walkthrough check stays red until Stage 7 settles that comment, so an open PR never passes as tested before its run lands.
|
|
6
|
+
|
|
7
|
+
## Turn preambles
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
**Stage 5.5 — Open PR** — pushing the branch and opening the PR before E2E.
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
**Stage 7 — Report on the PR** — settling the walkthrough with the E2E result.
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Inputs
|
|
18
|
+
|
|
19
|
+
- Per-repo: name, path, branch.
|
|
20
|
+
- Requirements: goal, acceptance criteria.
|
|
21
|
+
- The validation strategy from `state.md` — Stage 5.5 titles the PR from it, since no run has happened yet.
|
|
22
|
+
- Stage 7 only: the **optional** E2E acceptance report from Stage 6. Produced by [`../e2e-acceptance.md`](../e2e-acceptance.md) — inline, or returned by this change's background acceptance-tester ([`../background-e2e.md`](../background-e2e.md)); schema in [`../../muggle-pr-visual-walkthrough/SKILL.md`](../../muggle-pr-visual-walkthrough/SKILL.md). Only this change's own report: a sibling change's run never settles this PR.
|
|
23
|
+
|
|
24
|
+
## Wave cycles
|
|
25
|
+
|
|
26
|
+
`state.md` records `Wave: on` → follow the Stage 5.5 and Stage 7 ordering in [`../wave-e2e.md`](../wave-e2e.md): open every wave PR before Stage 6 starts, add the `## Wave` section to each body, give every member the same title prefix, and settle each PR's walkthrough with the same report (Mode A, PR number + repo passed explicitly). The per-repo steps below run with those changes.
|
|
27
|
+
|
|
28
|
+
## Stage 5.5 — open the PR
|
|
29
|
+
|
|
30
|
+
Per repo:
|
|
31
|
+
|
|
32
|
+
0. **`autoCreatePR` gate** — apply per [`../../muggle-preferences/preference-gates/autoCreatePR.md`](../../muggle-preferences/preference-gates/autoCreatePR.md), its explicit-request rule included. On skip, record the reason in `result.md` and move on; Stage 6 still runs.
|
|
33
|
+
|
|
34
|
+
1. **Sync with the base:** run [`../../_shared/sync-branch-with-base.md`](../../_shared/sync-branch-with-base.md) with `base` set to the PR target recorded in `state.md` — gated by [`autoRebase`](../../muggle-preferences/preference-gates/autoRebase.md), fires only when `behind > 0`. The branch is not on the remote yet, so the rebase lands without a force-push. Sync here rather than leaving it to Stage 6: a `unit-only` or `skip` run never reaches the E2E stage's sync at all, and on a run that does, the PR opens before that sync. If the sync escalates — conflicts under `autoResolveConflicts=never`, or a resolution that fails the verify-or-rollback gate — stop and report; never open a PR on a tree that did not verify.
|
|
35
|
+
|
|
36
|
+
1.5. **CI check:** GitHub repos only, gated by [`autoInstallCiWorkflow`](../../muggle-preferences/preference-gates/autoInstallCiWorkflow.md).
|
|
37
|
+
- **Tree lacks `.github/workflows/muggle-walkthrough.yml`** — on `always`, or `CI check: add` recorded by pre-flight, run `muggle ci-install` in the working tree and commit the workflow as `ci: add the Muggle E2E walkthrough check`, so it ships in this PR. On `never` or `CI check: skip`, leave CI alone.
|
|
38
|
+
- **Tree has it** — unless the gate resolves to `never`, run `muggle ci-install` without `--force`. It replaces only an unedited copy an earlier release wrote and leaves a current or edited one alone, so nothing needs asking. When it reports `Updated`, commit the file as `ci: update the Muggle E2E walkthrough check`.
|
|
39
|
+
|
|
40
|
+
2. **Push:** Execute per [`../../_shared/vcs/common/push-to-branch.md`](../../_shared/vcs/common/push-to-branch.md) — the tool-agnostic instruction for pushing commits (handles the signing gate and directs to provider-specific recipes).
|
|
41
|
+
|
|
42
|
+
3. **Title** (under 70 chars), from the validation strategy:
|
|
43
|
+
- `unit-only` → `[UNIT-ONLY] <goal>`
|
|
44
|
+
- `skip` → `[UNVERIFIED] <goal>`
|
|
45
|
+
- Otherwise → `<goal>`. Stage 7 adds `[E2E FAILING]` if the run fails.
|
|
46
|
+
|
|
47
|
+
The prefix goes on at creation: no later stage adds `[UNIT-ONLY]` or `[UNVERIFIED]`.
|
|
48
|
+
|
|
49
|
+
4. **Body** — assemble in order:
|
|
50
|
+
- `## Goal` — from requirements.
|
|
51
|
+
- `## Acceptance Criteria` — bulleted; omit if empty.
|
|
52
|
+
- `## Changes` — summary of what changed in this repo.
|
|
53
|
+
- `## Validation` — one line naming the strategy: `local-e2e — results in the walkthrough comment`, `unit-only`, or `skip — <reason>`. Stage 7 adds a report's **Deliverables** tables below it.
|
|
54
|
+
- The walkthrough does **not** go in the body. It settles the PR's designated walkthrough comment in Stage 7, so a rerun updates one comment instead of rewriting the description.
|
|
55
|
+
- **Signature** — write the assembled body to a file and sign it with `--command /muggle-do --mode editable` per [`../../_shared/vcs/post-signature.md`](../../_shared/vcs/post-signature.md). `editable` is the mode a description carries so later refreshes replace it instead of stacking.
|
|
56
|
+
|
|
57
|
+
5. **Create:** resolve the provider per [`../../_shared/vcs/detect-vcs.md`](../../_shared/vcs/detect-vcs.md).
|
|
58
|
+
- `github` → `gh pr create --title "<Step 3 title>" --body-file <signed-file> --head <branch>`, passing Step 3's title, prefix included, and the file signed in Step 4. Capture the PR URL and number.
|
|
59
|
+
- `gitlab` → open the change via [`../../_shared/vcs/gitlab/mr-create.md`](../../_shared/vcs/gitlab/mr-create.md): `glab mr create --source-branch <branch> --target-branch <base> --title "<Step 3 title>" --description "..."`. Capture the MR URL and iid.
|
|
60
|
+
|
|
61
|
+
A create that fails ends the cycle for that repo: report it under **Errors** and run no E2E for it, since the run would have no PR to settle.
|
|
62
|
+
|
|
63
|
+
## Stage 7 — report on the PR
|
|
64
|
+
|
|
65
|
+
Runs once Stage 6 has recorded this change's verdict; a Stage 6 readiness halt never reaches it. Per repo, using the provider resolved in Stage 5.5:
|
|
66
|
+
|
|
67
|
+
1. **Push the tested head.** Stage 6's readiness check syncs the worktree onto the latest base, so a base that moved after Stage 5.5 leaves HEAD — the commit the run tested — rebased past what the PR shows. When HEAD differs from the PR's head, push it per [`../../_shared/vcs/common/push-to-branch.md`](../../_shared/vcs/common/push-to-branch.md) with `git push --force-with-lease`, since the rebase rewrote commits the remote already has. Never sync again here: a rebase after the run would put a tree the run never tested under its walkthrough.
|
|
68
|
+
|
|
69
|
+
2. **Title:** a report with failures → retitle `[E2E FAILING] <goal>` per [`../../_shared/vcs/github/pr-edit.md`](../../_shared/vcs/github/pr-edit.md) (`gitlab`: [`../../_shared/vcs/gitlab/mr-edit.md`](../../_shared/vcs/gitlab/mr-edit.md)). Otherwise the Stage 5.5 title stands.
|
|
70
|
+
|
|
71
|
+
3. **Body:** a report with a **Deliverables** block → add its tables below `## Validation` per [`../../_shared/deliverable-categories.md`](../../_shared/deliverable-categories.md#evidence-on-the-pr), with the `--body-file` form of the same edit recipe. Delete the old signature block from the `<!-- muggle-works:signature -->` marker to the end and re-sign the body as Stage 5.5 Step 4 did, so it keeps exactly one signature.
|
|
72
|
+
|
|
73
|
+
4. **Settle the designated walkthrough comment.** Creating the PR reserved one comment for the walkthrough, marked `muggle-pr-walkthrough`; the run's PR progress fills it with per-case rows, and the PR's walkthrough check fails until it is settled.
|
|
74
|
+
- E2E report exists → fire [`postPRVisualWalkthrough`](../../muggle-preferences/preference-gates/postPRVisualWalkthrough.md); on skip, leave the comment to the gate's own skip record. Otherwise invoke [`../../muggle-pr-visual-walkthrough/SKILL.md`](../../muggle-pr-visual-walkthrough/SKILL.md) Mode A with the PR number and repo passed explicitly — it replaces the progress rows with the walkthrough in place. Explicit because a session carrying several changes may sit in another change's worktree, where the current branch's PR is the wrong one.
|
|
75
|
+
- No E2E report (validation was `unit-only` or `skip`), a `SKIPPED` report, or a report whose browser part was skipped (a `**Browser skip:**` line, or deliverable entries and no test cases) → the skip Stage 6 declared from this PR's worktree settles it. A background run returns its skip code instead of declaring it: declare it now, from this PR's worktree, with the same code — `echo "MUGGLE_E2E_SKIP: <CODE>: <detail>"`, codes per [`../e2e-acceptance.md`](../e2e-acceptance.md). An accepted code settles only the PRs of that worktree's change — the PRs opened from it and its checked-out branch's PR; a free-text reason is rejected and leaves it unsettled. A PR whose title says `[UNIT-ONLY]` still owes reviewers the why. The write runs detached, so confirm it landed: the walkthrough Stop gate holds the turn while the PR still shows the placeholder, and its block names a foreground command that prints `{"settled":true}` once the PR reads back the skip — run it, never a hand-written PATCH.
|
|
76
|
+
|
|
77
|
+
5. **Overflow comment:** if the walkthrough skill returned a non-null `comment`, post it once — `github` per [`../../_shared/vcs/github/top-level-comment.md`](../../_shared/vcs/github/top-level-comment.md), `gitlab` per [`../../_shared/vcs/gitlab/mr-note.md`](../../_shared/vcs/gitlab/mr-note.md). End the posted body with the signature line (command `/muggle-do`) per [`../../_shared/vcs/post-signature.md`](../../_shared/vcs/post-signature.md). Never post when `comment` is `null`.
|
|
78
|
+
|
|
79
|
+
## Stage 7.5 gate
|
|
80
|
+
|
|
81
|
+
The E2E repair loop ([`../e2e-repair.md`](../e2e-repair.md)) runs once Stage 7 has settled the walkthrough, and before the handoff below. Proceed only on its `green`, `waived`, or `iteration-cap` clearance — handing a red run to a watcher puts it in front of reviewers with nobody looking at the failures. When Stage 6 recorded `PASS` or `SKIPPED` the loop clears in its own Step 0 at no cost, so there is never a reason to skip it.
|
|
82
|
+
|
|
83
|
+
## Stage 8 handoff
|
|
84
|
+
|
|
85
|
+
After every repo is processed and Stage 7.5 has cleared, build the watcher manifest and arm one watch per opened PR. The arms are the LAST action this stage takes.
|
|
86
|
+
|
|
87
|
+
Write `~/.muggle-ai/muggle-do/sessions/<slug>/prs.json` per [`../../muggle-pr-followup/state-schemas.md`](../../muggle-pr-followup/state-schemas.md#prsjson):
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
[{ "repo": "owner/repo", "number": 142, "url": "...", "head_sha": "...", "state": "open" }]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Seed `~/.muggle-ai/muggle-do/sessions/<slug>/last_seen.json` per [`../../muggle-pr-followup/state-schemas.md`](../../muggle-pr-followup/state-schemas.md#last_seenjson) — empty-watermark shape with `pushed_shas: []`. Forward mode never has prior reviews to skip, so `lastBodyReviewId: 0`.
|
|
94
|
+
|
|
95
|
+
**Do not** seed `cycle.json` or `requirements.md`. The watcher is a dumb pipe; `/muggle-do` reads reviews off GitHub.
|
|
96
|
+
|
|
97
|
+
For each entry in `prs.json`, arm its watch per [`../../muggle-pr-followup/arm-watcher.md`](../../muggle-pr-followup/arm-watcher.md) — the same procedure [`../respawn-watcher.md`](../respawn-watcher.md) settles every later watch with: one drain tick, the watermark seeded from it, then one persistent labeled monitor. Never a recurring `/loop` cron — every cron fire is a model turn, while the monitor polls token-free. The PR counts as watched only once that monitor's loop is running; a seeded slot alone is not a watch.
|
|
98
|
+
|
|
99
|
+
If `prs.json` is empty, **do not arm** — record the reason in `result.md` and exit.
|
|
100
|
+
|
|
101
|
+
## Invariants
|
|
102
|
+
|
|
103
|
+
- Branch synced with its base before the push, never after; PR opened per non-skipped repo before Stage 6 starts; the tested head is the PR's head before its walkthrough settles; designated walkthrough comment settled via Mode A, or its skip reason stated; `prs.json`+`last_seen.json` seeded (no `cycle.json`, no `requirements.md`); Stage 7.5 cleared before arming; arming per `arm-watcher.md` is the last action.
|
|
104
|
+
|
|
105
|
+
## Output
|
|
106
|
+
|
|
107
|
+
**Synced with base:** repo → `rebased onto <base> (<n> behind)` | `already up to date` | `skipped (autoRebase)`
|
|
108
|
+
**PRs Created:** repo → URL
|
|
109
|
+
**Skipped:** repo → reason (when `autoCreatePR` short-circuited)
|
|
110
|
+
**Tested head:** repo → `already the PR head` | `force-pushed <short-sha> (Stage 6 synced onto a moved base)`
|
|
111
|
+
**Overflow comments posted:** repo → PR #
|
|
112
|
+
**Stage 7.5:** `green` | `waived — <reason>` | `iteration-cap`
|
|
113
|
+
**Stage 8:** `Watching <N> PR(s) — one watch loop per PR, armed per arm-watcher.md` | `No PRs to watch — stage 8 not armed`
|
|
114
|
+
**Errors:** repo → message
|
|
115
|
+
|
|
116
|
+
## Post-merge cleanup
|
|
117
|
+
|
|
118
|
+
Gated by `autoCleanup`. Triggered when the watcher's terminal tick observes the merge and dispatches `/muggle-do`'s cleanup directive ([`../cleanup.md`](../cleanup.md)) — never from this stage. See [`../../_shared/post-merge-cleanup.md`](../../_shared/post-merge-cleanup.md).
|
|
119
|
+
|
|
120
|
+
Append one short reminder tied to the gate value:
|
|
121
|
+
|
|
122
|
+
- `always` → `Once merged, I'll run the cleanup sequence automatically.`
|
|
123
|
+
- `never` → omit.
|
|
124
|
+
- `ask` / absent → `Once merged, I'll check with you about cleanup.`
|
|
125
|
+
|
|
126
|
+
Regardless of the gate, also append: `Once it's merged or closed, I'll move to the next plan item — or ask where to go next if there's no plan.`
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# Create-or-Update PR (
|
|
1
|
+
# Create-or-Update PR (Stages 5.5 and 7)
|
|
2
2
|
|
|
3
3
|
Two modes, set by the `/muggle-do` invocation. Each consumer loads only its mode's file.
|
|
4
4
|
|
|
5
5
|
| Mode | When | Procedure |
|
|
6
6
|
| :--- | :--- | :-------- |
|
|
7
|
-
| Forward |
|
|
7
|
+
| Forward | A fresh feature, called by `/muggle-do`'s forward pipeline. Opens the PR after Stage 5 (Stage 5.5), settles its walkthrough after Stage 6 (Stage 7), seeds state, dispatches the first watcher. | [`open-prs/forward.md`](open-prs/forward.md) |
|
|
8
8
|
| Update | The PR already exists; the address-reviews orchestrator called this stage to push + refresh title/description/walkthrough. | [`open-prs/update.md`](open-prs/update.md) |
|
|
@@ -19,7 +19,7 @@ You receive:
|
|
|
19
19
|
|
|
20
20
|
For each repo:
|
|
21
21
|
|
|
22
|
-
1. **Run the test command** using Bash in the repo's directory. Use the provided test command (default: `pnpm test`). Suites must run in one-shot mode (`
|
|
22
|
+
1. **Run the test command** using Bash in the repo's directory. Use the provided test command (default: `pnpm test`). Suites must run in one-shot mode (`vitest run`, jest `--watchAll=false`) — never watch mode: an orphaned watcher fork-bombs on Windows. Never set `CI=true` for a local run: repos key their local worker cap and changed-files scoping on `CI` being unset, so it runs the full suite at one worker per core. Launch through the shipped cap so the process tree is kernel-bounded and reaped if this run is killed: `node "${CLAUDE_PLUGIN_ROOT}/scripts/guard-run.mjs" -- <test command>`.
|
|
23
23
|
2. **Capture the full output** — both stdout and stderr.
|
|
24
24
|
3. **Determine pass/fail** — exit code 0 means pass, anything else means fail.
|
|
25
25
|
4. **If tests fail**, extract the specific failing test names/descriptions from the output.
|
|
@@ -26,7 +26,7 @@ Under `## Pre-flight answers`, alongside `Repos:`:
|
|
|
26
26
|
- <owner/repo-b> → <worktree path b> (branch <branch>)
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
Stage
|
|
29
|
+
Stage 5.5 appends each member's PR number to its line once the PRs exist.
|
|
30
30
|
|
|
31
31
|
The worktree path is where that repo's wave branch is checked out — the path its service must start from. Record it per repo; never derive it later from the branch name.
|
|
32
32
|
|
|
@@ -44,21 +44,27 @@ The report carries one extra metadata block:
|
|
|
44
44
|
|
|
45
45
|
```markdown
|
|
46
46
|
**Wave:**
|
|
47
|
-
- <owner/repo-a> @ <head sha> → PR #<n>
|
|
47
|
+
- <owner/repo-a> @ <head sha> → PR #<n>
|
|
48
48
|
- <owner/repo-b> @ <head sha> → PR #<n>
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
The SHAs are what the run tested. A result is only valid for the PRs at those SHAs.
|
|
52
52
|
|
|
53
|
-
## Stage
|
|
53
|
+
## Stage 5.5 — open every PR before the run
|
|
54
54
|
|
|
55
|
-
[`open-prs/forward.md`](open-prs/forward.md) runs per repo as usual, with the wave ordering:
|
|
55
|
+
[`open-prs/forward.md`](open-prs/forward.md) Stage 5.5 runs per repo as usual, with the wave ordering:
|
|
56
56
|
|
|
57
|
-
1. **Open every PR
|
|
57
|
+
1. **Open every PR** before Stage 6 starts. The run's report and each PR's walkthrough name the siblings, so all PR numbers must exist before the wave stack starts.
|
|
58
58
|
2. **Body.** Add a `## Wave` section to each PR's body, after `## Validation`: one line per sibling PR (`owner/repo#n`), and the line `Tested together — merge all PRs in this wave together.`
|
|
59
|
-
3. **Title.** Every PR in the wave takes the same
|
|
60
|
-
4. **
|
|
61
|
-
|
|
59
|
+
3. **Title.** Every PR in the wave takes the same prefix.
|
|
60
|
+
4. **Record the PR numbers** on the `Wave members` lines in `state.md` (`… (branch <branch>) → PR #<n>`), so a later cycle on any one PR can find its siblings. Every slot a wave PR's watcher runs from gets the same `Wave` block.
|
|
61
|
+
|
|
62
|
+
## Stage 7 — post the same result to every PR
|
|
63
|
+
|
|
64
|
+
[`open-prs/forward.md`](open-prs/forward.md) Stage 7 runs per repo as usual, with these changes:
|
|
65
|
+
|
|
66
|
+
1. **Title.** A wave run with failures retitles every member `[E2E FAILING]`, not only the implicated one — the run tested them as one change.
|
|
67
|
+
2. **Walkthrough.** Settle each PR's designated walkthrough comment with the **same** E2E report through [`muggle-pr-visual-walkthrough`](../muggle-pr-visual-walkthrough/SKILL.md) Mode A, passing that PR's number and repo explicitly — Mode A otherwise looks up the PR from the current branch, which in a multi-repo cycle is the wrong repo. The runs, screenshots, and dashboard links are identical on every PR; only the PR it is posted to differs. A `SKIPPED` wave run is re-declared from each member's worktree in turn: a declaration settles only the PR of the tree it runs in.
|
|
62
68
|
|
|
63
69
|
## Stage 7.5 — repair across the wave
|
|
64
70
|
|