@alwaysmeticulous/cli 2.292.1 → 2.293.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.
@@ -1,12 +1,15 @@
1
1
  "use strict";
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="8bd4e484-ad21-53f2-97d9-b51c7dc7986a")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c6fd7be6-1c99-540f-91e8-a1e4aa24d9db")}catch(e){}}();
3
3
 
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.agentCommand = void 0;
6
+ const js_coverage_diff_command_1 = require("./js-coverage-diff.command");
7
+ const js_coverage_command_1 = require("./js-coverage.command");
6
8
  const screenshot_dom_diff_command_1 = require("./screenshot-dom-diff.command");
7
9
  const screenshot_image_files_command_1 = require("./screenshot-image-files.command");
8
10
  const screenshot_image_command_1 = require("./screenshot-image.command");
9
11
  const test_run_diffs_command_1 = require("./test-run-diffs.command");
12
+ const test_run_for_commit_command_1 = require("./test-run-for-commit.command");
10
13
  const timeline_command_1 = require("./timeline.command");
11
14
  exports.agentCommand = {
12
15
  command: "agent",
@@ -14,6 +17,9 @@ exports.agentCommand = {
14
17
  builder: (yargs) => yargs
15
18
  .command(test_run_diffs_command_1.testRunDiffsCommand)
16
19
  .command(screenshot_dom_diff_command_1.domDiffCommand)
20
+ .command(test_run_for_commit_command_1.testRunForCommitCommand)
21
+ .command(js_coverage_command_1.jsCoverageCommand)
22
+ .command(js_coverage_diff_command_1.jsCoverageDiffCommand)
17
23
  .command(screenshot_image_files_command_1.imageFilesCommand)
18
24
  .command(screenshot_image_command_1.imageUrlsCommand)
19
25
  .command(timeline_command_1.timelineDiffCommand)
@@ -24,4 +30,4 @@ exports.agentCommand = {
24
30
  },
25
31
  };
26
32
  //# sourceMappingURL=index.js.map
27
- //# debugId=8bd4e484-ad21-53f2-97d9-b51c7dc7986a
33
+ //# debugId=c6fd7be6-1c99-540f-91e8-a1e4aa24d9db
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/commands/agent/index.ts"],"sourceRoot":"","names":[],"mappings":";;;;;AACA,+EAA+D;AAC/D,qFAAqE;AACrE,yEAA8D;AAC9D,qEAA+D;AAC/D,yDAAyD;AAE5C,QAAA,YAAY,GAAkB;IACzC,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE,4CAA4C;IACtD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,KAAK;SACF,OAAO,CAAC,4CAAmB,CAAC;SAC5B,OAAO,CAAC,4CAAc,CAAC;SACvB,OAAO,CAAC,kDAAiB,CAAC;SAC1B,OAAO,CAAC,2CAAgB,CAAC;SACzB,OAAO,CAAC,sCAAmB,CAAC;SAC5B,aAAa,EAAE;SACf,IAAI,EAAE;IACX,OAAO,EAAE,GAAG,EAAE;QACZ,0BAA0B;IAC5B,CAAC;CACF,CAAC","debugId":"8bd4e484-ad21-53f2-97d9-b51c7dc7986a"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/commands/agent/index.ts"],"sourceRoot":"","names":[],"mappings":";;;;;AACA,yEAAmE;AACnE,+DAA0D;AAC1D,+EAA+D;AAC/D,qFAAqE;AACrE,yEAA8D;AAC9D,qEAA+D;AAC/D,+EAAwE;AACxE,yDAAyD;AAE5C,QAAA,YAAY,GAAkB;IACzC,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE,4CAA4C;IACtD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,KAAK;SACF,OAAO,CAAC,4CAAmB,CAAC;SAC5B,OAAO,CAAC,4CAAc,CAAC;SACvB,OAAO,CAAC,qDAAuB,CAAC;SAChC,OAAO,CAAC,uCAAiB,CAAC;SAC1B,OAAO,CAAC,gDAAqB,CAAC;SAC9B,OAAO,CAAC,kDAAiB,CAAC;SAC1B,OAAO,CAAC,2CAAgB,CAAC;SACzB,OAAO,CAAC,sCAAmB,CAAC;SAC5B,aAAa,EAAE;SACf,IAAI,EAAE;IACX,OAAO,EAAE,GAAG,EAAE;QACZ,0BAA0B;IAC5B,CAAC;CACF,CAAC","debugId":"c6fd7be6-1c99-540f-91e8-a1e4aa24d9db"}
@@ -0,0 +1,9 @@
1
+ import { CommandModule } from "yargs";
2
+ interface Options {
3
+ apiToken?: string | null | undefined;
4
+ replayDiffId: string;
5
+ screenshotName: string | undefined;
6
+ json: boolean;
7
+ }
8
+ export declare const jsCoverageDiffCommand: CommandModule<unknown, Options>;
9
+ export {};
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7d6dd7d6-e567-56ed-a00a-fb1b0fbbcb09")}catch(e){}}();
3
+
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.jsCoverageDiffCommand = void 0;
6
+ const client_1 = require("@alwaysmeticulous/client");
7
+ const common_1 = require("@alwaysmeticulous/common");
8
+ const sentry_utils_1 = require("../../command-utils/sentry.utils");
9
+ const format_coverage_ranges_1 = require("../../utils/format-coverage-ranges");
10
+ const log = (...args) => process.stderr.write(args.join(" ") + "\n");
11
+ const handler = async ({ apiToken, replayDiffId, screenshotName, json, }) => {
12
+ (0, common_1.initLogger)();
13
+ const client = await (0, client_1.createClientWithOAuth)({
14
+ apiToken,
15
+ enableOAuthLogin: true,
16
+ });
17
+ const result = await (0, client_1.getReplayDiffJsCoverage)(client, replayDiffId, screenshotName);
18
+ if (json) {
19
+ console.log(JSON.stringify(result, null, 2));
20
+ return;
21
+ }
22
+ const header = ["repoFilePath", "status", "baseRanges", "headRanges"];
23
+ console.log(header.join("\t"));
24
+ let added = 0;
25
+ let removed = 0;
26
+ let modified = 0;
27
+ for (const d of result.diff) {
28
+ if (d.status === "added") {
29
+ added++;
30
+ }
31
+ else if (d.status === "removed") {
32
+ removed++;
33
+ }
34
+ else if (d.status === "modified") {
35
+ modified++;
36
+ }
37
+ const fields = [
38
+ d.filePath,
39
+ d.status,
40
+ (0, format_coverage_ranges_1.formatCoverageRanges)(d.baseRanges),
41
+ (0, format_coverage_ranges_1.formatCoverageRanges)(d.headRanges),
42
+ ];
43
+ console.log(fields.join("\t"));
44
+ }
45
+ log(`${result.diff.length} file(s) with coverage changes ` +
46
+ `(${added} added, ${removed} removed, ${modified} modified); ` +
47
+ `base ${result.base?.length ?? 0} file(s), head ${result.head?.length ?? 0} file(s)`);
48
+ };
49
+ exports.jsCoverageDiffCommand = {
50
+ command: "js-coverage-diff",
51
+ describe: "Get the JS coverage diff (base vs head) for a replay diff, for a single screenshot or the whole replay",
52
+ builder: {
53
+ apiToken: { string: true, description: "Meticulous API token" },
54
+ replayDiffId: {
55
+ string: true,
56
+ description: "The replay diff ID",
57
+ demandOption: true,
58
+ },
59
+ screenshotName: {
60
+ string: true,
61
+ description: 'Screenshot name (e.g. "after-event-5" or "end-state"). Omit for the whole-replay diff.',
62
+ },
63
+ json: {
64
+ boolean: true,
65
+ description: "Output the raw coverage response as JSON",
66
+ default: false,
67
+ },
68
+ },
69
+ handler: (0, sentry_utils_1.wrapHandler)(handler),
70
+ };
71
+ //# sourceMappingURL=js-coverage-diff.command.js.map
72
+ //# debugId=7d6dd7d6-e567-56ed-a00a-fb1b0fbbcb09
@@ -0,0 +1 @@
1
+ {"version":3,"file":"js-coverage-diff.command.js","sources":["../../../src/commands/agent/js-coverage-diff.command.ts"],"sourceRoot":"","names":[],"mappings":";;;;;AAAA,qDAGkC;AAClC,qDAAsD;AAEtD,mEAA+D;AAC/D,+EAA0E;AAS1E,MAAM,GAAG,GAAG,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;AAEhF,MAAM,OAAO,GAAG,KAAK,EAAE,EACrB,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,IAAI,GACI,EAAiB,EAAE;IAC3B,IAAA,mBAAU,GAAE,CAAC;IACb,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAqB,EAAC;QACzC,QAAQ;QACR,gBAAgB,EAAE,IAAI;KACvB,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,IAAA,gCAAuB,EAC1C,MAAM,EACN,YAAY,EACZ,cAAc,CACf,CAAC;IAEF,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAE/B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YACzB,KAAK,EAAE,CAAC;QACV,CAAC;aAAM,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAClC,OAAO,EAAE,CAAC;QACZ,CAAC;aAAM,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YACnC,QAAQ,EAAE,CAAC;QACb,CAAC;QACD,MAAM,MAAM,GAAG;YACb,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,MAAM;YACR,IAAA,6CAAoB,EAAC,CAAC,CAAC,UAAU,CAAC;YAClC,IAAA,6CAAoB,EAAC,CAAC,CAAC,UAAU,CAAC;SACnC,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACjC,CAAC;IAED,GAAG,CACD,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,iCAAiC;QACpD,IAAI,KAAK,WAAW,OAAO,aAAa,QAAQ,cAAc;QAC9D,QAAQ,MAAM,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,kBAAkB,MAAM,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,UAAU,CACvF,CAAC;AACJ,CAAC,CAAC;AAEW,QAAA,qBAAqB,GAAoC;IACpE,OAAO,EAAE,kBAAkB;IAC3B,QAAQ,EACN,wGAAwG;IAC1G,OAAO,EAAE;QACP,QAAQ,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,sBAAsB,EAAE;QAC/D,YAAY,EAAE;YACZ,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,oBAAoB;YACjC,YAAY,EAAE,IAAI;SACnB;QACD,cAAc,EAAE;YACd,MAAM,EAAE,IAAI;YACZ,WAAW,EACT,wFAAwF;SAC3F;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,0CAA0C;YACvD,OAAO,EAAE,KAAK;SACf;KACF;IACD,OAAO,EAAE,IAAA,0BAAW,EAAC,OAAO,CAAC;CAC9B,CAAC","debugId":"7d6dd7d6-e567-56ed-a00a-fb1b0fbbcb09"}
@@ -0,0 +1,11 @@
1
+ import { CommandModule } from "yargs";
2
+ interface Options {
3
+ apiToken?: string | null | undefined;
4
+ replayId: string | undefined;
5
+ testRunId: string | undefined;
6
+ commitSha: string | undefined;
7
+ screenshotName: string | undefined;
8
+ json: boolean;
9
+ }
10
+ export declare const jsCoverageCommand: CommandModule<unknown, Options>;
11
+ export {};
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="8ab59c0a-1e32-51df-a4a5-0bf5ab020386")}catch(e){}}();
3
+
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.jsCoverageCommand = void 0;
6
+ const client_1 = require("@alwaysmeticulous/client");
7
+ const common_1 = require("@alwaysmeticulous/common");
8
+ const sentry_utils_1 = require("../../command-utils/sentry.utils");
9
+ const cli_user_error_1 = require("../../utils/cli-user-error");
10
+ const format_coverage_ranges_1 = require("../../utils/format-coverage-ranges");
11
+ const resolve_test_run_from_commit_1 = require("../../utils/resolve-test-run-from-commit");
12
+ const log = (...args) => process.stderr.write(args.join(" ") + "\n");
13
+ const handler = async ({ apiToken, replayId, testRunId, commitSha, screenshotName, json, }) => {
14
+ (0, common_1.initLogger)();
15
+ if (screenshotName != null && replayId == null) {
16
+ throw new cli_user_error_1.CliUserError("--screenshotName only applies to --replayId.");
17
+ }
18
+ const apiToken_ = await (0, client_1.resolveApiTokenWithOAuth)({
19
+ apiToken,
20
+ enableOAuthLogin: true,
21
+ });
22
+ const client = (0, client_1.createClient)({ apiToken: apiToken_ });
23
+ // --replayId takes precedence: repo file paths are resolved against the run
24
+ // that executed the replay, and a --testRunId / --commitSha passed alongside
25
+ // it acts as a membership gate / disambiguator (see below) rather than
26
+ // selecting test-run coverage.
27
+ if (replayId != null) {
28
+ await printReplayCoverage(client, apiToken_, {
29
+ replayId,
30
+ screenshotName,
31
+ testRunId,
32
+ commitSha,
33
+ json,
34
+ });
35
+ }
36
+ else {
37
+ if (testRunId != null && commitSha != null) {
38
+ throw new cli_user_error_1.CliUserError("Pass either --testRunId or --commitSha, not both.");
39
+ }
40
+ // Test-run coverage: use --testRunId, else resolve the run from --commitSha
41
+ // or, when neither is given, from the local checkout's HEAD. Either way the
42
+ // run must have finished for coverage to exist.
43
+ if (testRunId != null) {
44
+ await (0, resolve_test_run_from_commit_1.throwIfTestRunCoverageNotReady)(client, testRunId);
45
+ await printTestRunCoverage(client, testRunId, json);
46
+ }
47
+ else {
48
+ const resolvedTestRunId = await resolveCompletedTestRunIdForCommit(client, apiToken_, commitSha);
49
+ await printTestRunCoverage(client, resolvedTestRunId, json);
50
+ }
51
+ }
52
+ };
53
+ // Resolves a commit to a test run for coverage. Coverage only exists once a run
54
+ // has finished, so an in-progress run is reported as not-yet-available rather
55
+ // than queried.
56
+ const resolveCompletedTestRunIdForCommit = async (client, apiToken, commitSha) => {
57
+ const { testRunId, status } = await (0, resolve_test_run_from_commit_1.resolveTestRunForCommitOrThrow)(client, apiToken, commitSha);
58
+ if ((0, resolve_test_run_from_commit_1.isTestRunInProgress)(status)) {
59
+ throw new cli_user_error_1.CliUserError(`Test run ${testRunId} for this commit is still in progress (status: ${status}); coverage is not available yet.`);
60
+ }
61
+ return testRunId;
62
+ };
63
+ const printReplayCoverage = async (client, apiToken, { replayId, screenshotName, testRunId, commitSha, json, }) => {
64
+ // An explicit --commitSha selects the run client-side (the endpoint only
65
+ // understands testRunId); --testRunId is passed through as-is.
66
+ const effectiveTestRunId = testRunId ??
67
+ (commitSha != null
68
+ ? await resolveCompletedTestRunIdForCommit(client, apiToken, commitSha)
69
+ : undefined);
70
+ try {
71
+ const result = await (0, client_1.getReplayJsCoverage)(client, replayId, {
72
+ screenshotName,
73
+ testRunId: effectiveTestRunId,
74
+ });
75
+ printReplayResult(result, json);
76
+ }
77
+ catch (error) {
78
+ // When the caller gave us no run to anchor on and the replay is the head of
79
+ // several runs, the endpoint can't pick one. Fall back to the run for the
80
+ // local checkout's HEAD and retry; if that can't be resolved, surface the
81
+ // original (actionable "pass testRunId") error unchanged.
82
+ if (effectiveTestRunId == null && isAmbiguousTestRunError(error)) {
83
+ const fallback = await (0, resolve_test_run_from_commit_1.tryResolveTestRunForCommit)(client, apiToken, undefined);
84
+ // Only retry against a finished run — an in-progress one has no coverage.
85
+ if (fallback != null && !(0, resolve_test_run_from_commit_1.isTestRunInProgress)(fallback.status)) {
86
+ try {
87
+ const result = await (0, client_1.getReplayJsCoverage)(client, replayId, {
88
+ screenshotName,
89
+ testRunId: fallback.testRunId,
90
+ });
91
+ // Only announce the fallback once it has actually worked, so a doomed
92
+ // retry doesn't leave a misleading "retrying against run X" line.
93
+ log(`Replay is the head of multiple test runs; resolved coverage against test run ${fallback.testRunId} from the local commit.`);
94
+ printReplayResult(result, json);
95
+ return;
96
+ }
97
+ catch {
98
+ // The local-HEAD run doesn't contain this replay (e.g. inspecting a
99
+ // replay from a different commit), so it can't disambiguate. Surface
100
+ // the original, actionable "pass --testRunId" error instead.
101
+ throw error;
102
+ }
103
+ }
104
+ }
105
+ throw error;
106
+ }
107
+ };
108
+ const printReplayResult = (result, json) => {
109
+ if (json) {
110
+ console.log(JSON.stringify(result, null, 2));
111
+ return;
112
+ }
113
+ console.log(["repoFilePath", "executedRanges"].join("\t"));
114
+ // Replay coverage is keyed by repo path (source-map paths that don't resolve
115
+ // are dropped), matching the test-run shape.
116
+ const files = result.files ?? [];
117
+ for (const [filePath, ranges] of files) {
118
+ console.log([filePath, (0, format_coverage_ranges_1.formatCoverageRanges)(ranges)].join("\t"));
119
+ }
120
+ log(`${files.length} file(s) with coverage`);
121
+ };
122
+ const printTestRunCoverage = async (client, testRunId, json) => {
123
+ const result = await (0, client_1.getTestRunJsCoverage)(client, testRunId);
124
+ if (json) {
125
+ console.log(JSON.stringify(result, null, 2));
126
+ return;
127
+ }
128
+ console.log(["repoFilePath", "executedRanges"].join("\t"));
129
+ // Test-run coverage is the precomputed repo-mapped coverage, keyed by repo paths.
130
+ for (const [filePath, ranges] of result.files) {
131
+ console.log([filePath, (0, format_coverage_ranges_1.formatCoverageRanges)(ranges)].join("\t"));
132
+ }
133
+ log(`${result.files.length} file(s) with coverage`);
134
+ };
135
+ const isAmbiguousTestRunError = (error) => (0, client_1.isFetchError)(error) &&
136
+ error.response?.data?.reason ===
137
+ "ambiguous-test-run";
138
+ exports.jsCoverageCommand = {
139
+ command: "js-coverage",
140
+ describe: "Get JS coverage for a single replay or a whole test run (use js-coverage-diff for base vs head)",
141
+ builder: {
142
+ apiToken: { string: true, description: "Meticulous API token" },
143
+ replayId: {
144
+ string: true,
145
+ description: "The replay ID. Pass the base or head replay to get each side's coverage. Repo file paths are resolved against the run that executed the replay; --testRunId / --commitSha may be combined to disambiguate when the replay was the head of more than one run.",
146
+ },
147
+ testRunId: {
148
+ string: true,
149
+ description: "The test run ID. On its own, returns coverage for the whole test run. Combined with --replayId, the replay must belong to this run (head or base); if it was this run's head, paths resolve against this run, otherwise against the replay's own execution run.",
150
+ },
151
+ commitSha: {
152
+ string: true,
153
+ description: "A commit SHA, used as an alternative to --testRunId: the latest test run for the commit is resolved and used. For whole-test-run coverage, defaults to the local git HEAD when neither --testRunId nor --commitSha is given.",
154
+ },
155
+ screenshotName: {
156
+ string: true,
157
+ description: 'Screenshot name (e.g. "after-event-5" or "end-state"), for use with --replayId. Omit for the whole replay.',
158
+ },
159
+ json: {
160
+ boolean: true,
161
+ description: "Output the raw coverage response as JSON",
162
+ default: false,
163
+ },
164
+ },
165
+ handler: (0, sentry_utils_1.wrapHandler)(handler),
166
+ };
167
+ //# sourceMappingURL=js-coverage.command.js.map
168
+ //# debugId=8ab59c0a-1e32-51df-a4a5-0bf5ab020386
@@ -0,0 +1 @@
1
+ {"version":3,"file":"js-coverage.command.js","sources":["../../../src/commands/agent/js-coverage.command.ts"],"sourceRoot":"","names":[],"mappings":"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","debugId":"8ab59c0a-1e32-51df-a4a5-0bf5ab020386"}
@@ -1,7 +1,9 @@
1
1
  import { CommandModule } from "yargs";
