ccqa 0.3.9 → 0.4.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.
- package/README.md +39 -301
- package/dist/bin/ccqa.mjs +2180 -1124
- package/dist/package.json +2 -2
- package/dist/runtime/test-helpers.mjs +1 -53
- package/dist/runtime/vitest.config.d.mts +10 -10
- package/dist/spawn-ab-BxjEhA5e.mjs +65 -0
- package/package.json +2 -2
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccqa",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Browser test recorder powered by Claude Code and agent-browser",
|
|
6
6
|
"repository": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@anthropic-ai/claude-agent-sdk": "^0.2.87",
|
|
28
28
|
"commander": "^14.0.3",
|
|
29
|
-
"
|
|
29
|
+
"yaml": "^2.9.0",
|
|
30
30
|
"zod": "^4.3.6"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
@@ -1,58 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { spawnSync } from "node:child_process";
|
|
1
|
+
import { n as spawnAB, t as sleepSync } from "../spawn-ab-BxjEhA5e.mjs";
|
|
3
2
|
//#region src/runtime/test-helpers.ts
|
|
4
|
-
const AB = createRequire(import.meta.url).resolve("agent-browser/bin/agent-browser.js");
|
|
5
|
-
const EAGAIN_PATTERN = /Resource temporarily unavailable|os error 35/i;
|
|
6
|
-
const EAGAIN_TOTAL_BUDGET_MS = 3e4;
|
|
7
|
-
const EAGAIN_BACKOFF_MS = [
|
|
8
|
-
100,
|
|
9
|
-
200,
|
|
10
|
-
300,
|
|
11
|
-
500,
|
|
12
|
-
700,
|
|
13
|
-
1e3,
|
|
14
|
-
1500,
|
|
15
|
-
2e3,
|
|
16
|
-
2500,
|
|
17
|
-
3e3,
|
|
18
|
-
3e3,
|
|
19
|
-
3e3,
|
|
20
|
-
3e3,
|
|
21
|
-
3e3,
|
|
22
|
-
3e3
|
|
23
|
-
];
|
|
24
3
|
const POST_OPEN_SETTLE_MS = 600;
|
|
25
|
-
function sleepSync(ms) {
|
|
26
|
-
const buf = new SharedArrayBuffer(4);
|
|
27
|
-
Atomics.wait(new Int32Array(buf), 0, 0, ms);
|
|
28
|
-
}
|
|
29
|
-
const PROCESS_HARD_TIMEOUT_MS = 9e4;
|
|
30
|
-
function spawnABOnce(args) {
|
|
31
|
-
const result = spawnSync(AB, args, {
|
|
32
|
-
stdio: "pipe",
|
|
33
|
-
timeout: PROCESS_HARD_TIMEOUT_MS
|
|
34
|
-
});
|
|
35
|
-
return {
|
|
36
|
-
status: result.status,
|
|
37
|
-
stdout: result.stdout?.toString() ?? "",
|
|
38
|
-
stderr: (result.stderr?.toString() ?? "") + (result.signal === "SIGTERM" ? "\n[ccqa] agent-browser killed after hard timeout" : "")
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
function spawnAB(args) {
|
|
42
|
-
let result = spawnABOnce(args);
|
|
43
|
-
let elapsed = 0;
|
|
44
|
-
let attempt = 0;
|
|
45
|
-
while (result.status !== 0 && elapsed < EAGAIN_TOTAL_BUDGET_MS) {
|
|
46
|
-
const combined = `${result.stdout}\n${result.stderr}`;
|
|
47
|
-
if (!EAGAIN_PATTERN.test(combined)) return result;
|
|
48
|
-
const wait = EAGAIN_BACKOFF_MS[attempt] ?? 3e3;
|
|
49
|
-
sleepSync(wait);
|
|
50
|
-
elapsed += wait;
|
|
51
|
-
attempt++;
|
|
52
|
-
result = spawnABOnce(args);
|
|
53
|
-
}
|
|
54
|
-
return result;
|
|
55
|
-
}
|
|
56
4
|
function logStep(action, args) {
|
|
57
5
|
const pretty = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
58
6
|
process.stdout.write(` ▶ ${action.padEnd(14)} ${pretty}\n`);
|
|
@@ -17,7 +17,7 @@ import SassEmbedded from "sass-embedded";
|
|
|
17
17
|
import Less from "less";
|
|
18
18
|
import Stylus from "stylus";
|
|
19
19
|
|
|
20
|
-
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.
|
|
20
|
+
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.17_yaml@2.9.0/node_modules/vite/types/hmrPayload.d.ts
|
|
21
21
|
type HotPayload = ConnectedPayload | PingPayload | UpdatePayload | FullReloadPayload | CustomPayload | ErrorPayload | PrunePayload;
|
|
22
22
|
interface ConnectedPayload {
|
|
23
23
|
type: 'connected';
|
|
@@ -82,7 +82,7 @@ interface ErrorPayload {
|
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
84
|
//#endregion
|
|
85
|
-
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.
|
|
85
|
+
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.17_yaml@2.9.0/node_modules/vite/dist/node/chunks/moduleRunnerTransport.d.ts
|
|
86
86
|
//#region src/shared/invokeMethods.d.ts
|
|
87
87
|
interface FetchFunctionOptions {
|
|
88
88
|
cached?: boolean;
|
|
@@ -135,7 +135,7 @@ interface ViteFetchResult {
|
|
|
135
135
|
invalidate: boolean;
|
|
136
136
|
}
|
|
137
137
|
//#endregion
|
|
138
|
-
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.
|
|
138
|
+
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.17_yaml@2.9.0/node_modules/vite/types/customEvent.d.ts
|
|
139
139
|
interface CustomEventMap {
|
|
140
140
|
// client events
|
|
141
141
|
'vite:beforeUpdate': UpdatePayload;
|
|
@@ -6230,13 +6230,13 @@ interface TransformOptions$1 extends BindingEnhancedTransformOptions {}
|
|
|
6230
6230
|
* @category Utilities
|
|
6231
6231
|
*/
|
|
6232
6232
|
//#endregion
|
|
6233
|
-
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.
|
|
6233
|
+
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.17_yaml@2.9.0/node_modules/vite/types/internal/esbuildOptions.d.ts
|
|
6234
6234
|
/* eslint-enable @typescript-eslint/ban-ts-comment */
|
|
6235
6235
|
type EsbuildTarget = string | string[];
|
|
6236
6236
|
type EsbuildTransformOptions = esbuild.TransformOptions;
|
|
6237
6237
|
type DepsOptimizerEsbuildOptions = Omit<esbuild.BuildOptions, 'bundle' | 'entryPoints' | 'external' | 'write' | 'watch' | 'outdir' | 'outfile' | 'outbase' | 'outExtension' | 'metafile'>;
|
|
6238
6238
|
//#endregion
|
|
6239
|
-
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.
|
|
6239
|
+
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.17_yaml@2.9.0/node_modules/vite/types/metadata.d.ts
|
|
6240
6240
|
interface AssetMetadata {
|
|
6241
6241
|
importedAssets: Set<string>;
|
|
6242
6242
|
importedCss: Set<string>;
|
|
@@ -6279,16 +6279,16 @@ declare module 'rolldown' {
|
|
|
6279
6279
|
}
|
|
6280
6280
|
}
|
|
6281
6281
|
//#endregion
|
|
6282
|
-
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.
|
|
6282
|
+
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.17_yaml@2.9.0/node_modules/vite/types/internal/terserOptions.d.ts
|
|
6283
6283
|
/* eslint-enable @typescript-eslint/ban-ts-comment */
|
|
6284
6284
|
type TerserMinifyOptions = Terser.MinifyOptions;
|
|
6285
6285
|
//#endregion
|
|
6286
|
-
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.
|
|
6286
|
+
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.17_yaml@2.9.0/node_modules/vite/types/internal/lightningcssOptions.d.ts
|
|
6287
6287
|
/* eslint-enable @typescript-eslint/ban-ts-comment */
|
|
6288
6288
|
type LightningCSSOptions = Omit<Lightningcss.BundleAsyncOptions<Lightningcss.CustomAtRules>, 'filename' | 'resolver' | 'minify' | 'sourceMap' | 'analyzeDependencies' // properties not overridden by Vite, but does not make sense to set by end users
|
|
6289
6289
|
| 'inputSourceMap' | 'projectRoot'>;
|
|
6290
6290
|
//#endregion
|
|
6291
|
-
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.
|
|
6291
|
+
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.17_yaml@2.9.0/node_modules/vite/types/internal/cssPreprocessorOptions.d.ts
|
|
6292
6292
|
/* eslint-enable @typescript-eslint/ban-ts-comment */
|
|
6293
6293
|
// https://github.com/type-challenges/type-challenges/issues/29285
|
|
6294
6294
|
type IsAny<T> = boolean extends (T extends never ? true : false) ? true : false;
|
|
@@ -6307,7 +6307,7 @@ declare global {
|
|
|
6307
6307
|
interface HTMLLinkElement {}
|
|
6308
6308
|
}
|
|
6309
6309
|
//#endregion
|
|
6310
|
-
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.
|
|
6310
|
+
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.17_yaml@2.9.0/node_modules/vite/types/importGlob.d.ts
|
|
6311
6311
|
/**
|
|
6312
6312
|
* Declare Worker in case DOM is not added to the tsconfig lib causing
|
|
6313
6313
|
* Worker interface is not defined. For developers with DOM lib added,
|
|
@@ -6318,7 +6318,7 @@ declare global {
|
|
|
6318
6318
|
interface Worker {}
|
|
6319
6319
|
}
|
|
6320
6320
|
//#endregion
|
|
6321
|
-
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.
|
|
6321
|
+
//#region node_modules/.pnpm/vite@8.0.9_@types+node@22.19.17_yaml@2.9.0/node_modules/vite/dist/node/index.d.ts
|
|
6322
6322
|
//#region \0rolldown/runtime.js
|
|
6323
6323
|
//#endregion
|
|
6324
6324
|
//#region ../../node_modules/.pnpm/@vitejs+devtools@0.1.14_typescript@6.0.2_vite@packages+vite/node_modules/@vitejs/devtools/dist/cli-commands.d.ts
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
//#region src/runtime/spawn-ab.ts
|
|
4
|
+
const AB = createRequire(import.meta.url).resolve("agent-browser/bin/agent-browser.js");
|
|
5
|
+
const EAGAIN_PATTERN = /Resource temporarily unavailable|os error 35/i;
|
|
6
|
+
const EAGAIN_TOTAL_BUDGET_MS = 3e4;
|
|
7
|
+
const EAGAIN_BACKOFF_MS = [
|
|
8
|
+
100,
|
|
9
|
+
200,
|
|
10
|
+
300,
|
|
11
|
+
500,
|
|
12
|
+
700,
|
|
13
|
+
1e3,
|
|
14
|
+
1500,
|
|
15
|
+
2e3,
|
|
16
|
+
2500,
|
|
17
|
+
3e3,
|
|
18
|
+
3e3,
|
|
19
|
+
3e3,
|
|
20
|
+
3e3,
|
|
21
|
+
3e3,
|
|
22
|
+
3e3
|
|
23
|
+
];
|
|
24
|
+
const PROCESS_HARD_TIMEOUT_MS = 9e4;
|
|
25
|
+
function sleepSync(ms) {
|
|
26
|
+
const buf = new SharedArrayBuffer(4);
|
|
27
|
+
Atomics.wait(new Int32Array(buf), 0, 0, ms);
|
|
28
|
+
}
|
|
29
|
+
function spawnABOnce(args) {
|
|
30
|
+
const result = spawnSync(AB, args, {
|
|
31
|
+
stdio: "pipe",
|
|
32
|
+
timeout: PROCESS_HARD_TIMEOUT_MS
|
|
33
|
+
});
|
|
34
|
+
return {
|
|
35
|
+
status: result.status,
|
|
36
|
+
stdout: result.stdout?.toString() ?? "",
|
|
37
|
+
stderr: (result.stderr?.toString() ?? "") + (result.signal === "SIGTERM" ? "\n[ccqa] agent-browser killed after hard timeout" : "")
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Invoke `agent-browser` once and return its exit status/stdout/stderr,
|
|
42
|
+
* retrying internally up to ~30s while the daemon's state file is in the
|
|
43
|
+
* "Resource temporarily unavailable" race window. Used by both the test
|
|
44
|
+
* runtime (`test-helpers.ts`) and the post-trace replay validation
|
|
45
|
+
* (`replay-validate.ts`). Kept out of `test-helpers.ts` because that
|
|
46
|
+
* module is also the public surface for generated test scripts — exposing
|
|
47
|
+
* the raw spawner there would widen the contract for end users.
|
|
48
|
+
*/
|
|
49
|
+
function spawnAB(args) {
|
|
50
|
+
let result = spawnABOnce(args);
|
|
51
|
+
let elapsed = 0;
|
|
52
|
+
let attempt = 0;
|
|
53
|
+
while (result.status !== 0 && elapsed < EAGAIN_TOTAL_BUDGET_MS) {
|
|
54
|
+
const combined = `${result.stdout}\n${result.stderr}`;
|
|
55
|
+
if (!EAGAIN_PATTERN.test(combined)) return result;
|
|
56
|
+
const wait = EAGAIN_BACKOFF_MS[attempt] ?? 3e3;
|
|
57
|
+
sleepSync(wait);
|
|
58
|
+
elapsed += wait;
|
|
59
|
+
attempt++;
|
|
60
|
+
result = spawnABOnce(args);
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { spawnAB as n, sleepSync as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccqa",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Browser test recorder powered by Claude Code and agent-browser",
|
|
6
6
|
"repository": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@anthropic-ai/claude-agent-sdk": "^0.2.87",
|
|
28
28
|
"commander": "^14.0.3",
|
|
29
|
-
"
|
|
29
|
+
"yaml": "^2.9.0",
|
|
30
30
|
"zod": "^4.3.6"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|