@tangle-network/browser-agent-driver 0.29.0 → 0.30.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/dist/brain/index.d.ts +15 -1
- package/dist/brain/index.d.ts.map +1 -1
- package/dist/brain/index.js +67 -5
- package/dist/brain/index.js.map +1 -1
- package/dist/cli-design-audit.d.ts +4 -0
- package/dist/cli-design-audit.d.ts.map +1 -1
- package/dist/cli-design-audit.js +144 -7
- package/dist/cli-design-audit.js.map +1 -1
- package/dist/cli-ui.d.ts.map +1 -1
- package/dist/cli-ui.js +5 -1
- package/dist/cli-ui.js.map +1 -1
- package/dist/cli.js +23 -1
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +4 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/design/audit/evaluate.d.ts +69 -0
- package/dist/design/audit/evaluate.d.ts.map +1 -1
- package/dist/design/audit/evaluate.js +414 -55
- package/dist/design/audit/evaluate.js.map +1 -1
- package/dist/design/audit/pipeline.d.ts +14 -0
- package/dist/design/audit/pipeline.d.ts.map +1 -1
- package/dist/design/audit/pipeline.js +67 -2
- package/dist/design/audit/pipeline.js.map +1 -1
- package/dist/design/audit/rubric/fragments/universal-product-intent.md +48 -0
- package/dist/design/audit/rubric/loader.d.ts.map +1 -1
- package/dist/design/audit/rubric/loader.js +32 -1
- package/dist/design/audit/rubric/loader.js.map +1 -1
- package/dist/provider-defaults.d.ts +1 -1
- package/dist/provider-defaults.d.ts.map +1 -1
- package/dist/provider-defaults.js +8 -0
- package/dist/provider-defaults.js.map +1 -1
- package/dist/supervisor/critic.d.ts +1 -1
- package/dist/supervisor/critic.d.ts.map +1 -1
- package/dist/supervisor/critic.js +50 -5
- package/dist/supervisor/critic.js.map +1 -1
- package/dist/telemetry/client.d.ts +42 -0
- package/dist/telemetry/client.d.ts.map +1 -0
- package/dist/telemetry/client.js +203 -0
- package/dist/telemetry/client.js.map +1 -0
- package/dist/telemetry/hash.d.ts +4 -0
- package/dist/telemetry/hash.d.ts.map +1 -0
- package/dist/telemetry/hash.js +7 -0
- package/dist/telemetry/hash.js.map +1 -0
- package/dist/telemetry/index.d.ts +6 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +5 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/schema.d.ts +85 -0
- package/dist/telemetry/schema.d.ts.map +1 -0
- package/dist/telemetry/schema.js +13 -0
- package/dist/telemetry/schema.js.map +1 -0
- package/dist/telemetry/sink.d.ts +46 -0
- package/dist/telemetry/sink.d.ts.map +1 -0
- package/dist/telemetry/sink.js +97 -0
- package/dist/telemetry/sink.js.map +1 -0
- package/dist/types.d.ts +5 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -1
package/dist/cli-design-audit.js
CHANGED
|
@@ -15,7 +15,10 @@ import { resolveProviderApiKey, resolveProviderModelName } from './provider-defa
|
|
|
15
15
|
import { loadLocalEnvFiles } from './env-loader.js';
|
|
16
16
|
import { cliError } from './cli-ui.js';
|
|
17
17
|
import { auditOnePage } from './design/audit/pipeline.js';
|
|
18
|
+
import { resolveAuditPasses } from './design/audit/evaluate.js';
|
|
18
19
|
import { detectSystemicFindings, topByRoi } from './design/audit/roi.js';
|
|
20
|
+
import { getTelemetry, setInvocation } from './telemetry/index.js';
|
|
21
|
+
import { randomUUID } from 'node:crypto';
|
|
19
22
|
// ---------------------------------------------------------------------------
|
|
20
23
|
// Page discovery — find key pages by crawling links
|
|
21
24
|
// ---------------------------------------------------------------------------
|
|
@@ -194,15 +197,34 @@ export async function runDesignAudit(opts) {
|
|
|
194
197
|
const provider = (opts.provider ?? 'claude-code');
|
|
195
198
|
const modelName = resolveProviderModelName(provider, opts.model);
|
|
196
199
|
const apiKey = opts.apiKey ?? resolveProviderApiKey(provider);
|
|
200
|
+
const auditPasses = resolveAuditPasses(opts.auditPasses);
|
|
201
|
+
// Telemetry: every design-audit invocation gets a stable runId. Children
|
|
202
|
+
// (per-page, evolve rounds) link back via parentRunId so a fleet rollup can
|
|
203
|
+
// reconstruct the tree.
|
|
204
|
+
const runId = randomUUID();
|
|
205
|
+
const runStartedAt = Date.now();
|
|
206
|
+
const invocation = opts.evolve ? 'design-audit:evolve' : opts.reproducibility ? 'design-audit:reproducibility' : 'design-audit';
|
|
207
|
+
setInvocation(invocation);
|
|
208
|
+
const telemetry = getTelemetry();
|
|
197
209
|
const [vw, vh] = (opts.viewport ?? '1440x900').split('x').map(Number);
|
|
198
210
|
console.log('');
|
|
199
211
|
console.log(` ${chalk.bold('bad design-audit')}`);
|
|
200
212
|
const profileLabel = profile ?? chalk.dim('auto-classify');
|
|
201
|
-
|
|
213
|
+
const passLabel = auditPasses.length === 1 && auditPasses[0] === 'standard'
|
|
214
|
+
? '1 audit pass'
|
|
215
|
+
: `${auditPasses.length} audit passes (${auditPasses.join(', ')})`;
|
|
216
|
+
console.log(` ${profileLabel} ${chalk.dim('·')} ${chalk.cyan(modelName)} ${chalk.dim('·')} ${vw}×${vh} ${chalk.dim('·')} ${passLabel} ${chalk.dim('·')} up to ${maxPages} pages`);
|
|
202
217
|
console.log(` ${chalk.dim('→')} ${opts.url}`);
|
|
203
218
|
console.log('');
|
|
219
|
+
const storageState = opts.storageState ? path.resolve(opts.storageState) : undefined;
|
|
220
|
+
if (storageState && !fs.existsSync(storageState)) {
|
|
221
|
+
cliError(`storage state file not found: ${storageState}`);
|
|
222
|
+
}
|
|
204
223
|
const browser = await chromium.launch({ headless: opts.headless ?? true });
|
|
205
|
-
const context = await browser.newContext({
|
|
224
|
+
const context = await browser.newContext({
|
|
225
|
+
viewport: { width: vw, height: vh },
|
|
226
|
+
...(storageState ? { storageState } : {}),
|
|
227
|
+
});
|
|
206
228
|
const page = await context.newPage();
|
|
207
229
|
// Discover pages
|
|
208
230
|
console.log(` ${chalk.dim('Discovering pages…')}`);
|
|
@@ -220,7 +242,8 @@ export async function runDesignAudit(opts) {
|
|
|
220
242
|
const brain = new Brain({
|
|
221
243
|
model: modelName,
|
|
222
244
|
apiKey,
|
|
223
|
-
provider:
|
|
245
|
+
provider: provider,
|
|
246
|
+
baseUrl: opts.baseUrl ?? process.env.LLM_BASE_URL,
|
|
224
247
|
vision: true,
|
|
225
248
|
debug: opts.debug,
|
|
226
249
|
llmTimeoutMs: 120_000, // design audits generate ~8k tokens of structured JSON — need 2min
|
|
@@ -239,6 +262,10 @@ export async function runDesignAudit(opts) {
|
|
|
239
262
|
profileOverride: profile,
|
|
240
263
|
screenshotDir,
|
|
241
264
|
userRubricsDir: opts.rubricsDir,
|
|
265
|
+
auditPasses,
|
|
266
|
+
runId,
|
|
267
|
+
provider,
|
|
268
|
+
model: modelName,
|
|
242
269
|
});
|
|
243
270
|
const result = gen2;
|
|
244
271
|
results.push(result);
|
|
@@ -310,6 +337,11 @@ export async function runDesignAudit(opts) {
|
|
|
310
337
|
url,
|
|
311
338
|
profileOverride: profile,
|
|
312
339
|
userRubricsDir: opts.rubricsDir,
|
|
340
|
+
auditPasses,
|
|
341
|
+
runId,
|
|
342
|
+
provider,
|
|
343
|
+
model: modelName,
|
|
344
|
+
parentRunId: runId,
|
|
313
345
|
});
|
|
314
346
|
repResults.push(gen2);
|
|
315
347
|
}
|
|
@@ -343,11 +375,11 @@ export async function runDesignAudit(opts) {
|
|
|
343
375
|
if (evolveMode !== 'css') {
|
|
344
376
|
// Agent-dispatched evolve — a coding agent edits the actual source code
|
|
345
377
|
const projectDir = opts.projectDir ?? process.cwd();
|
|
346
|
-
evolveResult = await runAgentEvolveLoop(brain, driver, page, pages, evolveProfile, results, outputDir, opts.evolveRounds ?? 3, evolveMode, projectDir, opts.debug);
|
|
378
|
+
evolveResult = await runAgentEvolveLoop(brain, driver, page, pages, evolveProfile, results, outputDir, opts.evolveRounds ?? 3, evolveMode, projectDir, opts.debug, auditPasses, runId, provider, modelName);
|
|
347
379
|
}
|
|
348
380
|
else {
|
|
349
381
|
// CSS-injection evolve — ephemeral fixes injected into the browser page
|
|
350
|
-
evolveResult = await runEvolveLoop(brain, driver, page, pages, evolveProfile, results, outputDir, opts.evolveRounds ?? 3);
|
|
382
|
+
evolveResult = await runEvolveLoop(brain, driver, page, pages, evolveProfile, results, outputDir, opts.evolveRounds ?? 3, auditPasses, runId, provider, modelName);
|
|
351
383
|
}
|
|
352
384
|
// Write evolve report
|
|
353
385
|
const evolvePath = path.join(outputDir, 'evolve-report.md');
|
|
@@ -364,10 +396,62 @@ export async function runDesignAudit(opts) {
|
|
|
364
396
|
fs.writeFileSync(evJsonPath, JSON.stringify(evolveResult, null, 2));
|
|
365
397
|
}
|
|
366
398
|
console.log('');
|
|
399
|
+
telemetry.emit({
|
|
400
|
+
kind: 'design-evolve-run',
|
|
401
|
+
runId,
|
|
402
|
+
ok: true,
|
|
403
|
+
durationMs: Date.now() - runStartedAt,
|
|
404
|
+
model: { provider, name: modelName },
|
|
405
|
+
data: {
|
|
406
|
+
url: opts.url,
|
|
407
|
+
pages: pages.length,
|
|
408
|
+
rounds: evolveResult.scoreHistory.length - 1,
|
|
409
|
+
scoreHistory: evolveResult.scoreHistory,
|
|
410
|
+
appliedFixCount: evolveResult.appliedFixes?.length ?? 0,
|
|
411
|
+
evolveMode: evolveMode === 'css' ? 'css' : `agent:${evolveMode}`,
|
|
412
|
+
},
|
|
413
|
+
metrics: {
|
|
414
|
+
initialScore: evolveResult.scoreHistory[0] ?? 0,
|
|
415
|
+
finalScore: evolveResult.scoreHistory[evolveResult.scoreHistory.length - 1] ?? 0,
|
|
416
|
+
delta: (evolveResult.scoreHistory[evolveResult.scoreHistory.length - 1] ?? 0) - (evolveResult.scoreHistory[0] ?? 0),
|
|
417
|
+
rounds: evolveResult.scoreHistory.length - 1,
|
|
418
|
+
},
|
|
419
|
+
});
|
|
367
420
|
}
|
|
421
|
+
// Run-level summary envelope — fires for every design-audit invocation,
|
|
422
|
+
// evolve or not. This is the row a fleet rollup queries to track audit
|
|
423
|
+
// health across repos over time.
|
|
424
|
+
telemetry.emit({
|
|
425
|
+
kind: 'design-audit-run',
|
|
426
|
+
runId,
|
|
427
|
+
ok: true,
|
|
428
|
+
durationMs: Date.now() - runStartedAt,
|
|
429
|
+
model: { provider, name: modelName },
|
|
430
|
+
data: {
|
|
431
|
+
url: opts.url,
|
|
432
|
+
pages: pages.length,
|
|
433
|
+
profile: profile ?? null,
|
|
434
|
+
auditPasses,
|
|
435
|
+
outputDir,
|
|
436
|
+
},
|
|
437
|
+
metrics: {
|
|
438
|
+
avgScore,
|
|
439
|
+
pageCount: pages.length,
|
|
440
|
+
totalFindings: allFindings.length,
|
|
441
|
+
criticalFindings: critical,
|
|
442
|
+
majorFindings: major,
|
|
443
|
+
minorFindings: minor,
|
|
444
|
+
topFixCount: topFixes.length,
|
|
445
|
+
},
|
|
446
|
+
tags: {
|
|
447
|
+
evolveMode: opts.evolve ? (opts.evolve === true || opts.evolve === 'css' ? 'css' : 'agent') : 'off',
|
|
448
|
+
reproducibility: opts.reproducibility ? 'on' : 'off',
|
|
449
|
+
},
|
|
450
|
+
});
|
|
368
451
|
await browser.close();
|
|
369
452
|
}
|
|
370
|
-
async function runEvolveLoop(brain, driver, page, pages, profile, initialResults, outputDir, maxRounds) {
|
|
453
|
+
async function runEvolveLoop(brain, driver, page, pages, profile, initialResults, outputDir, maxRounds, auditPasses, parentRunId, provider, model) {
|
|
454
|
+
const telemetry = parentRunId ? getTelemetry() : undefined;
|
|
371
455
|
const initialAvg = initialResults.reduce((s, r) => s + r.score, 0) / initialResults.length;
|
|
372
456
|
const scoreHistory = [initialAvg];
|
|
373
457
|
const appliedFixes = [];
|
|
@@ -463,6 +547,10 @@ async function runEvolveLoop(brain, driver, page, pages, profile, initialResults
|
|
|
463
547
|
url,
|
|
464
548
|
profileOverride: profile,
|
|
465
549
|
screenshotDir,
|
|
550
|
+
auditPasses,
|
|
551
|
+
...(parentRunId ? { runId: parentRunId, parentRunId } : {}),
|
|
552
|
+
...(provider ? { provider } : {}),
|
|
553
|
+
...(model ? { model } : {}),
|
|
466
554
|
}));
|
|
467
555
|
roundResults.push(result);
|
|
468
556
|
}
|
|
@@ -482,6 +570,28 @@ async function runEvolveLoop(brain, driver, page, pages, profile, initialResults
|
|
|
482
570
|
const delta = roundAvg - currentAvg;
|
|
483
571
|
const deltaStr = delta >= 0 ? chalk.green(`+${delta.toFixed(1)}`) : chalk.red(delta.toFixed(1));
|
|
484
572
|
console.log(` ${chalk.dim(' Score:')} ${roundAvg.toFixed(1)}/10 (${deltaStr})`);
|
|
573
|
+
if (telemetry && parentRunId) {
|
|
574
|
+
telemetry.emit({
|
|
575
|
+
kind: 'design-evolve-round',
|
|
576
|
+
runId: parentRunId,
|
|
577
|
+
parentRunId,
|
|
578
|
+
ok: true,
|
|
579
|
+
durationMs: 0, // round-level wall time would require a per-round timer; the parent run captures total duration
|
|
580
|
+
...(provider && model ? { model: { provider, name: model } } : {}),
|
|
581
|
+
data: {
|
|
582
|
+
mode: 'css',
|
|
583
|
+
round,
|
|
584
|
+
fixesApplied: fixableFixes.length,
|
|
585
|
+
},
|
|
586
|
+
metrics: {
|
|
587
|
+
round,
|
|
588
|
+
beforeScore: currentAvg,
|
|
589
|
+
afterScore: roundAvg,
|
|
590
|
+
delta,
|
|
591
|
+
fixesApplied: fixableFixes.length,
|
|
592
|
+
},
|
|
593
|
+
});
|
|
594
|
+
}
|
|
485
595
|
currentResults = roundResults;
|
|
486
596
|
currentAvg = roundAvg;
|
|
487
597
|
// Check convergence — if no improvement, stop
|
|
@@ -638,7 +748,8 @@ Do NOT:
|
|
|
638
748
|
- Refactor unrelated code
|
|
639
749
|
- Change component structure or HTML semantics unless a finding specifically requires it`;
|
|
640
750
|
}
|
|
641
|
-
async function runAgentEvolveLoop(brain, driver, page, pages, profile, initialResults, outputDir, maxRounds, agentName, projectDir, debug) {
|
|
751
|
+
async function runAgentEvolveLoop(brain, driver, page, pages, profile, initialResults, outputDir, maxRounds, agentName, projectDir, debug, auditPasses, parentRunId, provider, model) {
|
|
752
|
+
const telemetry = parentRunId ? getTelemetry() : undefined;
|
|
642
753
|
const initialAvg = initialResults.reduce((s, r) => s + r.score, 0) / initialResults.length;
|
|
643
754
|
const scoreHistory = [initialAvg];
|
|
644
755
|
const appliedFixes = [];
|
|
@@ -719,6 +830,10 @@ async function runAgentEvolveLoop(brain, driver, page, pages, profile, initialRe
|
|
|
719
830
|
url,
|
|
720
831
|
profileOverride: profile,
|
|
721
832
|
screenshotDir: roundScreenshotDir,
|
|
833
|
+
auditPasses,
|
|
834
|
+
...(parentRunId ? { runId: parentRunId, parentRunId } : {}),
|
|
835
|
+
...(provider ? { provider } : {}),
|
|
836
|
+
...(model ? { model } : {}),
|
|
722
837
|
}));
|
|
723
838
|
roundResults.push(result);
|
|
724
839
|
}
|
|
@@ -738,6 +853,28 @@ async function runAgentEvolveLoop(brain, driver, page, pages, profile, initialRe
|
|
|
738
853
|
finding: `Score: ${currentAvg.toFixed(1)} → ${roundAvg.toFixed(1)}`,
|
|
739
854
|
});
|
|
740
855
|
}
|
|
856
|
+
if (telemetry && parentRunId) {
|
|
857
|
+
telemetry.emit({
|
|
858
|
+
kind: 'design-evolve-round',
|
|
859
|
+
runId: parentRunId,
|
|
860
|
+
parentRunId,
|
|
861
|
+
ok: true,
|
|
862
|
+
durationMs: 0,
|
|
863
|
+
...(provider && model ? { model: { provider, name: model } } : {}),
|
|
864
|
+
data: {
|
|
865
|
+
mode: `agent:${agentName}`,
|
|
866
|
+
round,
|
|
867
|
+
resolvedCount,
|
|
868
|
+
},
|
|
869
|
+
metrics: {
|
|
870
|
+
round,
|
|
871
|
+
beforeScore: currentAvg,
|
|
872
|
+
afterScore: roundAvg,
|
|
873
|
+
delta,
|
|
874
|
+
findingsResolved: resolvedCount,
|
|
875
|
+
},
|
|
876
|
+
});
|
|
877
|
+
}
|
|
741
878
|
currentResults = roundResults;
|
|
742
879
|
currentAvg = roundAvg;
|
|
743
880
|
// Check convergence
|