@vitest-agent/mcp 1.3.6 → 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.
package/tools/tdd-task.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { idempotentProcedure } from "../middleware/idempotency.js";
2
2
  import { DataReader, DataStore, GoalDetail } from "@vitest-agent/sdk";
3
- import { Effect, Match, Option, ParseResult, Schema } from "effect";
3
+ import { Effect, Match, Option, Schema, SchemaGetter } from "effect";
4
4
 
5
5
  //#region src/tools/tdd-task.ts
6
6
  /**
@@ -22,7 +22,7 @@ const TddPhaseRow = Schema.Struct({
22
22
  startedAt: Schema.String,
23
23
  endedAt: Schema.NullOr(Schema.String),
24
24
  transitionReason: Schema.NullOr(Schema.String)
25
- }).annotations({ identifier: "TddTaskPhaseRow" });
25
+ }).annotate({ identifier: "TddTaskPhaseRow" });
26
26
  const TddArtifactDetailRow = Schema.Struct({
27
27
  id: Schema.Number,
28
28
  phaseId: Schema.Number,
@@ -30,7 +30,7 @@ const TddArtifactDetailRow = Schema.Struct({
30
30
  testCaseId: Schema.NullOr(Schema.Number),
31
31
  testRunId: Schema.NullOr(Schema.Number),
32
32
  recordedAt: Schema.String
33
- }).annotations({ identifier: "TddTaskArtifactRow" });
33
+ }).annotate({ identifier: "TddTaskArtifactRow" });
34
34
  const TddTaskDetailSchema = Schema.Struct({
35
35
  tddTaskId: Schema.Number,
36
36
  sessionId: Schema.Number,
@@ -42,35 +42,39 @@ const TddTaskDetailSchema = Schema.Struct({
42
42
  goals: Schema.Array(GoalDetail),
43
43
  phases: Schema.Array(TddPhaseRow),
44
44
  artifacts: Schema.Array(TddArtifactDetailRow)
45
- }).annotations({ identifier: "TddTaskDetailSchema" });
45
+ }).annotate({ identifier: "TddTaskDetailSchema" });
46
46
  const CurrentPhaseLookup = Schema.Struct({
47
47
  id: Schema.Number,
48
48
  phase: Schema.String,
49
49
  startedAt: Schema.String,
50
50
  behaviorId: Schema.NullOr(Schema.Number)
51
- }).annotations({ identifier: "TddTaskCurrentPhaseLookup" });
51
+ }).annotate({ identifier: "TddTaskCurrentPhaseLookup" });
52
52
  const TddTaskStartOk = Schema.Struct({
53
53
  action: Schema.Literal("start"),
54
54
  tddTaskId: Schema.Number,
55
55
  goal: Schema.String,
56
56
  runId: Schema.optional(Schema.String)
57
- }).annotations({ identifier: "TddTaskStartOk" });
57
+ }).annotate({ identifier: "TddTaskStartOk" });
58
58
  const TddTaskEndOk = Schema.Struct({
59
59
  action: Schema.Literal("end"),
60
60
  tddTaskId: Schema.Number,
61
- outcome: Schema.Literal("succeeded", "blocked", "abandoned")
62
- }).annotations({ identifier: "TddTaskEndOk" });
61
+ outcome: Schema.Literals([
62
+ "succeeded",
63
+ "blocked",
64
+ "abandoned"
65
+ ])
66
+ }).annotate({ identifier: "TddTaskEndOk" });
63
67
  const TddTaskGetFound = Schema.Struct({
64
68
  action: Schema.Literal("get"),
65
69
  found: Schema.Literal(true),
66
70
  task: TddTaskDetailSchema,
67
71
  currentPhase: Schema.NullOr(CurrentPhaseLookup)
68
- }).annotations({ identifier: "TddTaskGetFound" });
72
+ }).annotate({ identifier: "TddTaskGetFound" });
69
73
  const TddTaskGetMissing = Schema.Struct({
70
74
  action: Schema.Literal("get"),
71
75
  found: Schema.Literal(false),
72
76
  tddTaskId: Schema.Number
73
- }).annotations({ identifier: "TddTaskGetMissing" });
77
+ }).annotate({ identifier: "TddTaskGetMissing" });
74
78
  const TddTaskResumeFound = Schema.Struct({
75
79
  action: Schema.Literal("resume"),
76
80
  found: Schema.Literal(true),
@@ -80,13 +84,20 @@ const TddTaskResumeFound = Schema.Struct({
80
84
  currentPhase: Schema.NullOr(CurrentPhaseLookup),
81
85
  phasesRecorded: Schema.Number,
82
86
  artifactsRecorded: Schema.Number
83
- }).annotations({ identifier: "TddTaskResumeFound" });
87
+ }).annotate({ identifier: "TddTaskResumeFound" });
84
88
  const TddTaskResumeMissing = Schema.Struct({
85
89
  action: Schema.Literal("resume"),
86
90
  found: Schema.Literal(false),
87
91
  tddTaskId: Schema.Number
88
- }).annotations({ identifier: "TddTaskResumeMissing" });
89
- const TddTaskResult = Schema.Union(TddTaskStartOk, TddTaskEndOk, TddTaskGetFound, TddTaskGetMissing, TddTaskResumeFound, TddTaskResumeMissing).annotations({
92
+ }).annotate({ identifier: "TddTaskResumeMissing" });
93
+ const TddTaskResult = Schema.Union([
94
+ TddTaskStartOk,
95
+ TddTaskEndOk,
96
+ TddTaskGetFound,
97
+ TddTaskGetMissing,
98
+ TddTaskResumeFound,
99
+ TddTaskResumeMissing
100
+ ]).annotate({
90
101
  identifier: "TddTaskResult",
91
102
  title: "tdd_task result",
92
103
  description: "Discriminate on `action`. `get` and `resume` further discriminate on `found`. `get` carries the full nested task tree."
@@ -146,11 +157,10 @@ const formatTddTaskMarkdown = (data) => {
146
157
  lines.push("", `Use \`tdd_task({ action: "get", tddTaskId: ${data.tddTaskId} })\` for the full detail tree, or call \`tdd_phase_transition_request\` to advance.`);
147
158
  return lines.join("\n");
148
159
  };
149
- const TddTaskAsMarkdown = Schema.transformOrFail(TddTaskResult, Schema.String, {
150
- strict: true,
151
- decode: (data) => ParseResult.succeed(formatTddTaskMarkdown(data)),
152
- encode: (text, _options, ast) => ParseResult.fail(new ParseResult.Forbidden(ast, text, "TddTaskAsMarkdown is one-way."))
153
- });
160
+ const TddTaskAsMarkdown = TddTaskResult.pipe(Schema.decodeTo(Schema.String, {
161
+ decode: SchemaGetter.transform((data) => formatTddTaskMarkdown(data)),
162
+ encode: SchemaGetter.forbidden(() => "TddTaskAsMarkdown is one-way.")
163
+ }));
154
164
  const StartVariant = Schema.Struct({
155
165
  action: Schema.Literal("start"),
156
166
  goal: Schema.String,
@@ -163,7 +173,11 @@ const StartVariant = Schema.Struct({
163
173
  const EndVariant = Schema.Struct({
164
174
  action: Schema.Literal("end"),
165
175
  tddTaskId: Schema.Number,
166
- outcome: Schema.Literal("succeeded", "blocked", "abandoned"),
176
+ outcome: Schema.Literals([
177
+ "succeeded",
178
+ "blocked",
179
+ "abandoned"
180
+ ]),
167
181
  summaryNoteId: Schema.optional(Schema.Number)
168
182
  });
169
183
  const GetVariant = Schema.Struct({
@@ -174,8 +188,13 @@ const ResumeVariant = Schema.Struct({
174
188
  action: Schema.Literal("resume"),
175
189
  tddTaskId: Schema.Number
176
190
  });
177
- const TddTaskInput = Schema.Union(StartVariant, EndVariant, GetVariant, ResumeVariant);
178
- const tddTask = idempotentProcedure.input(Schema.standardSchemaV1(TddTaskInput)).mutation(async ({ ctx, input }) => {
191
+ const TddTaskInput = Schema.Union([
192
+ StartVariant,
193
+ EndVariant,
194
+ GetVariant,
195
+ ResumeVariant
196
+ ]);
197
+ const tddTask = idempotentProcedure.input(Schema.toStandardSchemaV1(TddTaskInput)).mutation(async ({ ctx, input }) => {
179
198
  return ctx.runtime.runPromise(Match.value(input).pipe(Match.discriminatorsExhaustive("action")({
180
199
  start: (variant) => Effect.gen(function* () {
181
200
  const reader = yield* DataReader;
package/tools/test.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { publicProcedure } from "../context.js";
2
2
  import { DataReader } from "@vitest-agent/sdk";
3
- import { Effect, Match, Option, ParseResult, Schema } from "effect";
3
+ import { Effect, Match, Option, Schema, SchemaGetter } from "effect";
4
4
 
5
5
  //#region src/tools/test.ts
6
6
  /**
@@ -20,17 +20,17 @@ const TestRowSchema = Schema.Struct({
20
20
  duration: Schema.NullOr(Schema.Number),
21
21
  module: Schema.String,
22
22
  classification: Schema.NullOr(Schema.String)
23
- }).annotations({ identifier: "TestListRow" });
23
+ }).annotate({ identifier: "TestListRow" });
24
24
  const TestErrorRowMini = Schema.Struct({
25
25
  name: Schema.NullOr(Schema.String),
26
26
  message: Schema.String,
27
27
  diff: Schema.NullOr(Schema.String),
28
28
  stack: Schema.NullOr(Schema.String)
29
- }).annotations({ identifier: "TestGetErrorRow" });
29
+ }).annotate({ identifier: "TestGetErrorRow" });
30
30
  const TestRunRow = Schema.Struct({
31
- state: Schema.Literal("passed", "failed"),
31
+ state: Schema.Literals(["passed", "failed"]),
32
32
  timestamp: Schema.String
33
- }).annotations({ identifier: "TestGetRunRow" });
33
+ }).annotate({ identifier: "TestGetRunRow" });
34
34
  const TestListGroup = Schema.Struct({
35
35
  project: Schema.String,
36
36
  tests: Schema.Array(TestRowSchema)
@@ -39,7 +39,7 @@ const TestListResult = Schema.Struct({
39
39
  action: Schema.Literal("list"),
40
40
  count: Schema.Number,
41
41
  groups: Schema.Array(TestListGroup)
42
- }).annotations({ identifier: "TestList" });
42
+ }).annotate({ identifier: "TestList" });
43
43
  const TestGetFound = Schema.Struct({
44
44
  action: Schema.Literal("get"),
45
45
  found: Schema.Literal(true),
@@ -47,26 +47,32 @@ const TestGetFound = Schema.Struct({
47
47
  test: TestRowSchema,
48
48
  errors: Schema.Array(TestErrorRowMini),
49
49
  runs: Schema.Array(TestRunRow)
50
- }).annotations({ identifier: "TestGetFound" });
50
+ }).annotate({ identifier: "TestGetFound" });
51
51
  const TestGetMissing = Schema.Struct({
52
52
  action: Schema.Literal("get"),
53
53
  found: Schema.Literal(false),
54
54
  project: Schema.String,
55
55
  fullName: Schema.String
56
- }).annotations({ identifier: "TestGetMissing" });
56
+ }).annotate({ identifier: "TestGetMissing" });
57
57
  const TestForFileResult = Schema.Struct({
58
58
  action: Schema.Literal("for_file"),
59
59
  filePath: Schema.String,
60
60
  count: Schema.Number,
61
61
  testFiles: Schema.Array(Schema.String)
62
- }).annotations({ identifier: "TestForFile" });
62
+ }).annotate({ identifier: "TestForFile" });
63
63
  const TestForTagResult = Schema.Struct({
64
64
  action: Schema.Literal("for_tag"),
65
65
  tag: Schema.String,
66
66
  count: Schema.Number,
67
67
  groups: Schema.Array(TestListGroup)
68
- }).annotations({ identifier: "TestForTag" });
69
- const TestResult = Schema.Union(TestListResult, TestGetFound, TestGetMissing, TestForFileResult, TestForTagResult).annotations({
68
+ }).annotate({ identifier: "TestForTag" });
69
+ const TestResult = Schema.Union([
70
+ TestListResult,
71
+ TestGetFound,
72
+ TestGetMissing,
73
+ TestForFileResult,
74
+ TestForTagResult
75
+ ]).annotate({
70
76
  identifier: "TestResult",
71
77
  title: "test result",
72
78
  description: "Discriminate on `action`. `get` further discriminates on `found`. `list`, `for_file`, and `for_tag` all carry counted arrays — `list` and `for_tag` group by project."
@@ -160,11 +166,10 @@ const formatTestMarkdown = (data) => {
160
166
  for (const f of data.testFiles) lines.push(`- \`${f}\``);
161
167
  return lines.join("\n");
162
168
  };
163
- const TestAsMarkdown = Schema.transformOrFail(TestResult, Schema.String, {
164
- strict: true,
165
- decode: (data) => ParseResult.succeed(formatTestMarkdown(data)),
166
- encode: (text, _options, ast) => ParseResult.fail(new ParseResult.Forbidden(ast, text, "TestAsMarkdown is one-way."))
167
- });
169
+ const TestAsMarkdown = TestResult.pipe(Schema.decodeTo(Schema.String, {
170
+ decode: SchemaGetter.transform((data) => formatTestMarkdown(data)),
171
+ encode: SchemaGetter.forbidden(() => "TestAsMarkdown is one-way.")
172
+ }));
168
173
  const ListVariant = Schema.Struct({
169
174
  action: Schema.Literal("list"),
170
175
  project: Schema.optional(Schema.String),
@@ -186,8 +191,13 @@ const ForTagVariant = Schema.Struct({
186
191
  tag: Schema.String,
187
192
  project: Schema.optional(Schema.String)
188
193
  });
189
- const TestInput = Schema.Union(ListVariant, GetVariant, ForFileVariant, ForTagVariant);
190
- const test = publicProcedure.input(Schema.standardSchemaV1(TestInput)).query(async ({ ctx, input }) => {
194
+ const TestInput = Schema.Union([
195
+ ListVariant,
196
+ GetVariant,
197
+ ForFileVariant,
198
+ ForTagVariant
199
+ ]);
200
+ const test = publicProcedure.input(Schema.toStandardSchemaV1(TestInput)).query(async ({ ctx, input }) => {
191
201
  return ctx.runtime.runPromise(Match.value(input).pipe(Match.discriminatorsExhaustive("action")({
192
202
  list: (variant) => Effect.gen(function* () {
193
203
  const reader = yield* DataReader;
package/tools/trends.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { publicProcedure } from "../context.js";
2
2
  import { DataReader, TrendRecord } from "@vitest-agent/sdk";
3
- import { Effect, Option, ParseResult, Schema } from "effect";
3
+ import { Effect, Option, Schema, SchemaGetter } from "effect";
4
4
 
5
5
  //#region src/tools/trends.ts
6
6
  /**
@@ -14,15 +14,15 @@ import { Effect, Option, ParseResult, Schema } from "effect";
14
14
  * @packageDocumentation
15
15
  */
