@vitest-agent/sdk 1.3.4 → 2.0.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.
Files changed (58) hide show
  1. package/errors/DataStoreError.js +22 -13
  2. package/index.d.ts +1032 -1101
  3. package/index.js +3 -3
  4. package/layers/ConfigLive.js +8 -9
  5. package/layers/DataReaderLive.js +2 -2
  6. package/layers/DataStoreLive.js +2 -2
  7. package/layers/DiscoveryRegistryLive.js +1 -1
  8. package/layers/LoggerLive.js +24 -24
  9. package/layers/PathResolutionLive.js +18 -17
  10. package/layers/PerClientSessionMapLive.js +1 -1
  11. package/layers/ProjectDiscoveryLive.js +1 -2
  12. package/layers/ProjectIdentityLive.js +16 -12
  13. package/layers/RunContextLive.js +20 -20
  14. package/migrations/0001_initial.js +1 -1
  15. package/migrations/registry_0001_initial.js +1 -1
  16. package/migrations/session_map_0001_initial.js +1 -1
  17. package/package.json +18 -18
  18. package/schemas/AgentReport.js +6 -9
  19. package/schemas/Baselines.js +3 -3
  20. package/schemas/CacheManifest.js +2 -2
  21. package/schemas/ChannelEvent.js +30 -3
  22. package/schemas/Common.js +76 -14
  23. package/schemas/ConsoleLeaks.js +2 -2
  24. package/schemas/Coverage.js +8 -8
  25. package/schemas/CoverageTargets.js +16 -10
  26. package/schemas/History.js +4 -4
  27. package/schemas/Identity.js +19 -7
  28. package/schemas/Options.js +3 -3
  29. package/schemas/RenderState.js +26 -19
  30. package/schemas/RunEvent.js +154 -115
  31. package/schemas/Tdd.js +16 -6
  32. package/schemas/Thresholds.js +6 -6
  33. package/schemas/Transport.js +1 -1
  34. package/schemas/Trends.js +7 -3
  35. package/schemas/turns/FileEditPayload.js +5 -1
  36. package/schemas/turns/HookFirePayload.js +15 -1
  37. package/schemas/turns/index.js +9 -1
  38. package/services/Config.js +3 -3
  39. package/services/DataReader.js +1 -1
  40. package/services/DataStore.js +1 -1
  41. package/services/DetailResolver.js +1 -1
  42. package/services/DiscoveryRegistry.js +1 -1
  43. package/services/EnvironmentDetector.js +1 -1
  44. package/services/ExecutorResolver.js +1 -1
  45. package/services/FormatSelector.js +1 -1
  46. package/services/HistoryTracker.js +1 -1
  47. package/services/OutputRenderer.js +1 -1
  48. package/services/PerClientSessionMap.js +2 -2
  49. package/services/ProjectDiscovery.js +1 -1
  50. package/services/ProjectIdentity.js +1 -1
  51. package/services/RunContext.js +1 -1
  52. package/testing/layers.js +2 -2
  53. package/testing.d.ts +312 -332
  54. package/tsdoc-metadata.json +1 -1
  55. package/utils/build-report.js +16 -1
  56. package/utils/ensure-migrated.js +3 -3
  57. package/utils/resolve-data-path.js +3 -3
  58. package/utils/resolve-workspace-key.js +11 -6
@@ -12,8 +12,21 @@ import { Schema } from "effect";
12
12
  * behavior events are advisory and may be overwritten.
13
13
  */
14
14
  /** @public */
