carrick 0.3.70 → 0.3.73

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 (55) hide show
  1. package/README.md +10 -2
  2. package/bin/carrick.mjs +4 -1
  3. package/dist/contract.d.ts +3 -0
  4. package/dist/contract.js.map +1 -1
  5. package/dist/init/doctor.d.ts +3 -1
  6. package/dist/init/doctor.js +33 -6
  7. package/dist/init/doctor.js.map +1 -1
  8. package/dist/init/install-id.d.ts +32 -0
  9. package/dist/init/install-id.js +118 -0
  10. package/dist/init/install-id.js.map +1 -0
  11. package/dist/init/mcp.d.ts +59 -5
  12. package/dist/init/mcp.js +133 -27
  13. package/dist/init/mcp.js.map +1 -1
  14. package/dist/init/remove.d.ts +4 -0
  15. package/dist/init/remove.js +26 -5
  16. package/dist/init/remove.js.map +1 -1
  17. package/dist/init/run.d.ts +8 -0
  18. package/dist/init/run.js +20 -2
  19. package/dist/init/run.js.map +1 -1
  20. package/dist/native.d.ts +25 -5
  21. package/dist/native.js +41 -10
  22. package/dist/native.js.map +1 -1
  23. package/dist/render.js +7 -2
  24. package/dist/render.js.map +1 -1
  25. package/package.json +6 -6
  26. package/sidecar/dist/src/capture/anchors.d.ts +15 -0
  27. package/sidecar/dist/src/capture/anchors.js +70 -5
  28. package/sidecar/dist/src/capture/api.d.ts +43 -4
  29. package/sidecar/dist/src/capture/check-classify.d.ts +2 -0
  30. package/sidecar/dist/src/capture/check-classify.js +28 -0
  31. package/sidecar/dist/src/capture/check-deep.js +1 -1
  32. package/sidecar/dist/src/capture/check-probe.d.ts +1 -1
  33. package/sidecar/dist/src/capture/check-probe.js +16 -0
  34. package/sidecar/dist/src/capture/deep-walk.d.ts +33 -6
  35. package/sidecar/dist/src/capture/deep-walk.js +81 -28
  36. package/sidecar/dist/src/capture/index.js +16 -6
  37. package/sidecar/dist/src/capture/installed-package.d.ts +58 -0
  38. package/sidecar/dist/src/capture/installed-package.js +311 -0
  39. package/sidecar/dist/src/capture/lockfile.d.ts +8 -0
  40. package/sidecar/dist/src/capture/lockfile.js +1 -1
  41. package/sidecar/dist/src/capture/node-builder.d.ts +27 -0
  42. package/sidecar/dist/src/capture/node-builder.js +107 -1
  43. package/sidecar/dist/src/capture/paths-rewrite.d.ts +23 -6
  44. package/sidecar/dist/src/capture/paths-rewrite.js +43 -11
  45. package/sidecar/dist/src/capture/self-check.js +12 -3
  46. package/sidecar/dist/src/capture/unresolved.d.ts +28 -0
  47. package/sidecar/dist/src/capture/unresolved.js +107 -0
  48. package/sidecar/dist/src/type-inferrer.d.ts +227 -30
  49. package/sidecar/dist/src/type-inferrer.js +926 -144
  50. package/sidecar/dist/src/type-structural-expander.d.ts +53 -3
  51. package/sidecar/dist/src/type-structural-expander.js +108 -19
  52. package/sidecar/dist/src/type-text-canonicalizer.d.ts +14 -0
  53. package/sidecar/dist/src/type-text-canonicalizer.js +23 -2
  54. package/sidecar/dist/src/validators.d.ts +10 -0
  55. package/sidecar/dist/src/validators.js +1 -0
@@ -28,22 +28,72 @@
28
28
  * `type-inferrer.ts` (consumer-side inference), so both paths emit the same
29
29
  * structural form rather than a dangling name.
30
30
  */
31
- import { type Type } from 'ts-morph';
31
+ import { type Node, type Type } from 'ts-morph';
32
32
  /**
33
33
  * Bound on the structural-expansion recursion. Deep enough for every realistic
34
34
  * request/response shape; a backstop against pathological/recursive types the
35
35
  * cycle set somehow misses.
36
36
  */
37
37
  export declare const MAX_EXPANSION_DEPTH = 12;