16
16
  const TrendsAvailable = Schema.Struct({
17
- dataAvailable: Schema.Literal(true).annotations({ description: "Discriminant — `true` when at least one trend entry exists for the project." }),
17
+ dataAvailable: Schema.Literal(true).annotate({ description: "Discriminant — `true` when at least one trend entry exists for the project." }),
18
18
  project: Schema.String,
19
- trends: TrendRecord.annotations({ description: "Trend entries oldest-first; the latest entry drives `direction` and the headline metrics." })
20
- }).annotations({ identifier: "TestTrendsAvailable" });
19
+ trends: TrendRecord.annotate({ description: "Trend entries oldest-first; the latest entry drives `direction` and the headline metrics." })
20
+ }).annotate({ identifier: "TestTrendsAvailable" });
21
21
  const TrendsAbsent = Schema.Struct({
22
- dataAvailable: Schema.Literal(false).annotations({ description: "Discriminant — `false` when fewer than two runs have been recorded for the project." }),
22
+ dataAvailable: Schema.Literal(false).annotate({ description: "Discriminant — `false` when fewer than two runs have been recorded for the project." }),
23
23
  project: Schema.String
24
- }).annotations({ identifier: "TestTrendsAbsent" });
25
- const TestTrendsResult = Schema.Union(TrendsAvailable, TrendsAbsent).annotations({
24
+ }).annotate({ identifier: "TestTrendsAbsent" });
25
+ const TestTrendsResult = Schema.Union([TrendsAvailable, TrendsAbsent]).annotate({
26
26
  identifier: "TestTrendsResult",
27
27
  title: "test_trends result",
28
28
  description: "Coverage trend record per project. Discriminate on `dataAvailable` to handle the cold-start case."
@@ -88,12 +88,11 @@ const formatTestTrendsMarkdown = (data) => {
88
88
  }
89
89
  return lines.join("\n");
90
90
  };
91
- const TestTrendsAsMarkdown = Schema.transformOrFail(TestTrendsResult, Schema.String, {
92
- strict: true,
93
- decode: (data) => ParseResult.succeed(formatTestTrendsMarkdown(data)),
94
- encode: (text, _options, ast) => ParseResult.fail(new ParseResult.Forbidden(ast, text, "TestTrendsAsMarkdown is one-way: markdown cannot be parsed back to TestTrendsResult."))
95
- });
96
- const testTrends = publicProcedure.input(Schema.standardSchemaV1(Schema.Struct({
91
+ const TestTrendsAsMarkdown = TestTrendsResult.pipe(Schema.decodeTo(Schema.String, {
92
+ decode: SchemaGetter.transform((data) => formatTestTrendsMarkdown(data)),
93
+ encode: SchemaGetter.forbidden(() => "TestTrendsAsMarkdown is one-way: markdown cannot be parsed back to TestTrendsResult.")
94
+ }));
95
+ const testTrends = publicProcedure.input(Schema.toStandardSchemaV1(Schema.Struct({
97
96
  project: Schema.String,
98
97
  limit: Schema.optional(Schema.Number)
99
98
  }))).query(async ({ ctx, input }) => ctx.runtime.runPromise(Effect.gen(function* () {
@@ -14,14 +14,14 @@ import { Effect, Schema } from "effect";
14
14
  * @packageDocumentation
15
15
  */
16
16
  const TriageBriefResult = Schema.Struct({
17
- hasContent: Schema.Boolean.annotations({ description: "`false` when no orientation signal is available yet (run tests to populate)." }),
18
- markdown: Schema.String.annotations({ description: "Pre-rendered markdown brief or the empty-state message." })
19
- }).annotations({
17
+ hasContent: Schema.Boolean.annotate({ description: "`false` when no orientation signal is available yet (run tests to populate)." }),
18
+ markdown: Schema.String.annotate({ description: "Pre-rendered markdown brief or the empty-state message." })
19
+ }).annotate({
20
20
  identifier: "TriageBriefResult",
21
21
  title: "triage_brief result",
22
22
  description: "Orientation triage envelope. Branch on `hasContent` for cold-start; consume `markdown` for rendering."
23
23
  });
24
- const triageBrief = publicProcedure.input(Schema.standardSchemaV1(Schema.Struct({
24
+ const triageBrief = publicProcedure.input(Schema.toStandardSchemaV1(Schema.Struct({
25
25
  project: Schema.optional(Schema.String),
26
26
  maxLines: Schema.optional(Schema.Number)
27
27
  }))).query(async ({ ctx, input }) => ctx.runtime.runPromise(Effect.gen(function* () {
@@ -1,6 +1,6 @@
1
1
  import { publicProcedure } from "../context.js";
2
2
  import { DataReader } from "@vitest-agent/sdk";
3
- import { Effect, ParseResult, Schema } from "effect";
3
+ import { Effect, Schema, SchemaGetter } from "effect";
4
4
 
5
5
  //#region src/tools/turn-search.ts
6
6
  /**
@@ -9,20 +9,20 @@ import { Effect, ParseResult, Schema } from "effect";
9
9
  * @packageDocumentation
10
10
  */
11
11
  const TurnRow = Schema.Struct({
12
- id: Schema.Number.annotations({ description: "Numeric primary key of this turn row." }),
13
- sessionId: Schema.Number.annotations({ description: "Owning `sessions.id` (integer FK)." }),
14
- turnNo: Schema.Number.annotations({ description: "Turn ordinal within the session (1-based)." }),
15
- type: Schema.String.annotations({ description: "Turn category (`user_prompt`, `tool_call`, `tool_result`, `file_edit`, `hook_fire`, `note`, `hypothesis`)." }),
16
- payload: Schema.String.annotations({ description: "Type-specific payload as a JSON-encoded string. Decode shape depends on `type`." }),
17
- occurredAt: Schema.String.annotations({ description: "ISO-8601 timestamp the turn was recorded at." })
18
- }).annotations({
12
+ id: Schema.Number.annotate({ description: "Numeric primary key of this turn row." }),
13
+ sessionId: Schema.Number.annotate({ description: "Owning `sessions.id` (integer FK)." }),
14
+ turnNo: Schema.Number.annotate({ description: "Turn ordinal within the session (1-based)." }),
15
+ type: Schema.String.annotate({ description: "Turn category (`user_prompt`, `tool_call`, `tool_result`, `file_edit`, `hook_fire`, `note`, `hypothesis`)." }),
16
+ payload: Schema.String.annotate({ description: "Type-specific payload as a JSON-encoded string. Decode shape depends on `type`." }),
17
+ occurredAt: Schema.String.annotate({ description: "ISO-8601 timestamp the turn was recorded at." })
18
+ }).annotate({
19
19
  identifier: "TurnRow",
20
20
  description: "One row from the turns log."
21
21
  });
22
22
  const TurnSearchResult = Schema.Struct({
23
- count: Schema.Number.annotations({ description: "Number of matching turn rows returned." }),
24
- turns: Schema.Array(TurnRow).annotations({ description: "Matching turns ordered by `occurredAt` ascending." })
25
- }).annotations({
23
+ count: Schema.Number.annotate({ description: "Number of matching turn rows returned." }),
24
+ turns: Schema.Array(TurnRow).annotate({ description: "Matching turns ordered by `occurredAt` ascending." })
25
+ }).annotate({
26
26
  identifier: "TurnSearchResult",
27
27
  title: "turn_search result",
28
28
  description: "Turn-log search results across all sessions, optionally filtered by session, time, type."
@@ -33,15 +33,22 @@ const formatTurnSearchMarkdown = (data) => {
33
33
  for (const t of data.turns) lines.push(`- session=${t.sessionId} turn=${t.turnNo} type=${t.type} at=${t.occurredAt}`);
34
34
  return lines.join("\n");
35
35
  };
36
- const TurnSearchAsMarkdown = Schema.transformOrFail(TurnSearchResult, Schema.String, {
37
- strict: true,
38
- decode: (data) => ParseResult.succeed(formatTurnSearchMarkdown(data)),
39
- encode: (text, _options, ast) => ParseResult.fail(new ParseResult.Forbidden(ast, text, "TurnSearchAsMarkdown is one-way: markdown cannot be parsed back to TurnSearchResult."))
40
- });
41
- const turnSearch = publicProcedure.input(Schema.standardSchemaV1(Schema.Struct({
36
+ const TurnSearchAsMarkdown = TurnSearchResult.pipe(Schema.decodeTo(Schema.String, {
37
+ decode: SchemaGetter.transform((data) => formatTurnSearchMarkdown(data)),
38
+ encode: SchemaGetter.forbidden(() => "TurnSearchAsMarkdown is one-way: markdown cannot be parsed back to TurnSearchResult.")
39
+ }));
40
+ const turnSearch = publicProcedure.input(Schema.toStandardSchemaV1(Schema.Struct({
42
41
  sessionId: Schema.optional(Schema.Number),
43
42
  since: Schema.optional(Schema.String),
44
- type: Schema.optional(Schema.Literal("user_prompt", "tool_call", "tool_result", "file_edit", "hook_fire", "note", "hypothesis")),
43
+ type: Schema.optional(Schema.Literals([
44
+ "user_prompt",
45
+ "tool_call",
46
+ "tool_result",
47
+ "file_edit",
48
+ "hook_fire",
49
+ "note",
50
+ "hypothesis"
51
+ ])),
45
52
  limit: Schema.optional(Schema.Number)
46
53
  }))).query(async ({ ctx, input }) => ctx.runtime.runPromise(Effect.gen(function* () {
47
54
  const rows = yield* (yield* DataReader).searchTurns({
@@ -13,18 +13,30 @@ import { Effect, Schema } from "effect";
13
13
  * @packageDocumentation
14
14
  */
15
15
  const WrapupPromptResult = Schema.Struct({
16
- hasContent: Schema.Boolean.annotations({ description: "`false` when there is nothing to wrap up for the named session/kind." }),
17
- kind: Schema.Literal("stop", "session_end", "pre_compact", "tdd_handoff", "user_prompt_nudge").annotations({ description: "Echo of the wrap-up kind that was rendered (defaulted to `session_end` when omitted)." }),
18
- markdown: Schema.String.annotations({ description: "Pre-rendered wrap-up markdown or the empty-state message." })
19
- }).annotations({
16
+ hasContent: Schema.Boolean.annotate({ description: "`false` when there is nothing to wrap up for the named session/kind." }),
17
+ kind: Schema.Literals([
18
+ "stop",
19
+ "session_end",
20
+ "pre_compact",
21
+ "tdd_handoff",
22
+ "user_prompt_nudge"
23
+ ]).annotate({ description: "Echo of the wrap-up kind that was rendered (defaulted to `session_end` when omitted)." }),
24
+ markdown: Schema.String.annotate({ description: "Pre-rendered wrap-up markdown or the empty-state message." })
25
+ }).annotate({
20
26
  identifier: "WrapupPromptResult",
21
27
  title: "wrapup_prompt result",
22
28
  description: "Wrap-up envelope. Branch on `hasContent` for the empty case; consume `markdown` for rendering."
23
29
  });
24
- const wrapupPrompt = publicProcedure.input(Schema.standardSchemaV1(Schema.Struct({
30
+ const wrapupPrompt = publicProcedure.input(Schema.toStandardSchemaV1(Schema.Struct({
25
31
  sessionId: Schema.optional(Schema.Number),
26
32
  chatId: Schema.optional(Schema.String),
27
- kind: Schema.optional(Schema.Literal("stop", "session_end", "pre_compact", "tdd_handoff", "user_prompt_nudge")),
33
+ kind: Schema.optional(Schema.Literals([
34
+ "stop",
35
+ "session_end",
36
+ "pre_compact",
37
+ "tdd_handoff",
38
+ "user_prompt_nudge"
39
+ ])),
28
40
  userPromptHint: Schema.optional(Schema.String)
29
41
  }))).query(async ({ ctx, input }) => ctx.runtime.runPromise(Effect.gen(function* () {
30
42
  const kind = input.kind ?? "session_end";
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.58.9"
8
+ "packageVersion": "7.58.10"
9
9
  }
10
10
  ]
11
11
  }
@@ -1,10 +1,19 @@
1
- import { JSONSchema } from "effect";
1
+ import { Schema } from "effect";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region src/utils/effect-to-zod.ts
5
5
  /**
6
- * Convert an Effect `Schema.Schema<A, I, never>` to a zod schema by
7
- * serializing it to JSON Schema (`JSONSchema.make`) and ingesting the
6
+ * Bridge an Effect Schema to a zod schema by routing through JSON
7
+ * Schema. Used at the MCP `registerTool` boundary so a tool can keep
8
+ * Effect Schema as the canonical source of truth for its output shape
9
+ * while the SDK still receives the zod instance it expects in the
10
+ * `outputSchema` field.
11
+ *
12
+ * @packageDocumentation
13
+ */
14
+ /**
15
+ * Convert an Effect `Schema.Codec<A, I>` to a zod schema by
16
+ * serializing it to JSON Schema (`Schema.toJsonSchemaDocument`) and ingesting the
8
17
  * result via zod 4's `z.fromJSONSchema`.
9
18
  *
10
19
  * Trade-offs:
@@ -22,7 +31,7 @@ import { z } from "zod";
22
31
  *
23
32
  * Implementation note: zod 4's `z.fromJSONSchema` does not resolve
24
33
  * `$ref` lookups into `$defs` — every `{ $ref: "#/$defs/X" }` it
25
- * encounters throws "Reference not found". Effect's `JSONSchema.make`
34
+ * encounters throws "Reference not found". Effect's `Schema.toJsonSchemaDocument`
26
35
  * emits a `$ref`-and-`$defs` representation whenever a Schema carries
27
36
  * an `identifier` annotation. The bridge therefore inlines every
28
37
  * `$ref` in the document before handing it to zod (recursive
@@ -42,7 +51,11 @@ import { z } from "zod";
42
51
  * if the rich listing matters.
43
52
  */
44
53
  const effectToZodSchema = (schema) => {
45
- const jsonSchema = JSONSchema.make(schema);
54
+ const document = Schema.toJsonSchemaDocument(schema);
55
+ const jsonSchema = {
56
+ ...document.schema,
57
+ $defs: document.definitions
58
+ };
46
59
  const inlined = inlineAllRefs(jsonSchema);
47
60
  const zodSchema = z.fromJSONSchema(inlined);
48
61
  if (isObjectLike(zodSchema)) return zodSchema;