15
- const SessionOutcome = Schema.Literal("succeeded", "blocked", "abandoned");
16
- const PhaseLiteral = Schema.Literal("spike", "red", "red.triangulate", "green", "green.fake-it", "refactor", "extended-red", "green-without-red");
15
+ const SessionOutcome = Schema.Literals([
16
+ "succeeded",
17
+ "blocked",
18
+ "abandoned"
19
+ ]);
20
+ const PhaseLiteral = Schema.Literals([
21
+ "spike",
22
+ "red",
23
+ "red.triangulate",
24
+ "green",
25
+ "green.fake-it",
26
+ "refactor",
27
+ "extended-red",
28
+ "green-without-red"
29
+ ]);
17
30
  const GoalSummary = Schema.Struct({
18
31
  id: Schema.Number,
19
32
  ordinal: Schema.Number,
@@ -118,7 +131,21 @@ const SessionCompleteEvent = Schema.Struct({
118
131
  outcome: SessionOutcome
119
132
  });
120
133
  /** @public */
121
- const ChannelEvent = Schema.Union(GoalsReadyEvent, GoalAddedEvent, GoalStartedEvent, GoalCompletedEvent, GoalAbandonedEvent, BehaviorsReadyEvent, BehaviorAddedEvent, BehaviorStartedEvent, PhaseTransitionEvent, BehaviorCompletedEvent, BehaviorAbandonedEvent, BlockedEvent, SessionCompleteEvent);
134
+ const ChannelEvent = Schema.Union([
135
+ GoalsReadyEvent,
136
+ GoalAddedEvent,
137
+ GoalStartedEvent,
138
+ GoalCompletedEvent,
139
+ GoalAbandonedEvent,
140
+ BehaviorsReadyEvent,
141
+ BehaviorAddedEvent,
142
+ BehaviorStartedEvent,
143
+ PhaseTransitionEvent,
144
+ BehaviorCompletedEvent,
145
+ BehaviorAbandonedEvent,
146
+ BlockedEvent,
147
+ SessionCompleteEvent
148
+ ]);
122
149
  /**
123
150
  * Event types whose `goalId` and `sessionId` should be resolved
124
151
  * server-side from `behaviorId` (per spec: "not trusting the
package/schemas/Common.js CHANGED
@@ -11,22 +11,41 @@ import { Schema } from "effect";
11
11
  * Possible states for an individual test case.
12
12
  * @public
13
13
  */
14
- const TestState = Schema.Literal("passed", "failed", "skipped", "pending").annotations({ identifier: "TestState" });
14
+ const TestState = Schema.Literals([
15
+ "passed",
16
+ "failed",
17
+ "skipped",
18
+ "pending"
19
+ ]).annotate({ identifier: "TestState" });
15
20
  /**
16
21
  * Overall outcome of a test run.
17
22
  * @public
18
23
  */
19
- const TestRunReason = Schema.Literal("passed", "failed", "interrupted").annotations({ identifier: "TestRunReason" });
24
+ const TestRunReason = Schema.Literals([
25
+ "passed",
26
+ "failed",
27
+ "interrupted"
28
+ ]).annotate({ identifier: "TestRunReason" });
20
29
  /**
21
30
  * Classification of a test's failure history across runs.
22
31
  * @public
23
32
  */
24
- const TestClassification = Schema.Literal("stable", "new-failure", "persistent", "flaky", "recovered").annotations({ identifier: "TestClassification" });
33
+ const TestClassification = Schema.Literals([
34
+ "stable",
35
+ "new-failure",
36
+ "persistent",
37
+ "flaky",
38
+ "recovered"
39
+ ]).annotate({ identifier: "TestClassification" });
25
40
  /**
26
41
  * Console output verbosity mode for AgentReporter.
27
42
  * @public
28
43
  */
29
- const ConsoleOutputMode = Schema.Literal("failures", "full", "silent").annotations({ identifier: "ConsoleOutputMode" });
44
+ const ConsoleOutputMode = Schema.Literals([
45
+ "failures",
46
+ "full",
47
+ "silent"
48
+ ]).annotate({ identifier: "ConsoleOutputMode" });
30
49
  /**
31
50
  * Console output choices per executor type.
32
51
  *
@@ -45,42 +64,85 @@ const ConsoleOutputMode = Schema.Literal("failures", "full", "silent").annotatio
45
64
  * so the default for `ci` is `passthrough` until it lands.
46
65
  * @public
47
66
  */
48
- const HumanConsoleMode = Schema.Literal("passthrough", "silent", "stream", "agent").annotations({ identifier: "HumanConsoleMode" });
67
+ const HumanConsoleMode = Schema.Literals([
68
+ "passthrough",
69
+ "silent",
70
+ "stream",
71
+ "agent"
72
+ ]).annotate({ identifier: "HumanConsoleMode" });
49
73
  /** @public */
50
- const AgentConsoleMode = Schema.Literal("passthrough", "silent", "agent").annotations({ identifier: "AgentConsoleMode" });
74
+ const AgentConsoleMode = Schema.Literals([
75
+ "passthrough",
76
+ "silent",
77
+ "agent"
78
+ ]).annotate({ identifier: "AgentConsoleMode" });
51
79
  /** @public */
52
- const CiConsoleMode = Schema.Literal("passthrough", "silent", "ci-annotations").annotations({ identifier: "CiConsoleMode" });
80
+ const CiConsoleMode = Schema.Literals([
81
+ "passthrough",
82
+ "silent",
83
+ "ci-annotations"
84
+ ]).annotate({ identifier: "CiConsoleMode" });
53
85
  /**
54
86
  * Union of every legal console-output value across the three executor slots.
55
87
  * Useful for type-narrowing in renderers that take the resolved value.
56
88
  * @public
57
89
  */
58
- const ConsoleMode = Schema.Union(HumanConsoleMode, AgentConsoleMode, CiConsoleMode).annotations({ identifier: "ConsoleMode" });
90
+ const ConsoleMode = Schema.Union([
91
+ HumanConsoleMode,
92
+ AgentConsoleMode,
93
+ CiConsoleMode
94
+ ]).annotate({ identifier: "ConsoleMode" });
59
95
  /**
60
96
  * Supported package managers for run command generation.
61
97
  * @public
62
98
  */
63
- const PackageManager = Schema.Literal("pnpm", "npm", "yarn", "bun").annotations({ identifier: "PackageManager" });
99
+ const PackageManager = Schema.Literals([
100
+ "pnpm",
101
+ "npm",
102
+ "yarn",
103
+ "bun"
104
+ ]).annotate({ identifier: "PackageManager" });
64
105
  /**
65
106
  * Runtime environment where tests are being executed.
66
107
  * @public
67
108
  */
68
- const Environment = Schema.Literal("agent-shell", "terminal", "ci-github", "ci-generic").annotations({ identifier: "Environment" });
109
+ const Environment = Schema.Literals([
110
+ "agent-shell",
111
+ "terminal",
112
+ "ci-github",
113
+ "ci-generic"
114
+ ]).annotate({ identifier: "Environment" });
69
115
  /**
70
116
  * Who or what is executing the test run.
71
117
  * @public
72
118
  */
73
- const Executor = Schema.Literal("human", "agent", "ci").annotations({ identifier: "Executor" });
119
+ const Executor = Schema.Literals([
120
+ "human",
121
+ "agent",
122
+ "ci"
123
+ ]).annotate({ identifier: "Executor" });
74
124
  /**
75
125
  * Output format for the reporter pipeline.
76
126
  * @public
77
127
  */
78
- const OutputFormat = Schema.Literal("terminal", "markdown", "json", "vitest-bypass", "silent", "ci-annotations").annotations({ identifier: "OutputFormat" });
128
+ const OutputFormat = Schema.Literals([
129
+ "terminal",
130
+ "markdown",
131
+ "json",
132
+ "vitest-bypass",
133
+ "silent",
134
+ "ci-annotations"
135
+ ]).annotate({ identifier: "OutputFormat" });
79
136
  /**
80
137
  * Level of detail in reporter output.
81
138
  * @public
82
139
  */
83
- const DetailLevel = Schema.Literal("minimal", "neutral", "standard", "verbose").annotations({ identifier: "DetailLevel" });
140
+ const DetailLevel = Schema.Literals([
141
+ "minimal",
142
+ "neutral",
143
+ "standard",
144
+ "verbose"
145
+ ]).annotate({ identifier: "DetailLevel" });
84
146
  /**
85
147
  * A single test or module error with optional stack trace, diff, and
86
148
  * structured assertion values.
@@ -99,7 +161,7 @@ const ReportError = Schema.Struct({
99
161
  diff: Schema.optional(Schema.String),
100
162
  expected: Schema.optional(Schema.String),
101
163
  received: Schema.optional(Schema.String)
102
- }).annotations({ identifier: "ReportError" });
164
+ }).annotate({ identifier: "ReportError" });
103
165
 
104
166
  //#endregion
105
167
  export { AgentConsoleMode, CiConsoleMode, ConsoleMode, ConsoleOutputMode, DetailLevel, Environment, Executor, HumanConsoleMode, OutputFormat, PackageManager, ReportError, TestClassification, TestRunReason, TestState };
@@ -12,7 +12,7 @@ const ConsoleLeakFile = Schema.Struct({
12
12
  stderr: Schema.Number,
13
13
  tests: Schema.optional(Schema.Array(Schema.String)),
14
14
  sample: Schema.optional(Schema.String)
15
- }).annotations({ identifier: "ConsoleLeakFile" });
15
+ }).annotate({ identifier: "ConsoleLeakFile" });
16
16
  /**
17
17
  * Aggregate stray-console-output signal for a single test run. Omitted from
18
18
  * a report entirely when the run produced no user console output.
@@ -22,7 +22,7 @@ const ConsoleLeaks = Schema.Struct({
22
22
  total: Schema.Number,
23
23
  byFile: Schema.Array(ConsoleLeakFile),
24
24
  truncated: Schema.optional(Schema.Boolean)
25
- }).annotations({ identifier: "ConsoleLeaks" });
25
+ }).annotate({ identifier: "ConsoleLeaks" });
26
26
 
27
27
  //#endregion
28
28
  export { ConsoleLeakFile, ConsoleLeaks };
@@ -1,5 +1,5 @@
1
1
  import { MetricThresholds, PatternThresholds } from "./Thresholds.js";
2
- import { Schema } from "effect";
2
+ import { Effect, Schema } from "effect";
3
3
 
4
4
  //#region src/schemas/Coverage.ts
5
5
  /**
@@ -11,7 +11,7 @@ const CoverageTotals = Schema.Struct({
11
11
  branches: Schema.Number,
12
12
  functions: Schema.Number,
13
13
  lines: Schema.Number
14
- }).annotations({ identifier: "CoverageTotals" });
14
+ }).annotate({ identifier: "CoverageTotals" });
15
15
  /**
16
16
  * Per-file coverage data including uncovered line ranges.
17
17
  * @public
@@ -20,7 +20,7 @@ const FileCoverageReport = Schema.Struct({
20
20
  file: Schema.String,
21
21
  summary: CoverageTotals,
22
22
  uncoveredLines: Schema.String
23
- }).annotations({ identifier: "FileCoverageReport" });
23
+ }).annotate({ identifier: "FileCoverageReport" });
24
24
  /**
25
25
  * Complete coverage report attached to an AgentReport.
26
26
  * @public
@@ -29,23 +29,23 @@ const CoverageReport = Schema.Struct({
29
29
  totals: CoverageTotals,
30
30
  thresholds: Schema.Struct({
31
31
  global: MetricThresholds,
32
- patterns: Schema.optionalWith(Schema.Array(PatternThresholds), { default: () => [] })
32
+ patterns: Schema.Array(PatternThresholds).pipe(Schema.withDecodingDefaultKey(Effect.succeed([])))
33
33
  }),
34
34
  targets: Schema.optional(Schema.Struct({
35
35
  global: MetricThresholds,
36
- patterns: Schema.optionalWith(Schema.Array(PatternThresholds), { default: () => [] })
36
+ patterns: Schema.Array(PatternThresholds).pipe(Schema.withDecodingDefaultKey(Effect.succeed([])))
37
37
  })),
38
38
  baselines: Schema.optional(Schema.Struct({
39
39
  global: MetricThresholds,
40
- patterns: Schema.optionalWith(Schema.Array(PatternThresholds), { default: () => [] })
40
+ patterns: Schema.Array(PatternThresholds).pipe(Schema.withDecodingDefaultKey(Effect.succeed([])))
41
41
  })),
42
- scoped: Schema.optionalWith(Schema.Boolean, { default: () => false }),
42
+ scoped: Schema.Boolean.pipe(Schema.withDecodingDefaultKey(Effect.succeed(false))),
43
43
  scopedFiles: Schema.optional(Schema.Array(Schema.String)),
44
44
  lowCoverage: Schema.Array(FileCoverageReport),
45
45
  lowCoverageFiles: Schema.Array(Schema.String),
46
46
  belowTarget: Schema.optional(Schema.Array(FileCoverageReport)),
47
47
  belowTargetFiles: Schema.optional(Schema.Array(Schema.String))
48
- }).annotations({ identifier: "CoverageReport" });
48
+ }).annotate({ identifier: "CoverageReport" });
49
49
 
50
50
  //#endregion
51
51
  export { CoverageReport, CoverageTotals, FileCoverageReport };
@@ -2,17 +2,22 @@ import { Schema } from "effect";
2
2
 
3
3
  //#region src/schemas/CoverageTargets.ts
4
4
  /**
5
+ * A strictly-positive coverage percentage. Negatives and zeros are rejected
6
+ * at decode time.
7
+ */
8
+ const PositivePercent = Schema.Number.check(Schema.isGreaterThan(0));
9
+ /**
5
10
  * Per-metric leaf shape for coverageTargets entries. Allows optional
6
11
  * numeric targets per metric and the `100: true` shortcut.
7
12
  * @public
8
13
  */
9
14
  const CoverageTargetsMetrics = Schema.Struct({
10
- lines: Schema.optional(Schema.Positive),
11
- functions: Schema.optional(Schema.Positive),
12
- branches: Schema.optional(Schema.Positive),
13
- statements: Schema.optional(Schema.Positive),
15
+ lines: Schema.optional(PositivePercent),
16
+ functions: Schema.optional(PositivePercent),
17
+ branches: Schema.optional(PositivePercent),
18
+ statements: Schema.optional(PositivePercent),
14
19
  100: Schema.optional(Schema.Literal(true))
15
- }).annotations({ identifier: "CoverageTargetsMetrics" });
20
+ }).annotate({ identifier: "CoverageTargetsMetrics" });
16
21
  /**
17
22
  * Typed schema for the coverageTargets option.
18
23
  *
@@ -28,12 +33,13 @@ const CoverageTargetsMetrics = Schema.Struct({
28
33
  * at key `"100"`.
29
34
  * @public
30
35
  */
