@muggleai/works 5.31.0-staging.278 → 5.31.0-staging.279
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/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 +74 -9
- package/dist/release-manifest.json +3 -3
- 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 +74 -9
|
@@ -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.279"
|
|
13
13
|
}
|
|
14
14
|
]
|
|
15
15
|
}
|
|
@@ -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.279",
|
|
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.279",
|
|
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.279",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Muggle AI",
|
|
8
8
|
"email": "support@muggle-ai.com"
|
package/dist/plugin/.mcp.json
CHANGED
|
@@ -446,6 +446,7 @@ var USER_WAIVE_PHRASE = "SKIP E2E";
|
|
|
446
446
|
var MIN_NOT_APPLICABLE_REASON_WORDS = 4;
|
|
447
447
|
var DEV_SERVER_PROBE_TIMEOUT_MS = 2e3;
|
|
448
448
|
var GIT_PROBE_TIMEOUT_MS = 5e3;
|
|
449
|
+
var BASE_REMOTE = "origin";
|
|
449
450
|
var WEB_SERVER_COMMAND = /\b(vite|next\s+(dev|start)|react-scripts|ng\s+serve|nuxt|astro\s+dev|remix\s+dev|webpack(-dev)?-server|http-server|serve\s+-s|gatsby\s+develop|vue-cli-service\s+serve)\b/;
|
|
450
451
|
var BROWSER_FRAMEWORK_PACKAGES = [
|
|
451
452
|
"react-dom",
|
|
@@ -635,6 +636,68 @@ var defaultSkipProbes = {
|
|
|
635
636
|
isReachable
|
|
636
637
|
};
|
|
637
638
|
|
|
639
|
+
// src/git-dir/constants.ts
|
|
640
|
+
var DOT_GIT = ".git";
|
|
641
|
+
var GITDIR_POINTER = /^gitdir:\s*(.+?)\s*$/m;
|
|
642
|
+
var HEAD_BRANCH_REF = /^ref:\s*refs\/heads\/(.+?)\s*$/;
|
|
643
|
+
var REMOTE_HEAD_REF = /^ref:\s*refs\/remotes\/(.+?)\s*$/;
|
|
644
|
+
var CONFIG_SECTION_HEADER = /^\s*\[\s*([A-Za-z0-9.-]+)(?:\s+"((?:[^"\\]|\\.)*)")?\s*\]/;
|
|
645
|
+
var CONFIG_KEY_VALUE = /^\s*([A-Za-z][A-Za-z0-9-]*)\s*=\s*(.*)$/;
|
|
646
|
+
var CONFIG_INDIRECTION = /^\s*(?:\[\s*include(?:If)?\b|[^#;]*\binsteadOf\s*=)/im;
|
|
647
|
+
|
|
648
|
+
// src/git-dir/gitDir.ts
|
|
649
|
+
function locateGitDir(cwd, readTextFile2) {
|
|
650
|
+
let dir = resolve(cwd);
|
|
651
|
+
for (; ; ) {
|
|
652
|
+
const dotGit = join(dir, DOT_GIT);
|
|
653
|
+
const pointer = readTextFile2(dotGit)?.match(GITDIR_POINTER);
|
|
654
|
+
const gitDir = pointer ? resolve(dir, pointer[1]) : readTextFile2(join(dotGit, "HEAD")) !== null ? dotGit : null;
|
|
655
|
+
if (gitDir) {
|
|
656
|
+
const commonDirPointer = readTextFile2(join(gitDir, "commondir"))?.trim();
|
|
657
|
+
return { gitDir, commonDir: commonDirPointer ? resolve(gitDir, commonDirPointer) : gitDir };
|
|
658
|
+
}
|
|
659
|
+
const parent = dirname(dir);
|
|
660
|
+
if (parent === dir) return null;
|
|
661
|
+
dir = parent;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
function readCurrentBranch(cwd, readTextFile2) {
|
|
665
|
+
const location = locateGitDir(cwd, readTextFile2);
|
|
666
|
+
const head = location ? readTextFile2(join(location.gitDir, "HEAD")) : null;
|
|
667
|
+
if (head === null) return null;
|
|
668
|
+
return head.match(HEAD_BRANCH_REF)?.[1] ?? "";
|
|
669
|
+
}
|
|
670
|
+
function parseConfigValue(rawValue) {
|
|
671
|
+
const value = rawValue.trim();
|
|
672
|
+
if (value.startsWith('"')) {
|
|
673
|
+
const closingQuote = value.slice(1).search(/(?<!\\)"/);
|
|
674
|
+
const quoted = closingQuote < 0 ? value.slice(1) : value.slice(1, closingQuote + 1);
|
|
675
|
+
return quoted.replace(/\\(["\\])/g, "$1");
|
|
676
|
+
}
|
|
677
|
+
return value.replace(/\s*[#;].*$/, "");
|
|
678
|
+
}
|
|
679
|
+
function readRemoteUrl(cwd, remote, readTextFile2) {
|
|
680
|
+
const location = locateGitDir(cwd, readTextFile2);
|
|
681
|
+
const config = location ? readTextFile2(join(location.commonDir, "config")) : null;
|
|
682
|
+
if (config === null || CONFIG_INDIRECTION.test(config)) return null;
|
|
683
|
+
let isInRemoteSection = false;
|
|
684
|
+
for (const line of config.split(/\r?\n/)) {
|
|
685
|
+
const header = line.match(CONFIG_SECTION_HEADER);
|
|
686
|
+
if (header) {
|
|
687
|
+
isInRemoteSection = header[1].toLowerCase() === "remote" && header[2] === remote;
|
|
688
|
+
continue;
|
|
689
|
+
}
|
|
690
|
+
const entry = isInRemoteSection ? line.match(CONFIG_KEY_VALUE) : null;
|
|
691
|
+
if (entry && entry[1].toLowerCase() === "url") return parseConfigValue(entry[2]) || null;
|
|
692
|
+
}
|
|
693
|
+
return null;
|
|
694
|
+
}
|
|
695
|
+
function readRemoteHeadBranch(cwd, remote, readTextFile2) {
|
|
696
|
+
const location = locateGitDir(cwd, readTextFile2);
|
|
697
|
+
const ref = location ? readTextFile2(join(location.commonDir, "refs", "remotes", remote, "HEAD")) : null;
|
|
698
|
+
return ref?.match(REMOTE_HEAD_REF)?.[1] ?? null;
|
|
699
|
+
}
|
|
700
|
+
|
|
638
701
|
// src/guardrails/changeIdentity.ts
|
|
639
702
|
function toRepoKey(host2, path) {
|
|
640
703
|
const repoPath = path.replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "");
|
|
@@ -661,21 +724,24 @@ function repoKeyOfRemoteUrl(remoteUrl) {
|
|
|
661
724
|
return void 0;
|
|
662
725
|
}
|
|
663
726
|
}
|
|
664
|
-
function resolveTreeChange(cwd,
|
|
727
|
+
function resolveTreeChange(cwd, probes = defaultSkipProbes) {
|
|
665
728
|
if (!cwd) return void 0;
|
|
666
|
-
const
|
|
667
|
-
const
|
|
668
|
-
const
|
|
669
|
-
|
|
729
|
+
const writtenUrl = readRemoteUrl(cwd, CHANGE_REPO_REMOTE, probes.readTextFile);
|
|
730
|
+
const writtenRepo = writtenUrl ? repoKeyOfRemoteUrl(writtenUrl) : void 0;
|
|
731
|
+
const remoteUrl = writtenRepo ? null : probes.runGit(["remote", "get-url", CHANGE_REPO_REMOTE], cwd);
|
|
732
|
+
const repo = writtenRepo ?? (remoteUrl ? repoKeyOfRemoteUrl(remoteUrl) : void 0);
|
|
733
|
+
if (!repo) return void 0;
|
|
734
|
+
const branch = (readCurrentBranch(cwd, probes.readTextFile) ?? probes.runGit(["branch", "--show-current"], cwd))?.trim();
|
|
735
|
+
return branch ? { repo, branch } : void 0;
|
|
670
736
|
}
|
|
671
|
-
function resolveOpenedPrChange(command, prUrl, cwd,
|
|
737
|
+
function resolveOpenedPrChange(command, prUrl, cwd, probes = defaultSkipProbes) {
|
|
672
738
|
const repo = repoKeyOfPrUrl(prUrl);
|
|
673
739
|
if (!repo) return void 0;
|
|
674
740
|
const openAt = command.search(PR_OPEN_COMMAND);
|
|
675
741
|
const headFlag = openAt < 0 ? null : command.slice(openAt).match(PR_HEAD_BRANCH_FLAG);
|
|
676
742
|
if (headFlag) return { repo, branch: headFlag[1].slice(headFlag[1].lastIndexOf(":") + 1) };
|
|
677
743
|
if (DIRECTORY_CHANGE_COMMAND.test(command)) return void 0;
|
|
678
|
-
const treeChange = resolveTreeChange(cwd,
|
|
744
|
+
const treeChange = resolveTreeChange(cwd, probes);
|
|
679
745
|
return treeChange?.repo === repo ? treeChange : void 0;
|
|
680
746
|
}
|
|
681
747
|
function isSameChange(left, right) {
|
|
@@ -2378,8 +2444,7 @@ var verifyDevServerUnreachable = (context, detail) => {
|
|
|
2378
2444
|
};
|
|
2379
2445
|
var verifyEmptyDiff = (context) => {
|
|
2380
2446
|
if (!context.cwd) return refuted("no working directory was available to inspect");
|
|
2381
|
-
const
|
|
2382
|
-
const base = head?.trim();
|
|
2447
|
+
const base = (readRemoteHeadBranch(context.cwd, BASE_REMOTE, context.probe.readTextFile) ?? context.probe.runGit(["symbolic-ref", `refs/remotes/${BASE_REMOTE}/HEAD`, "--short"], context.cwd))?.trim();
|
|
2383
2448
|
if (!base) return refuted("the repo's base branch could not be resolved");
|
|
2384
2449
|
const diff = context.probe.runGit(["diff", `${base}...HEAD`, "--stat"], context.cwd);
|
|
2385
2450
|
if (diff === null) return refuted("the diff against the base branch could not be read");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"release": "5.26.0",
|
|
3
|
-
"buildId": "run-
|
|
4
|
-
"commitSha": "
|
|
5
|
-
"buildTime": "2026-11-
|
|
3
|
+
"buildId": "run-279-1",
|
|
4
|
+
"commitSha": "999126987b03bfc3a3b2f8fbc337415e695fbbab",
|
|
5
|
+
"buildTime": "2026-11-02T08:18:32Z",
|
|
6
6
|
"serviceName": "muggle-ai-works-mcp"
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@muggleai/works",
|
|
3
3
|
"mcpName": "io.github.multiplex-ai/muggle",
|
|
4
|
-
"version": "5.31.0-staging.
|
|
4
|
+
"version": "5.31.0-staging.279",
|
|
5
5
|
"description": "13 years of Microsoft hyperscale engineering, packaged as a harness for your AI coding agent.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.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.279",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Muggle AI",
|
|
7
7
|
"email": "support@muggle-ai.com"
|
package/plugin/.codex-mcp.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "muggle",
|
|
3
|
-
"version": "5.31.0-staging.
|
|
3
|
+
"version": "5.31.0-staging.279",
|
|
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.279",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Muggle AI",
|
|
8
8
|
"email": "support@muggle-ai.com"
|
package/plugin/.mcp.json
CHANGED
|
@@ -446,6 +446,7 @@ var USER_WAIVE_PHRASE = "SKIP E2E";
|
|
|
446
446
|
var MIN_NOT_APPLICABLE_REASON_WORDS = 4;
|
|
447
447
|
var DEV_SERVER_PROBE_TIMEOUT_MS = 2e3;
|
|
448
448
|
var GIT_PROBE_TIMEOUT_MS = 5e3;
|
|
449
|
+
var BASE_REMOTE = "origin";
|
|
449
450
|
var WEB_SERVER_COMMAND = /\b(vite|next\s+(dev|start)|react-scripts|ng\s+serve|nuxt|astro\s+dev|remix\s+dev|webpack(-dev)?-server|http-server|serve\s+-s|gatsby\s+develop|vue-cli-service\s+serve)\b/;
|
|
450
451
|
var BROWSER_FRAMEWORK_PACKAGES = [
|
|
451
452
|
"react-dom",
|
|
@@ -635,6 +636,68 @@ var defaultSkipProbes = {
|
|
|
635
636
|
isReachable
|
|
636
637
|
};
|
|
637
638
|
|
|
639
|
+
// src/git-dir/constants.ts
|
|
640
|
+
var DOT_GIT = ".git";
|
|
641
|
+
var GITDIR_POINTER = /^gitdir:\s*(.+?)\s*$/m;
|
|
642
|
+
var HEAD_BRANCH_REF = /^ref:\s*refs\/heads\/(.+?)\s*$/;
|
|
643
|
+
var REMOTE_HEAD_REF = /^ref:\s*refs\/remotes\/(.+?)\s*$/;
|
|
644
|
+
var CONFIG_SECTION_HEADER = /^\s*\[\s*([A-Za-z0-9.-]+)(?:\s+"((?:[^"\\]|\\.)*)")?\s*\]/;
|
|
645
|
+
var CONFIG_KEY_VALUE = /^\s*([A-Za-z][A-Za-z0-9-]*)\s*=\s*(.*)$/;
|
|
646
|
+
var CONFIG_INDIRECTION = /^\s*(?:\[\s*include(?:If)?\b|[^#;]*\binsteadOf\s*=)/im;
|
|
647
|
+
|
|
648
|
+
// src/git-dir/gitDir.ts
|
|
649
|
+
function locateGitDir(cwd, readTextFile2) {
|
|
650
|
+
let dir = resolve(cwd);
|
|
651
|
+
for (; ; ) {
|
|
652
|
+
const dotGit = join(dir, DOT_GIT);
|
|
653
|
+
const pointer = readTextFile2(dotGit)?.match(GITDIR_POINTER);
|
|
654
|
+
const gitDir = pointer ? resolve(dir, pointer[1]) : readTextFile2(join(dotGit, "HEAD")) !== null ? dotGit : null;
|
|
655
|
+
if (gitDir) {
|
|
656
|
+
const commonDirPointer = readTextFile2(join(gitDir, "commondir"))?.trim();
|
|
657
|
+
return { gitDir, commonDir: commonDirPointer ? resolve(gitDir, commonDirPointer) : gitDir };
|
|
658
|
+
}
|
|
659
|
+
const parent = dirname(dir);
|
|
660
|
+
if (parent === dir) return null;
|
|
661
|
+
dir = parent;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
function readCurrentBranch(cwd, readTextFile2) {
|
|
665
|
+
const location = locateGitDir(cwd, readTextFile2);
|
|
666
|
+
const head = location ? readTextFile2(join(location.gitDir, "HEAD")) : null;
|
|
667
|
+
if (head === null) return null;
|
|
668
|
+
return head.match(HEAD_BRANCH_REF)?.[1] ?? "";
|
|
669
|
+
}
|
|
670
|
+
function parseConfigValue(rawValue) {
|
|
671
|
+
const value = rawValue.trim();
|
|
672
|
+
if (value.startsWith('"')) {
|
|
673
|
+
const closingQuote = value.slice(1).search(/(?<!\\)"/);
|
|
674
|
+
const quoted = closingQuote < 0 ? value.slice(1) : value.slice(1, closingQuote + 1);
|
|
675
|
+
return quoted.replace(/\\(["\\])/g, "$1");
|
|
676
|
+
}
|
|
677
|
+
return value.replace(/\s*[#;].*$/, "");
|
|
678
|
+
}
|
|
679
|
+
function readRemoteUrl(cwd, remote, readTextFile2) {
|
|
680
|
+
const location = locateGitDir(cwd, readTextFile2);
|
|
681
|
+
const config = location ? readTextFile2(join(location.commonDir, "config")) : null;
|
|
682
|
+
if (config === null || CONFIG_INDIRECTION.test(config)) return null;
|
|
683
|
+
let isInRemoteSection = false;
|
|
684
|
+
for (const line of config.split(/\r?\n/)) {
|
|
685
|
+
const header = line.match(CONFIG_SECTION_HEADER);
|
|
686
|
+
if (header) {
|
|
687
|
+
isInRemoteSection = header[1].toLowerCase() === "remote" && header[2] === remote;
|
|
688
|
+
continue;
|
|
689
|
+
}
|
|
690
|
+
const entry = isInRemoteSection ? line.match(CONFIG_KEY_VALUE) : null;
|
|
691
|
+
if (entry && entry[1].toLowerCase() === "url") return parseConfigValue(entry[2]) || null;
|
|
692
|
+
}
|
|
693
|
+
return null;
|
|
694
|
+
}
|
|
695
|
+
function readRemoteHeadBranch(cwd, remote, readTextFile2) {
|
|
696
|
+
const location = locateGitDir(cwd, readTextFile2);
|
|
697
|
+
const ref = location ? readTextFile2(join(location.commonDir, "refs", "remotes", remote, "HEAD")) : null;
|
|
698
|
+
return ref?.match(REMOTE_HEAD_REF)?.[1] ?? null;
|
|
699
|
+
}
|
|
700
|
+
|
|
638
701
|
// src/guardrails/changeIdentity.ts
|
|
639
702
|
function toRepoKey(host2, path) {
|
|
640
703
|
const repoPath = path.replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "");
|
|
@@ -661,21 +724,24 @@ function repoKeyOfRemoteUrl(remoteUrl) {
|
|
|
661
724
|
return void 0;
|
|
662
725
|
}
|
|
663
726
|
}
|
|
664
|
-
function resolveTreeChange(cwd,
|
|
727
|
+
function resolveTreeChange(cwd, probes = defaultSkipProbes) {
|
|
665
728
|
if (!cwd) return void 0;
|
|
666
|
-
const
|
|
667
|
-
const
|
|
668
|
-
const
|
|
669
|
-
|
|
729
|
+
const writtenUrl = readRemoteUrl(cwd, CHANGE_REPO_REMOTE, probes.readTextFile);
|
|
730
|
+
const writtenRepo = writtenUrl ? repoKeyOfRemoteUrl(writtenUrl) : void 0;
|
|
731
|
+
const remoteUrl = writtenRepo ? null : probes.runGit(["remote", "get-url", CHANGE_REPO_REMOTE], cwd);
|
|
732
|
+
const repo = writtenRepo ?? (remoteUrl ? repoKeyOfRemoteUrl(remoteUrl) : void 0);
|
|
733
|
+
if (!repo) return void 0;
|
|
734
|
+
const branch = (readCurrentBranch(cwd, probes.readTextFile) ?? probes.runGit(["branch", "--show-current"], cwd))?.trim();
|
|
735
|
+
return branch ? { repo, branch } : void 0;
|
|
670
736
|
}
|
|
671
|
-
function resolveOpenedPrChange(command, prUrl, cwd,
|
|
737
|
+
function resolveOpenedPrChange(command, prUrl, cwd, probes = defaultSkipProbes) {
|
|
672
738
|
const repo = repoKeyOfPrUrl(prUrl);
|
|
673
739
|
if (!repo) return void 0;
|
|
674
740
|
const openAt = command.search(PR_OPEN_COMMAND);
|
|
675
741
|
const headFlag = openAt < 0 ? null : command.slice(openAt).match(PR_HEAD_BRANCH_FLAG);
|
|
676
742
|
if (headFlag) return { repo, branch: headFlag[1].slice(headFlag[1].lastIndexOf(":") + 1) };
|
|
677
743
|
if (DIRECTORY_CHANGE_COMMAND.test(command)) return void 0;
|
|
678
|
-
const treeChange = resolveTreeChange(cwd,
|
|
744
|
+
const treeChange = resolveTreeChange(cwd, probes);
|
|
679
745
|
return treeChange?.repo === repo ? treeChange : void 0;
|
|
680
746
|
}
|
|
681
747
|
function isSameChange(left, right) {
|
|
@@ -2378,8 +2444,7 @@ var verifyDevServerUnreachable = (context, detail) => {
|
|
|
2378
2444
|
};
|
|
2379
2445
|
var verifyEmptyDiff = (context) => {
|
|
2380
2446
|
if (!context.cwd) return refuted("no working directory was available to inspect");
|
|
2381
|
-
const
|
|
2382
|
-
const base = head?.trim();
|
|
2447
|
+
const base = (readRemoteHeadBranch(context.cwd, BASE_REMOTE, context.probe.readTextFile) ?? context.probe.runGit(["symbolic-ref", `refs/remotes/${BASE_REMOTE}/HEAD`, "--short"], context.cwd))?.trim();
|
|
2383
2448
|
if (!base) return refuted("the repo's base branch could not be resolved");
|
|
2384
2449
|
const diff = context.probe.runGit(["diff", `${base}...HEAD`, "--stat"], context.cwd);
|
|
2385
2450
|
if (diff === null) return refuted("the diff against the base branch could not be read");
|