devharness 0.9.14 → 0.9.16
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/build/github/issue-body.d.ts +4 -4
- package/build/mcp-supervisor.js +60 -2
- package/build/mcp-supervisor.js.map +1 -1
- package/build/supervisor/client-watcher.d.ts +13 -2
- package/build/supervisor/client-watcher.d.ts.map +1 -1
- package/build/supervisor/client-watcher.js +60 -16
- package/build/supervisor/client-watcher.js.map +1 -1
- package/build/supervisor/client-watcher.test.js +110 -3
- package/build/supervisor/client-watcher.test.js.map +1 -1
- package/build/supervisor/stderr-log.d.ts +29 -0
- package/build/supervisor/stderr-log.d.ts.map +1 -0
- package/build/supervisor/stderr-log.js +52 -0
- package/build/supervisor/stderr-log.js.map +1 -0
- package/build/supervisor/stderr-log.test.d.ts +9 -0
- package/build/supervisor/stderr-log.test.d.ts.map +1 -0
- package/build/supervisor/stderr-log.test.js +80 -0
- package/build/supervisor/stderr-log.test.js.map +1 -0
- package/build/tools/issues-tools.d.ts.map +1 -1
- package/build/tools/issues-tools.js +29 -3
- package/build/tools/issues-tools.js.map +1 -1
- package/build/tools/issues-tools.test.js +86 -0
- package/build/tools/issues-tools.test.js.map +1 -1
- package/build/tools/replay-executor.d.ts +9 -0
- package/build/tools/replay-executor.d.ts.map +1 -1
- package/build/tools/replay-executor.js +15 -1
- package/build/tools/replay-executor.js.map +1 -1
- package/build/tools/replay-nested-rebase.test.d.ts +15 -0
- package/build/tools/replay-nested-rebase.test.d.ts.map +1 -0
- package/build/tools/replay-nested-rebase.test.js +139 -0
- package/build/tools/replay-nested-rebase.test.js.map +1 -0
- package/build/tools/replay-rebase.test.js +25 -0
- package/build/tools/replay-rebase.test.js.map +1 -1
- package/build/tools/replay-run-all-parity.test.d.ts +2 -0
- package/build/tools/replay-run-all-parity.test.d.ts.map +1 -0
- package/build/tools/replay-run-all-parity.test.js +90 -0
- package/build/tools/replay-run-all-parity.test.js.map +1 -0
- package/build/tools/replay-tools.d.ts +21 -21
- package/build/tools/replay-tools.d.ts.map +1 -1
- package/build/tools/replay-tools.js +17 -8
- package/build/tools/replay-tools.js.map +1 -1
- package/docs/instructions.md +3 -2
- package/docs/messages.md +3 -2
- package/docs/replay.md +17 -4
- package/package.json +1 -1
- package/plugin/skills/devharness/SKILL.md +1 -1
- package/plugin/skills/devharness/references/tool-categories.md +1 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `runAll` fans `run` out over a folder, so a per-run option either carries or
|
|
3
|
+
* is deliberately withheld. Two carry that a suite needs:
|
|
4
|
+
*
|
|
5
|
+
* - `baseUrl` retargets every sequence at the same deployment. A suite that
|
|
6
|
+
* could only run against the recorded origin is a suite that can only test
|
|
7
|
+
* the machine it was recorded on.
|
|
8
|
+
* - `killChromeOnFinish` means the SUITE's finish, so only the last sequence
|
|
9
|
+
* carries it: passing it to each one tears down the browser between
|
|
10
|
+
* sequences and destroys the state a _helpers preamble established.
|
|
11
|
+
*
|
|
12
|
+
* The rest (startFrom/stepTo/stepCount/startUrl) address one specific
|
|
13
|
+
* sequence and are cleared.
|
|
14
|
+
*/
|
|
15
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
16
|
+
import { promises as fs } from 'fs';
|
|
17
|
+
import { tmpdir } from 'os';
|
|
18
|
+
import { join } from 'path';
|
|
19
|
+
import { CommandRecorder } from '../command-recorder.js';
|
|
20
|
+
import { createReplayTools } from './replay-tools.js';
|
|
21
|
+
import { productionShaped } from '../test-support/fake-execute-tool-call.js';
|
|
22
|
+
let dir;
|
|
23
|
+
let recorder;
|
|
24
|
+
let replay;
|
|
25
|
+
let gotoUrls;
|
|
26
|
+
let killCalls;
|
|
27
|
+
const writeSequence = async (name, url) => {
|
|
28
|
+
await fs.writeFile(join(dir, `${name}.json`), JSON.stringify({
|
|
29
|
+
id: `seq-${name}`, name, createdAt: 1,
|
|
30
|
+
commands: [{ tool: 'navigate', params: { action: 'goto', url, connectionReason: 'suite' } }],
|
|
31
|
+
}));
|
|
32
|
+
};
|
|
33
|
+
beforeEach(async () => {
|
|
34
|
+
dir = await fs.mkdtemp(join(tmpdir(), 'cdp-runall-parity-'));
|
|
35
|
+
recorder = new CommandRecorder();
|
|
36
|
+
gotoUrls = [];
|
|
37
|
+
killCalls = 0;
|
|
38
|
+
vi.spyOn(recorder, 'getSequencesDir').mockReturnValue(dir);
|
|
39
|
+
({ replay } = createReplayTools(recorder, vi.fn(productionShaped(async (tool, params) => {
|
|
40
|
+
if (tool === 'navigate' && params.action === 'goto')
|
|
41
|
+
gotoUrls.push(String(params.url));
|
|
42
|
+
if (tool === 'killChrome')
|
|
43
|
+
killCalls++;
|
|
44
|
+
return { content: [{ type: 'text', text: '' }] };
|
|
45
|
+
})), async () => null, // no page -> no cursor/overlay injection
|
|
46
|
+
async () => 9222, undefined));
|
|
47
|
+
});
|
|
48
|
+
afterEach(async () => {
|
|
49
|
+
recorder.stopSequenceWatch();
|
|
50
|
+
await fs.rm(dir, { recursive: true, force: true });
|
|
51
|
+
});
|
|
52
|
+
const runAll = (params = {}) => replay.handler({ action: 'runAll', ...params });
|
|
53
|
+
describe('runAll carries baseUrl', () => {
|
|
54
|
+
it('retargets every sequence in the suite', async () => {
|
|
55
|
+
await writeSequence('a-first', 'https://staging.example.com/one');
|
|
56
|
+
await writeSequence('b-second', 'https://staging.example.com/two?q=1');
|
|
57
|
+
await runAll({ baseUrl: 'https://cue-test.pages.dev', connectionReason: 'suite' });
|
|
58
|
+
expect(gotoUrls).toEqual([
|
|
59
|
+
'https://cue-test.pages.dev/one',
|
|
60
|
+
'https://cue-test.pages.dev/two?q=1',
|
|
61
|
+
]);
|
|
62
|
+
});
|
|
63
|
+
it('leaves the recorded origin in place when no baseUrl is given', async () => {
|
|
64
|
+
await writeSequence('a-first', 'https://staging.example.com/one');
|
|
65
|
+
await runAll({ connectionReason: 'suite' });
|
|
66
|
+
expect(gotoUrls).toEqual(['https://staging.example.com/one']);
|
|
67
|
+
});
|
|
68
|
+
it('does not write the retarget back to the sequence file', async () => {
|
|
69
|
+
await writeSequence('a-first', 'https://staging.example.com/one');
|
|
70
|
+
await runAll({ baseUrl: 'https://cue-test.pages.dev', connectionReason: 'suite' });
|
|
71
|
+
const onDisk = JSON.parse(await fs.readFile(join(dir, 'a-first.json'), 'utf-8'));
|
|
72
|
+
expect(onDisk.commands[0].params.url).toBe('https://staging.example.com/one');
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
describe('runAll carries killChromeOnFinish once', () => {
|
|
76
|
+
it('kills after the last sequence, not between them', async () => {
|
|
77
|
+
await writeSequence('a-first', 'https://staging.example.com/one');
|
|
78
|
+
await writeSequence('b-second', 'https://staging.example.com/two');
|
|
79
|
+
await runAll({ killChromeOnFinish: true, connectionReason: 'suite' });
|
|
80
|
+
expect(gotoUrls.length).toBe(2);
|
|
81
|
+
expect(killCalls).toBe(1);
|
|
82
|
+
});
|
|
83
|
+
it('kills nothing when it is not asked for', async () => {
|
|
84
|
+
await writeSequence('a-first', 'https://staging.example.com/one');
|
|
85
|
+
await writeSequence('b-second', 'https://staging.example.com/two');
|
|
86
|
+
await runAll({ connectionReason: 'suite' });
|
|
87
|
+
expect(killCalls).toBe(0);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
//# sourceMappingURL=replay-run-all-parity.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay-run-all-parity.test.js","sourceRoot":"","sources":["../../src/tools/replay-run-all-parity.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -115,6 +115,13 @@ getKnownToolNames?: () => string[]): {
|
|
|
115
115
|
connectionReason?: string | undefined;
|
|
116
116
|
stepTimeout?: number | undefined;
|
|
117
117
|
totalTimeout?: number | undefined;
|
|
118
|
+
requiredConnections?: {
|
|
119
|
+
reference: string;
|
|
120
|
+
profile?: string | undefined;
|
|
121
|
+
url?: string | undefined;
|
|
122
|
+
forceNewInstance?: boolean | undefined;
|
|
123
|
+
role?: string | undefined;
|
|
124
|
+
}[] | undefined;
|
|
118
125
|
limit?: number | undefined;
|
|
119
126
|
comment?: string | undefined;
|
|
120
127
|
stepTo?: number | undefined;
|
|
@@ -131,13 +138,6 @@ getKnownToolNames?: () => string[]): {
|
|
|
131
138
|
runId?: string | undefined;
|
|
132
139
|
format?: "sequence" | "playwright" | "puppeteer" | undefined;
|
|
133
140
|
intoHistory?: boolean | undefined;
|
|
134
|
-
requiredConnections?: {
|
|
135
|
-
reference: string;
|
|
136
|
-
profile?: string | undefined;
|
|
137
|
-
url?: string | undefined;
|
|
138
|
-
forceNewInstance?: boolean | undefined;
|
|
139
|
-
role?: string | undefined;
|
|
140
|
-
}[] | undefined;
|
|
141
141
|
tags?: string[] | undefined;
|
|
142
142
|
requiredSockets?: string[] | undefined;
|
|
143
143
|
connections?: Record<string, string> | undefined;
|
|
@@ -173,6 +173,13 @@ getKnownToolNames?: () => string[]): {
|
|
|
173
173
|
connectionReason?: string | undefined;
|
|
174
174
|
stepTimeout?: number | undefined;
|
|
175
175
|
totalTimeout?: number | undefined;
|
|
176
|
+
requiredConnections?: {
|
|
177
|
+
reference: string;
|
|
178
|
+
profile?: string | undefined;
|
|
179
|
+
url?: string | undefined;
|
|
180
|
+
forceNewInstance?: boolean | undefined;
|
|
181
|
+
role?: string | undefined;
|
|
182
|
+
}[] | undefined;
|
|
176
183
|
limit?: number | undefined;
|
|
177
184
|
comment?: string | undefined;
|
|
178
185
|
stepTo?: number | undefined;
|
|
@@ -189,13 +196,6 @@ getKnownToolNames?: () => string[]): {
|
|
|
189
196
|
runId?: string | undefined;
|
|
190
197
|
format?: "sequence" | "playwright" | "puppeteer" | undefined;
|
|
191
198
|
intoHistory?: boolean | undefined;
|
|
192
|
-
requiredConnections?: {
|
|
193
|
-
reference: string;
|
|
194
|
-
profile?: string | undefined;
|
|
195
|
-
url?: string | undefined;
|
|
196
|
-
forceNewInstance?: boolean | undefined;
|
|
197
|
-
role?: string | undefined;
|
|
198
|
-
}[] | undefined;
|
|
199
199
|
tags?: string[] | undefined;
|
|
200
200
|
requiredSockets?: string[] | undefined;
|
|
201
201
|
connections?: Record<string, string> | undefined;
|
|
@@ -238,6 +238,13 @@ getKnownToolNames?: () => string[]): {
|
|
|
238
238
|
connectionReason?: string | undefined;
|
|
239
239
|
stepTimeout?: number | undefined;
|
|
240
240
|
totalTimeout?: number | undefined;
|
|
241
|
+
requiredConnections?: {
|
|
242
|
+
reference: string;
|
|
243
|
+
profile?: string | undefined;
|
|
244
|
+
url?: string | undefined;
|
|
245
|
+
forceNewInstance?: boolean | undefined;
|
|
246
|
+
role?: string | undefined;
|
|
247
|
+
}[] | undefined;
|
|
241
248
|
limit?: number | undefined;
|
|
242
249
|
comment?: string | undefined;
|
|
243
250
|
stepTo?: number | undefined;
|
|
@@ -254,13 +261,6 @@ getKnownToolNames?: () => string[]): {
|
|
|
254
261
|
runId?: string | undefined;
|
|
255
262
|
format?: "sequence" | "playwright" | "puppeteer" | undefined;
|
|
256
263
|
intoHistory?: boolean | undefined;
|
|
257
|
-
requiredConnections?: {
|
|
258
|
-
reference: string;
|
|
259
|
-
profile?: string | undefined;
|
|
260
|
-
url?: string | undefined;
|
|
261
|
-
forceNewInstance?: boolean | undefined;
|
|
262
|
-
role?: string | undefined;
|
|
263
|
-
}[] | undefined;
|
|
264
264
|
tags?: string[] | undefined;
|
|
265
265
|
requiredSockets?: string[] | undefined;
|
|
266
266
|
connections?: Record<string, string> | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replay-tools.d.ts","sourceRoot":"","sources":["../../src/tools/replay-tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,eAAe,EAAyD,MAAM,wBAAwB,CAAC;AACrH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAgFnD,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EACnC,cAAc,EAAE,MAAM,EAAE,GACvB,eAAe,EAAE,CAWnB;
|
|
1
|
+
{"version":3,"file":"replay-tools.d.ts","sourceRoot":"","sources":["../../src/tools/replay-tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,eAAe,EAAyD,MAAM,wBAAwB,CAAC;AACrH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAgFnD,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EACnC,cAAc,EAAE,MAAM,EAAE,GACvB,eAAe,EAAE,CAWnB;AA4wGD,wBAAgB,iBAAiB,CAC/B,eAAe,EAAE,eAAe,EAChC,eAAe,EAAE,eAAe,EAChC,oBAAoB,CAAC,EAAE,CAAC,gBAAgB,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,EACjE,iBAAiB,CAAC,EAAE,CAAC,gBAAgB,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;AACxE;;;;;GAKG;AACH,iBAAiB,CAAC,EAAE,MAAM,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwDnC"}
|
|
@@ -133,7 +133,7 @@ const replaySchema = z.object({
|
|
|
133
133
|
description: z.string().optional(),
|
|
134
134
|
expectedOutcome: z.string().optional(),
|
|
135
135
|
startUrl: z.string().optional().describe('create: sequence start URL. run: replace the stored startUrl for this run only (e.g. a freshly minted link)'),
|
|
136
|
-
baseUrl: z.string().optional().describe('run: retarget
|
|
136
|
+
baseUrl: z.string().optional().describe('run/runAll: retarget at another deployment — every absolute URL (startUrl, command params, a declared connection\u2019s launch url) keeps its path/query but takes this origin, in the sequence itself and in every sequence it reaches through a conditional or forEach. On runAll it applies to every sequence in the suite. Not preserved across a mid-run pause/step resume'),
|
|
137
137
|
indices: z.array(z.number()).optional().describe('Command indices'),
|
|
138
138
|
lines: z.array(z.number()).optional().describe('Log line numbers'),
|
|
139
139
|
sequenceId: z.string().optional(),
|
|
@@ -184,7 +184,7 @@ const replaySchema = z.object({
|
|
|
184
184
|
strict: z.enum(['errors', 'warnings']).optional().describe("run/runAll: fail the run when it PRODUCES console output - 'errors' fails on new console errors, 'warnings' also fails on new warnings. Counted per connection and diffed against the start of the run, so pre-existing noise is not blamed on this sequence. A sequence can be functionally correct and still be logging; strict is how you separate those questions"),
|
|
185
185
|
folder: z.string().optional().describe("runAll: sequences subfolder to run, relative to the sequences dir (e.g. 'spine'). Omit to run every sequence outside folders whose name starts with '_'. The whole tree is always LOADED first so name references (a conditional's then, a forEach's do) resolve wherever the helper lives"),
|
|
186
186
|
continueOnFailure: z.boolean().optional().describe('runAll: keep going after a sequence fails and report every result (default true). false stops at the first failure'),
|
|
187
|
-
killChromeOnFinish: z.boolean().optional().describe("run: after finishing (skipped on pause/abort), kill the browsers this run owns - its own connection plus any a launchChrome step actually created. A step that reached an already-bound reference only borrowed that browser and it is left running, so an instance you launched yourself survives. Also skipped for any browser whose port another live connection shares (a launchChrome step usually opens a tab in the same instance), and the run reports which connection kept it alive."),
|
|
187
|
+
killChromeOnFinish: z.boolean().optional().describe("run/runAll: after finishing (skipped on pause/abort), kill the browsers this run owns - its own connection plus any a launchChrome step actually created. A step that reached an already-bound reference only borrowed that browser and it is left running, so an instance you launched yourself survives. Also skipped for any browser whose port another live connection shares (a launchChrome step usually opens a tab in the same instance), and the run reports which connection kept it alive. On runAll only the LAST sequence carries it, so a preamble's browser survives between sequences and a suite that stops early leaves the browsers up."),
|
|
188
188
|
}).strict();
|
|
189
189
|
async function handleHistory(args, recorder) {
|
|
190
190
|
const limit = args.limit || 50;
|
|
@@ -840,7 +840,13 @@ async function handleRunAll(args, recorder, executeToolCall, getPageForConnectio
|
|
|
840
840
|
}
|
|
841
841
|
const keepGoing = args.continueOnFailure !== false;
|
|
842
842
|
const results = [];
|
|
843
|
-
for (const entry of selected) {
|
|
843
|
+
for (const [index, entry] of selected.entries()) {
|
|
844
|
+
// killChromeOnFinish means the SUITE's finish here, not each sequence's: a
|
|
845
|
+
// teardown between sequences destroys the state a _helpers preamble just
|
|
846
|
+
// established. Only the last sequence carries it, so a suite that stops
|
|
847
|
+
// early (continueOnFailure: false, a cancel) leaves the browsers up for
|
|
848
|
+
// the failure to be read in.
|
|
849
|
+
const isLast = index === selected.length - 1;
|
|
844
850
|
if (abortSignal?.aborted) {
|
|
845
851
|
results.push({ filename: entry.filename, name: entry.name, ok: false, detail: 'cancelled before it ran' });
|
|
846
852
|
continue;
|
|
@@ -863,11 +869,11 @@ async function handleRunAll(args, recorder, executeToolCall, getPageForConnectio
|
|
|
863
869
|
// no-op that a caller then has to notice.
|
|
864
870
|
variables: args.variables ?? {},
|
|
865
871
|
// Per-run args that are actively wrong when fanned across a suite:
|
|
866
|
-
// killChromeOnFinish would tear down the browser between sequences and
|
|
867
|
-
// destroy the state a _helpers preamble just established, and
|
|
868
872
|
// startFrom/stepTo/stepCount/startUrl mean something only for one
|
|
869
|
-
// specific sequence.
|
|
870
|
-
|
|
873
|
+
// specific sequence. baseUrl does carry - it retargets every
|
|
874
|
+
// sequence at the same deployment, which is what a suite run of a
|
|
875
|
+
// recorded set against another environment needs.
|
|
876
|
+
killChromeOnFinish: isLast ? args.killChromeOnFinish : undefined,
|
|
871
877
|
startFrom: undefined,
|
|
872
878
|
stepTo: undefined,
|
|
873
879
|
stepCount: undefined,
|
|
@@ -1618,7 +1624,10 @@ async function performRun(deps, abortSignal, runId, onProgress) {
|
|
|
1618
1624
|
logPrefix: 'run',
|
|
1619
1625
|
variableStore: {},
|
|
1620
1626
|
launchedConnections,
|
|
1621
|
-
...(connectionMap && { connectionMap })
|
|
1627
|
+
...(connectionMap && { connectionMap }),
|
|
1628
|
+
// Carried on the context so nested sequences inherit the retarget; the
|
|
1629
|
+
// top-level sequence was already rebased in handleRun.
|
|
1630
|
+
...(args.baseUrl && { rebaseOrigin: args.baseUrl })
|
|
1622
1631
|
};
|
|
1623
1632
|
// Ensure connection is ready
|
|
1624
1633
|
let didAutoLaunch = false;
|