31
- const CoverageTargets = Schema.Record({
32
- key: Schema.String,
33
- value: Schema.Union(Schema.Positive, Schema.Literal(true), CoverageTargetsMetrics)
34
- }).pipe(Schema.filter((targets) => {
36
+ const CoverageTargets = Schema.Record(Schema.String, Schema.Union([
37
+ PositivePercent,
38
+ Schema.Literal(true),
39
+ CoverageTargetsMetrics
40
+ ])).check(Schema.makeFilter((targets) => {
35
41
  for (const [key, value] of Object.entries(targets)) if (value === true && key !== "100") return `coverageTargets.${key} cannot be true. The "true" shorthand is only valid at key "100" (meaning 100% across all metrics).`;
36
- }), Schema.annotations({ identifier: "CoverageTargets" }));
42
+ })).annotate({ identifier: "CoverageTargets" });
37
43
 
38
44
  //#endregion
39
45
  export { CoverageTargets, CoverageTargetsMetrics };
@@ -7,8 +7,8 @@ import { Schema } from "effect";
7
7
  */
8
8
  const TestRun = Schema.Struct({
9
9
  timestamp: Schema.String,
10
- state: Schema.Literal("passed", "failed")
11
- }).annotations({ identifier: "TestRun" });
10
+ state: Schema.Literals(["passed", "failed"])
11
+ }).annotate({ identifier: "TestRun" });
12
12
  /**
13
13
  * History for a single test across multiple runs.
14
14
  * @public
@@ -17,7 +17,7 @@ const TestHistory = Schema.Struct({
17
17
  modulePath: Schema.String,
18
18
  fullName: Schema.String,
19
19
  runs: Schema.Array(TestRun)
20
- }).annotations({ identifier: "TestHistory" });
20
+ }).annotate({ identifier: "TestHistory" });
21
21
  /**
22
22
  * Per-project history record containing all tracked tests.
23
23
  * @public
@@ -26,7 +26,7 @@ const HistoryRecord = Schema.Struct({
26
26
  project: Schema.String,
27
27
  updatedAt: Schema.String,
28
28
  tests: Schema.Array(TestHistory)
29
- }).annotations({ identifier: "HistoryRecord" });
29
+ }).annotate({ identifier: "HistoryRecord" });
30
30
 
31
31
  //#endregion
32
32
  export { HistoryRecord, TestHistory, TestRun };
@@ -7,14 +7,14 @@ import { Schema } from "effect";
7
7
  * agent's lifetime.
8
8
  * @public
9
9
  */