38
+ /**
39
+ * Types to print at named member positions instead of the walked type
40
+ * (carrick#1105).
41
+ *
42
+ * A validation schema's request contract is its INPUT, except at a member
43
+ * whose input is `unknown` and whose output is concrete (a coercion): that
44
+ * member prints the OUTPUT type. The substitution is per member, so it has to
45
+ * happen inside the walk, where the member is printed.
46
+ *
47
+ * Positions use the member-path notation of the provenance entries: `''` for
48
+ * the root, `sub.field` for a property (keyed by symbol name), `items<0>` for
49
+ * an array element; union and intersection members share their parent's
50
+ * position. The walk records every position it printed an override at in
51
+ * `applied`, so a caller can tell a substitution the walk could not reach (a
52
+ * tuple, a cycle, the depth backstop) from one it made.
53
+ *
54
+ * `at` is the node the member types are read at while walking toward an
55
+ * override. A library's inferred object type is a mapped type whose member
56
+ * declaration sits inside a generic, where the member reads as `any`; read at
57
+ * the schema's own node it is the instantiated type, the same read the
58
+ * caller's position walk makes.
59
+ */
60
+ export interface MemberOverrides {
61
+ readonly types: ReadonlyMap<string, Type>;
62
+ readonly applied: Set<string>;
63
+ readonly at: Node;
64
+ }
65
+ /**
66
+ * The representation a type is printed in.
67
+ *
68
+ * `'declared'` prints the type the source declares. `'json'` prints what a
69
+ * JSON serialiser puts on the wire for a value of that type (carrick#1163):
70
+ * `JSON.stringify` calls a value's `toJSON()` and serialises its RESULT, so a
71
+ * `Date` travels as the string its `toJSON` returns, and so does any other
72
+ * type that declares one. The mapping is read from the compiler's own
73
+ * signature, never from a list of type names.
74
+ */
75
+ export type WireFormat = 'declared' | 'json';
38
76
  /**
39
77
  * Recursively render a `Type` as fully-inlined structural text.
40
78
  *
41
79
  * Named object/interface types are expanded to their member structure;
42
80
  * primitives, literals, library types (`Date`, `Promise`, tuples, …) and
43
81
  * functions stay by name. The `seen` set (object type ids on the current
44
- * branch) breaks reference cycles; `depth` is a hard backstop.
82
+ * branch) breaks reference cycles; `depth` is a hard backstop. `overrides`
83
+ * substitutes a type at named member positions (`MemberOverrides`); without
84
+ * it the print is unchanged. `wire` picks the representation (`WireFormat`).
85
+ */
86
+ export declare function expandTypeStructural(type: Type, seen?: Set<number>, depth?: number, overrides?: MemberOverrides, wire?: WireFormat): string;
87
+ /**
88
+ * The type `JSON.stringify` serialises in place of a value of `type`: the
89
+ * return type of the value's own `toJSON()`, or `undefined` when it declares
90
+ * none (carrick#1163).
91
+ *
92
+ * Only a callable `toJSON` member counts, and only a return type that says
93
+ * something: an `any` return describes nothing, and a `toJSON` that returns
94
+ * its own type again maps nothing either.
45
95
  */
46
- export declare function expandTypeStructural(type: Type, seen?: Set<number>, depth?: number): string;
96
+ export declare function jsonWireType(type: Type): Type | undefined;
47
97
  /**
48
98
  * Non-expanded text for a type. Passes `undefined` as the enclosing node so
49
99
  * the compiler can't throw on an invalid node context (tuples and some
@@ -29,24 +29,92 @@
29
29
  * structural form rather than a dangling name.
30
30
  */
31
31
  import { ts } from 'ts-morph';
32
- import { canonicalizeUnionsInText } from './type-text-canonicalizer.js';
32
+ import { canonicalizeUnionsInText, foldBooleanLiterals, } from './type-text-canonicalizer.js';
33
33
  /**
34
34
  * Bound on the structural-expansion recursion. Deep enough for every realistic
35
35
  * request/response shape; a backstop against pathological/recursive types the
36
36
  * cycle set somehow misses.
37
37
  */
38
38
  export const MAX_EXPANSION_DEPTH = 12;
