@tangle-network/browser-agent-driver 0.29.0 → 0.31.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-ack-patch.d.ts +39 -0
- package/dist/cli-ack-patch.d.ts.map +1 -0
- package/dist/cli-ack-patch.js +47 -0
- package/dist/cli-ack-patch.js.map +1 -0
- package/dist/cli-design-audit.d.ts +16 -0
- package/dist/cli-design-audit.d.ts.map +1 -1
- package/dist/cli-design-audit.js +232 -7
- package/dist/cli-design-audit.js.map +1 -1
- package/dist/cli-jobs.d.ts +13 -0
- package/dist/cli-jobs.d.ts.map +1 -0
- package/dist/cli-jobs.js +262 -0
- package/dist/cli-jobs.js.map +1 -0
- package/dist/cli-patterns.d.ts +26 -0
- package/dist/cli-patterns.d.ts.map +1 -0
- package/dist/cli-patterns.js +49 -0
- package/dist/cli-patterns.js.map +1 -0
- package/dist/cli-reports.d.ts +12 -0
- package/dist/cli-reports.d.ts.map +1 -0
- package/dist/cli-reports.js +97 -0
- package/dist/cli-reports.js.map +1 -0
- 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 +52 -2
- 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/attribution/aggregate.d.ts +16 -0
- package/dist/design/audit/attribution/aggregate.d.ts.map +1 -0
- package/dist/design/audit/attribution/aggregate.js +81 -0
- package/dist/design/audit/attribution/aggregate.js.map +1 -0
- package/dist/design/audit/attribution/store.d.ts +36 -0
- package/dist/design/audit/attribution/store.d.ts.map +1 -0
- package/dist/design/audit/attribution/store.js +108 -0
- package/dist/design/audit/attribution/store.js.map +1 -0
- package/dist/design/audit/attribution/types.d.ts +13 -0
- package/dist/design/audit/attribution/types.d.ts.map +1 -0
- package/dist/design/audit/attribution/types.js +10 -0
- package/dist/design/audit/attribution/types.js.map +1 -0
- package/dist/design/audit/classify-ensemble.d.ts +46 -0
- package/dist/design/audit/classify-ensemble.d.ts.map +1 -0
- package/dist/design/audit/classify-ensemble.js +207 -0
- package/dist/design/audit/classify-ensemble.js.map +1 -0
- package/dist/design/audit/ethics/check.d.ts +59 -0
- package/dist/design/audit/ethics/check.d.ts.map +1 -0
- package/dist/design/audit/ethics/check.js +137 -0
- package/dist/design/audit/ethics/check.js.map +1 -0
- package/dist/design/audit/ethics/loader.d.ts +21 -0
- package/dist/design/audit/ethics/loader.d.ts.map +1 -0
- package/dist/design/audit/ethics/loader.js +207 -0
- package/dist/design/audit/ethics/loader.js.map +1 -0
- package/dist/design/audit/ethics/rules/finance.yaml +37 -0
- package/dist/design/audit/ethics/rules/kids.yaml +37 -0
- package/dist/design/audit/ethics/rules/legal.yaml +35 -0
- package/dist/design/audit/ethics/rules/medical.yaml +36 -0
- 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 +417 -55
- package/dist/design/audit/evaluate.js.map +1 -1
- package/dist/design/audit/first-principles-mode.d.ts +42 -0
- package/dist/design/audit/first-principles-mode.d.ts.map +1 -0
- package/dist/design/audit/first-principles-mode.js +77 -0
- package/dist/design/audit/first-principles-mode.js.map +1 -0
- package/dist/design/audit/modality/android.d.ts +14 -0
- package/dist/design/audit/modality/android.d.ts.map +1 -0
- package/dist/design/audit/modality/android.js +18 -0
- package/dist/design/audit/modality/android.js.map +1 -0
- package/dist/design/audit/modality/html.d.ts +22 -0
- package/dist/design/audit/modality/html.d.ts.map +1 -0
- package/dist/design/audit/modality/html.js +51 -0
- package/dist/design/audit/modality/html.js.map +1 -0
- package/dist/design/audit/modality/index.d.ts +8 -0
- package/dist/design/audit/modality/index.d.ts.map +1 -0
- package/dist/design/audit/modality/index.js +15 -0
- package/dist/design/audit/modality/index.js.map +1 -0
- package/dist/design/audit/modality/ios.d.ts +16 -0
- package/dist/design/audit/modality/ios.d.ts.map +1 -0
- package/dist/design/audit/modality/ios.js +19 -0
- package/dist/design/audit/modality/ios.js.map +1 -0
- package/dist/design/audit/modality/types.d.ts +9 -0
- package/dist/design/audit/modality/types.d.ts.map +1 -0
- package/dist/design/audit/modality/types.js +9 -0
- package/dist/design/audit/modality/types.js.map +1 -0
- package/dist/design/audit/patches/index.d.ts +8 -0
- package/dist/design/audit/patches/index.d.ts.map +1 -0
- package/dist/design/audit/patches/index.js +5 -0
- package/dist/design/audit/patches/index.js.map +1 -0
- package/dist/design/audit/patches/parse.d.ts +29 -0
- package/dist/design/audit/patches/parse.d.ts.map +1 -0
- package/dist/design/audit/patches/parse.js +153 -0
- package/dist/design/audit/patches/parse.js.map +1 -0
- package/dist/design/audit/patches/render.d.ts +20 -0
- package/dist/design/audit/patches/render.d.ts.map +1 -0
- package/dist/design/audit/patches/render.js +55 -0
- package/dist/design/audit/patches/render.js.map +1 -0
- package/dist/design/audit/patches/severity-enforcement.d.ts +23 -0
- package/dist/design/audit/patches/severity-enforcement.d.ts.map +1 -0
- package/dist/design/audit/patches/severity-enforcement.js +42 -0
- package/dist/design/audit/patches/severity-enforcement.js.map +1 -0
- package/dist/design/audit/patches/validate.d.ts +34 -0
- package/dist/design/audit/patches/validate.d.ts.map +1 -0
- package/dist/design/audit/patches/validate.js +53 -0
- package/dist/design/audit/patches/validate.js.map +1 -0
- package/dist/design/audit/patterns/match.d.ts +24 -0
- package/dist/design/audit/patterns/match.d.ts.map +1 -0
- package/dist/design/audit/patterns/match.js +48 -0
- package/dist/design/audit/patterns/match.js.map +1 -0
- package/dist/design/audit/patterns/mine.d.ts +31 -0
- package/dist/design/audit/patterns/mine.d.ts.map +1 -0
- package/dist/design/audit/patterns/mine.js +35 -0
- package/dist/design/audit/patterns/mine.js.map +1 -0
- package/dist/design/audit/patterns/store.d.ts +14 -0
- package/dist/design/audit/patterns/store.d.ts.map +1 -0
- package/dist/design/audit/patterns/store.js +53 -0
- package/dist/design/audit/patterns/store.js.map +1 -0
- package/dist/design/audit/patterns/types.d.ts +53 -0
- package/dist/design/audit/patterns/types.d.ts.map +1 -0
- package/dist/design/audit/patterns/types.js +13 -0
- package/dist/design/audit/patterns/types.js.map +1 -0
- package/dist/design/audit/pipeline.d.ts +26 -0
- package/dist/design/audit/pipeline.d.ts.map +1 -1
- package/dist/design/audit/pipeline.js +131 -4
- package/dist/design/audit/pipeline.js.map +1 -1
- package/dist/design/audit/rubric/anchor-loader.d.ts +44 -0
- package/dist/design/audit/rubric/anchor-loader.d.ts.map +1 -0
- package/dist/design/audit/rubric/anchor-loader.js +210 -0
- package/dist/design/audit/rubric/anchor-loader.js.map +1 -0
- package/dist/design/audit/rubric/anchors/blog.yaml +33 -0
- package/dist/design/audit/rubric/anchors/dashboard.yaml +35 -0
- package/dist/design/audit/rubric/anchors/docs.yaml +35 -0
- package/dist/design/audit/rubric/anchors/ecommerce.yaml +33 -0
- package/dist/design/audit/rubric/anchors/marketing.yaml +34 -0
- package/dist/design/audit/rubric/anchors/saas-app.yaml +38 -0
- package/dist/design/audit/rubric/anchors/social.yaml +33 -0
- package/dist/design/audit/rubric/anchors/tool.yaml +33 -0
- package/dist/design/audit/rubric/anchors/utility.yaml +33 -0
- package/dist/design/audit/rubric/fragments/audience-clinician.md +42 -0
- package/dist/design/audit/rubric/fragments/audience-developer.md +40 -0
- package/dist/design/audit/rubric/fragments/audience-kids.md +35 -0
- package/dist/design/audit/rubric/fragments/audience-vulnerability-minor-facing.md +37 -0
- package/dist/design/audit/rubric/fragments/first-principles.md +65 -0
- package/dist/design/audit/rubric/fragments/modality-mobile.md +39 -0
- package/dist/design/audit/rubric/fragments/modality-tablet.md +35 -0
- package/dist/design/audit/rubric/fragments/regulatory-coppa.md +32 -0
- package/dist/design/audit/rubric/fragments/regulatory-gdpr.md +33 -0
- package/dist/design/audit/rubric/fragments/regulatory-hipaa.md +36 -0
- package/dist/design/audit/rubric/fragments/universal-product-intent.md +48 -0
- package/dist/design/audit/rubric/loader.d.ts +26 -6
- package/dist/design/audit/rubric/loader.d.ts.map +1 -1
- package/dist/design/audit/rubric/loader.js +77 -27
- package/dist/design/audit/rubric/loader.js.map +1 -1
- package/dist/design/audit/rubric/rollup-weights.d.ts +25 -0
- package/dist/design/audit/rubric/rollup-weights.d.ts.map +1 -0
- package/dist/design/audit/rubric/rollup-weights.js +51 -0
- package/dist/design/audit/rubric/rollup-weights.js.map +1 -0
- package/dist/design/audit/types.d.ts +28 -0
- package/dist/design/audit/types.d.ts.map +1 -1
- package/dist/design/audit/v2/build-result.d.ts +47 -0
- package/dist/design/audit/v2/build-result.d.ts.map +1 -0
- package/dist/design/audit/v2/build-result.js +163 -0
- package/dist/design/audit/v2/build-result.js.map +1 -0
- package/dist/design/audit/v2/score.d.ts +49 -0
- package/dist/design/audit/v2/score.d.ts.map +1 -0
- package/dist/design/audit/v2/score.js +211 -0
- package/dist/design/audit/v2/score.js.map +1 -0
- package/dist/design/audit/v2/types.d.ts +431 -0
- package/dist/design/audit/v2/types.d.ts.map +1 -0
- package/dist/design/audit/v2/types.js +26 -0
- package/dist/design/audit/v2/types.js.map +1 -0
- package/dist/discover/index.d.ts +16 -0
- package/dist/discover/index.d.ts.map +1 -0
- package/dist/discover/index.js +25 -0
- package/dist/discover/index.js.map +1 -0
- package/dist/discover/wayback.d.ts +49 -0
- package/dist/discover/wayback.d.ts.map +1 -0
- package/dist/discover/wayback.js +123 -0
- package/dist/discover/wayback.js.map +1 -0
- package/dist/jobs/anti-bot.d.ts +19 -0
- package/dist/jobs/anti-bot.d.ts.map +1 -0
- package/dist/jobs/anti-bot.js +64 -0
- package/dist/jobs/anti-bot.js.map +1 -0
- package/dist/jobs/cost-estimate.d.ts +12 -0
- package/dist/jobs/cost-estimate.d.ts.map +1 -0
- package/dist/jobs/cost-estimate.js +21 -0
- package/dist/jobs/cost-estimate.js.map +1 -0
- package/dist/jobs/cost-history.d.ts +19 -0
- package/dist/jobs/cost-history.d.ts.map +1 -0
- package/dist/jobs/cost-history.js +42 -0
- package/dist/jobs/cost-history.js.map +1 -0
- package/dist/jobs/index.d.ts +31 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +37 -0
- package/dist/jobs/index.js.map +1 -0
- package/dist/jobs/orchestrator.d.ts +42 -0
- package/dist/jobs/orchestrator.d.ts.map +1 -0
- package/dist/jobs/orchestrator.js +282 -0
- package/dist/jobs/orchestrator.js.map +1 -0
- package/dist/jobs/queue.d.ts +45 -0
- package/dist/jobs/queue.d.ts.map +1 -0
- package/dist/jobs/queue.js +114 -0
- package/dist/jobs/queue.js.map +1 -0
- package/dist/jobs/retry.d.ts +36 -0
- package/dist/jobs/retry.d.ts.map +1 -0
- package/dist/jobs/retry.js +77 -0
- package/dist/jobs/retry.js.map +1 -0
- package/dist/jobs/store.d.ts +31 -0
- package/dist/jobs/store.d.ts.map +1 -0
- package/dist/jobs/store.js +92 -0
- package/dist/jobs/store.js.map +1 -0
- package/dist/jobs/types.d.ts +106 -0
- package/dist/jobs/types.d.ts.map +1 -0
- package/dist/jobs/types.js +13 -0
- package/dist/jobs/types.js.map +1 -0
- 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/reports/aggregate.d.ts +38 -0
- package/dist/reports/aggregate.d.ts.map +1 -0
- package/dist/reports/aggregate.js +145 -0
- package/dist/reports/aggregate.js.map +1 -0
- package/dist/reports/index.d.ts +21 -0
- package/dist/reports/index.d.ts.map +1 -0
- package/dist/reports/index.js +15 -0
- package/dist/reports/index.js.map +1 -0
- package/dist/reports/narrate.d.ts +19 -0
- package/dist/reports/narrate.d.ts.map +1 -0
- package/dist/reports/narrate.js +40 -0
- package/dist/reports/narrate.js.map +1 -0
- package/dist/reports/templates.d.ts +43 -0
- package/dist/reports/templates.d.ts.map +1 -0
- package/dist/reports/templates.js +200 -0
- package/dist/reports/templates.js.map +1 -0
- package/dist/reports/tokens.d.ts +77 -0
- package/dist/reports/tokens.d.ts.map +1 -0
- package/dist/reports/tokens.js +88 -0
- package/dist/reports/tokens.js.map +1 -0
- package/dist/reports/tools.d.ts +76 -0
- package/dist/reports/tools.d.ts.map +1 -0
- package/dist/reports/tools.js +205 -0
- package/dist/reports/tools.js.map +1 -0
- package/dist/reports/types.d.ts +51 -0
- package/dist/reports/types.d.ts.map +1 -0
- package/dist/reports/types.js +9 -0
- package/dist/reports/types.js.map +1 -0
- 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 +5 -1
|
@@ -12,10 +12,12 @@ export interface DesignAuditOptions {
|
|
|
12
12
|
model?: string;
|
|
13
13
|
provider?: string;
|
|
14
14
|
apiKey?: string;
|
|
15
|
+
baseUrl?: string;
|
|
15
16
|
output?: string;
|
|
16
17
|
json?: boolean;
|
|
17
18
|
headless?: boolean;
|
|
18
19
|
debug?: boolean;
|
|
20
|
+
storageState?: string;
|
|
19
21
|
viewport?: string;
|
|
20
22
|
extractTokens?: boolean;
|
|
21
23
|
/** Evolve mode: true/css for CSS injection, or agent name (claude-code, codex, opencode) for agent dispatch */
|
|
@@ -28,6 +30,20 @@ export interface DesignAuditOptions {
|
|
|
28
30
|
projectDir?: string;
|
|
29
31
|
/** Optional path to user-supplied rubric fragments */
|
|
30
32
|
rubricsDir?: string;
|
|
33
|
+
/** Subjective LLM audit passes: standard, deep, max, number, or comma-list */
|
|
34
|
+
auditPasses?: string;
|
|
35
|
+
/** Bypass the ethics floor entirely. Audited + warned. Test-only. */
|
|
36
|
+
skipEthics?: boolean;
|
|
37
|
+
/** Override directory for ethics rule yaml files. */
|
|
38
|
+
ethicsRulesDir?: string;
|
|
39
|
+
/** Comma-separated audience tags: developer, clinician, kids, ... */
|
|
40
|
+
audience?: string;
|
|
41
|
+
/** Comma-separated regulatory contexts: hipaa, gdpr, coppa, ... */
|
|
42
|
+
regulatoryContext?: string;
|
|
43
|
+
/** Comma-separated audience-vulnerability tags: patient-facing, minor-facing, ... */
|
|
44
|
+
audienceVulnerability?: string;
|
|
45
|
+
/** Single modality: mobile, tablet, desktop, tv, kiosk */
|
|
46
|
+
modality?: string;
|
|
31
47
|
}
|
|
32
48
|
export declare function runDesignAudit(opts: DesignAuditOptions): Promise<void>;
|
|
33
49
|
export interface ExtractDesignTokensOptions {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-design-audit.d.ts","sourceRoot":"","sources":["../src/cli-design-audit.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,KAAK,EAA4B,YAAY,EAA8L,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"cli-design-audit.d.ts","sourceRoot":"","sources":["../src/cli-design-audit.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,KAAK,EAA4B,YAAY,EAA8L,MAAM,YAAY,CAAA;AA0RpQ,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,+GAA+G;IAC/G,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACzB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,mEAAmE;IACnE,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,qEAAqE;IACrE,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mEAAmE;IACnE,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,qFAAqF;IACrF,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4U5E;AAsxCD,MAAM,WAAW,0BAA0B;IACzC,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAClE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CACjK;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,YAAY,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACxC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,0BAA0B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAsRrG"}
|
package/dist/cli-design-audit.js
CHANGED
|
@@ -15,7 +15,66 @@ 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
|
+
/** Split "a, b , c" → ['a','b','c']. Returns undefined for empty input so the
|
|
19
|
+
* v2 predicate predicates can distinguish "operator did not say" from "[]". */
|
|
20
|
+
function parseTagList(input) {
|
|
21
|
+
if (!input)
|
|
22
|
+
return undefined;
|
|
23
|
+
const tags = input.split(',').map(s => s.trim()).filter(Boolean);
|
|
24
|
+
return tags.length > 0 ? tags : undefined;
|
|
25
|
+
}
|
|
26
|
+
/** Pretty-print the ethics-violation report for a set of pages. Prints
|
|
27
|
+
* nothing when no page tripped a rule. Each rule is shown with severity,
|
|
28
|
+
* remediation, and citation so the operator can act without re-running. */
|
|
29
|
+
function printEthicsViolations(pages) {
|
|
30
|
+
const offenders = pages.filter(p => (p.ethicsViolations?.length ?? 0) > 0);
|
|
31
|
+
if (offenders.length === 0)
|
|
32
|
+
return;
|
|
33
|
+
console.log('');
|
|
34
|
+
console.log(` ${chalk.bgRed.white.bold(' ETHICS VIOLATIONS ')}`);
|
|
35
|
+
for (const page of offenders) {
|
|
36
|
+
console.log(` ${chalk.dim('Page:')} ${page.url}`);
|
|
37
|
+
for (const v of page.ethicsViolations ?? []) {
|
|
38
|
+
const sevColor = v.severity === 'critical-floor' ? chalk.red : chalk.yellow;
|
|
39
|
+
console.log(` ${sevColor('•')} ${chalk.bold(v.ruleId)} ${chalk.dim('—')} ${sevColor(v.severity)} ${chalk.dim(`(rollup capped at ${v.rollupCap})`)}`);
|
|
40
|
+
console.log(` ${chalk.dim('fix:')} ${v.remediation}`);
|
|
41
|
+
if (v.citation)
|
|
42
|
+
console.log(` ${chalk.dim('cite:')} ${v.citation}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** Lowest rollup cap across all violated pages, or undefined if none fired. */
|
|
47
|
+
function lowestRollupCap(pages) {
|
|
48
|
+
const caps = pages.flatMap(p => p.ethicsViolations ?? []).map(v => v.rollupCap);
|
|
49
|
+
return caps.length === 0 ? undefined : Math.min(...caps);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Layer 1 — print the per-dimension breakdown for one page when an
|
|
53
|
+
* `auditResultV2` is attached. Five dim lines + one rollup line; each shows
|
|
54
|
+
* score, range, and confidence so an agent can reason about uncertainty.
|
|
55
|
+
*/
|
|
56
|
+
function printV2Breakdown(page) {
|
|
57
|
+
const v2 = page.auditResultV2;
|
|
58
|
+
if (!v2 || !v2.scores || !v2.rollup)
|
|
59
|
+
return;
|
|
60
|
+
const dimOrder = ['product_intent', 'visual_craft', 'trust_clarity', 'workflow', 'content_ia'];
|
|
61
|
+
for (const dim of dimOrder) {
|
|
62
|
+
const s = v2.scores[dim];
|
|
63
|
+
if (!s)
|
|
64
|
+
continue;
|
|
65
|
+
const sevColor = s.score >= 8 ? chalk.green : s.score >= 5 ? chalk.yellow : chalk.red;
|
|
66
|
+
const confColor = s.confidence === 'high' ? chalk.green : s.confidence === 'medium' ? chalk.yellow : chalk.dim;
|
|
67
|
+
console.log(` ${chalk.dim(dim.padEnd(15))} ${sevColor(`${s.score}/10`)} ${chalk.dim(`[${s.range[0]}-${s.range[1]}]`)} ${confColor(s.confidence)}`);
|
|
68
|
+
}
|
|
69
|
+
const r = v2.rollup;
|
|
70
|
+
const rColor = r.score >= 8 ? chalk.green : r.score >= 5 ? chalk.yellow : chalk.red;
|
|
71
|
+
const confColor = r.confidence === 'high' ? chalk.green : r.confidence === 'medium' ? chalk.yellow : chalk.dim;
|
|
72
|
+
console.log(` ${chalk.dim('rollup'.padEnd(15))} ${rColor(`${r.score.toFixed(1)}/10`)} ${chalk.dim(`[${r.range[0].toFixed(1)}-${r.range[1].toFixed(1)}]`)} ${confColor(r.confidence)} ${chalk.dim(r.rule)}`);
|
|
73
|
+
}
|
|
74
|
+
import { resolveAuditPasses } from './design/audit/evaluate.js';
|
|
18
75
|
import { detectSystemicFindings, topByRoi } from './design/audit/roi.js';
|
|
76
|
+
import { getTelemetry, setInvocation } from './telemetry/index.js';
|
|
77
|
+
import { randomUUID } from 'node:crypto';
|
|
19
78
|
// ---------------------------------------------------------------------------
|
|
20
79
|
// Page discovery — find key pages by crawling links
|
|
21
80
|
// ---------------------------------------------------------------------------
|
|
@@ -194,15 +253,46 @@ export async function runDesignAudit(opts) {
|
|
|
194
253
|
const provider = (opts.provider ?? 'claude-code');
|
|
195
254
|
const modelName = resolveProviderModelName(provider, opts.model);
|
|
196
255
|
const apiKey = opts.apiKey ?? resolveProviderApiKey(provider);
|
|
256
|
+
const auditPasses = resolveAuditPasses(opts.auditPasses);
|
|
257
|
+
// Layer 7 — ethics gate options. Threaded into every auditOnePage call site.
|
|
258
|
+
if (opts.skipEthics) {
|
|
259
|
+
console.warn(` ${chalk.yellow('⚠')} ${chalk.bold('--skip-ethics')} ${chalk.dim('— ethics floor disabled (test-only)')}`);
|
|
260
|
+
}
|
|
261
|
+
const ethicsCommonOpts = {
|
|
262
|
+
skipEthics: opts.skipEthics,
|
|
263
|
+
ethicsRulesDir: opts.ethicsRulesDir,
|
|
264
|
+
audience: parseTagList(opts.audience),
|
|
265
|
+
regulatoryContext: parseTagList(opts.regulatoryContext),
|
|
266
|
+
audienceVulnerability: parseTagList(opts.audienceVulnerability),
|
|
267
|
+
modality: parseTagList(opts.modality),
|
|
268
|
+
};
|
|
269
|
+
// Telemetry: every design-audit invocation gets a stable runId. Children
|
|
270
|
+
// (per-page, evolve rounds) link back via parentRunId so a fleet rollup can
|
|
271
|
+
// reconstruct the tree.
|
|
272
|
+
const runId = randomUUID();
|
|
273
|
+
const runStartedAt = Date.now();
|
|
274
|
+
const invocation = opts.evolve ? 'design-audit:evolve' : opts.reproducibility ? 'design-audit:reproducibility' : 'design-audit';
|
|
275
|
+
setInvocation(invocation);
|
|
276
|
+
const telemetry = getTelemetry();
|
|
197
277
|
const [vw, vh] = (opts.viewport ?? '1440x900').split('x').map(Number);
|
|
198
278
|
console.log('');
|
|
199
279
|
console.log(` ${chalk.bold('bad design-audit')}`);
|
|
200
280
|
const profileLabel = profile ?? chalk.dim('auto-classify');
|
|
201
|
-
|
|
281
|
+
const passLabel = auditPasses.length === 1 && auditPasses[0] === 'standard'
|
|
282
|
+
? '1 audit pass'
|
|
283
|
+
: `${auditPasses.length} audit passes (${auditPasses.join(', ')})`;
|
|
284
|
+
console.log(` ${profileLabel} ${chalk.dim('·')} ${chalk.cyan(modelName)} ${chalk.dim('·')} ${vw}×${vh} ${chalk.dim('·')} ${passLabel} ${chalk.dim('·')} up to ${maxPages} pages`);
|
|
202
285
|
console.log(` ${chalk.dim('→')} ${opts.url}`);
|
|
203
286
|
console.log('');
|
|
287
|
+
const storageState = opts.storageState ? path.resolve(opts.storageState) : undefined;
|
|
288
|
+
if (storageState && !fs.existsSync(storageState)) {
|
|
289
|
+
cliError(`storage state file not found: ${storageState}`);
|
|
290
|
+
}
|
|
204
291
|
const browser = await chromium.launch({ headless: opts.headless ?? true });
|
|
205
|
-
const context = await browser.newContext({
|
|
292
|
+
const context = await browser.newContext({
|
|
293
|
+
viewport: { width: vw, height: vh },
|
|
294
|
+
...(storageState ? { storageState } : {}),
|
|
295
|
+
});
|
|
206
296
|
const page = await context.newPage();
|
|
207
297
|
// Discover pages
|
|
208
298
|
console.log(` ${chalk.dim('Discovering pages…')}`);
|
|
@@ -220,7 +310,8 @@ export async function runDesignAudit(opts) {
|
|
|
220
310
|
const brain = new Brain({
|
|
221
311
|
model: modelName,
|
|
222
312
|
apiKey,
|
|
223
|
-
provider:
|
|
313
|
+
provider: provider,
|
|
314
|
+
baseUrl: opts.baseUrl ?? process.env.LLM_BASE_URL,
|
|
224
315
|
vision: true,
|
|
225
316
|
debug: opts.debug,
|
|
226
317
|
llmTimeoutMs: 120_000, // design audits generate ~8k tokens of structured JSON — need 2min
|
|
@@ -239,6 +330,11 @@ export async function runDesignAudit(opts) {
|
|
|
239
330
|
profileOverride: profile,
|
|
240
331
|
screenshotDir,
|
|
241
332
|
userRubricsDir: opts.rubricsDir,
|
|
333
|
+
auditPasses,
|
|
334
|
+
runId,
|
|
335
|
+
provider,
|
|
336
|
+
model: modelName,
|
|
337
|
+
...ethicsCommonOpts,
|
|
242
338
|
});
|
|
243
339
|
const result = gen2;
|
|
244
340
|
results.push(result);
|
|
@@ -249,6 +345,7 @@ export async function runDesignAudit(opts) {
|
|
|
249
345
|
? chalk.dim(` (${result.classification.type}/${result.classification.domain})`)
|
|
250
346
|
: '';
|
|
251
347
|
console.log(` ${icon} ${scoreColor(`${result.score}/10`)} ${chalk.dim('—')} ${findingCount} finding${findingCount !== 1 ? 's' : ''}${classLabel}`);
|
|
348
|
+
printV2Breakdown(result);
|
|
252
349
|
}
|
|
253
350
|
// Cross-page systemic detection + top-fixes ranking.
|
|
254
351
|
// Findings appearing on 2+ pages collapse into a single systemic finding.
|
|
@@ -270,16 +367,29 @@ export async function runDesignAudit(opts) {
|
|
|
270
367
|
const minor = allFindings.filter(f => f.severity === 'minor').length;
|
|
271
368
|
if (opts.json) {
|
|
272
369
|
const jsonPath = path.join(outputDir, 'report.json');
|
|
370
|
+
// Layer 1 — emit BOTH schemaVersion 1 (legacy) and schemaVersion 2 (new)
|
|
371
|
+
// shapes for one release. Consumers can migrate to v2 incrementally.
|
|
372
|
+
const v2Pages = results
|
|
373
|
+
.map(r => r.auditResultV2)
|
|
374
|
+
.filter((r) => r !== undefined);
|
|
273
375
|
fs.writeFileSync(jsonPath, JSON.stringify({
|
|
376
|
+
schemaVersion: 1,
|
|
274
377
|
timestamp: new Date().toISOString(),
|
|
275
378
|
profile,
|
|
276
379
|
url: opts.url,
|
|
277
380
|
pages: results,
|
|
278
381
|
topFixes,
|
|
279
382
|
summary: { avgScore, totalFindings: allFindings.length, critical, major, minor },
|
|
383
|
+
v2: {
|
|
384
|
+
schemaVersion: 2,
|
|
385
|
+
pages: v2Pages,
|
|
386
|
+
},
|
|
280
387
|
}, null, 2));
|
|
281
388
|
console.log(` ${chalk.dim('JSON →')} ${jsonPath}`);
|
|
282
389
|
}
|
|
390
|
+
// ── Layer 7 — surface ethics violations BEFORE the score summary so the
|
|
391
|
+
// operator sees the floor reason, not just the capped number. ──
|
|
392
|
+
printEthicsViolations(results);
|
|
283
393
|
// Summary
|
|
284
394
|
console.log('');
|
|
285
395
|
console.log(` ${chalk.dim('─'.repeat(52))}`);
|
|
@@ -292,6 +402,10 @@ export async function runDesignAudit(opts) {
|
|
|
292
402
|
if (minor > 0)
|
|
293
403
|
findingParts.push(chalk.dim(`${minor} minor`));
|
|
294
404
|
console.log(` Avg: ${avgColor(`${avgScore.toFixed(1)}/10`)} ${chalk.dim('·')} ${allFindings.length} findings ${findingParts.length ? chalk.dim('(') + findingParts.join(chalk.dim(' · ')) + chalk.dim(')') : ''}`);
|
|
405
|
+
const lowestCap = lowestRollupCap(results);
|
|
406
|
+
if (lowestCap !== undefined) {
|
|
407
|
+
console.log(` ${chalk.red('⚠ Rollup capped at')} ${chalk.bold(`${lowestCap}/10`)} ${chalk.dim('— resolve ethics violations to lift the cap')}`);
|
|
408
|
+
}
|
|
295
409
|
console.log(` ${chalk.dim('Report →')} ${reportPath}`);
|
|
296
410
|
if (screenshotDir)
|
|
297
411
|
console.log(` ${chalk.dim('Screenshots →')} ${screenshotDir}`);
|
|
@@ -310,6 +424,12 @@ export async function runDesignAudit(opts) {
|
|
|
310
424
|
url,
|
|
311
425
|
profileOverride: profile,
|
|
312
426
|
userRubricsDir: opts.rubricsDir,
|
|
427
|
+
auditPasses,
|
|
428
|
+
runId,
|
|
429
|
+
provider,
|
|
430
|
+
model: modelName,
|
|
431
|
+
parentRunId: runId,
|
|
432
|
+
...ethicsCommonOpts,
|
|
313
433
|
});
|
|
314
434
|
repResults.push(gen2);
|
|
315
435
|
}
|
|
@@ -343,11 +463,11 @@ export async function runDesignAudit(opts) {
|
|
|
343
463
|
if (evolveMode !== 'css') {
|
|
344
464
|
// Agent-dispatched evolve — a coding agent edits the actual source code
|
|
345
465
|
const projectDir = opts.projectDir ?? process.cwd();
|
|
346
|
-
evolveResult = await runAgentEvolveLoop(brain, driver, page, pages, evolveProfile, results, outputDir, opts.evolveRounds ?? 3, evolveMode, projectDir, opts.debug);
|
|
466
|
+
evolveResult = await runAgentEvolveLoop(brain, driver, page, pages, evolveProfile, results, outputDir, opts.evolveRounds ?? 3, evolveMode, projectDir, opts.debug, auditPasses, runId, provider, modelName);
|
|
347
467
|
}
|
|
348
468
|
else {
|
|
349
469
|
// CSS-injection evolve — ephemeral fixes injected into the browser page
|
|
350
|
-
evolveResult = await runEvolveLoop(brain, driver, page, pages, evolveProfile, results, outputDir, opts.evolveRounds ?? 3);
|
|
470
|
+
evolveResult = await runEvolveLoop(brain, driver, page, pages, evolveProfile, results, outputDir, opts.evolveRounds ?? 3, auditPasses, runId, provider, modelName);
|
|
351
471
|
}
|
|
352
472
|
// Write evolve report
|
|
353
473
|
const evolvePath = path.join(outputDir, 'evolve-report.md');
|
|
@@ -364,10 +484,62 @@ export async function runDesignAudit(opts) {
|
|
|
364
484
|
fs.writeFileSync(evJsonPath, JSON.stringify(evolveResult, null, 2));
|
|
365
485
|
}
|
|
366
486
|
console.log('');
|
|
487
|
+
telemetry.emit({
|
|
488
|
+
kind: 'design-evolve-run',
|
|
489
|
+
runId,
|
|
490
|
+
ok: true,
|
|
491
|
+
durationMs: Date.now() - runStartedAt,
|
|
492
|
+
model: { provider, name: modelName },
|
|
493
|
+
data: {
|
|
494
|
+
url: opts.url,
|
|
495
|
+
pages: pages.length,
|
|
496
|
+
rounds: evolveResult.scoreHistory.length - 1,
|
|
497
|
+
scoreHistory: evolveResult.scoreHistory,
|
|
498
|
+
appliedFixCount: evolveResult.appliedFixes?.length ?? 0,
|
|
499
|
+
evolveMode: evolveMode === 'css' ? 'css' : `agent:${evolveMode}`,
|
|
500
|
+
},
|
|
501
|
+
metrics: {
|
|
502
|
+
initialScore: evolveResult.scoreHistory[0] ?? 0,
|
|
503
|
+
finalScore: evolveResult.scoreHistory[evolveResult.scoreHistory.length - 1] ?? 0,
|
|
504
|
+
delta: (evolveResult.scoreHistory[evolveResult.scoreHistory.length - 1] ?? 0) - (evolveResult.scoreHistory[0] ?? 0),
|
|
505
|
+
rounds: evolveResult.scoreHistory.length - 1,
|
|
506
|
+
},
|
|
507
|
+
});
|
|
367
508
|
}
|
|
509
|
+
// Run-level summary envelope — fires for every design-audit invocation,
|
|
510
|
+
// evolve or not. This is the row a fleet rollup queries to track audit
|
|
511
|
+
// health across repos over time.
|
|
512
|
+
telemetry.emit({
|
|
513
|
+
kind: 'design-audit-run',
|
|
514
|
+
runId,
|
|
515
|
+
ok: true,
|
|
516
|
+
durationMs: Date.now() - runStartedAt,
|
|
517
|
+
model: { provider, name: modelName },
|
|
518
|
+
data: {
|
|
519
|
+
url: opts.url,
|
|
520
|
+
pages: pages.length,
|
|
521
|
+
profile: profile ?? null,
|
|
522
|
+
auditPasses,
|
|
523
|
+
outputDir,
|
|
524
|
+
},
|
|
525
|
+
metrics: {
|
|
526
|
+
avgScore,
|
|
527
|
+
pageCount: pages.length,
|
|
528
|
+
totalFindings: allFindings.length,
|
|
529
|
+
criticalFindings: critical,
|
|
530
|
+
majorFindings: major,
|
|
531
|
+
minorFindings: minor,
|
|
532
|
+
topFixCount: topFixes.length,
|
|
533
|
+
},
|
|
534
|
+
tags: {
|
|
535
|
+
evolveMode: opts.evolve ? (opts.evolve === true || opts.evolve === 'css' ? 'css' : 'agent') : 'off',
|
|
536
|
+
reproducibility: opts.reproducibility ? 'on' : 'off',
|
|
537
|
+
},
|
|
538
|
+
});
|
|
368
539
|
await browser.close();
|
|
369
540
|
}
|
|
370
|
-
async function runEvolveLoop(brain, driver, page, pages, profile, initialResults, outputDir, maxRounds) {
|
|
541
|
+
async function runEvolveLoop(brain, driver, page, pages, profile, initialResults, outputDir, maxRounds, auditPasses, parentRunId, provider, model) {
|
|
542
|
+
const telemetry = parentRunId ? getTelemetry() : undefined;
|
|
371
543
|
const initialAvg = initialResults.reduce((s, r) => s + r.score, 0) / initialResults.length;
|
|
372
544
|
const scoreHistory = [initialAvg];
|
|
373
545
|
const appliedFixes = [];
|
|
@@ -463,6 +635,10 @@ async function runEvolveLoop(brain, driver, page, pages, profile, initialResults
|
|
|
463
635
|
url,
|
|
464
636
|
profileOverride: profile,
|
|
465
637
|
screenshotDir,
|
|
638
|
+
auditPasses,
|
|
639
|
+
...(parentRunId ? { runId: parentRunId, parentRunId } : {}),
|
|
640
|
+
...(provider ? { provider } : {}),
|
|
641
|
+
...(model ? { model } : {}),
|
|
466
642
|
}));
|
|
467
643
|
roundResults.push(result);
|
|
468
644
|
}
|
|
@@ -482,6 +658,28 @@ async function runEvolveLoop(brain, driver, page, pages, profile, initialResults
|
|
|
482
658
|
const delta = roundAvg - currentAvg;
|
|
483
659
|
const deltaStr = delta >= 0 ? chalk.green(`+${delta.toFixed(1)}`) : chalk.red(delta.toFixed(1));
|
|
484
660
|
console.log(` ${chalk.dim(' Score:')} ${roundAvg.toFixed(1)}/10 (${deltaStr})`);
|
|
661
|
+
if (telemetry && parentRunId) {
|
|
662
|
+
telemetry.emit({
|
|
663
|
+
kind: 'design-evolve-round',
|
|
664
|
+
runId: parentRunId,
|
|
665
|
+
parentRunId,
|
|
666
|
+
ok: true,
|
|
667
|
+
durationMs: 0, // round-level wall time would require a per-round timer; the parent run captures total duration
|
|
668
|
+
...(provider && model ? { model: { provider, name: model } } : {}),
|
|
669
|
+
data: {
|
|
670
|
+
mode: 'css',
|
|
671
|
+
round,
|
|
672
|
+
fixesApplied: fixableFixes.length,
|
|
673
|
+
},
|
|
674
|
+
metrics: {
|
|
675
|
+
round,
|
|
676
|
+
beforeScore: currentAvg,
|
|
677
|
+
afterScore: roundAvg,
|
|
678
|
+
delta,
|
|
679
|
+
fixesApplied: fixableFixes.length,
|
|
680
|
+
},
|
|
681
|
+
});
|
|
682
|
+
}
|
|
485
683
|
currentResults = roundResults;
|
|
486
684
|
currentAvg = roundAvg;
|
|
487
685
|
// Check convergence — if no improvement, stop
|
|
@@ -638,7 +836,8 @@ Do NOT:
|
|
|
638
836
|
- Refactor unrelated code
|
|
639
837
|
- Change component structure or HTML semantics unless a finding specifically requires it`;
|
|
640
838
|
}
|
|
641
|
-
async function runAgentEvolveLoop(brain, driver, page, pages, profile, initialResults, outputDir, maxRounds, agentName, projectDir, debug) {
|
|
839
|
+
async function runAgentEvolveLoop(brain, driver, page, pages, profile, initialResults, outputDir, maxRounds, agentName, projectDir, debug, auditPasses, parentRunId, provider, model) {
|
|
840
|
+
const telemetry = parentRunId ? getTelemetry() : undefined;
|
|
642
841
|
const initialAvg = initialResults.reduce((s, r) => s + r.score, 0) / initialResults.length;
|
|
643
842
|
const scoreHistory = [initialAvg];
|
|
644
843
|
const appliedFixes = [];
|
|
@@ -719,6 +918,10 @@ async function runAgentEvolveLoop(brain, driver, page, pages, profile, initialRe
|
|
|
719
918
|
url,
|
|
720
919
|
profileOverride: profile,
|
|
721
920
|
screenshotDir: roundScreenshotDir,
|
|
921
|
+
auditPasses,
|
|
922
|
+
...(parentRunId ? { runId: parentRunId, parentRunId } : {}),
|
|
923
|
+
...(provider ? { provider } : {}),
|
|
924
|
+
...(model ? { model } : {}),
|
|
722
925
|
}));
|
|
723
926
|
roundResults.push(result);
|
|
724
927
|
}
|
|
@@ -738,6 +941,28 @@ async function runAgentEvolveLoop(brain, driver, page, pages, profile, initialRe
|
|
|
738
941
|
finding: `Score: ${currentAvg.toFixed(1)} → ${roundAvg.toFixed(1)}`,
|
|
739
942
|
});
|
|
740
943
|
}
|
|
944
|
+
if (telemetry && parentRunId) {
|
|
945
|
+
telemetry.emit({
|
|
946
|
+
kind: 'design-evolve-round',
|
|
947
|
+
runId: parentRunId,
|
|
948
|
+
parentRunId,
|
|
949
|
+
ok: true,
|
|
950
|
+
durationMs: 0,
|
|
951
|
+
...(provider && model ? { model: { provider, name: model } } : {}),
|
|
952
|
+
data: {
|
|
953
|
+
mode: `agent:${agentName}`,
|
|
954
|
+
round,
|
|
955
|
+
resolvedCount,
|
|
956
|
+
},
|
|
957
|
+
metrics: {
|
|
958
|
+
round,
|
|
959
|
+
beforeScore: currentAvg,
|
|
960
|
+
afterScore: roundAvg,
|
|
961
|
+
delta,
|
|
962
|
+
findingsResolved: resolvedCount,
|
|
963
|
+
},
|
|
964
|
+
});
|
|
965
|
+
}
|
|
741
966
|
currentResults = roundResults;
|
|
742
967
|
currentAvg = roundAvg;
|
|
743
968
|
// Check convergence
|