10
- const AgentId = Schema.UUID.pipe(Schema.brand("AgentId"));
10
+ const AgentId = Schema.String.check(Schema.isUUID()).pipe(Schema.brand("AgentId"));
11
11
  /**
12
12
  * The unit "all work on this feature" rolls up to. Survives
13
13
  * `claude --resume` and parallel windows; lives in the host's
14
14
  * transcript filename for Claude Code.
15
15
  * @public
16
16
  */
17
- const ConversationId = Schema.UUID.pipe(Schema.brand("ConversationId"));
17
+ const ConversationId = Schema.String.check(Schema.isUUID()).pipe(Schema.brand("ConversationId"));
18
18
  /**
19
19
  * The agent host process's chat id (Claude Code's per-process chat
20
20
  * UUID, etc.). Shorter-lived than a conversation; one conversation can
@@ -22,13 +22,13 @@ const ConversationId = Schema.UUID.pipe(Schema.brand("ConversationId"));
22
22
  * `sessions.id` (the SQLite agent-run PK).
23
23
  * @public
24
24
  */
25
- const ChatId = Schema.UUID.pipe(Schema.brand("ChatId"));
25
+ const ChatId = Schema.String.check(Schema.isUUID()).pipe(Schema.brand("ChatId"));
26
26
  /**
27
27
  * One TDD orchestration task. Replaces the legacy `tdd_session_id`
28
28
  * vocabulary so "session" is unambiguous in the codebase.
29
29
  * @public
30
30
  */
