@attest-ai/vitest 0.6.0 → 1.0.0-rc.1

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.
@@ -1,20 +1,55 @@
1
+ import type { TestContext } from "vitest";
1
2
  import { type ExpectChain, AgentResult, AttestClient } from "@attest-ai/core";
3
+ export interface InspectOptions {
4
+ /** Throw when the cumulative session cost exceeds this USD amount. */
5
+ budget?: number;
6
+ /**
7
+ * The running test's context (`it("…", async (context) => …)`). Used to
8
+ * attach results to the right test for AttestReporter and to skip it;
9
+ * required under `test.concurrent` and, for skips, on Vitest before 4.1.
10
+ */
11
+ context?: TestContext;
12
+ }
13
+ export interface EvaluateOptions extends InspectOptions {
14
+ /**
15
+ * Fail (instead of skip) when an assertion was not evaluated. Defaults to
16
+ * the ATTEST_STRICT environment variable ("1", "true" or "yes").
17
+ */
18
+ strict?: boolean;
19
+ }
20
+ /**
21
+ * Fail or skip the running Vitest test according to the batch outcome:
22
+ * any hard_fail throws with rendered diagnostics; otherwise any
23
+ * not_evaluated skips with "not evaluated: <reasons>" (throws when strict);
24
+ * soft failures pass.
25
+ */
26
+ export declare function enforceOutcome(result: AgentResult, strict: boolean, context?: TestContext): AgentResult;
2
27
  export declare class AttestEngineFixture {
3
28
  private manager;
4
29
  private _client;
30
+ private starting;
5
31
  constructor(options?: {
6
32
  enginePath?: string;
7
33
  logLevel?: string;
34
+ client?: AttestClient;
8
35
  });
36
+ /**
37
+ * Start the engine. In simulation mode the engine is started with
38
+ * ATTEST_SIMULATION=1 so it evaluates layers 1-4 and reports layers 5-6
39
+ * as not evaluated; an engine without that capability is rejected.
40
+ */
9
41
  start(): Promise<void>;
10
42
  stop(): Promise<void>;
11
43
  get client(): AttestClient;
12
- evaluate(chain: ExpectChain, options?: {
13
- budget?: number;
14
- }): Promise<AgentResult>;
44
+ private ensureStarted;
45
+ /** Evaluate collected assertions without enforcing the test outcome. */
46
+ inspect(chain: ExpectChain, options?: InspectOptions): Promise<AgentResult>;
47
+ /** Evaluate collected assertions and enforce the test outcome. */
48
+ evaluate(chain: ExpectChain, options?: EvaluateOptions): Promise<AgentResult>;
15
49
  }
16
50
  export declare function useAttest(): AttestEngineFixture;
17
- export declare function evaluate(chain: ExpectChain, options?: {
18
- budget?: number;
19
- }): Promise<AgentResult>;
51
+ /** Evaluate and enforce: hard_fail throws, not_evaluated skips (strict: throws). */
52
+ export declare function evaluate(chain: ExpectChain, options?: EvaluateOptions): Promise<AgentResult>;
53
+ /** Evaluate without enforcing; use for trial loops and custom checks. */
54
+ export declare function inspect(chain: ExpectChain, options?: InspectOptions): Promise<AgentResult>;
20
55
  //# sourceMappingURL=fixtures.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../src/fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAKhB,WAAW,EACX,YAAY,EAKb,MAAM,iBAAiB,CAAC;AAEzB,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,OAAO,CAA2B;gBAE9B,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;IAS1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,IAAI,MAAM,IAAI,YAAY,CAKzB;IAEK,QAAQ,CACZ,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAC5B,OAAO,CAAC,WAAW,CAAC;CAqCxB;AAED,wBAAgB,SAAS,IAAI,mBAAmB,CAiB/C;AAED,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5B,OAAO,CAAC,WAAW,CAAC,CAGtB"}