39
+ /** True when some override sits strictly below `position`. */
40
+ function hasOverrideBelow({ overrides, position }) {
41
+ for (const key of overrides.types.keys()) {
42
+ if (position === ''
43
+ ? key !== ''
44
+ : key.startsWith(`${position}.`) || key.startsWith(`${position}<`)) {
45
+ return true;
46
+ }
47
+ }
48
+ return false;
49
+ }
50
+ function childCursor(cursor, segment) {
51
+ if (!cursor)
52
+ return undefined;
53
+ const position = segment.startsWith('<')
54
+ ? `${cursor.position}${segment}`
55
+ : cursor.position === ''
56
+ ? segment
57
+ : `${cursor.position}.${segment}`;
58
+ return { overrides: cursor.overrides, position };
59
+ }
39
60
  /**
40
61
  * Recursively render a `Type` as fully-inlined structural text.
41
62
  *
42
63
  * Named object/interface types are expanded to their member structure;
43
64
  * primitives, literals, library types (`Date`, `Promise`, tuples, …) and
44
65
  * functions stay by name. The `seen` set (object type ids on the current
45
- * branch) breaks reference cycles; `depth` is a hard backstop.
66
+ * branch) breaks reference cycles; `depth` is a hard backstop. `overrides`
67
+ * substitutes a type at named member positions (`MemberOverrides`); without
68
+ * it the print is unchanged. `wire` picks the representation (`WireFormat`).
69
+ */
70
+ export function expandTypeStructural(type, seen = new Set(), depth = 0, overrides, wire = 'declared') {
71
+ return expandAt(type, seen, depth, overrides ? { overrides, position: '' } : undefined, wire);
72
+ }
73
+ /**
74
+ * The type `JSON.stringify` serialises in place of a value of `type`: the
75
+ * return type of the value's own `toJSON()`, or `undefined` when it declares
76
+ * none (carrick#1163).
77
+ *
78
+ * Only a callable `toJSON` member counts, and only a return type that says
79
+ * something: an `any` return describes nothing, and a `toJSON` that returns
80
+ * its own type again maps nothing either.
46
81
  */