31
- const TddTaskId = Schema.UUID.pipe(Schema.brand("TddTaskId"));
31
+ const TddTaskId = Schema.String.check(Schema.isUUID()).pipe(Schema.brand("TddTaskId"));
32
32
  /**
33
33
  * Filesystem-safe key for the per-project data store directory under
34
34
  * `$XDG_DATA_HOME/vitest-agent/<projectKey>/`. Resolved by the
@@ -37,7 +37,7 @@ const TddTaskId = Schema.UUID.pipe(Schema.brand("TddTaskId"));
37
37
  * value is `ProjectIdentityNotResolvableError`, not an empty string).
38
38
  * @public
39
39
  */
40
- const ProjectKey = Schema.String.pipe(Schema.minLength(1), Schema.brand("ProjectKey"));
40
+ const ProjectKey = Schema.String.check(Schema.isMinLength(1)).pipe(Schema.brand("ProjectKey"));
41
41
  /**
42
42
  * Who initiated the action (test run, hypothesis, note, TDD phase, …).
43
43
  * Recorded on every action row alongside `agent_id`.
@@ -47,7 +47,11 @@ const ProjectKey = Schema.String.pipe(Schema.minLength(1), Schema.brand("Project
47
47
  * - `system` — a CI run, scheduler, or other non-human/non-agent actor
48
48
  * @public
49
49
  */