1
+ {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../src/fixtures.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EACL,KAAK,WAAW,EAChB,WAAW,EACX,YAAY,EAQb,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,cAAc;IAC7B,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA8CD;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,OAAO,EACf,OAAO,CAAC,EAAE,WAAW,GACpB,WAAW,CAUb;AAmBD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,QAAQ,CAA4B;gBAEhC,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,YAAY,CAAA;KAAE;IAWvF;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,IAAI,MAAM,IAAI,YAAY,CAKzB;YAEa,aAAa;IAM3B,wEAAwE;IAClE,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;IA4CjF,kEAAkE;IAC5D,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;CAIpF;AAOD,wBAAgB,SAAS,IAAI,mBAAmB,CAO/C;AAED,oFAAoF;AACpF,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,WAAW,CAAC,CAEtB;AAED,yEAAyE;AACzE,wBAAsB,OAAO,CAC3B,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,WAAW,CAAC,CAEtB"}
package/dist/fixtures.js CHANGED
@@ -1,22 +1,112 @@
1
- import { AgentResult, AttestClient, EngineManager, isSimulationMode, simulationEvaluateBatch, STATUS_SOFT_FAIL, } from "@attest-ai/core";
1
+ import * as vitest from "vitest";
2
+ import { AgentResult, AttestClient, EngineManager, isSimulationMode, renderDiagnostics, requireSimulationCapability, OUTCOME_FAIL, OUTCOME_SKIP, STATUS_SOFT_FAIL, } from "@attest-ai/core";
3
+ /**
4
+ * The running test: `TestRunner.getCurrentTest()` on Vitest 4.1+, `vitest/suite`
5
+ * before that (loaded only there, because Vitest 4.1 warns when it is imported).
6
+ */
7
+ async function runningTest() {
8
+ const runner = vitest.TestRunner;
9
+ if (runner !== undefined)
10
+ return runner.getCurrentTest();
11
+ const suite = await import("vitest/suite");
12
+ return suite.getCurrentTest();
13
+ }
14
+ /**
15
+ * Attach the results to the running test's meta so AttestReporter, in the main
16
+ * process, can write them with the test's file and line. Results from an earlier
17
+ * attempt of a retried test are dropped, so the report matches the outcome Vitest
18
+ * reports. Outside a test (e.g. in a beforeAll hook) there is no test to attach to.
19
+ */
20
+ async function recordOnTest(result, context) {
21
+ const test = context?.task ?? (await runningTest());
22
+ if (test === undefined)
23
+ return;
24
+ if (context === undefined && test.concurrent === true) {
25
+ throw new Error("Attest results from a test.concurrent test — pass the test context: " +
26
+ "inspect(chain, { context }) or evaluate(chain, { context })");
27
+ }
28
+ const attempt = test.result?.retryCount ?? 0;
29
+ let meta = test.meta.attest;
30
+ if (meta === undefined || meta.attempt !== attempt) {
31
+ meta = { attempt, results: [], totalCost: 0, totalDurationMs: 0 };
32
+ test.meta.attest = meta;
33
+ }
34
+ meta.results.push(...result.assertionResults);
35
+ meta.totalCost += result.totalCost;
36
+ meta.totalDurationMs += result.totalDurationMs;
37
+ }
38
+ function strictFromEnv() {
39
+ const v = (process.env["ATTEST_STRICT"] ?? "").trim().toLowerCase();
40
+ return v === "1" || v === "true" || v === "yes";
41
+ }
42
+ /**
43
+ * Fail or skip the running Vitest test according to the batch outcome:
44
+ * any hard_fail throws with rendered diagnostics; otherwise any
45
+ * not_evaluated skips with "not evaluated: <reasons>" (throws when strict);
46
+ * soft failures pass.
47
+ */
48
+ export function enforceOutcome(result, strict, context) {
49
+ const outcome = result.outcome({ strict });
50
+ if (outcome === OUTCOME_FAIL) {
51
+ const header = result.hardFailures.length === 0 ? `strict: ${result.skipReason()}\n` : "";
52
+ throw new Error(header + renderDiagnostics(result).replace(/^\n/, ""));
53
+ }
54
+ if (outcome === OUTCOME_SKIP) {
55
+ (context ?? currentTestContext(result)).skip(result.skipReason());
56
+ }
57
+ return result;
58
+ }
59
+ /**
60
+ * The running test's context when Vitest can name it unambiguously:
61
+ * TestRunner exists from Vitest 4.1, and under test.concurrent the
62
+ * "current test" may be another test, so the caller must pass `context`.
63
+ */
64
+ function currentTestContext(result) {
65
+ const runner = vitest.TestRunner;
66
+ const test = runner?.getCurrentTest();
67
+ if (test === undefined || test.concurrent === true) {
68
+ throw new Error(`${result.skipReason()} — pass the test context to skip this test: ` +
69
+ "evaluate(chain, { context }) (required for test.concurrent and Vitest < 4.1)");
70
+ }
71
+ return test.context;
72
+ }
2
73
  export class AttestEngineFixture {
3
74
  manager;
4
75
  _client;
76
+ starting;
5
77
  constructor(options) {
6
- if (!isSimulationMode()) {
7
- this.manager = new EngineManager({
8
- enginePath: options?.enginePath,
9
- logLevel: options?.logLevel ?? "warn",
10
- });
78
+ if (options?.client !== undefined) {
79
+ this._client = options.client;
80
+ return;
11
81
  }
82
+ this.manager = new EngineManager({
83
+ enginePath: options?.enginePath,
84
+ logLevel: options?.logLevel ?? "warn",
85
+ });
12
86
  }
87
+ /**
88
+ * Start the engine. In simulation mode the engine is started with
89
+ * ATTEST_SIMULATION=1 so it evaluates layers 1-4 and reports layers 5-6
90
+ * as not evaluated; an engine without that capability is rejected.
91
+ */
13
92
  async start() {
14
- if (isSimulationMode())
15
- return;
16
93
  if (this.manager === undefined) {
17
94
  throw new Error("AttestEngineFixture already stopped.");
18
95
  }
19
- await this.manager.start();
96
+ const simulation = isSimulationMode();
97
+ if (simulation) {
98
+ process.env["ATTEST_SIMULATION"] = "1";
99
+ }
100
+ const init = await this.manager.start();
101
+ if (simulation) {
102
+ try {
103
+ requireSimulationCapability(init);
104
+ }
105
+ catch (err) {
106
+ await this.manager.stop();
107
+ throw err;
108
+ }
109
+ }
20
110
  this._client = new AttestClient(this.manager);
21
111
  }
22
112
  async stop() {
@@ -27,25 +117,37 @@ export class AttestEngineFixture {
27
117
  }
28
118
  }
29
119
  get client() {
30
- if (this._client === undefined && !isSimulationMode()) {
120
+ if (this._client === undefined) {
31
121
  throw new Error("Engine not started. Call start() first.");
32
122
  }
33
123
  return this._client;
34
124
  }
35
- async evaluate(chain, options) {
36
- let result;
37
- if (isSimulationMode()) {
38
- result = simulationEvaluateBatch(chain.assertions);
39
- }
40
- else {
41
- result = await this.client.evaluateBatch(chain.trace, chain.assertions);
42
- }
125
+ async ensureStarted() {
126
+ if (this._client !== undefined)
127
+ return;
128
+ this.starting ??= this.start();
129
+ await this.starting;
130
+ }
131
+ /** Evaluate collected assertions without enforcing the test outcome. */
132
+ async inspect(chain, options) {
133
+ await this.ensureStarted();
134
+ const result = await this.client.evaluateBatch(chain.trace, chain.assertions);
43
135
  globalThis.__attest_session_cost__ =
44
136
  (globalThis.__attest_session_cost__ ?? 0) + (result.total_cost ?? 0);
45
137
  const softFailCount = (result.results ?? []).filter((r) => r.status === STATUS_SOFT_FAIL).length;
46
138
  globalThis.__attest_session_soft_failures__ =
47
139
  (globalThis.__attest_session_soft_failures__ ?? 0) + softFailCount;
48
140
  const agentResult = new AgentResult(chain.trace, result.results ?? [], result.total_cost ?? 0, result.total_duration_ms ?? 0);
141
+ await recordOnTest(agentResult, options?.context);
142
+ // Track non-passing AgentResults so AttestCostReporter can render the
143
+ // diagnostic block at the end of the run. Bound size because long
144
+ // suites with many failures should not balloon RAM.
145
+ if (!agentResult.passed) {
146
+ const list = (globalThis.__attest_session_failures__ ??= []);
147
+ if (list.length < 200) {
148
+ list.push(agentResult);
149
+ }
150
+ }
49
151
  if (options?.budget !== undefined &&
50
152
  globalThis.__attest_session_cost__ > options.budget) {
51
153
  throw new Error(`Attest budget exceeded: cost $${globalThis.__attest_session_cost__.toFixed(6)}` +
@@ -53,22 +155,30 @@ export class AttestEngineFixture {
53
155
  }
54
156
  return agentResult;
55
157
  }
158
+ /** Evaluate collected assertions and enforce the test outcome. */
159
+ async evaluate(chain, options) {
160
+ const result = await this.inspect(chain, options);
161
+ return enforceOutcome(result, options?.strict ?? strictFromEnv(), options?.context);
162
+ }
56
163
  }
164
+ // Vitest runs globalSetup in the main process and tests in workers, so a
165
+ // worker that cannot see the global client starts its own engine on first use.
166
+ // The engine exits when its stdin closes, i.e. when the worker exits.
167
+ let workerFixture;
57
168
  export function useAttest() {
58
- if (isSimulationMode() || globalThis.__attest_simulation_mode__) {
59
- return new AttestEngineFixture();
60
- }
61
169
  const client = globalThis.__attest_client__;
62
- const engine = globalThis.__attest_engine__;
63
- if (client === undefined || engine === undefined) {
64
- throw new Error("Attest engine not available. Configure attestGlobalSetup() in vitest.config.ts globalSetup.");
170
+ if (client !== undefined) {
171
+ return new AttestEngineFixture({ client });
65
172
  }
66
- const fixture = new AttestEngineFixture();
67
- Object.defineProperty(fixture, "client", { get: () => client });
68
- return fixture;
173
+ workerFixture ??= new AttestEngineFixture();
174
+ return workerFixture;
69
175
  }
176
+ /** Evaluate and enforce: hard_fail throws, not_evaluated skips (strict: throws). */
70
177
  export async function evaluate(chain, options) {
71
- const fixture = useAttest();
72
- return fixture.evaluate(chain, options);
178
+ return useAttest().evaluate(chain, options);
179
+ }
180
+ /** Evaluate without enforcing; use for trial loops and custom checks. */
181
+ export async function inspect(chain, options) {
182
+ return useAttest().inspect(chain, options);
73
183
  }
74
184
  //# sourceMappingURL=fixtures.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../src/fixtures.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../src/fixtures.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  export { attestGlobalSetup } from "./plugin.js";
2
2
  export type { AttestGlobalSetupOptions } from "./plugin.js";
3
- export { AttestEngineFixture, useAttest, evaluate } from "./fixtures.js";
4
- export { AttestCostReporter } from "./reporter.js";
3
+ export { AttestEngineFixture, useAttest, evaluate, inspect, enforceOutcome } from "./fixtures.js";
4
+ export type { EvaluateOptions, InspectOptions } from "./fixtures.js";
5
+ export { AttestCostReporter, AttestReporter } from "./reporter.js";
6
+ export type { AttestReporterOptions } from "./reporter.js";
7
+ export { buildReport, REPORT_VERSION } from "./report.js";
8
+ export type { AttestTaskMeta, TestOutcome, TestRecord } from "./report.js";
5
9
  export { filterByTier } from "./tier-filter.js";
6
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAClG,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACnE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { attestGlobalSetup } from "./plugin.js";
2
- export { AttestEngineFixture, useAttest, evaluate } from "./fixtures.js";
3
- export { AttestCostReporter } from "./reporter.js";
2
+ export { AttestEngineFixture, useAttest, evaluate, inspect, enforceOutcome } from "./fixtures.js";
3
+ export { AttestCostReporter, AttestReporter } from "./reporter.js";
4
+ export { buildReport, REPORT_VERSION } from "./report.js";
4
5
  export { filterByTier } from "./tier-filter.js";
5
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAElG,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEnE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/plugin.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { EngineManager, AttestClient } from "@attest-ai/core";
1
+ import { EngineManager, AttestClient, type AgentResult } from "@attest-ai/core";
2
2
  export interface AttestGlobalSetupOptions {
3
3
  enginePath?: string;
4
4
  logLevel?: string;
@@ -8,7 +8,7 @@ declare global {
8
8
  var __attest_client__: AttestClient | undefined;
9
9
  var __attest_session_cost__: number;
10
10
  var __attest_session_soft_failures__: number;
11
- var __attest_simulation_mode__: boolean;
11
+ var __attest_session_failures__: AgentResult[] | undefined;
12
12
  }
13
13
  export declare function attestGlobalSetup(options?: AttestGlobalSetupOptions): {
14
14
  setup(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAoB,MAAM,iBAAiB,CAAC;AAKhF,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,iBAAiB,EAAE,aAAa,GAAG,SAAS,CAAC;IAEjD,IAAI,iBAAiB,EAAE,YAAY,GAAG,SAAS,CAAC;IAEhD,IAAI,uBAAuB,EAAE,MAAM,CAAC;IAEpC,IAAI,gCAAgC,EAAE,MAAM,CAAC;IAE7C,IAAI,0BAA0B,EAAE,OAAO,CAAC;CACzC;AAED,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,wBAAwB;;;EAmCnE"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,YAAY,EAGZ,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AAKzB,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,iBAAiB,EAAE,aAAa,GAAG,SAAS,CAAC;IAEjD,IAAI,iBAAiB,EAAE,YAAY,GAAG,SAAS,CAAC;IAEhD,IAAI,uBAAuB,EAAE,MAAM,CAAC;IAEpC,IAAI,gCAAgC,EAAE,MAAM,CAAC;IAE7C,IAAI,2BAA2B,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;CAC5D;AAED,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,wBAAwB;;;EA8CnE"}
package/dist/plugin.js CHANGED
@@ -1,4 +1,4 @@
1
- import { EngineManager, AttestClient, isSimulationMode } from "@attest-ai/core";
1
+ import { EngineManager, AttestClient, isSimulationMode, requireSimulationCapability, } from "@attest-ai/core";
2
2
  let engineManager;
3
3
  let attestClient;
4
4
  export function attestGlobalSetup(options) {
@@ -6,15 +6,27 @@ export function attestGlobalSetup(options) {
6
6
  async setup() {
7
7
  globalThis.__attest_session_cost__ = 0;
8
8
  globalThis.__attest_session_soft_failures__ = 0;
9
+ globalThis.__attest_session_failures__ = [];
9
10
  if (isSimulationMode()) {
10
- globalThis.__attest_simulation_mode__ = true;
11
- return;
11
+ // The engine decides simulation at startup from its environment;
12
+ // this also covers config({ simulation: true }).
13
+ process.env["ATTEST_SIMULATION"] = "1";
12
14
  }
13
15
  engineManager = new EngineManager({
14
16
  enginePath: options?.enginePath,
15
17
  logLevel: options?.logLevel ?? "warn",
16
18
  });
17
- await engineManager.start();
19
+ const init = await engineManager.start();
20
+ if (isSimulationMode()) {
21
+ try {
22
+ requireSimulationCapability(init);
23
+ }
24
+ catch (err) {
25
+ await engineManager.stop();
26
+ engineManager = undefined;
27
+ throw err;
28
+ }
29
+ }
18
30
  attestClient = new AttestClient(engineManager);
19
31
  globalThis.__attest_engine__ = engineManager;
20
32
  globalThis.__attest_client__ = attestClient;
@@ -27,7 +39,7 @@ export function attestGlobalSetup(options) {
27
39
  }
28
40
  globalThis.__attest_engine__ = undefined;
29
41
  globalThis.__attest_client__ = undefined;
30
- globalThis.__attest_simulation_mode__ = false;
42
+ globalThis.__attest_session_failures__ = undefined;
31
43
  },
32
44
  };
33
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEhF,IAAI,aAAwC,CAAC;AAC7C,IAAI,YAAsC,CAAC;AAoB3C,MAAM,UAAU,iBAAiB,CAAC,OAAkC;IAClE,OAAO;QACL,KAAK,CAAC,KAAK;YACT,UAAU,CAAC,uBAAuB,GAAG,CAAC,CAAC;YACvC,UAAU,CAAC,gCAAgC,GAAG,CAAC,CAAC;YAEhD,IAAI,gBAAgB,EAAE,EAAE,CAAC;gBACvB,UAAU,CAAC,0BAA0B,GAAG,IAAI,CAAC;gBAC7C,OAAO;YACT,CAAC;YAED,aAAa,GAAG,IAAI,aAAa,CAAC;gBAChC,UAAU,EAAE,OAAO,EAAE,UAAU;gBAC/B,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,MAAM;aACtC,CAAC,CAAC;YAEH,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC;YAC5B,YAAY,GAAG,IAAI,YAAY,CAAC,aAAa,CAAC,CAAC;YAE/C,UAAU,CAAC,iBAAiB,GAAG,aAAa,CAAC;YAC7C,UAAU,CAAC,iBAAiB,GAAG,YAAY,CAAC;QAC9C,CAAC;QAED,KAAK,CAAC,QAAQ;YACZ,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC;gBAC3B,aAAa,GAAG,SAAS,CAAC;gBAC1B,YAAY,GAAG,SAAS,CAAC;YAC3B,CAAC;YAED,UAAU,CAAC,iBAAiB,GAAG,SAAS,CAAC;YACzC,UAAU,CAAC,iBAAiB,GAAG,SAAS,CAAC;YACzC,UAAU,CAAC,0BAA0B,GAAG,KAAK,CAAC;QAChD,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,2BAA2B,GAE5B,MAAM,iBAAiB,CAAC;AAEzB,IAAI,aAAwC,CAAC;AAC7C,IAAI,YAAsC,CAAC;AAoB3C,MAAM,UAAU,iBAAiB,CAAC,OAAkC;IAClE,OAAO;QACL,KAAK,CAAC,KAAK;YACT,UAAU,CAAC,uBAAuB,GAAG,CAAC,CAAC;YACvC,UAAU,CAAC,gCAAgC,GAAG,CAAC,CAAC;YAChD,UAAU,CAAC,2BAA2B,GAAG,EAAE,CAAC;YAE5C,IAAI,gBAAgB,EAAE,EAAE,CAAC;gBACvB,iEAAiE;gBACjE,iDAAiD;gBACjD,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,GAAG,GAAG,CAAC;YACzC,CAAC;YAED,aAAa,GAAG,IAAI,aAAa,CAAC;gBAChC,UAAU,EAAE,OAAO,EAAE,UAAU;gBAC/B,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,MAAM;aACtC,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC;YACzC,IAAI,gBAAgB,EAAE,EAAE,CAAC;gBACvB,IAAI,CAAC;oBACH,2BAA2B,CAAC,IAAI,CAAC,CAAC;gBACpC,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC;oBAC3B,aAAa,GAAG,SAAS,CAAC;oBAC1B,MAAM,GAAG,CAAC;gBACZ,CAAC;YACH,CAAC;YACD,YAAY,GAAG,IAAI,YAAY,CAAC,aAAa,CAAC,CAAC;YAE/C,UAAU,CAAC,iBAAiB,GAAG,aAAa,CAAC;YAC7C,UAAU,CAAC,iBAAiB,GAAG,YAAY,CAAC;QAC9C,CAAC;QAED,KAAK,CAAC,QAAQ;YACZ,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC;gBAC3B,aAAa,GAAG,SAAS,CAAC;gBAC1B,YAAY,GAAG,SAAS,CAAC;YAC3B,CAAC;YAED,UAAU,CAAC,iBAAiB,GAAG,SAAS,CAAC;YACzC,UAAU,CAAC,iBAAiB,GAAG,SAAS,CAAC;YACzC,UAAU,CAAC,2BAA2B,GAAG,SAAS,CAAC;QACrD,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * report-v2 builder (proto/attest/v1/report-v2.schema.json, contract C3).
3
+ *
4
+ * One row per assertion in `results`, each carrying the test id, file and line
5
+ * of the test that requested it, and one row per test in `tests` with its
6
+ * outcome. `attest policy evaluate` gates on `results`; the pr-annotate action
7
+ * places inline comments with `file` and `line`.
8
+ */
9
+ import { type AssertionResult } from "@attest-ai/core";
10
+ export declare const REPORT_VERSION = 2;
11
+ export type TestOutcome = "passed" | "failed" | "skipped";
12
+ /** Attest results a test recorded, carried from the worker in task meta. */
13
+ export interface AttestTaskMeta {
14
+ /** `retryCount` of the attempt that produced `results`. */
15
+ attempt: number;
16
+ results: AssertionResult[];
17
+ totalCost: number;
18
+ totalDurationMs: number;
19
+ }
20
+ declare module "vitest" {
21
+ interface TaskMeta {
22
+ attest?: AttestTaskMeta;
23
+ }
24
+ }
25
+ export interface TestRecord {
26
+ testId: string;
27
+ name: string;
28
+ /** Relative to the Vitest root, forward slashes. */
29
+ file: string;
30
+ /** 1-based line of the test definition. */
31
+ line: number;
32
+ outcome: TestOutcome;
33
+ durationMs: number;
34
+ attest: AttestTaskMeta | undefined;
35
+ }
36
+ export declare function buildReport(tests: readonly TestRecord[], simulated: boolean): Record<string, unknown>;
37
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,iBAAiB,CAAC;AAEzB,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE1D,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,OAAO,QAAQ,QAAQ,CAAC;IACtB,UAAU,QAAQ;QAChB,MAAM,CAAC,EAAE,cAAc,CAAC;KACzB;CACF;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,cAAc,GAAG,SAAS,CAAC;CACpC;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA8CrG"}
package/dist/report.js ADDED
@@ -0,0 +1,59 @@
1
+ /**
2
+ * report-v2 builder (proto/attest/v1/report-v2.schema.json, contract C3).
3
+ *
4
+ * One row per assertion in `results`, each carrying the test id, file and line
5
+ * of the test that requested it, and one row per test in `tests` with its
6
+ * outcome. `attest policy evaluate` gates on `results`; the pr-annotate action
7
+ * places inline comments with `file` and `line`.
8
+ */
9
+ import { STATUS_HARD_FAIL, STATUS_NOT_EVALUATED, STATUS_PASS, STATUS_SOFT_FAIL, } from "@attest-ai/core";
10
+ export const REPORT_VERSION = 2;
11
+ export function buildReport(tests, simulated) {
12
+ const rows = [];
13
+ const testRows = [];
14
+ let totalCost = 0;
15
+ let totalDurationMs = 0;
16
+ for (const test of tests) {
17
+ if (test.line < 1)
18
+ throw new Error(`${test.testId}: line must be >= 1, got ${test.line}`);
19
+ const assertionIds = [];
20
+ const reasons = [];
21
+ totalCost += test.attest?.totalCost ?? 0;
22
+ totalDurationMs += test.attest?.totalDurationMs ?? 0;
23
+ for (const result of test.attest?.results ?? []) {
24
+ rows.push({ ...result, test_id: test.testId, file: test.file, line: test.line });
25
+ assertionIds.push(result.assertion_id);
26
+ if (result.status === STATUS_NOT_EVALUATED && !reasons.includes(String(result.reason))) {
27
+ reasons.push(String(result.reason));
28
+ }
29
+ }
30
+ testRows.push({
31
+ test_id: test.testId,
32
+ name: test.name,
33
+ file: test.file,
34
+ line: test.line,
35
+ outcome: test.outcome,
36
+ ...(reasons.length > 0 ? { not_evaluated_reasons: reasons } : {}),
37
+ assertion_ids: assertionIds,
38
+ duration_ms: Math.round(test.durationMs),
39
+ });
40
+ }
41
+ const count = (status) => rows.filter((r) => r["status"] === status).length;
42
+ return {
43
+ report_version: REPORT_VERSION,
44
+ timestamp: new Date().toISOString().replace(/\.\d{3}Z$/, "Z"),
45
+ simulated,
46
+ summary: {
47
+ total: rows.length,
48
+ passed: count(STATUS_PASS),
49
+ soft_fail: count(STATUS_SOFT_FAIL),
50
+ hard_fail: count(STATUS_HARD_FAIL),
51
+ not_evaluated: count(STATUS_NOT_EVALUATED),
52
+ },
53
+ results: rows,
54
+ tests: testRows,
55
+ total_cost: totalCost,
56
+ total_duration_ms: totalDurationMs,
57
+ };
58
+ }
59
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,44 @@
1
+ import type { Reporter, TestModule, Vitest } from "vitest/node";
1
2
  interface ReporterContext {
2
3
  printInfo: (message: string) => void;
3
4
  }
5
+ /**
6
+ * Vitest reporter that prints the cost report and a hierarchical
7
+ * diagnostic block for every failed Attest evaluation in the run.
8
+ *
9
+ * Produces the same shape as the Python pytest plugin's
10
+ * "Attest Diagnostics" section so reviewers see consistent output
11
+ * across both ecosystems.
12
+ */
4
13
  export declare class AttestCostReporter {
5
14
  onFinished(_files: unknown, _errors: unknown, context?: ReporterContext): void;
6
15
  }
7
- export {};
16
+ export interface AttestReporterOptions {
17
+ /**
18
+ * Path of the report-v2 JSON file, relative to the Vitest root. Overrides
19
+ * `--outputFile.attest=<path>`.
20
+ */
21
+ outputFile?: string;
22
+ }
23
+ /**
24
+ * Vitest reporter that writes a report-v2 file (proto/attest/v1/report-v2.schema.json)
25
+ * when the run ends: every test with its outcome, file and line, and every Attest
26
+ * assertion result tagged with the test that requested it. Feed the file to
27
+ * `attest policy evaluate --report` and the pr-annotate action.
28
+ *
29
+ * Writes only when an output file is set: `new AttestReporter({ outputFile })` in the
30
+ * Vitest config, or on the command line, the counterpart of pytest's
31
+ * `--attest-report=<path>`:
32
+ * `vitest run --reporter=default --reporter=@attest-ai/vitest/reporter --outputFile.attest=<path>`. Turns on `includeTaskLocation` so each test carries its
33
+ * line. Requires Vitest 3+.
34
+ */
35
+ export declare class AttestReporter implements Reporter {
36
+ private outputFile;
37
+ private root;
38
+ constructor(options?: AttestReporterOptions);
39
+ onInit(vitest: Vitest): void;
40
+ onTestRunEnd(testModules: ReadonlyArray<TestModule>): void;
41
+ }
42
+ /** `vitest run --reporter=@attest-ai/vitest/reporter` loads the default export. */
43
+ export default AttestReporter;
8
44
  //# sourceMappingURL=reporter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA,UAAU,eAAe;IACvB,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,qBAAa,kBAAkB;IAC7B,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI;CAuB/E"}
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGhE,UAAU,eAAe;IACvB,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED;;;;;;;GAOG;AACH,qBAAa,kBAAkB;IAC7B,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI;CAwC/E;AAED,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,cAAe,YAAW,QAAQ;IAC7C,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,IAAI,CAAiB;gBAEjB,OAAO,GAAE,qBAA0B;IAI/C,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAS5B,YAAY,CAAC,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,IAAI;CA+B3D;AAED,mFAAmF;AACnF,eAAe,cAAc,CAAC"}
package/dist/reporter.js CHANGED
@@ -1,17 +1,29 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { dirname, relative, resolve, sep } from "node:path";
3
+ import { isSimulationMode, renderDiagnostics, renderSummary } from "@attest-ai/core";
4
+ import { buildReport } from "./report.js";
5
+ /**
6
+ * Vitest reporter that prints the cost report and a hierarchical
7
+ * diagnostic block for every failed Attest evaluation in the run.
8
+ *
9
+ * Produces the same shape as the Python pytest plugin's
10
+ * "Attest Diagnostics" section so reviewers see consistent output
11
+ * across both ecosystems.
12
+ */
1
13
  export class AttestCostReporter {
2
14
  onFinished(_files, _errors, context) {
3
15
  const cost = globalThis.__attest_session_cost__ ?? 0;
4
16
  const softFailures = globalThis.__attest_session_soft_failures__ ?? 0;
5
- const lines = [
6
- "",
7
- "=".repeat(50),
8
- " Attest Cost Report",
9
- "=".repeat(50),
10
- ` Total LLM cost this session: $${cost.toFixed(6)} USD`,
11
- ` Soft failures recorded: ${softFailures}`,
12
- "=".repeat(50),
13
- "",
14
- ];
17
+ const failures = globalThis.__attest_session_failures__ ?? [];
18
+ const lines = [];
19
+ if (failures.length > 0) {
20
+ lines.push("", "=".repeat(50), " Attest Diagnostics", "=".repeat(50));
21
+ for (const result of failures) {
22
+ lines.push(renderDiagnostics(result));
23
+ lines.push(` Summary: ${renderSummary(result)}`);
24
+ }
25
+ }
26
+ lines.push("", "=".repeat(50), " Attest Cost Report", "=".repeat(50), ` Total LLM cost this session: $${cost.toFixed(6)} USD`, ` Soft failures recorded: ${softFailures}`, ` Failed runs: ${failures.length}`, "=".repeat(50), "");
15
27
  const output = lines.join("\n");
16
28
  if (context?.printInfo) {
17
29
  context.printInfo(output);
@@ -21,4 +33,63 @@ export class AttestCostReporter {
21
33
  }
22
34
  }
23
35
  }
36
+ /**
37
+ * Vitest reporter that writes a report-v2 file (proto/attest/v1/report-v2.schema.json)
38
+ * when the run ends: every test with its outcome, file and line, and every Attest
39
+ * assertion result tagged with the test that requested it. Feed the file to
40
+ * `attest policy evaluate --report` and the pr-annotate action.
41
+ *
42
+ * Writes only when an output file is set: `new AttestReporter({ outputFile })` in the
43
+ * Vitest config, or on the command line, the counterpart of pytest's
44
+ * `--attest-report=<path>`:
45
+ * `vitest run --reporter=default --reporter=@attest-ai/vitest/reporter --outputFile.attest=<path>`. Turns on `includeTaskLocation` so each test carries its
46
+ * line. Requires Vitest 3+.
47
+ */
48
+ export class AttestReporter {
49
+ outputFile;
50
+ root = process.cwd();
51
+ constructor(options = {}) {
52
+ this.outputFile = options.outputFile;
53
+ }
54
+ onInit(vitest) {
55
+ this.root = vitest.config.root;
56
+ const configured = vitest.config.outputFile;
57
+ if (this.outputFile === undefined && typeof configured === "object") {
58
+ this.outputFile = configured["attest"];
59
+ }
60
+ vitest.config.includeTaskLocation = true;
61
+ }
62
+ onTestRunEnd(testModules) {
63
+ const outputFile = this.outputFile;
64
+ if (outputFile === undefined)
65
+ return;
66
+ const tests = [];
67
+ for (const testModule of testModules) {
68
+ const file = relative(this.root, testModule.moduleId).split(sep).join("/");
69
+ for (const testCase of testModule.children.allTests()) {
70
+ const location = testCase.location;
71
+ if (location === undefined) {
72
+ throw new Error(`AttestReporter: no source location for "${testCase.fullName}". Vitest records ` +
73
+ "locations only when test.includeTaskLocation is true and the test file path matches " +
74
+ "the root; set test.root to the real path (no symlinks) if it is set.");
75
+ }
76
+ const state = testCase.result().state;
77
+ tests.push({
78
+ testId: `${file} > ${testCase.fullName}`,
79
+ name: testCase.name,
80
+ file,
81
+ line: location.line,
82
+ outcome: state === "passed" || state === "failed" ? state : "skipped",
83
+ durationMs: testCase.diagnostic()?.duration ?? 0,
84
+ attest: testCase.meta().attest,
85
+ });
86
+ }
87
+ }
88
+ const path = resolve(this.root, outputFile);
89
+ mkdirSync(dirname(path), { recursive: true });
90
+ writeFileSync(path, `${JSON.stringify(buildReport(tests, isSimulationMode()), null, 2)}\n`);
91
+ }
92
+ }
93
+ /** `vitest run --reporter=@attest-ai/vitest/reporter` loads the default export. */
94
+ export default AttestReporter;
24
95
  //# sourceMappingURL=reporter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,kBAAkB;IAC7B,UAAU,CAAC,MAAe,EAAE,OAAgB,EAAE,OAAyB;QACrE,MAAM,IAAI,GAAG,UAAU,CAAC,uBAAuB,IAAI,CAAC,CAAC;QACrD,MAAM,YAAY,GAAG,UAAU,CAAC,gCAAgC,IAAI,CAAC,CAAC;QAEtE,MAAM,KAAK,GAAG;YACZ,EAAE;YACF,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACd,sBAAsB;YACtB,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACd,mCAAmC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;YACxD,mCAAmC,YAAY,EAAE;YACjD,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACd,EAAE;SACH,CAAC;QAEF,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEhC,IAAI,OAAO,EAAE,SAAS,EAAE,CAAC;YACvB,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@attest-ai/vitest",
3
- "version": "0.6.0",
3
+ "version": "1.0.0-rc.1",
4
4
  "description": "Attest vitest integration — global setup, fixtures, cost reporter, tier filtering",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -13,6 +13,10 @@
13
13
  "./setup": {
14
14
  "import": "./dist/plugin.js",
15
15
  "types": "./dist/plugin.d.ts"
16
+ },
17
+ "./reporter": {
18
+ "import": "./dist/reporter.js",
19
+ "types": "./dist/reporter.d.ts"
16
20
  }
17
21
  },
18
22
  "files": [
@@ -38,14 +42,15 @@
38
42
  "attest"
39
43
  ],
40
44
  "peerDependencies": {
41
- "@attest-ai/core": ">=0.3.0",
42
- "vitest": ">=2.0.0"
45
+ "@attest-ai/core": ">=1.0.0-rc",
46
+ "vitest": ">=3.0.0"
43
47
  },
44
48
  "devDependencies": {
45
- "@types/node": "^25.6.0",
49
+ "@types/node": "^26.1.2",
50
+ "ajv": "^8.20.0",
46
51
  "typescript": "^5.9.3",
47
- "vitest": "^4.1.4",
48
- "@attest-ai/core": "0.6.0"
52
+ "vitest": "^4.1.10",
53
+ "@attest-ai/core": "1.0.0-rc.1"
49
54
  },
50
55
  "scripts": {
51
56
  "build": "tsc",