47
- export function expandTypeStructural(type, seen = new Set(), depth = 0) {
82
+ export function jsonWireType(type) {
83
+ if (!type.isObject() || type.isArray() || isTuple(type))
84
+ return undefined;
85
+ const member = type.getProperty('toJSON');
86
+ if (!member)
87
+ return undefined;
88
+ const declaration = member.getValueDeclaration() ?? member.getDeclarations()[0];
89
+ const memberType = declaration
90
+ ? member.getTypeAtLocation(declaration)
91
+ : member.getDeclaredType();
92
+ const signature = memberType.getCallSignatures()[0];
93
+ if (!signature)
94
+ return undefined;
95
+ const serialised = signature.getReturnType();
96
+ if (serialised.isAny() || serialised.isUnknown())
97
+ return undefined;
98
+ const id = type.compilerType.id;
99
+ const serialisedId = serialised.compilerType.id;
100
+ if (id != null && id === serialisedId)
101
+ return undefined;
102
+ return serialised;
103
+ }
104
+ function expandAt(type, seen, depth, at, wire) {
48
105
  if (depth > MAX_EXPANSION_DEPTH)
49
106
  return backstopText(type);
107
+ let cursor = at;
108
+ if (cursor) {
109
+ const replacement = cursor.overrides.types.get(cursor.position);
110
+ if (replacement) {
111
+ cursor.overrides.applied.add(cursor.position);
112
+ return expandAt(replacement, seen, depth, undefined, wire);
113
+ }
114
+ // Nothing to substitute below here: print exactly as without overrides.
115
+ if (!hasOverrideBelow(cursor))
116
+ cursor = undefined;
117
+ }
50
118
  // Primitives & literals: nothing to inline.
51
119
  if (type.isString() ||
52
120
  type.isNumber() ||
@@ -65,10 +133,10 @@ export function expandTypeStructural(type, seen = new Set(), depth = 0) {
65
133
  }
66
134
  // Unions / intersections: expand each member, in canonical order.
67
135
  if (type.isUnion()) {
68
- return canonicalMembers(type.getUnionTypes(), seen, depth).join(' | ');
136
+ return canonicalMembers(type.getUnionTypes(), seen, depth, cursor, wire).join(' | ');
69
137
  }
70
138
  if (type.isIntersection()) {
71
- return canonicalMembers(type.getIntersectionTypes(), seen, depth).join(' & ');
139
+ return canonicalMembers(type.getIntersectionTypes(), seen, depth, cursor, wire).join(' & ');
72
140
  }
73
141
  // Tuples are array-like but must keep their `[a, b]` shape, not be walked
74
142
  // as objects (which explodes into `Array.prototype`). Handle before arrays.
@@ -79,7 +147,7 @@ export function expandTypeStructural(type, seen = new Set(), depth = 0) {
79
147
  const element = type.getArrayElementType();
80
148
  if (!element)
81
149
  return namedText(type);
82
- const inner = expandTypeStructural(element, seen, depth + 1);
150
+ const inner = expandAt(element, seen, depth + 1, childCursor(cursor, '<0>'), wire);
83
151
  // Parenthesise a union/intersection element so `(A | B)[]` doesn't misparse
84
152
  // as `A | B[]`. Decide from the TYPE, not the string: a single object
85
153
  // literal like `{ a: A | B }` is NOT a union and must not be parenthesised,
@@ -87,8 +155,17 @@ export function expandTypeStructural(type, seen = new Set(), depth = 0) {
87
155
  const needsParens = element.isUnion() || element.isIntersection();
88
156
  return needsParens ? `(${inner})[]` : `${inner}[]`;
89
157
  }
90
- // Library / built-in types (Date, Promise, RegExp, …): keep by name.
91
- if (isLibraryType(type)) {
158
+ // On the JSON wire a value with `toJSON()` is its serialised form, library
159
+ // type or not, so this runs before the by-name bail-out below.
160
+ if (wire === 'json') {
161
+ const serialised = jsonWireType(type);
162
+ if (serialised)
163
+ return expandAt(serialised, seen, depth + 1, undefined, wire);
164
+ }
165
+ // Library / built-in types (Date, Promise, RegExp, …): keep by name, unless
166
+ // a member below has to be substituted — a schema library declares its
167
+ // inferred object types itself, and they are only walkable, not by-name.
168
+ if (!cursor && isLibraryType(type)) {
92
169
  return namedText(type);
93
170
  }
94
171
  // Callable/constructable object types (functions): keep by name; their
@@ -105,7 +182,7 @@ export function expandTypeStructural(type, seen = new Set(), depth = 0) {
105
182
  const props = type.getProperties();
106
183
  if (props.length === 0)
107
184
  return namedText(type);
108
- const parts = props.map((prop) => expandProperty(prop, nextSeen, depth));
185
+ const parts = props.map((prop) => expandProperty(prop, nextSeen, depth, cursor, wire));
109
186
  return `{ ${parts.join('; ')}; }`;
110
187
  }
111
188
  return namedText(type);
@@ -164,8 +241,8 @@ function backstopText(type) {
164
241
  * Ties can only happen between two members that render identically, in which
165
242
  * case the joined output is the same whichever way round they go.
166
243
  */
167
- function canonicalMembers(members, seen, depth) {
168
- return orderMembers(members, (member) => expandTypeStructural(member, seen, depth + 1));
244
+ function canonicalMembers(members, seen, depth, cursor, wire) {
245
+ return orderMembers(members, (member) => expandAt(member, seen, depth + 1, cursor, wire));
169
246
  }
170
247
  /**
171
248
  * The canonical order itself, over whatever text `render` gives each member.
@@ -174,9 +251,9 @@ function canonicalMembers(members, seen, depth) {
174
251
  * cannot be ordered two ways depending on how deep it sits.
175
252
  */
176
253
  function orderMembers(members, render) {
177
- const rendered = members.map((member, index) => ({
254
+ const rendered = foldBooleanLiterals(members.map(render)).map((text, index) => ({
178
255
  index,
179
- text: render(member),
256
+ text,
180
257
  }));
181
258
  rendered.sort((a, b) => {
182
259
  if (a.text !== b.text)
@@ -186,16 +263,28 @@ function orderMembers(members, render) {
186
263
  return rendered.map((entry) => entry.text);
187
264
  }
188
265
  /** Render a single property as `name[?]: <expanded>`. */
189
- function expandProperty(prop, seen, depth) {
266
+ function expandProperty(prop, seen, depth, at, wire) {
190
267
  const optional = (prop.getFlags() & ts.SymbolFlags.Optional) !== 0;
191
268
  const propDecl = prop.getDeclarations()[0];
192
269
  // Render the key from the declaration's name node so quoted/computed keys
193
270
  // ('x-y', "x y", [Symbol.iterator]) survive as valid TS text rather than
194
271
  // being unquoted into invalid output; fall back to the bare symbol name.
195
272
  const name = renderPropertyName(prop, propDecl);
196
- let propType = propDecl
197
- ? prop.getTypeAtLocation(propDecl)
198
- : prop.getDeclaredType();
273
+ let propType = at
274
+ ? prop.getTypeAtLocation(at.overrides.at)
275
+ : propDecl
276
+ ? prop.getTypeAtLocation(propDecl)
277
+ : prop.getDeclaredType();
278
+ // A substituted member takes the override's TYPE but keeps this key's
279
+ // optionality, and is looked up before the `undefined` strip below so an
280
+ // override that carries `| undefined` strips like any other optional key.
281
+ let cursor = childCursor(at, prop.getName());
282
+ const replacement = cursor && cursor.overrides.types.get(cursor.position);
283
+ if (cursor && replacement) {
284
+ cursor.overrides.applied.add(cursor.position);
285
+ propType = replacement;
286
+ cursor = undefined;
287
+ }
199
288
  // An optional property's type includes `undefined`; the structural label
200
289
  // drops it (`note?: string`, not `note?: string | undefined`).
201
290
  if (optional && propType.isUnion()) {
@@ -206,11 +295,11 @@ function expandProperty(prop, seen, depth) {
206
295
  propType = nonUndefined[0];
207
296
  }
208
297
  else if (nonUndefined.length > 1) {
209
- const inner = canonicalMembers(nonUndefined, seen, depth).join(' | ');
298
+ const inner = canonicalMembers(nonUndefined, seen, depth, cursor, wire).join(' | ');
210
299
  return `${name}?: ${inner}`;
211
300
  }
212
301
  }
213
- const inner = expandTypeStructural(propType, seen, depth + 1);
302
+ const inner = expandAt(propType, seen, depth + 1, cursor, wire);
214
303
  return `${name}${optional ? '?' : ''}: ${inner}`;
215
304
  }
216
305
  /**
@@ -38,3 +38,17 @@
38
38
  * a definition resolve must not fail because one member confused a scanner.
39
39
  */
40
40
  export declare function canonicalizeUnionsInText(text: string): string;
41
+ /**
42
+ * A union's rendered members with the literal pair `false`, `true` folded into
43
+ * `boolean` (carrick#1165).
44
+ *
45
+ * The compiler stores `boolean` as exactly that pair, and its own printer folds
46
+ * it back. Anything that renders a union member by member — the structural
47
+ * walk, and this file's reordering of a compiler print — sees the two literals
48
+ * separately, and sorting them apart produced `false | null | true` for
49
+ * `boolean | null`. Folding before the sort gives the one print a reader and a
50
+ * diff expect. A lone literal is a literal type and is kept. Shared by
51
+ * `orderMembers` in `type-structural-expander.ts`, so both halves of the normal
52
+ * form fold the same way.
53
+ */
54
+ export declare function foldBooleanLiterals(members: string[]): string[];
@@ -156,8 +156,8 @@ function canonicalizeMember(member) {
156
156
  * the compiler rendered it.
157
157
  */
158
158
  function orderTextMembers(members) {
159
- return members
160
- .map((text, index) => ({ text: text.trim(), index }))
159
+ return foldBooleanLiterals(members.map((text) => text.trim()))
160
+ .map((text, index) => ({ text, index }))
161
161
  .sort((a, b) => {
162
162
  if (a.text !== b.text)
163
163
  return a.text < b.text ? -1 : 1;
@@ -165,6 +165,27 @@ function orderTextMembers(members) {
165
165
  })
166
166
  .map((entry) => entry.text);
167
167
  }
168
+ /**
169
+ * A union's rendered members with the literal pair `false`, `true` folded into
170
+ * `boolean` (carrick#1165).
171
+ *
172
+ * The compiler stores `boolean` as exactly that pair, and its own printer folds
173
+ * it back. Anything that renders a union member by member — the structural
174
+ * walk, and this file's reordering of a compiler print — sees the two literals
175
+ * separately, and sorting them apart produced `false | null | true` for
176
+ * `boolean | null`. Folding before the sort gives the one print a reader and a
177
+ * diff expect. A lone literal is a literal type and is kept. Shared by
178
+ * `orderMembers` in `type-structural-expander.ts`, so both halves of the normal
179
+ * form fold the same way.
180
+ */
181
+ export function foldBooleanLiterals(members) {
182
+ const falseAt = members.indexOf('false');
183
+ const trueAt = members.indexOf('true');
184
+ if (falseAt === -1 || trueAt === -1)
185
+ return members;
186
+ const rest = members.filter((member) => member !== 'false' && member !== 'true');
187
+ return rest.includes('boolean') ? rest : [...rest, 'boolean'];
188
+ }
168
189
  /**
169
190
  * The spans between depth-zero occurrences of `separator`. Depth counts the
170
191
  * four bracket pairs; quoted runs are skipped whole, so a separator inside a
@@ -415,16 +415,19 @@ export declare const CaptureV2RequestSchema: z.ZodObject<{
415
415
  alias: z.ZodString;
416
416
  type_text: z.ZodString;
417
417
  anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill"]>;
418
+ source_file: z.ZodOptional<z.ZodString>;
418
419
  }, "strip", z.ZodTypeAny, {
419
420
  kind: "literal";
420
421
  alias: string;
421
422
  anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
422
423
  type_text: string;
424
+ source_file?: string | undefined;
423
425
  }, {
424
426
  kind: "literal";
425
427
  alias: string;
426
428
  anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
427
429
  type_text: string;
430
+ source_file?: string | undefined;
428
431
  }>]>, "many">;
429
432
  out_dir: z.ZodString;
430
433
  tsconfig_path: z.ZodOptional<z.ZodString>;
@@ -461,6 +464,7 @@ export declare const CaptureV2RequestSchema: z.ZodObject<{
461
464
  alias: string;
462
465
  anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
463
466
  type_text: string;
467
+ source_file?: string | undefined;
464
468
  })[];
465
469
  out_dir: string;
466
470
  tsconfig_path?: string | undefined;
@@ -497,6 +501,7 @@ export declare const CaptureV2RequestSchema: z.ZodObject<{
497
501
  alias: string;
498
502
  anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
499
503
  type_text: string;
504
+ source_file?: string | undefined;
500
505
  })[];
501
506
  out_dir: string;
502
507
  tsconfig_path?: string | undefined;
@@ -1476,16 +1481,19 @@ export declare const SidecarRequestSchema: z.ZodDiscriminatedUnion<"action", [z.
1476
1481
  alias: z.ZodString;
1477
1482
  type_text: z.ZodString;
1478
1483
  anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill"]>;
1484
+ source_file: z.ZodOptional<z.ZodString>;
1479
1485
  }, "strip", z.ZodTypeAny, {
1480
1486
  kind: "literal";
1481
1487
  alias: string;
1482
1488
  anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1483
1489
  type_text: string;
1490
+ source_file?: string | undefined;
1484
1491
  }, {
1485
1492
  kind: "literal";
1486
1493
  alias: string;
1487
1494
  anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1488
1495
  type_text: string;
1496
+ source_file?: string | undefined;
1489
1497
  }>]>, "many">;
1490
1498
  out_dir: z.ZodString;
1491
1499
  tsconfig_path: z.ZodOptional<z.ZodString>;
@@ -1522,6 +1530,7 @@ export declare const SidecarRequestSchema: z.ZodDiscriminatedUnion<"action", [z.
1522
1530
  alias: string;
1523
1531
  anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1524
1532
  type_text: string;
1533
+ source_file?: string | undefined;
1525
1534
  })[];
1526
1535
  out_dir: string;
1527
1536
  tsconfig_path?: string | undefined;
@@ -1558,6 +1567,7 @@ export declare const SidecarRequestSchema: z.ZodDiscriminatedUnion<"action", [z.
1558
1567
  alias: string;
1559
1568
  anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1560
1569
  type_text: string;
1570
+ source_file?: string | undefined;
1561
1571
  })[];
1562
1572
  out_dir: string;
1563
1573
  tsconfig_path?: string | undefined;
@@ -219,6 +219,7 @@ const CaptureAnchorRequestSchema = z.discriminatedUnion('kind', [
219
219
  alias: z.string().min(1),
220
220
  type_text: z.string().min(1),
221
221
  anchor_origin: AnchorOriginSchema,
222
+ source_file: z.string().min(1).optional(),
222
223
  }),
223
224
  ]);
224
225
  export const CaptureV2RequestSchema = BaseRequestSchema.extend({