50
- const ActorType = Schema.Literal("agent", "user", "system").annotations({ identifier: "ActorType" });
50
+ const ActorType = Schema.Literals([
51
+ "agent",
52
+ "user",
53
+ "system"
54
+ ]).annotate({ identifier: "ActorType" });
51
55
  /**
52
56
  * Recommended canonical host identifiers. Open enum at the SDK level so
53
57
  * a new client doesn't require an SDK release; the MCP server defaults
@@ -58,7 +62,15 @@ const ActorType = Schema.Literal("agent", "user", "system").annotations({ identi
58
62
  * match a known pattern — preferred over guessing.
59
63
  * @public
60
64
  */
61
- const HostKind = Schema.Literal("claude-code", "claude-desktop", "cursor", "goose", "chatgpt", "mcp-inspector", "unknown").annotations({ identifier: "HostKind" });
65
+ const HostKind = Schema.Literals([
66
+ "claude-code",
67
+ "claude-desktop",
68
+ "cursor",
69
+ "goose",
70
+ "chatgpt",
71
+ "mcp-inspector",
72
+ "unknown"
73
+ ]).annotate({ identifier: "HostKind" });
62
74
 
63
75
  //#endregion
64
76
  export { ActorType, AgentId, ChatId, ConversationId, HostKind, ProjectKey, TddTaskId };
