infiniloom-node 0.6.1 → 0.6.3

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/schemas.ts ADDED
@@ -0,0 +1,691 @@
1
+ /**
2
+ * Zod schemas for runtime validation of infiniloom-node options
3
+ *
4
+ * These schemas provide runtime validation with helpful error messages.
5
+ * Use them when accepting options from external sources (API calls, config files, etc.)
6
+ *
7
+ * Usage:
8
+ * ```typescript
9
+ * import { PackOptionsSchema, validatePackOptions } from 'infiniloom-node/schemas';
10
+ * import { pack } from 'infiniloom-node';
11
+ *
12
+ * // Validate options from external source
13
+ * const result = PackOptionsSchema.safeParse(userInput);
14
+ * if (!result.success) {
15
+ * console.error('Invalid options:', result.error.format());
16
+ * return;
17
+ * }
18
+ *
19
+ * // Or use the helper function
20
+ * const options = validatePackOptions(userInput);
21
+ * const output = pack('./repo', options);
22
+ * ```
23
+ */
24
+
25
+ import { z } from 'zod';
26
+
27
+ // ============================================================================
28
+ // Enum Schemas
29
+ // ============================================================================
30
+
31
+ /**
32
+ * Output format enum schema
33
+ */
34
+ export const OutputFormatSchema = z.enum([
35
+ 'xml',
36
+ 'markdown',
37
+ 'json',
38
+ 'yaml',
39
+ 'toon',
40
+ 'plain',
41
+ ]);
42
+ export type OutputFormat = z.infer<typeof OutputFormatSchema>;
43
+
44
+ /**
45
+ * Tokenizer model enum schema
46
+ */
47
+ export const TokenizerModelSchema = z.enum([
48
+ // OpenAI models (exact tokenization via tiktoken)
49
+ 'gpt-5.2',
50
+ 'gpt-5.2-pro',
51
+ 'gpt-5.1',
52
+ 'gpt-5.1-mini',
53
+ 'gpt-5.1-codex',
54
+ 'gpt-5',
55
+ 'gpt-5-mini',
56
+ 'gpt-5-nano',
57
+ 'o4-mini',
58
+ 'o3',
59
+ 'o3-mini',
60
+ 'o1',
61
+ 'o1-mini',
62
+ 'o1-preview',
63
+ 'gpt-4o',
64
+ 'gpt-4o-mini',
65
+ 'gpt-4',
66
+ 'gpt-4-turbo',
67
+ 'gpt-3.5-turbo',
68
+ // Anthropic
69
+ 'claude',
70
+ // Google
71
+ 'gemini',
72
+ 'gemini-1.5',
73
+ 'gemini-2.0',
74
+ // Meta
75
+ 'llama',
76
+ 'llama-3',
77
+ 'llama-3.1',
78
+ 'llama-3.2',
79
+ 'codellama',
80
+ // Mistral
81
+ 'mistral',
82
+ 'mixtral',
83
+ // DeepSeek
84
+ 'deepseek',
85
+ 'deepseek-v3',
86
+ // Alibaba
87
+ 'qwen',
88
+ 'qwen-2.5',
89
+ // Cohere
90
+ 'cohere',
91
+ 'command-r',
92
+ // xAI
93
+ 'grok',
94
+ ]);
95
+ export type TokenizerModel = z.infer<typeof TokenizerModelSchema>;
96
+
97
+ /**
98
+ * Compression level enum schema
99
+ */
100
+ export const CompressionLevelSchema = z.enum([
101
+ 'none',
102
+ 'minimal',
103
+ 'balanced',
104
+ 'aggressive',
105
+ 'extreme',
106
+ 'focused',
107
+ 'semantic',
108
+ ]);
109
+ export type CompressionLevel = z.infer<typeof CompressionLevelSchema>;
110
+
111
+ /**
112
+ * Security severity enum schema
113
+ */
114
+ export const SecuritySeveritySchema = z.enum([
115
+ 'critical',
116
+ 'high',
117
+ 'medium',
118
+ 'low',
119
+ 'info',
120
+ ]);
121
+ export type SecuritySeverity = z.infer<typeof SecuritySeveritySchema>;
122
+
123
+ /**
124
+ * Symbol kind enum schema
125
+ */
126
+ export const SymbolKindSchema = z.enum([
127
+ 'function',
128
+ 'method',
129
+ 'class',
130
+ 'struct',
131
+ 'interface',
132
+ 'trait',
133
+ 'enum',
134
+ 'constant',
135
+ 'variable',
136
+ 'import',
137
+ 'export',
138
+ 'type',
139
+ 'module',
140
+ 'macro',
141
+ ]);
142
+ export type SymbolKind = z.infer<typeof SymbolKindSchema>;
143
+
144
+ /**
145
+ * Visibility enum schema
146
+ */
147
+ export const VisibilitySchema = z.enum([
148
+ 'public',
149
+ 'private',
150
+ 'protected',
151
+ 'internal',
152
+ ]);
153
+ export type Visibility = z.infer<typeof VisibilitySchema>;
154
+
155
+ /**
156
+ * Chunk strategy enum schema
157
+ */
158
+ export const ChunkStrategySchema = z.enum([
159
+ 'fixed',
160
+ 'file',
161
+ 'module',
162
+ 'symbol',
163
+ 'semantic',
164
+ 'dependency',
165
+ ]);
166
+ export type ChunkStrategy = z.infer<typeof ChunkStrategySchema>;
167
+
168
+ /**
169
+ * Impact level enum schema
170
+ */
171
+ export const ImpactLevelSchema = z.enum([
172
+ 'low',
173
+ 'medium',
174
+ 'high',
175
+ 'critical',
176
+ ]);
177
+ export type ImpactLevel = z.infer<typeof ImpactLevelSchema>;
178
+
179
+ /**
180
+ * Git status enum schema
181
+ */
182
+ export const GitStatusSchema = z.enum([
183
+ 'Added',
184
+ 'Modified',
185
+ 'Deleted',
186
+ 'Renamed',
187
+ 'Copied',
188
+ 'Unknown',
189
+ ]);
190
+ export type GitStatus = z.infer<typeof GitStatusSchema>;
191
+
192
+ /**
193
+ * Change type enum schema
194
+ */
195
+ export const ChangeTypeSchema = z.enum([
196
+ 'added',
197
+ 'modified',
198
+ 'deleted',
199
+ ]);
200
+ export type ChangeType = z.infer<typeof ChangeTypeSchema>;
201
+
202
+ /**
203
+ * Breaking change severity enum schema
204
+ */
205
+ export const ChangeSeveritySchema = z.enum([
206
+ 'critical',
207
+ 'high',
208
+ 'medium',
209
+ 'low',
210
+ ]);
211
+ export type ChangeSeverity = z.infer<typeof ChangeSeveritySchema>;
212
+
213
+ // ============================================================================
214
+ // Option Schemas
215
+ // ============================================================================
216
+
217
+ /**
218
+ * Pack options schema with full validation
219
+ */
220
+ export const PackOptionsSchema = z.object({
221
+ format: OutputFormatSchema.optional(),
222
+ model: TokenizerModelSchema.optional(),
223
+ compression: CompressionLevelSchema.optional(),
224
+ mapBudget: z.number().int().nonnegative().max(10_000_000).optional(),
225
+ maxSymbols: z.number().int().positive().max(10_000).optional(),
226
+ skipSecurity: z.boolean().optional(),
227
+ redactSecrets: z.boolean().optional(),
228
+ skipSymbols: z.boolean().optional(),
229
+ include: z.array(z.string().max(256)).max(100).optional(),
230
+ exclude: z.array(z.string().max(256)).max(100).optional(),
231
+ includeTests: z.boolean().optional(),
232
+ securityThreshold: SecuritySeveritySchema.optional(),
233
+ tokenBudget: z.number().int().nonnegative().max(10_000_000).optional(),
234
+ changedOnly: z.boolean().optional(),
235
+ baseSha: z.string().regex(/^[a-f0-9]{7,40}$/i).optional(),
236
+ headSha: z.string().regex(/^[a-f0-9]{7,40}$/i).optional(),
237
+ stagedOnly: z.boolean().optional(),
238
+ includeRelated: z.boolean().optional(),
239
+ relatedDepth: z.union([z.literal(1), z.literal(2), z.literal(3)]).optional(),
240
+ }).strict();
241
+ export type PackOptions = z.infer<typeof PackOptionsSchema>;
242
+
243
+ /**
244
+ * Scan options schema
245
+ */
246
+ export const ScanOptionsSchema = z.object({
247
+ model: TokenizerModelSchema.optional(),
248
+ include: z.array(z.string()).optional(),
249
+ exclude: z.array(z.string()).optional(),
250
+ includeTests: z.boolean().optional(),
251
+ applyDefaultIgnores: z.boolean().optional(),
252
+ }).strict();
253
+ export type ScanOptions = z.infer<typeof ScanOptionsSchema>;
254
+
255
+ /**
256
+ * Chunk options schema
257
+ */
258
+ export const ChunkOptionsSchema = z.object({
259
+ strategy: ChunkStrategySchema.optional(),
260
+ maxTokens: z.number().int().positive().max(100_000).optional(),
261
+ overlap: z.number().int().nonnegative().max(10_000).optional(),
262
+ model: TokenizerModelSchema.optional(),
263
+ format: OutputFormatSchema.optional(),
264
+ priorityFirst: z.boolean().optional(),
265
+ exclude: z.array(z.string().max(256)).max(100).optional(),
266
+ }).strict();
267
+ export type ChunkOptions = z.infer<typeof ChunkOptionsSchema>;
268
+
269
+ /**
270
+ * Index options schema
271
+ */
272
+ export const IndexOptionsSchema = z.object({
273
+ force: z.boolean().optional(),
274
+ includeTests: z.boolean().optional(),
275
+ maxFileSize: z.number().int().positive().max(100 * 1024 * 1024).optional(), // 100MB max
276
+ exclude: z.array(z.string().max(256)).max(100).optional(),
277
+ incremental: z.boolean().optional(),
278
+ }).strict();
279
+ export type IndexOptions = z.infer<typeof IndexOptionsSchema>;
280
+
281
+ /**
282
+ * Diff context options schema
283
+ */
284
+ export const DiffContextOptionsSchema = z.object({
285
+ depth: z.union([z.literal(1), z.literal(2), z.literal(3)]).optional(),
286
+ budget: z.number().int().positive().max(10_000_000).optional(),
287
+ includeDiff: z.boolean().optional(),
288
+ format: OutputFormatSchema.optional(),
289
+ model: TokenizerModelSchema.optional(),
290
+ exclude: z.array(z.string().max(256)).max(100).optional(),
291
+ include: z.array(z.string().max(256)).max(100).optional(),
292
+ }).strict();
293
+ export type DiffContextOptions = z.infer<typeof DiffContextOptionsSchema>;
294
+
295
+ /**
296
+ * Impact options schema
297
+ */
298
+ export const ImpactOptionsSchema = z.object({
299
+ depth: z.union([z.literal(1), z.literal(2), z.literal(3)]).optional(),
300
+ includeTests: z.boolean().optional(),
301
+ model: TokenizerModelSchema.optional(),
302
+ exclude: z.array(z.string().max(256)).max(100).optional(),
303
+ include: z.array(z.string().max(256)).max(100).optional(),
304
+ }).strict();
305
+ export type ImpactOptions = z.infer<typeof ImpactOptionsSchema>;
306
+
307
+ /**
308
+ * Embed options schema
309
+ */
310
+ export const EmbedOptionsSchema = z.object({
311
+ maxTokens: z.number().int().positive().max(100_000).optional(),
312
+ minTokens: z.number().int().nonnegative().max(10_000).optional(),
313
+ contextLines: z.number().int().nonnegative().max(1_000).optional(),
314
+ includeImports: z.boolean().optional(),
315
+ includeTopLevel: z.boolean().optional(),
316
+ includeTests: z.boolean().optional(),
317
+ securityScan: z.boolean().optional(),
318
+ includePatterns: z.array(z.string().max(256)).max(100).optional(),
319
+ excludePatterns: z.array(z.string().max(256)).max(100).optional(),
320
+ manifestPath: z.string().max(4096).refine(p => !p.includes('..'), { message: 'Path traversal not allowed' }).optional(),
321
+ diffOnly: z.boolean().optional(),
322
+ }).strict();
323
+ export type EmbedOptions = z.infer<typeof EmbedOptionsSchema>;
324
+
325
+ /**
326
+ * Query filter schema
327
+ */
328
+ export const QueryFilterSchema = z.object({
329
+ kinds: z.array(SymbolKindSchema).optional(),
330
+ excludeKinds: z.array(SymbolKindSchema).optional(),
331
+ }).strict();
332
+ export type QueryFilter = z.infer<typeof QueryFilterSchema>;
333
+
334
+ /**
335
+ * Symbol filter schema
336
+ */
337
+ export const SymbolFilterSchema = z.object({
338
+ kind: SymbolKindSchema.optional(),
339
+ visibility: VisibilitySchema.optional(),
340
+ }).strict();
341
+ export type SymbolFilter = z.infer<typeof SymbolFilterSchema>;
342
+
343
+ /**
344
+ * Call graph options schema
345
+ */
346
+ export const CallGraphOptionsSchema = z.object({
347
+ maxNodes: z.number().int().positive().max(100_000).optional(),
348
+ maxEdges: z.number().int().positive().max(100_000).optional(),
349
+ }).strict();
350
+ export type CallGraphOptions = z.infer<typeof CallGraphOptionsSchema>;
351
+
352
+ /**
353
+ * Semantic compress options schema
354
+ */
355
+ export const SemanticCompressOptionsSchema = z.object({
356
+ similarityThreshold: z.number().min(0).max(1).optional(),
357
+ budgetRatio: z.number().min(0).max(1).optional(),
358
+ minChunkSize: z.number().int().positive().max(100_000).optional(),
359
+ maxChunkSize: z.number().int().positive().max(100_000).optional(),
360
+ }).strict();
361
+ export type SemanticCompressOptions = z.infer<typeof SemanticCompressOptionsSchema>;
362
+
363
+ /**
364
+ * Generate map options schema
365
+ */
366
+ export const GenerateMapOptionsSchema = z.object({
367
+ budget: z.number().int().positive().max(10_000_000).optional(),
368
+ maxSymbols: z.number().int().positive().max(10_000).optional(),
369
+ }).strict();
370
+ export type GenerateMapOptions = z.infer<typeof GenerateMapOptionsSchema>;
371
+
372
+ /**
373
+ * Transitive callers options schema
374
+ */
375
+ export const TransitiveCallersOptionsSchema = z.object({
376
+ maxDepth: z.number().int().positive().max(100).optional(),
377
+ maxResults: z.number().int().positive().max(10_000).optional(),
378
+ }).strict();
379
+ export type TransitiveCallersOptions = z.infer<typeof TransitiveCallersOptionsSchema>;
380
+
381
+ /**
382
+ * Call sites context options schema
383
+ */
384
+ export const CallSitesContextOptionsSchema = z.object({
385
+ linesBefore: z.number().int().nonnegative().max(1_000).optional(),
386
+ linesAfter: z.number().int().nonnegative().max(1_000).optional(),
387
+ }).strict();
388
+ export type CallSitesContextOptions = z.infer<typeof CallSitesContextOptionsSchema>;
389
+
390
+ /**
391
+ * Changed symbols filter schema
392
+ */
393
+ export const ChangedSymbolsFilterSchema = z.object({
394
+ kinds: z.array(SymbolKindSchema).optional(),
395
+ excludeKinds: z.array(SymbolKindSchema).optional(),
396
+ }).strict();
397
+ export type ChangedSymbolsFilter = z.infer<typeof ChangedSymbolsFilterSchema>;
398
+
399
+ /**
400
+ * Breaking change options schema
401
+ */
402
+ export const BreakingChangeOptionsSchema = z.object({
403
+ oldRef: z.string().min(1),
404
+ newRef: z.string().min(1),
405
+ }).strict();
406
+ export type BreakingChangeOptions = z.infer<typeof BreakingChangeOptionsSchema>;
407
+
408
+ /**
409
+ * Dead code options schema
410
+ */
411
+ export const DeadCodeOptionsSchema = z.object({
412
+ paths: z.array(z.string()).optional(),
413
+ languages: z.array(z.string()).optional(),
414
+ }).strict();
415
+ export type DeadCodeOptions = z.infer<typeof DeadCodeOptionsSchema>;
416
+
417
+ /**
418
+ * Multi-repo entry schema
419
+ */
420
+ export const MultiRepoEntrySchema = z.object({
421
+ id: z.string().min(1),
422
+ name: z.string().min(1),
423
+ path: z.string().min(1),
424
+ }).strict();
425
+ export type MultiRepoEntry = z.infer<typeof MultiRepoEntrySchema>;
426
+
427
+ /**
428
+ * Multi-repo options schema
429
+ */
430
+ export const MultiRepoOptionsSchema = z.object({
431
+ repositories: z.array(MultiRepoEntrySchema),
432
+ }).strict();
433
+ export type MultiRepoOptions = z.infer<typeof MultiRepoOptionsSchema>;
434
+
435
+ /**
436
+ * Extract documentation options schema
437
+ */
438
+ export const ExtractDocOptionsSchema = z.object({
439
+ language: z.string().min(1),
440
+ }).strict();
441
+ export type ExtractDocOptions = z.infer<typeof ExtractDocOptionsSchema>;
442
+
443
+ /**
444
+ * Complexity options schema
445
+ */
446
+ export const ComplexityOptionsSchema = z.object({
447
+ language: z.string().min(1),
448
+ }).strict();
449
+ export type ComplexityOptions = z.infer<typeof ComplexityOptionsSchema>;
450
+
451
+ // ============================================================================
452
+ // Validation Helper Functions
453
+ // ============================================================================
454
+
455
+ /**
456
+ * Validate pack options with detailed error messages
457
+ * @throws {z.ZodError} if validation fails
458
+ */
459
+ export function validatePackOptions(input: unknown): PackOptions {
460
+ return PackOptionsSchema.parse(input);
461
+ }
462
+
463
+ /**
464
+ * Safely validate pack options, returns result object
465
+ */
466
+ export function safeValidatePackOptions(input: unknown): z.SafeParseReturnType<unknown, PackOptions> {
467
+ return PackOptionsSchema.safeParse(input);
468
+ }
469
+
470
+ /**
471
+ * Validate scan options
472
+ * @throws {z.ZodError} if validation fails
473
+ */
474
+ export function validateScanOptions(input: unknown): ScanOptions {
475
+ return ScanOptionsSchema.parse(input);
476
+ }
477
+
478
+ /**
479
+ * Safely validate scan options
480
+ */
481
+ export function safeValidateScanOptions(input: unknown): z.SafeParseReturnType<unknown, ScanOptions> {
482
+ return ScanOptionsSchema.safeParse(input);
483
+ }
484
+
485
+ /**
486
+ * Validate chunk options
487
+ * @throws {z.ZodError} if validation fails
488
+ */
489
+ export function validateChunkOptions(input: unknown): ChunkOptions {
490
+ return ChunkOptionsSchema.parse(input);
491
+ }
492
+
493
+ /**
494
+ * Safely validate chunk options
495
+ */
496
+ export function safeValidateChunkOptions(input: unknown): z.SafeParseReturnType<unknown, ChunkOptions> {
497
+ return ChunkOptionsSchema.safeParse(input);
498
+ }
499
+
500
+ /**
501
+ * Validate embed options
502
+ * @throws {z.ZodError} if validation fails
503
+ */
504
+ export function validateEmbedOptions(input: unknown): EmbedOptions {
505
+ return EmbedOptionsSchema.parse(input);
506
+ }
507
+
508
+ /**
509
+ * Safely validate embed options
510
+ */
511
+ export function safeValidateEmbedOptions(input: unknown): z.SafeParseReturnType<unknown, EmbedOptions> {
512
+ return EmbedOptionsSchema.safeParse(input);
513
+ }
514
+
515
+ /**
516
+ * Validate index options
517
+ * @throws {z.ZodError} if validation fails
518
+ */
519
+ export function validateIndexOptions(input: unknown): IndexOptions {
520
+ return IndexOptionsSchema.parse(input);
521
+ }
522
+
523
+ /**
524
+ * Safely validate index options
525
+ */
526
+ export function safeValidateIndexOptions(input: unknown): z.SafeParseReturnType<unknown, IndexOptions> {
527
+ return IndexOptionsSchema.safeParse(input);
528
+ }
529
+
530
+ /**
531
+ * Validate diff context options
532
+ * @throws {z.ZodError} if validation fails
533
+ */
534
+ export function validateDiffContextOptions(input: unknown): DiffContextOptions {
535
+ return DiffContextOptionsSchema.parse(input);
536
+ }
537
+
538
+ /**
539
+ * Safely validate diff context options
540
+ */
541
+ export function safeValidateDiffContextOptions(input: unknown): z.SafeParseReturnType<unknown, DiffContextOptions> {
542
+ return DiffContextOptionsSchema.safeParse(input);
543
+ }
544
+
545
+ /**
546
+ * Validate impact options
547
+ * @throws {z.ZodError} if validation fails
548
+ */
549
+ export function validateImpactOptions(input: unknown): ImpactOptions {
550
+ return ImpactOptionsSchema.parse(input);
551
+ }
552
+
553
+ /**
554
+ * Safely validate impact options
555
+ */
556
+ export function safeValidateImpactOptions(input: unknown): z.SafeParseReturnType<unknown, ImpactOptions> {
557
+ return ImpactOptionsSchema.safeParse(input);
558
+ }
559
+
560
+ // ============================================================================
561
+ // Output Schemas (for validating return values)
562
+ // ============================================================================
563
+
564
+ /**
565
+ * Language stat schema
566
+ */
567
+ export const LanguageStatSchema = z.object({
568
+ language: z.string(),
569
+ files: z.number().int().nonnegative(),
570
+ lines: z.number().int().nonnegative(),
571
+ percentage: z.number().min(0).max(100),
572
+ });
573
+ export type LanguageStat = z.infer<typeof LanguageStatSchema>;
574
+
575
+ /**
576
+ * Scan stats schema
577
+ */
578
+ export const ScanStatsSchema = z.object({
579
+ name: z.string(),
580
+ totalFiles: z.number().int().nonnegative(),
581
+ totalLines: z.number().int().nonnegative(),
582
+ totalTokens: z.number().int().nonnegative(),
583
+ primaryLanguage: z.string().optional(),
584
+ languages: z.array(LanguageStatSchema),
585
+ securityFindings: z.number().int().nonnegative(),
586
+ });
587
+ export type ScanStats = z.infer<typeof ScanStatsSchema>;
588
+
589
+ /**
590
+ * Security finding schema
591
+ */
592
+ export const SecurityFindingSchema = z.object({
593
+ file: z.string(),
594
+ line: z.number().int().positive(),
595
+ severity: z.string(),
596
+ kind: z.string(),
597
+ pattern: z.string(),
598
+ });
599
+ export type SecurityFinding = z.infer<typeof SecurityFindingSchema>;
600
+
601
+ /**
602
+ * Index status schema
603
+ */
604
+ export const IndexStatusSchema = z.object({
605
+ exists: z.boolean(),
606
+ fileCount: z.number().int().nonnegative(),
607
+ symbolCount: z.number().int().nonnegative(),
608
+ lastBuilt: z.string().optional(),
609
+ version: z.string().optional(),
610
+ filesUpdated: z.number().int().nonnegative().optional(),
611
+ incremental: z.boolean().optional(),
612
+ });
613
+ export type IndexStatus = z.infer<typeof IndexStatusSchema>;
614
+
615
+ /**
616
+ * Symbol info schema
617
+ */
618
+ export const SymbolInfoSchema = z.object({
619
+ id: z.number().int().nonnegative(),
620
+ name: z.string(),
621
+ kind: z.string(),
622
+ file: z.string(),
623
+ line: z.number().int().positive(),
624
+ endLine: z.number().int().positive(),
625
+ signature: z.string().optional(),
626
+ visibility: z.string(),
627
+ });
628
+ export type SymbolInfo = z.infer<typeof SymbolInfoSchema>;
629
+
630
+ /**
631
+ * Embed chunk schema
632
+ */
633
+ export const EmbedChunkSchema = z.object({
634
+ id: z.string().regex(/^ec_[a-f0-9]{32}$/),
635
+ fullHash: z.string(),
636
+ content: z.string(),
637
+ tokens: z.number().int().nonnegative(),
638
+ kind: z.string(),
639
+ source: z.object({
640
+ file: z.string(),
641
+ linesStart: z.number().int().positive(),
642
+ linesEnd: z.number().int().positive(),
643
+ symbol: z.string(),
644
+ fqn: z.string().optional(),
645
+ language: z.string(),
646
+ parent: z.string().optional(),
647
+ visibility: z.string(),
648
+ isTest: z.boolean(),
649
+ }),
650
+ context: z.object({
651
+ docstring: z.string().optional(),
652
+ comments: z.array(z.string()),
653
+ signature: z.string().optional(),
654
+ calls: z.array(z.string()),
655
+ calledBy: z.array(z.string()),
656
+ imports: z.array(z.string()),
657
+ tags: z.array(z.string()),
658
+ linesOfCode: z.number().int().nonnegative(),
659
+ maxNestingDepth: z.number().int().nonnegative(),
660
+ }),
661
+ part: z.object({
662
+ part: z.number().int().positive(),
663
+ of: z.number().int().positive(),
664
+ parentId: z.string(),
665
+ parentSignature: z.string().optional(),
666
+ }).optional(),
667
+ });
668
+ export type EmbedChunk = z.infer<typeof EmbedChunkSchema>;
669
+
670
+ /**
671
+ * Embed diff summary schema
672
+ */
673
+ export const EmbedDiffSummarySchema = z.object({
674
+ added: z.number().int().nonnegative(),
675
+ modified: z.number().int().nonnegative(),
676
+ removed: z.number().int().nonnegative(),
677
+ unchanged: z.number().int().nonnegative(),
678
+ totalChunks: z.number().int().nonnegative(),
679
+ });
680
+ export type EmbedDiffSummary = z.infer<typeof EmbedDiffSummarySchema>;
681
+
682
+ /**
683
+ * Embed result schema
684
+ */
685
+ export const EmbedResultSchema = z.object({
686
+ chunks: z.array(EmbedChunkSchema),
687
+ diff: EmbedDiffSummarySchema.optional(),
688
+ manifestVersion: z.number().int().nonnegative(),
689
+ elapsedMs: z.number().int().nonnegative(),
690
+ });
691
+ export type EmbedResult = z.infer<typeof EmbedResultSchema>;