2
2
  interface Options {
3
3
  apiToken?: string | null | undefined;
4
- testRunId: string;
4
+ testRunId: string | undefined;
5
+ commitSha: string | undefined;
6
+ waitForTestRunToComplete: boolean;
5
7
  includeMatches: boolean;
6
8
  includeReplayIds: boolean;
7
9
  verbose: boolean;
@@ -1,23 +1,53 @@
1
1
  "use strict";
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3eb8fec4-bccd-5f49-818f-8564a21113f8")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="799834e7-f63d-5e41-94e9-921895a4d6a9")}catch(e){}}();
3
3
 
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.testRunDiffsCommand = void 0;
6
6
  const client_1 = require("@alwaysmeticulous/client");
7
7
  const common_1 = require("@alwaysmeticulous/common");
8
8
  const sentry_utils_1 = require("../../command-utils/sentry.utils");
9
+ const cli_user_error_1 = require("../../utils/cli-user-error");
10
+ const resolve_test_run_from_commit_1 = require("../../utils/resolve-test-run-from-commit");
9
11
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
10
12
  const fmtMismatch = (v) => v != null ? v.toFixed(5) : "";
11
13
  const log = (...args) => process.stderr.write(args.join(" ") + "\n");
12
- const handler = async ({ apiToken, testRunId, includeMatches, includeReplayIds, verbose, }) => {
14
+ const handler = async ({ apiToken, testRunId, commitSha, waitForTestRunToComplete, includeMatches, includeReplayIds, verbose, }) => {
13
15
  (0, common_1.initLogger)();
14
- const client = await (0, client_1.createClientWithOAuth)({
16
+ if (testRunId != null && commitSha != null) {
17
+ throw new cli_user_error_1.CliUserError("Pass either --testRunId or --commitSha, not both.");
18
+ }
19
+ const apiToken_ = await (0, client_1.resolveApiTokenWithOAuth)({
15
20
  apiToken,
16
21
  enableOAuthLogin: true,
17
22
  });
23
+ const client = (0, client_1.createClient)({ apiToken: apiToken_ });
24
+ // Use --testRunId, else resolve the run from --commitSha or, when neither is
25
+ // given, from the local checkout's HEAD.
26
+ let resolvedTestRunId;
27
+ let status;
28
+ if (testRunId != null) {
29
+ resolvedTestRunId = testRunId;
30
+ status = (await (0, client_1.getTestRun)({ client, testRunId })).status;
31
+ }
32
+ else {
33
+ const run = await (0, resolve_test_run_from_commit_1.resolveTestRunForCommitOrThrow)(client, apiToken_, commitSha);
34
+ resolvedTestRunId = run.testRunId;
35
+ status = run.status;
36
+ }
37
+ // Diffs are only meaningful once the run has finished. If it is still running
38
+ // and the caller didn't opt to wait, report it and stop — regardless of how
39
+ // the run was selected.
40
+ if ((0, resolve_test_run_from_commit_1.isTestRunInProgress)(status) && !waitForTestRunToComplete) {
41
+ log(`Test run ${resolvedTestRunId} is still in progress (status: ${status}); ` +
42
+ "pass --waitForTestRunToComplete to block until it finishes and then show diffs.");
43
+ return;
44
+ }
45
+ if (waitForTestRunToComplete) {
46
+ await (0, resolve_test_run_from_commit_1.awaitTestRunCompletion)(client, resolvedTestRunId);
47
+ }
18
48
  const t0 = performance.now();
19
- log(`Fetching diffs summary for test run ${testRunId}...`);
20
- let response = await (0, client_1.getTestRunDiffsSummary)(client, testRunId, {
49
+ log(`Fetching diffs summary for test run ${resolvedTestRunId}...`);
50
+ let response = await (0, client_1.getTestRunDiffsSummary)(client, resolvedTestRunId, {
21
51
  includeReplayIds,
22
52
  includeMatches,
23
53
  });
@@ -26,7 +56,7 @@ const handler = async ({ apiToken, testRunId, includeMatches, includeReplayIds,
26
56
  if (verbose)
27
57
  log(`Status: ${response.status}`);
28
58
  await sleep(2000);
29
- response = await (0, client_1.getTestRunDiffsSummary)(client, testRunId, {
59
+ response = await (0, client_1.getTestRunDiffsSummary)(client, resolvedTestRunId, {
30
60
  includeReplayIds,
31
61
  includeMatches,
32
62
  });
@@ -83,8 +113,16 @@ exports.testRunDiffsCommand = {
83
113
  apiToken: { string: true, description: "Meticulous API token" },
84
114
  testRunId: {
85
115
  string: true,
86
- description: "The test run ID",
87
- demandOption: true,
116
+ description: "The test run ID. When omitted, the run is resolved from --commitSha, or from the local git HEAD when that is also omitted.",
117
+ },
118
+ commitSha: {
119
+ string: true,
120
+ description: "A commit SHA, used as an alternative to --testRunId: the latest test run for the commit is resolved and used. Defaults to the local git HEAD when neither --testRunId nor --commitSha is given.",
121
+ },
122
+ waitForTestRunToComplete: {
123
+ boolean: true,
124
+ default: false,
125
+ description: "If the test run is still in progress, block until it finishes before fetching diffs (otherwise an in-progress run is reported and the command exits).",
88
126
  },
89
127
  includeMatches: {
90
128
  boolean: true,
@@ -105,4 +143,4 @@ exports.testRunDiffsCommand = {
105
143
  handler: (0, sentry_utils_1.wrapHandler)(handler),
106
144
  };
107
145
  //# sourceMappingURL=test-run-diffs.command.js.map
108
- //# debugId=3eb8fec4-bccd-5f49-818f-8564a21113f8
146
+ //# debugId=799834e7-f63d-5e41-94e9-921895a4d6a9
@@ -1 +1 @@
1
- {"version":3,"file":"test-run-diffs.command.js","sources":["../../../src/commands/agent/test-run-diffs.command.ts"],"sourceRoot":"","names":[],"mappings":"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","debugId":"3eb8fec4-bccd-5f49-818f-8564a21113f8"}
1
+ {"version":3,"file":"test-run-diffs.command.js","sources":["../../../src/commands/agent/test-run-diffs.command.ts"],"sourceRoot":"","names":[],"mappings":"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","debugId":"799834e7-f63d-5e41-94e9-921895a4d6a9"}
@@ -0,0 +1,9 @@
1
+ import { CommandModule } from "yargs";
2
+ interface Options {
3
+ apiToken?: string | null | undefined;
4
+ commitSha: string | undefined;
5
+ waitForTestRunToComplete: boolean;
6
+ json: boolean;
7
+ }
8
+ export declare const testRunForCommitCommand: CommandModule<unknown, Options>;
9
+ export {};
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6ee01030-17bf-51f5-8c85-eb1bd6a1fb1e")}catch(e){}}();
3
+
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.testRunForCommitCommand = void 0;
6
+ const client_1 = require("@alwaysmeticulous/client");
7
+ const common_1 = require("@alwaysmeticulous/common");
8
+ const sentry_utils_1 = require("../../command-utils/sentry.utils");
9
+ const cli_user_error_1 = require("../../utils/cli-user-error");
10
+ const resolve_project_identifier_1 = require("../../utils/resolve-project-identifier");
11
+ const resolve_test_run_from_commit_1 = require("../../utils/resolve-test-run-from-commit");
12
+ const log = (...args) => process.stderr.write(args.join(" ") + "\n");
13
+ const handler = async ({ apiToken, commitSha, waitForTestRunToComplete, json, }) => {
14
+ (0, common_1.initLogger)();
15
+ // Default to the current checkout's HEAD so the command can be run with no
16
+ // arguments to auto-infer the test run for the working tree.
17
+ const resolvedCommitSha = await (0, common_1.getCommitSha)(commitSha);
18
+ if (!resolvedCommitSha) {
19
+ throw new cli_user_error_1.CliUserError("Could not determine a commit SHA. Pass --commitSha or run inside a git repository.");
20
+ }
21
+ const apiToken_ = await (0, client_1.resolveApiTokenWithOAuth)({
22
+ apiToken,
23
+ enableOAuthLogin: true,
24
+ });
25
+ // Project-scoped tokens pin the project (resolves to `{}`); OAuth tokens use
26
+ // the project chosen via `meticulous auth set-project`.
27
+ const { projectId } = (0, resolve_project_identifier_1.resolveProjectIdentifier)(apiToken_);
28
+ const client = (0, client_1.createClient)({ apiToken: apiToken_ });
29
+ let result = await (0, client_1.getTestRunForCommit)(client, resolvedCommitSha, {
30
+ projectId,
31
+ });
32
+ if (result.testRunId != null &&
33
+ result.status != null &&
34
+ waitForTestRunToComplete &&
35
+ (0, resolve_test_run_from_commit_1.isTestRunInProgress)(result.status)) {
36
+ const status = await (0, resolve_test_run_from_commit_1.awaitTestRunCompletion)(client, result.testRunId);
37
+ result = { ...result, status };
38
+ }
39
+ if (json) {
40
+ console.log(JSON.stringify(result, null, 2));
41
+ return;
42
+ }
43
+ if (result.testRunId == null) {
44
+ log(`No test run found for commit ${resolvedCommitSha}`);
45
+ return;
46
+ }
47
+ console.log(result.testRunId);
48
+ if (result.status != null && (0, resolve_test_run_from_commit_1.isTestRunInProgress)(result.status)) {
49
+ log(`Test run is still in progress (status: ${result.status}); ` +
50
+ "pass --waitForTestRunToComplete to block until it finishes.");
51
+ }
52
+ };
53
+ exports.testRunForCommitCommand = {
54
+ command: "test-run-for-commit",
55
+ describe: "Look up the latest test run for a commit (defaults to the current git HEAD)",
56
+ builder: {
57
+ apiToken: { string: true, description: "Meticulous API token" },
58
+ commitSha: {
59
+ string: true,
60
+ description: "Commit SHA to look up. Defaults to the current git HEAD when omitted.",
61
+ },
62
+ waitForTestRunToComplete: {
63
+ boolean: true,
64
+ default: false,
65
+ description: "If the matched test run is still in progress, block until it finishes before returning.",
66
+ },
67
+ json: {
68
+ boolean: true,
69
+ description: "Output the raw response as JSON",
70
+ default: false,
71
+ },
72
+ },
73
+ handler: (0, sentry_utils_1.wrapHandler)(handler),
74
+ };
75
+ //# sourceMappingURL=test-run-for-commit.command.js.map
76
+ //# debugId=6ee01030-17bf-51f5-8c85-eb1bd6a1fb1e
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-run-for-commit.command.js","sources":["../../../src/commands/agent/test-run-for-commit.command.ts"],"sourceRoot":"","names":[],"mappings":"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","debugId":"6ee01030-17bf-51f5-8c85-eb1bd6a1fb1e"}
@@ -0,0 +1,7 @@
1
+ import { CompactRange } from "@alwaysmeticulous/client";
2
+ /**
3
+ * Formats compact line ranges for TSV output, e.g. `[[1, 1], [4, 9]]` becomes
4
+ * `"1;4-9"`. A single-line range (`start === end`) is rendered as just the line
5
+ * number.
6
+ */
7
+ export declare const formatCoverageRanges: (ranges: CompactRange[]) => string;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="113db5c7-d290-522f-ae19-a67ddabc8608")}catch(e){}}();
3
+
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.formatCoverageRanges = void 0;
6
+ /**
7
+ * Formats compact line ranges for TSV output, e.g. `[[1, 1], [4, 9]]` becomes
8
+ * `"1;4-9"`. A single-line range (`start === end`) is rendered as just the line
9
+ * number.
10
+ */
11
+ const formatCoverageRanges = (ranges) => ranges
12
+ .map(([start, end]) => (start === end ? `${start}` : `${start}-${end}`))
13
+ .join(";");
14
+ exports.formatCoverageRanges = formatCoverageRanges;
15
+ //# sourceMappingURL=format-coverage-ranges.js.map
16
+ //# debugId=113db5c7-d290-522f-ae19-a67ddabc8608
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-coverage-ranges.js","sources":["../../src/utils/format-coverage-ranges.ts"],"sourceRoot":"","names":[],"mappings":";;;;;AAEA;;;;GAIG;AACI,MAAM,oBAAoB,GAAG,CAAC,MAAsB,EAAU,EAAE,CACrE,MAAM;KACH,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;KACvE,IAAI,CAAC,GAAG,CAAC,CAAC;AAHF,QAAA,oBAAoB,wBAGlB","debugId":"113db5c7-d290-522f-ae19-a67ddabc8608"}
@@ -0,0 +1,33 @@
1
+ import { TestRunStatus } from "@alwaysmeticulous/api";
2
+ import { MeticulousClient } from "@alwaysmeticulous/client";
3
+ export interface ResolvedTestRun {
4
+ testRunId: string;
5
+ status: TestRunStatus;
6
+ }
7
+ /** Whether a status means the run is still running (not yet usable). */
8
+ export declare const isTestRunInProgress: (status: TestRunStatus) => boolean;
9
+ /**
10
+ * Resolves the latest test run (including one in progress) from a commit (an
11
+ * explicit `commitSha`, or the local checkout's HEAD when omitted), throwing a
12
+ * `CliUserError` when the commit can't be determined or no run matches it.
13
+ */
14
+ export declare const resolveTestRunForCommitOrThrow: (client: MeticulousClient, apiToken: string, commitSha: string | undefined) => Promise<ResolvedTestRun>;
15
+ /**
16
+ * Best-effort variant for auto-retry paths: returns `null` (rather than
17
+ * throwing) when the commit can't be determined, no project is selected, or no
18
+ * run matches, so the caller can fall back to its original behaviour.
19
+ */
20
+ export declare const tryResolveTestRunForCommit: (client: MeticulousClient, apiToken: string, commitSha: string | undefined) => Promise<ResolvedTestRun | null>;
21
+ /**
22
+ * Throws a `CliUserError` if the given test run is still in progress, since
23
+ * coverage only exists once a run has finished. Used to guard an explicitly
24
+ * passed `testRunId`, mirroring the in-progress check applied to runs resolved
25
+ * from a commit.
26
+ */
27
+ export declare const throwIfTestRunCoverageNotReady: (client: MeticulousClient, testRunId: string) => Promise<void>;
28
+ /**
29
+ * Polls a (possibly in-progress) test run until it reaches a terminal status,
30
+ * logging each transition. Throws a `CliUserError` if the run finishes
31
+ * unsuccessfully (`ExecutionError`/`Aborted`). Returns the final status.
32
+ */
33
+ export declare const awaitTestRunCompletion: (client: MeticulousClient, testRunId: string) => Promise<TestRunStatus>;
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="caa70eb2-71ac-5c1c-ada9-44e904ea061a")}catch(e){}}();
3
+
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.awaitTestRunCompletion = exports.throwIfTestRunCoverageNotReady = exports.tryResolveTestRunForCommit = exports.resolveTestRunForCommitOrThrow = exports.isTestRunInProgress = void 0;
6
+ const client_1 = require("@alwaysmeticulous/client");
7
+ const common_1 = require("@alwaysmeticulous/common");
8
+ const cli_user_error_1 = require("./cli-user-error");
9
+ const resolve_project_identifier_1 = require("./resolve-project-identifier");
10
+ const POLL_INTERVAL_MS = 10_000;
11
+ const log = (...args) => process.stderr.write(args.join(" ") + "\n");
12
+ /** Whether a status means the run is still running (not yet usable). */
13
+ const isTestRunInProgress = (status) => client_1.IN_PROGRESS_TEST_RUN_STATUS.includes(status);
14
+ exports.isTestRunInProgress = isTestRunInProgress;
15
+ /**
16
+ * Resolves the latest test run (including one in progress) from a commit (an
17
+ * explicit `commitSha`, or the local checkout's HEAD when omitted), throwing a
18
+ * `CliUserError` when the commit can't be determined or no run matches it.
19
+ */
20
+ const resolveTestRunForCommitOrThrow = async (client, apiToken, commitSha) => {
21
+ const sha = await (0, common_1.getCommitSha)(commitSha);
22
+ if (!sha) {
23
+ throw new cli_user_error_1.CliUserError("Could not determine a commit SHA. Pass --commitSha or --testRunId, or run inside a git repository.");
24
+ }
25
+ const { projectId } = (0, resolve_project_identifier_1.resolveProjectIdentifier)(apiToken);
26
+ const { testRunId, status } = await (0, client_1.getTestRunForCommit)(client, sha, {
27
+ projectId,
28
+ });
29
+ if (testRunId == null || status == null) {
30
+ throw new cli_user_error_1.CliUserError(`No test run found for commit ${sha}.`);
31
+ }
32
+ log(`Resolved test run ${testRunId} for commit ${sha} (status: ${status}).`);
33
+ return { testRunId, status };
34
+ };
35
+ exports.resolveTestRunForCommitOrThrow = resolveTestRunForCommitOrThrow;
36
+ /**
37
+ * Best-effort variant for auto-retry paths: returns `null` (rather than
38
+ * throwing) when the commit can't be determined, no project is selected, or no
39
+ * run matches, so the caller can fall back to its original behaviour.
40
+ */
41
+ const tryResolveTestRunForCommit = async (client, apiToken, commitSha) => {
42
+ try {
43
+ const sha = await (0, common_1.getCommitSha)(commitSha);
44
+ if (!sha) {
45
+ return null;
46
+ }
47
+ const { projectId } = (0, resolve_project_identifier_1.resolveProjectIdentifier)(apiToken);
48
+ const { testRunId, status } = await (0, client_1.getTestRunForCommit)(client, sha, {
49
+ projectId,
50
+ });
51
+ return testRunId != null && status != null
52
+ ? { testRunId, status }
53
+ : null;
54
+ }
55
+ catch (error) {
56
+ // A CliUserError (e.g. no project selected for an OAuth caller) is an
57
+ // actionable configuration problem the user must address, not a reason to
58
+ // silently skip the fallback — let it propagate so its message surfaces.
59
+ if (error instanceof cli_user_error_1.CliUserError) {
60
+ throw error;
61
+ }
62
+ return null;
63
+ }
64
+ };
65
+ exports.tryResolveTestRunForCommit = tryResolveTestRunForCommit;
66
+ /**
67
+ * Throws a `CliUserError` if the given test run is still in progress, since
68
+ * coverage only exists once a run has finished. Used to guard an explicitly
69
+ * passed `testRunId`, mirroring the in-progress check applied to runs resolved
70
+ * from a commit.
71
+ */
72
+ const throwIfTestRunCoverageNotReady = async (client, testRunId) => {
73
+ const testRun = await (0, client_1.getTestRun)({ client, testRunId });
74
+ if ((0, exports.isTestRunInProgress)(testRun.status)) {
75
+ throw new cli_user_error_1.CliUserError(`Test run ${testRunId} is still in progress (status: ${testRun.status}); coverage is not available yet.`);
76
+ }
77
+ };
78
+ exports.throwIfTestRunCoverageNotReady = throwIfTestRunCoverageNotReady;
79
+ /**
80
+ * Polls a (possibly in-progress) test run until it reaches a terminal status,
81
+ * logging each transition. Throws a `CliUserError` if the run finishes
82
+ * unsuccessfully (`ExecutionError`/`Aborted`). Returns the final status.
83
+ */
84
+ const awaitTestRunCompletion = async (client, testRunId) => {
85
+ let testRun = await (0, client_1.getTestRun)({ client, testRunId });
86
+ if ((0, exports.isTestRunInProgress)(testRun.status)) {
87
+ log(`Waiting for test run ${testRunId} to complete...`);
88
+ }
89
+ while ((0, exports.isTestRunInProgress)(testRun.status)) {
90
+ await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
91
+ testRun = await (0, client_1.getTestRun)({ client, testRunId });
92
+ log(`Test run status: ${testRun.status}`);
93
+ }
94
+ if (testRun.status === "ExecutionError" || testRun.status === "Aborted") {
95
+ throw new cli_user_error_1.CliUserError(`Test run ${testRunId} finished unsuccessfully (status: ${testRun.status}).`);
96
+ }
97
+ return testRun.status;
98
+ };
99
+ exports.awaitTestRunCompletion = awaitTestRunCompletion;
100
+ //# sourceMappingURL=resolve-test-run-from-commit.js.map
101
+ //# debugId=caa70eb2-71ac-5c1c-ada9-44e904ea061a
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-test-run-from-commit.js","sources":["../../src/utils/resolve-test-run-from-commit.ts"],"sourceRoot":"","names":[],"mappings":"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","debugId":"caa70eb2-71ac-5c1c-ada9-44e904ea061a"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alwaysmeticulous/cli",
3
- "version": "2.292.1",
3
+ "version": "2.293.0",
4
4
  "description": "The Meticulous CLI",
5
5
  "license": "ISC",
6
6
  "main": "dist/index.js",
@@ -23,18 +23,18 @@
23
23
  "puppeteer-core": "24.14.0",
24
24
  "tar": "^7.5.8",
25
25
  "yargs": "^17.5.1",
26
- "@alwaysmeticulous/api": "2.292.1",
27
- "@alwaysmeticulous/client": "2.292.1",
28
- "@alwaysmeticulous/common": "2.290.3",
29
- "@alwaysmeticulous/debug-workspace": "2.292.1",
30
- "@alwaysmeticulous/downloading-helpers": "2.292.1",
31
- "@alwaysmeticulous/record": "2.292.1",
32
- "@alwaysmeticulous/remote-replay-launcher": "2.292.1",
26
+ "@alwaysmeticulous/api": "2.293.0",
27
+ "@alwaysmeticulous/client": "2.293.0",
28
+ "@alwaysmeticulous/common": "2.293.0",
29
+ "@alwaysmeticulous/debug-workspace": "2.293.0",
30
+ "@alwaysmeticulous/downloading-helpers": "2.293.0",
31
+ "@alwaysmeticulous/record": "2.293.0",
32
+ "@alwaysmeticulous/remote-replay-launcher": "2.293.0",
33
33
  "@alwaysmeticulous/replay-debugger-ui": "2.283.1",
34
- "@alwaysmeticulous/replay-orchestrator-launcher": "2.292.1",
35
- "@alwaysmeticulous/sdk-bundles-api": "2.292.1",
36
- "@alwaysmeticulous/sentry": "2.290.3",
37
- "@alwaysmeticulous/tunnels-client": "2.290.3"
34
+ "@alwaysmeticulous/replay-orchestrator-launcher": "2.293.0",
35
+ "@alwaysmeticulous/sdk-bundles-api": "2.293.0",
36
+ "@alwaysmeticulous/sentry": "2.293.0",
37
+ "@alwaysmeticulous/tunnels-client": "2.293.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/cli-progress": "^3.11.5",