@@ -23,7 +23,7 @@ const ConsoleOutputs = Schema.Struct({
23
23
  human: Schema.optional(HumanConsoleMode),
24
24
  agent: Schema.optional(AgentConsoleMode),
25
25
  ci: Schema.optional(CiConsoleMode)
26
- }).annotations({ identifier: "ConsoleOutputs" });
26
+ }).annotate({ identifier: "ConsoleOutputs" });
27
27
  /**
28
28
  * The 2.0 user-facing options for `AgentPlugin`.
29
29
  *
@@ -37,7 +37,7 @@ const AgentPluginOptions = Schema.Struct({
37
37
  console: Schema.optional(ConsoleOutputs),
38
38
  coverageTargets: Schema.optional(CoverageTargets),
39
39
  transport: Schema.optional(Transport)
40
- }).annotations({ identifier: "AgentPluginOptions" });
40
+ }).annotate({ identifier: "AgentPluginOptions" });
41
41
  /**
42
42
  * Reporter-implementation options.
43
43
  *
@@ -51,7 +51,7 @@ const AgentPluginOptions = Schema.Struct({
51
51
  */
52
52
  const AgentReporterOptions = Schema.Struct({
53
53
  /** Set by the plugin per-project. Filters reports to one project. */
54
- projectFilter: Schema.optional(Schema.String) }).annotations({ identifier: "AgentReporterOptions" });
54
+ projectFilter: Schema.optional(Schema.String) }).annotate({ identifier: "AgentReporterOptions" });
55
55
 
56
56
  //#endregion
57
57
  export { AgentPluginOptions, AgentReporterOptions, ConsoleOutputs };
@@ -12,10 +12,10 @@ import { Schema } from "effect";
12
12
  const TestRecord = Schema.Struct({
13
13
  testName: Schema.String,
14
14
  suitePath: Schema.Array(Schema.String),
15
- status: Schema.Union(TestState, Schema.Literal("running", "timed-out")),
15
+ status: Schema.Union([TestState, Schema.Literals(["running", "timed-out"])]),
16
16
  durationMs: Schema.NullOr(Schema.Number),
17
17
  error: Schema.optional(ReportError)
18
- }).annotations({ identifier: "TestRecord" });
18
+ }).annotate({ identifier: "TestRecord" });
19
19
  /**
20
20
  * Per-module aggregation. The reducer keeps modules keyed on
21
21
  * `modulePath` so out-of-order events can update the right slot.
@@ -23,7 +23,11 @@ const TestRecord = Schema.Struct({
23
23
  */
