@muggleai/works 5.20.0-staging.140 → 5.20.0-staging.142

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "muggle",
3
3
  "description": "Run real-browser end-to-end (E2E) acceptance tests on your web app from any AI coding agent. Generate test scripts from plain English, replay them on localhost, capture screenshots, and validate user flows like signup, checkout, and dashboards. Works across Claude Code, Cursor, Codex, and Windsurf.",
4
- "version": "5.20.0-staging.140",
4
+ "version": "5.20.0-staging.142",
5
5
  "author": {
6
6
  "name": "Muggle AI",
7
7
  "email": "support@muggle-ai.com"
@@ -2,7 +2,7 @@
2
2
  "name": "muggle",
3
3
  "displayName": "Muggle AI",
4
4
  "description": "Ship quality products with AI-powered end-to-end (E2E) acceptance testing that validates your web app like a real user — from Claude Code and Cursor to PR.",
5
- "version": "5.20.0-staging.140",
5
+ "version": "5.20.0-staging.142",
6
6
  "author": {
7
7
  "name": "Muggle AI",
8
8
  "email": "support@muggle-ai.com"
@@ -10,7 +10,7 @@ import { execFileSync } from 'child_process';
10
10
  var GH_PR_MERGED_LINE = /\b(?:Merged|Squashed and merged|Rebased and merged) pull request [\w./-]*#(\d+)/;
11
11
  var GH_PR_CLOSED_LINE = /\bClosed pull request [\w./-]*#(\d+)/;
12
12
  var GH_PR_REOPENED_LINE = /\bReopened pull request [\w./-]*#(\d+)/;
13
- var PR_MONITOR_TERMINAL_LINE = /\bTERMINAL pr=(\d+): (MERGED|CLOSED)\b/;
13
+ var PR_MONITOR_TERMINAL_LINE = /\bTERMINAL pr=(\d+)(?: state=|: )(MERGED|CLOSED)\b/;
14
14
  var MAX_PR_TERMINAL_BLOCKS = 3;
15
15
  var SHELL_TOOL_NAMES = ["Bash", "PowerShell"];
16
16
  var MAX_WATCH_BLOCKS = 3;
@@ -50,7 +50,7 @@ var CALL_FAILURE_SIGNALS = [
50
50
  /"isError"\s*:\s*true/
51
51
  ];
52
52
  var FORGE_TERMINAL_CMD = /\b(?:gh\s+pr\s+(?:merge|close|reopen)|glab\s+mr\s+(?:merge|close|reopen))\b/;
53
- var WATCH_LOOP_CMD = /pr-watch-loop\.sh/;
53
+ var WATCH_TERMINAL_CMD = /pr-watch-(?:loop|arm)\.sh/;
54
54
 
55
55
  // src/guardrails/store/fileLock.ts
56
56
  function isProcessAlive(pid) {
@@ -180,7 +180,7 @@ function terminalProvenance(input2) {
180
180
  if (command === void 0) return { acceptsForgeLine: true, acceptsMonitorLine: true };
181
181
  return {
182
182
  acceptsForgeLine: FORGE_TERMINAL_CMD.test(command),
183
- acceptsMonitorLine: WATCH_LOOP_CMD.test(command)
183
+ acceptsMonitorLine: WATCH_TERMINAL_CMD.test(command)
184
184
  };
185
185
  }
186
186
  function detectPrTerminal(input2) {
@@ -59,16 +59,16 @@ if [ -z "$state_line" ]; then
59
59
  exit 1
60
60
  fi
61
61
 
62
- mapfile -t fields < <(watch_split_state "$state_line")
63
- pr_state="${fields[0]-}"
64
- head_sha="${fields[1]-}"
65
- base_sha="${fields[2]-}"
66
- mergeable="${fields[3]-}"
67
- latest_review="${fields[4]-}"
68
- latest_comment="${fields[5]-}"
69
- unresolved_threads="${fields[6]-}"
70
- pending_checks="${fields[7]-}"
71
- failed_checks="${fields[8]-}"
62
+ watch_read_state_fields "$state_line"
63
+ pr_state="${STATE_FIELDS[0]-}"
64
+ head_sha="${STATE_FIELDS[1]-}"
65
+ base_sha="${STATE_FIELDS[2]-}"
66
+ mergeable="${STATE_FIELDS[3]-}"
67
+ latest_review="${STATE_FIELDS[4]-}"
68
+ latest_comment="${STATE_FIELDS[5]-}"
69
+ unresolved_threads="${STATE_FIELDS[6]-}"
70
+ pending_checks="${STATE_FIELDS[7]-}"
71
+ failed_checks="${STATE_FIELDS[8]-}"
72
72
 
73
73
  if [ "$pr_state" = "MERGED" ] || [ "$pr_state" = "CLOSED" ]; then
74
74
  echo "TERMINAL pr=$pr_number state=$pr_state — nothing to arm"
@@ -31,6 +31,18 @@ watch_split_state() {
31
31
  printf '%s\n' "$1" | awk -F'\t' '{for (i = 1; i <= NF; i++) print $i}'
32
32
  }
33
33
 
34
+ # Loads a state line's fields into the array STATE_FIELDS, empty fields kept.
35
+ # Read line by line rather than with `mapfile`, which bash 3.2 lacks — and 3.2
36
+ # is the system bash on macOS, where a missing builtin left every field empty
37
+ # and the watch unable to see a review, a red check, or a merge.
38
+ watch_read_state_fields() {
39
+ local field
40
+ STATE_FIELDS=()
41
+ while IFS= read -r field; do
42
+ STATE_FIELDS+=("$field")
43
+ done < <(watch_split_state "$1")
44
+ }
45
+
34
46
  # A submitted review newer than the floor. Monotonic ids, so `>` is the whole
35
47
  # test. PENDING (unsubmitted) reviews are excluded by the caller's query — they
36
48
  # are the reviewer's own drafts and are not feedback until submitted.
@@ -149,17 +149,17 @@ while :; do
149
149
  continue
150
150
  fi
151
151
 
152
- mapfile -t state_fields < <(watch_split_state "$state_line")
153
- pr_state="${state_fields[0]-}"
154
- head_sha="${state_fields[1]-}"
155
- base_sha="${state_fields[2]-}"
156
- mergeable="${state_fields[3]-}"
157
- latest_review="${state_fields[4]-}"
158
- latest_comment="${state_fields[5]-}"
159
- unresolved_threads="${state_fields[6]-}"
160
- pending_checks="${state_fields[7]-}"
161
- failed_checks="${state_fields[8]-}"
162
- ci_digest="${state_fields[9]-}"
152
+ watch_read_state_fields "$state_line"
153
+ pr_state="${STATE_FIELDS[0]-}"
154
+ head_sha="${STATE_FIELDS[1]-}"
155
+ base_sha="${STATE_FIELDS[2]-}"
156
+ mergeable="${STATE_FIELDS[3]-}"
157
+ latest_review="${STATE_FIELDS[4]-}"
158
+ latest_comment="${STATE_FIELDS[5]-}"
159
+ unresolved_threads="${STATE_FIELDS[6]-}"
160
+ pending_checks="${STATE_FIELDS[7]-}"
161
+ failed_checks="${STATE_FIELDS[8]-}"
162
+ ci_digest="${STATE_FIELDS[9]-}"
163
163
 
164
164
  if [ "$pr_state" = "MERGED" ] || [ "$pr_state" = "CLOSED" ]; then
165
165
  echo "TERMINAL pr=$pr_number state=$pr_state"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "release": "5.18.0",
3
- "buildId": "run-140-1",
4
- "commitSha": "92e4b5af6c1859fd2a83a388f49dc40efb3b1e3b",
5
- "buildTime": "2026-09-30T22:13:54Z",
3
+ "buildId": "run-142-1",
4
+ "commitSha": "80be7d3ad2babcef518d3decbafba51c75a0ecdb",
5
+ "buildTime": "2026-10-01T22:19:53Z",
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.20.0-staging.140",
4
+ "version": "5.20.0-staging.142",
5
5
  "description": "Ship quality products with AI-powered E2E acceptance testing that validates your web app like a real user — from Claude Code and Cursor to PR.",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "muggle",
3
3
  "description": "Run real-browser end-to-end (E2E) acceptance tests on your web app from any AI coding agent. Generate test scripts from plain English, replay them on localhost, capture screenshots, and validate user flows like signup, checkout, and dashboards. Works across Claude Code, Cursor, Codex, and Windsurf.",
4
- "version": "5.20.0-staging.140",
4
+ "version": "5.20.0-staging.142",
5
5
  "author": {
6
6
  "name": "Muggle AI",
7
7
  "email": "support@muggle-ai.com"
@@ -2,7 +2,7 @@
2
2
  "name": "muggle",
3
3
  "displayName": "Muggle AI",
4
4
  "description": "Ship quality products with AI-powered end-to-end (E2E) acceptance testing that validates your web app like a real user — from Claude Code and Cursor to PR.",
5
- "version": "5.20.0-staging.140",
5
+ "version": "5.20.0-staging.142",
6
6
  "author": {
7
7
  "name": "Muggle AI",
8
8
  "email": "support@muggle-ai.com"
@@ -10,7 +10,7 @@ import { execFileSync } from 'child_process';
10
10
  var GH_PR_MERGED_LINE = /\b(?:Merged|Squashed and merged|Rebased and merged) pull request [\w./-]*#(\d+)/;
11
11
  var GH_PR_CLOSED_LINE = /\bClosed pull request [\w./-]*#(\d+)/;
12
12
  var GH_PR_REOPENED_LINE = /\bReopened pull request [\w./-]*#(\d+)/;
13
- var PR_MONITOR_TERMINAL_LINE = /\bTERMINAL pr=(\d+): (MERGED|CLOSED)\b/;
13
+ var PR_MONITOR_TERMINAL_LINE = /\bTERMINAL pr=(\d+)(?: state=|: )(MERGED|CLOSED)\b/;
14
14
  var MAX_PR_TERMINAL_BLOCKS = 3;
15
15
  var SHELL_TOOL_NAMES = ["Bash", "PowerShell"];
16
16
  var MAX_WATCH_BLOCKS = 3;
@@ -50,7 +50,7 @@ var CALL_FAILURE_SIGNALS = [
50
50
  /"isError"\s*:\s*true/
51
51
  ];
52
52
  var FORGE_TERMINAL_CMD = /\b(?:gh\s+pr\s+(?:merge|close|reopen)|glab\s+mr\s+(?:merge|close|reopen))\b/;
53
- var WATCH_LOOP_CMD = /pr-watch-loop\.sh/;
53
+ var WATCH_TERMINAL_CMD = /pr-watch-(?:loop|arm)\.sh/;
54
54
 
55
55
  // src/guardrails/store/fileLock.ts
56
56
  function isProcessAlive(pid) {
@@ -180,7 +180,7 @@ function terminalProvenance(input2) {
180
180
  if (command === void 0) return { acceptsForgeLine: true, acceptsMonitorLine: true };
181
181
  return {
182
182
  acceptsForgeLine: FORGE_TERMINAL_CMD.test(command),
183
- acceptsMonitorLine: WATCH_LOOP_CMD.test(command)
183
+ acceptsMonitorLine: WATCH_TERMINAL_CMD.test(command)
184
184
  };
185
185
  }
186
186
  function detectPrTerminal(input2) {
@@ -59,16 +59,16 @@ if [ -z "$state_line" ]; then
59
59
  exit 1
60
60
  fi
61
61
 
62
- mapfile -t fields < <(watch_split_state "$state_line")
63
- pr_state="${fields[0]-}"
64
- head_sha="${fields[1]-}"
65
- base_sha="${fields[2]-}"
66
- mergeable="${fields[3]-}"
67
- latest_review="${fields[4]-}"
68
- latest_comment="${fields[5]-}"
69
- unresolved_threads="${fields[6]-}"
70
- pending_checks="${fields[7]-}"
71
- failed_checks="${fields[8]-}"
62
+ watch_read_state_fields "$state_line"
63
+ pr_state="${STATE_FIELDS[0]-}"
64
+ head_sha="${STATE_FIELDS[1]-}"
65
+ base_sha="${STATE_FIELDS[2]-}"
66
+ mergeable="${STATE_FIELDS[3]-}"
67
+ latest_review="${STATE_FIELDS[4]-}"
68
+ latest_comment="${STATE_FIELDS[5]-}"
69
+ unresolved_threads="${STATE_FIELDS[6]-}"
70
+ pending_checks="${STATE_FIELDS[7]-}"
71
+ failed_checks="${STATE_FIELDS[8]-}"
72
72
 
73
73
  if [ "$pr_state" = "MERGED" ] || [ "$pr_state" = "CLOSED" ]; then
74
74
  echo "TERMINAL pr=$pr_number state=$pr_state — nothing to arm"
@@ -31,6 +31,18 @@ watch_split_state() {
31
31
  printf '%s\n' "$1" | awk -F'\t' '{for (i = 1; i <= NF; i++) print $i}'
32
32
  }
33
33
 
34
+ # Loads a state line's fields into the array STATE_FIELDS, empty fields kept.
35
+ # Read line by line rather than with `mapfile`, which bash 3.2 lacks — and 3.2
36
+ # is the system bash on macOS, where a missing builtin left every field empty
37
+ # and the watch unable to see a review, a red check, or a merge.
38
+ watch_read_state_fields() {
39
+ local field
40
+ STATE_FIELDS=()
41
+ while IFS= read -r field; do
42
+ STATE_FIELDS+=("$field")
43
+ done < <(watch_split_state "$1")
44
+ }
45
+
34
46
  # A submitted review newer than the floor. Monotonic ids, so `>` is the whole
35
47
  # test. PENDING (unsubmitted) reviews are excluded by the caller's query — they
36
48
  # are the reviewer's own drafts and are not feedback until submitted.
@@ -149,17 +149,17 @@ while :; do
149
149
  continue
150
150
  fi
151
151
 
152
- mapfile -t state_fields < <(watch_split_state "$state_line")
153
- pr_state="${state_fields[0]-}"
154
- head_sha="${state_fields[1]-}"
155
- base_sha="${state_fields[2]-}"
156
- mergeable="${state_fields[3]-}"
157
- latest_review="${state_fields[4]-}"
158
- latest_comment="${state_fields[5]-}"
159
- unresolved_threads="${state_fields[6]-}"
160
- pending_checks="${state_fields[7]-}"
161
- failed_checks="${state_fields[8]-}"
162
- ci_digest="${state_fields[9]-}"
152
+ watch_read_state_fields "$state_line"
153
+ pr_state="${STATE_FIELDS[0]-}"
154
+ head_sha="${STATE_FIELDS[1]-}"
155
+ base_sha="${STATE_FIELDS[2]-}"
156
+ mergeable="${STATE_FIELDS[3]-}"
157
+ latest_review="${STATE_FIELDS[4]-}"
158
+ latest_comment="${STATE_FIELDS[5]-}"
159
+ unresolved_threads="${STATE_FIELDS[6]-}"
160
+ pending_checks="${STATE_FIELDS[7]-}"
161
+ failed_checks="${STATE_FIELDS[8]-}"
162
+ ci_digest="${STATE_FIELDS[9]-}"
163
163
 
164
164
  if [ "$pr_state" = "MERGED" ] || [ "$pr_state" = "CLOSED" ]; then
165
165
  echo "TERMINAL pr=$pr_number state=$pr_state"