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.
Files changed (46) hide show
  1. package/build/github/issue-body.d.ts +4 -4
  2. package/build/mcp-supervisor.js +60 -2
  3. package/build/mcp-supervisor.js.map +1 -1
  4. package/build/supervisor/client-watcher.d.ts +13 -2
  5. package/build/supervisor/client-watcher.d.ts.map +1 -1
  6. package/build/supervisor/client-watcher.js +60 -16
  7. package/build/supervisor/client-watcher.js.map +1 -1
  8. package/build/supervisor/client-watcher.test.js +110 -3
  9. package/build/supervisor/client-watcher.test.js.map +1 -1
  10. package/build/supervisor/stderr-log.d.ts +29 -0
  11. package/build/supervisor/stderr-log.d.ts.map +1 -0
  12. package/build/supervisor/stderr-log.js +52 -0
  13. package/build/supervisor/stderr-log.js.map +1 -0
  14. package/build/supervisor/stderr-log.test.d.ts +9 -0
  15. package/build/supervisor/stderr-log.test.d.ts.map +1 -0
  16. package/build/supervisor/stderr-log.test.js +80 -0
  17. package/build/supervisor/stderr-log.test.js.map +1 -0
  18. package/build/tools/issues-tools.d.ts.map +1 -1
  19. package/build/tools/issues-tools.js +29 -3
  20. package/build/tools/issues-tools.js.map +1 -1
  21. package/build/tools/issues-tools.test.js +86 -0
  22. package/build/tools/issues-tools.test.js.map +1 -1
  23. package/build/tools/replay-executor.d.ts +9 -0
  24. package/build/tools/replay-executor.d.ts.map +1 -1
  25. package/build/tools/replay-executor.js +15 -1
  26. package/build/tools/replay-executor.js.map +1 -1
  27. package/build/tools/replay-nested-rebase.test.d.ts +15 -0
  28. package/build/tools/replay-nested-rebase.test.d.ts.map +1 -0
  29. package/build/tools/replay-nested-rebase.test.js +139 -0
  30. package/build/tools/replay-nested-rebase.test.js.map +1 -0
  31. package/build/tools/replay-rebase.test.js +25 -0
  32. package/build/tools/replay-rebase.test.js.map +1 -1
  33. package/build/tools/replay-run-all-parity.test.d.ts +2 -0
  34. package/build/tools/replay-run-all-parity.test.d.ts.map +1 -0
  35. package/build/tools/replay-run-all-parity.test.js +90 -0
  36. package/build/tools/replay-run-all-parity.test.js.map +1 -0
  37. package/build/tools/replay-tools.d.ts +21 -21
  38. package/build/tools/replay-tools.d.ts.map +1 -1
  39. package/build/tools/replay-tools.js +17 -8
  40. package/build/tools/replay-tools.js.map +1 -1
  41. package/docs/instructions.md +3 -2
  42. package/docs/messages.md +3 -2
  43. package/docs/replay.md +17 -4
  44. package/package.json +1 -1
  45. package/plugin/skills/devharness/SKILL.md +1 -1
  46. 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;AAmwGD,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"}
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 the sequence at another deployment — every absolute URL (startUrl + command params) keeps its path/query but takes this origin. Not preserved across a mid-run pause/step resume'),
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
- killChromeOnFinish: undefined,
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;