24
24
  const ModuleRecord = Schema.Struct({
25
25
  modulePath: Schema.String,
26
- status: Schema.Literal("queued", "running", "finished"),
26
+ status: Schema.Literals([
27
+ "queued",
28
+ "running",
29
+ "finished"
30
+ ]),
27
31
  passCount: Schema.Number,
28
32
  failCount: Schema.Number,
29
33
  skipCount: Schema.Number,
@@ -43,11 +47,8 @@ const ModuleRecord = Schema.Struct({
43
47
  * module seeded by `ModuleQueued` (or replayed) has no start stamp.
44
48
  */
45
49
  startedAt: Schema.optional(Schema.String),
46
- tagCounts: Schema.optional(Schema.Record({
47
- key: Schema.String,
48
- value: Schema.Number
49
- }))
50
- }).annotations({ identifier: "ModuleRecord" });
50
+ tagCounts: Schema.optional(Schema.Record(Schema.String, Schema.Number))
51
+ }).annotate({ identifier: "ModuleRecord" });
51
52
  /**
52
53
  * One row in the failure list. A failure can exist before its
53
54
  * classification arrives (`FailureClassified` is emitted from a
@@ -61,7 +62,7 @@ const FailureRecord = Schema.Struct({
61
62
  error: Schema.optional(ReportError),
62
63
  timedOut: Schema.optional(Schema.Boolean),
63
64
  classification: Schema.NullOr(TestClassification)
64
- }).annotations({ identifier: "FailureRecord" });
65
+ }).annotate({ identifier: "FailureRecord" });
65
66
  /**
66
67
  * Coverage block, populated only after `CoverageReady`. Threshold
67
68
  * violations are accumulated separately as they arrive.
@@ -76,7 +77,7 @@ const CoverageRenderState = Schema.Struct({
76
77
  expected: Schema.Number,
77
78
  actual: Schema.Number
78
79
  }))
79
- }).annotations({ identifier: "CoverageRenderState" });
80
+ }).annotate({ identifier: "CoverageRenderState" });
80
81
  /**
81
82
  * A `SuggestedAction` event, denormalized into the queue the renderer reads.
82
83
  * @public
@@ -86,7 +87,7 @@ const SuggestedActionRecord = Schema.Struct({
86
87
  title: Schema.String,
87
88
  detail: Schema.String,
88
89
  targetTool: Schema.optional(Schema.String)
89
- }).annotations({ identifier: "SuggestedActionRecord" });
90
+ }).annotate({ identifier: "SuggestedActionRecord" });
90
91
  /**
91
92
  * Per-run totals, recomputed on every `ModuleFinished` and reconciled
92
93
  * against `RunFinished` (which carries the runner's own count).
@@ -98,7 +99,7 @@ const RenderTotals = Schema.Struct({
98
99
  skipCount: Schema.Number,
99
100
  timeoutCount: Schema.Number,
100
101
  durationMs: Schema.Number
101
- }).annotations({ identifier: "RenderTotals" });
102
+ }).annotate({ identifier: "RenderTotals" });
102
103
  /**
103
104
  * The renderer state. Both the human (Ink) and agent (string)
104
105
  * renderers read this shape; the reducer is the only producer.
@@ -111,25 +112,31 @@ const RenderTotals = Schema.Struct({
111
112
  * @public
112
113
  */
113
114
  const RenderState = Schema.Struct({
114
- phase: Schema.Literal("idle", "running", "finished", "timed-out"),
115
+ phase: Schema.Literals([
116
+ "idle",
117
+ "running",
118
+ "finished",
119
+ "timed-out"
120
+ ]),
115
121
  runId: Schema.NullOr(Schema.String),
116
122
  configHash: Schema.NullOr(Schema.String),
117
123
  startedAt: Schema.NullOr(Schema.String),
118
124
  finishedAt: Schema.NullOr(Schema.String),
119
- modules: Schema.Record({
120
- key: Schema.String,
121
- value: ModuleRecord
122
- }),
125
+ modules: Schema.Record(Schema.String, ModuleRecord),
123
126
  moduleOrder: Schema.Array(Schema.String),
124
127
  totals: RenderTotals,
125
128
  coverage: Schema.NullOr(CoverageRenderState),
126
129
  trend: Schema.NullOr(Schema.Struct({
127
- direction: Schema.Literal("improving", "regressing", "stable"),
130
+ direction: Schema.Literals([
131
+ "improving",
132
+ "regressing",
133
+ "stable"
134
+ ]),
128
135
  runCount: Schema.Number
129
136
  })),
130
137
  failures: Schema.Array(FailureRecord),
131
138
  suggestedActions: Schema.Array(SuggestedActionRecord)
132
- }).annotations({ identifier: "RenderState" });
139
+ }).annotate({ identifier: "RenderState" });
133
140
  /**
134
141
  * Initial state — what the reducer returns when no events have been
135
142
  * applied yet. Exported so tests and the renderers' bootstrapping