@vitronai/themis 0.1.0-beta.0 → 0.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/globals.d.ts CHANGED
@@ -1,4 +1,21 @@
1
- import type { Describe, Expect, Fn, Hook, Intent, MockControl, MockModule, SpyOn, Test } from './index';
1
+ import type {
2
+ Cleanup,
3
+ Describe,
4
+ Expect,
5
+ FireEventApi,
6
+ Fn,
7
+ Hook,
8
+ Intent,
9
+ MockControl,
10
+ MockModule,
11
+ Render,
12
+ ScreenApi,
13
+ SpyOn,
14
+ Test,
15
+ FetchMock,
16
+ FlushMicrotasks,
17
+ WaitFor
18
+ } from './index';
2
19
 
3
20
  declare global {
4
21
  var describe: Describe;
@@ -17,6 +34,19 @@ declare global {
17
34
  var clearAllMocks: MockControl;
18
35
  var resetAllMocks: MockControl;
19
36
  var restoreAllMocks: MockControl;
37
+ var render: Render;
38
+ var screen: ScreenApi;
39
+ var fireEvent: FireEventApi;
40
+ var waitFor: WaitFor;
41
+ var cleanup: Cleanup;
42
+ var useFakeTimers: () => void;
43
+ var useRealTimers: () => void;
44
+ var advanceTimersByTime: (ms: number) => void;
45
+ var runAllTimers: () => void;
46
+ var flushMicrotasks: FlushMicrotasks;
47
+ var mockFetch: (handlerOrResponse: unknown) => FetchMock;
48
+ var restoreFetch: () => void;
49
+ var resetFetchMocks: () => void;
20
50
  }
21
51
 
22
52
  export {};
package/index.d.ts CHANGED
@@ -62,6 +62,7 @@ export interface RunResult {
62
62
  files: FileResult[];
63
63
  summary: RunSummary;
64
64
  stability?: StabilityReport;
65
+ artifacts?: RunArtifacts;
65
66
  }
66
67
 
67
68
  export type TestEnvironment = 'node' | 'jsdom';
@@ -75,7 +76,8 @@ export interface RunOptions {
75
76
  environment?: TestEnvironment;
76
77
  setupFiles?: string[];
77
78
  tsconfigPath?: string | null;
78
- updateSnapshots?: boolean;
79
+ isolation?: 'worker' | 'in-process';
80
+ cache?: boolean;
79
81
  }
80
82
 
81
83
  export interface ThemisConfig {
@@ -86,6 +88,364 @@ export interface ThemisConfig {
86
88
  environment: TestEnvironment;
87
89
  setupFiles: string[];
88
90
  tsconfigPath: string | null;
91
+ testIgnore: string[];
92
+ }
93
+
94
+ export interface MigrationResult {
95
+ source: 'jest' | 'vitest';
96
+ configPath: string;
97
+ setupPath: string;
98
+ compatPath: string;
99
+ packageJsonPath: string | null;
100
+ packageUpdated: boolean;
101
+ rewriteImports: boolean;
102
+ rewrittenFiles: string[];
103
+ reportPath: string;
104
+ report: {
105
+ schema: 'themis.migration.report.v1';
106
+ source: 'jest' | 'vitest';
107
+ createdAt: string;
108
+ summary: {
109
+ matchedFiles: number;
110
+ jestGlobals: number;
111
+ vitest: number;
112
+ testingLibraryReact: number;
113
+ rewrittenFiles: number;
114
+ rewrittenImports: number;
115
+ };
116
+ files: Array<{
117
+ file: string;
118
+ imports: string[];
119
+ }>;
120
+ rewrites: string[];
121
+ nextActions: string[];
122
+ };
123
+ }
124
+
125
+ export interface MigrationOptions {
126
+ rewriteImports?: boolean;
127
+ }
128
+
129
+ export interface GenerateOptions {
130
+ targetDir?: string;
131
+ outputDir?: string;
132
+ force?: boolean;
133
+ strict?: boolean;
134
+ writeHints?: boolean;
135
+ plan?: boolean;
136
+ review?: boolean;
137
+ update?: boolean;
138
+ clean?: boolean;
139
+ changed?: boolean;
140
+ failOnSkips?: boolean;
141
+ failOnConflicts?: boolean;
142
+ requireConfidence?: string | null;
143
+ files?: string[] | string;
144
+ scenario?: string | null;
145
+ minConfidence?: string | null;
146
+ matchSource?: string | null;
147
+ matchExport?: string | null;
148
+ include?: string | null;
149
+ exclude?: string | null;
150
+ }
151
+
152
+ export interface GenerateSkippedFile {
153
+ file: string;
154
+ reason: string;
155
+ stage: string;
156
+ }
157
+
158
+ export interface GenerateScenarioSummary {
159
+ kind: string;
160
+ confidence: string;
161
+ exports: string[];
162
+ caseCount: number;
163
+ }
164
+
165
+ export interface GenerateEntrySummary {
166
+ action: string;
167
+ sourceFile: string;
168
+ testFile: string | null;
169
+ moduleKind: string;
170
+ confidence: string;
171
+ exactExports: boolean;
172
+ exportNames: string[];
173
+ hintsFile: string | null;
174
+ sourceHash: string | null;
175
+ scenarios: GenerateScenarioSummary[];
176
+ reason: string | null;
177
+ }
178
+
179
+ export interface GenerateFilterSummary {
180
+ plan: boolean;
181
+ changed: boolean;
182
+ files: string[];
183
+ scenario: string | null;
184
+ minConfidence: string | null;
185
+ matchSource: string | null;
186
+ matchExport: string | null;
187
+ include: string | null;
188
+ exclude: string | null;
189
+ }
190
+
191
+ export interface GenerateArtifacts {
192
+ generateMap: string;
193
+ helperFile: string;
194
+ generateResult: string;
195
+ generateHandoff: string;
196
+ generateBacklog: string;
197
+ }
198
+
199
+ export interface GenerateHintFiles {
200
+ created: string[];
201
+ updated: string[];
202
+ unchanged: string[];
203
+ }
204
+
205
+ export interface RunArtifactPaths {
206
+ lastRun: string;
207
+ failedTests: string;
208
+ runDiff: string;
209
+ runHistory: string;
210
+ fixHandoff: string;
211
+ }
212
+
213
+ export interface RunComparison {
214
+ status: 'baseline' | 'changed';
215
+ previousRunId: string;
216
+ previousRunAt: string;
217
+ currentRunAt: string;
218
+ delta: RunSummary;
219
+ newFailures: string[];
220
+ resolvedFailures: string[];
221
+ }
222
+
223
+ export interface RunArtifacts {
224
+ runId: string;
225
+ comparison: RunComparison;
226
+ paths: RunArtifactPaths;
227
+ }
228
+
229
+ export interface GenerateGateFailure {
230
+ code: string;
231
+ count: number;
232
+ message: string;
233
+ }
234
+
235
+ export interface GenerateGateSummary {
236
+ strict: boolean;
237
+ failOnSkips: boolean;
238
+ failOnConflicts: boolean;
239
+ requireConfidence: string | null;
240
+ failed: boolean;
241
+ failures: GenerateGateFailure[];
242
+ }
243
+
244
+ export interface GenerateBacklogItem {
245
+ type: string;
246
+ severity: 'warning' | 'error';
247
+ sourceFile: string;
248
+ testFile: string | null;
249
+ moduleKind: string | null;
250
+ confidence: string | null;
251
+ stage: string | null;
252
+ hintsFile: string | null;
253
+ reason: string;
254
+ suggestedAction: string;
255
+ suggestedCommand: string | null;
256
+ }
257
+
258
+ export interface GenerateBacklogSummary {
259
+ total: number;
260
+ errors: number;
261
+ warnings: number;
262
+ skipped: number;
263
+ conflicts: number;
264
+ confidence: number;
265
+ }
266
+
267
+ export interface GenerateBacklog {
268
+ summary: GenerateBacklogSummary;
269
+ items: GenerateBacklogItem[];
270
+ }
271
+
272
+ export interface GeneratePromptTarget {
273
+ action: string;
274
+ sourceFile: string;
275
+ testFile: string | null;
276
+ moduleKind: string;
277
+ confidence: string;
278
+ scenarios: string[];
279
+ }
280
+
281
+ export interface GeneratePromptReady {
282
+ summary: string;
283
+ targets: GeneratePromptTarget[];
284
+ unresolved: GenerateBacklogItem[];
285
+ nextActions: string[];
286
+ prompt: string;
287
+ }
288
+
289
+ export type FixHandoffCategory = 'source-drift' | 'generated-contract-failure';
290
+
291
+ export interface FixHandoffItem {
292
+ file: string;
293
+ name: string;
294
+ fullName: string;
295
+ message: string;
296
+ testFile: string;
297
+ sourceFile: string;
298
+ moduleKind: string | null;
299
+ confidence: string | null;
300
+ scenarios: string[];
301
+ hintsFile: string | null;
302
+ category: FixHandoffCategory;
303
+ failureCount: number;
304
+ failedTests: string[];
305
+ suggestedAction: string;
306
+ suggestedCommand: string | null;
307
+ repairStrategy: string;
308
+ candidateFiles: string[];
309
+ autofixCommand: string | null;
310
+ }
311
+
312
+ export interface FixHandoffPayload {
313
+ schema: 'themis.fix.handoff.v1';
314
+ runId: string;
315
+ createdAt: string;
316
+ summary: {
317
+ totalFailures: number;
318
+ generatedFailures: number;
319
+ staleSources: number;
320
+ contractFailures: number;
321
+ };
322
+ artifacts: {
323
+ failedTests: string;
324
+ generateMap: string;
325
+ generateBacklog: string;
326
+ fixHandoff: string;
327
+ };
328
+ items: FixHandoffItem[];
329
+ nextActions: string[];
330
+ }
331
+
332
+ export interface GeneratePayload {
333
+ schema: 'themis.generate.result.v1';
334
+ mode: {
335
+ review: boolean;
336
+ update: boolean;
337
+ clean: boolean;
338
+ changed: boolean;
339
+ plan: boolean;
340
+ writeHints: boolean;
341
+ };
342
+ source: {
343
+ targetDir: string;
344
+ outputDir: string;
345
+ };
346
+ filters: GenerateFilterSummary;
347
+ gates: GenerateGateSummary;
348
+ summary: {
349
+ scanned: number;
350
+ generated: number;
351
+ created: number;
352
+ updated: number;
353
+ unchanged: number;
354
+ removed: number;
355
+ skipped: number;
356
+ conflicts: number;
357
+ };
358
+ scannedFiles: string[];
359
+ generatedFiles: string[];
360
+ removedFiles: string[];
361
+ skippedFiles: GenerateSkippedFile[];
362
+ conflictFiles: string[];
363
+ hintFiles: GenerateHintFiles;
364
+ entries: GenerateEntrySummary[];
365
+ backlog: GenerateBacklog;
366
+ artifacts: GenerateArtifacts;
367
+ promptReady: GeneratePromptReady;
368
+ hints: {
369
+ runTests: string;
370
+ plan: string;
371
+ review: string;
372
+ updateOnly: string;
373
+ clean: string;
374
+ changed: string;
375
+ strict: string;
376
+ writeHints: string;
377
+ fileTarget: string;
378
+ };
379
+ }
380
+
381
+ export interface GenerateBacklogPayload {
382
+ schema: 'themis.generate.backlog.v1';
383
+ source: {
384
+ targetDir: string;
385
+ outputDir: string;
386
+ };
387
+ filters: GenerateFilterSummary;
388
+ gates: GenerateGateSummary;
389
+ summary: GenerateBacklogSummary;
390
+ items: GenerateBacklogItem[];
391
+ }
392
+
393
+ export interface GenerateHandoffPayload {
394
+ schema: 'themis.generate.handoff.v1';
395
+ source: {
396
+ targetDir: string;
397
+ outputDir: string;
398
+ };
399
+ filters: GenerateFilterSummary;
400
+ gates: GenerateGateSummary;
401
+ summary: GeneratePayload['summary'];
402
+ artifacts: {
403
+ generateMap: string;
404
+ generateResult: string;
405
+ generateBacklog: string;
406
+ };
407
+ hintFiles: GenerateHintFiles;
408
+ targets: GeneratePromptTarget[];
409
+ unresolved: GenerateBacklogItem[];
410
+ backlog: GenerateBacklogSummary;
411
+ nextActions: string[];
412
+ prompt: string;
413
+ }
414
+
415
+ export interface GenerateSummary {
416
+ targetDir: string;
417
+ outputDir: string;
418
+ helperFile: string;
419
+ mapFile: string;
420
+ scannedFiles: string[];
421
+ generatedFiles: string[];
422
+ removedFiles: string[];
423
+ skippedFiles: GenerateSkippedFile[];
424
+ createdFiles: string[];
425
+ updatedFiles: string[];
426
+ unchangedFiles: string[];
427
+ cleanedFiles: string[];
428
+ conflictFiles: string[];
429
+ entries: GenerateEntrySummary[];
430
+ plan: boolean;
431
+ review: boolean;
432
+ update: boolean;
433
+ clean: boolean;
434
+ changed: boolean;
435
+ writeHints: boolean;
436
+ filters: GenerateFilterSummary;
437
+ gateOptions: {
438
+ strict: boolean;
439
+ failOnSkips: boolean;
440
+ failOnConflicts: boolean;
441
+ requireConfidence: string | null;
442
+ };
443
+ gates: GenerateGateSummary;
444
+ hintFiles: GenerateHintFiles;
445
+ backlog: GenerateBacklog;
446
+ artifacts: GenerateArtifacts;
447
+ prompt: string;
448
+ helperRemoved: boolean;
89
449
  }
90
450
 
91
451
  export function main(argv: string[]): Promise<void>;
@@ -94,7 +454,17 @@ export function runTests(files: string[], options?: RunOptions): Promise<RunResu
94
454
  export function discoverTests(cwd: string, config: ThemisConfig): string[];
95
455
  export function loadConfig(cwd: string): ThemisConfig;
96
456
  export function initConfig(cwd: string): void;
457
+ export function runMigrate(cwd: string, framework: 'jest' | 'vitest', options?: MigrationOptions): MigrationResult;
97
458
  export const DEFAULT_CONFIG: ThemisConfig;
459
+ export function generateTestsFromSource(cwd: string, options?: GenerateOptions): GenerateSummary;
460
+ export function buildGeneratePayload(summary: GenerateSummary, cwd?: string): GeneratePayload;
461
+ export function buildGenerateBacklogPayload(summary: GenerateSummary, cwd?: string): GenerateBacklogPayload;
462
+ export function buildGenerateHandoff(payload: GeneratePayload): GenerateHandoffPayload;
463
+ export function writeGenerateArtifacts(summary: GenerateSummary, cwd?: string): {
464
+ payload: GeneratePayload;
465
+ handoff: GenerateHandoffPayload;
466
+ backlog: GenerateBacklogPayload;
467
+ };
98
468
 
99
469
  export interface MockResult {
100
470
  type: 'return' | 'throw';
@@ -134,7 +504,9 @@ export interface ExpectMatchers<TReceived = unknown> {
134
504
  toHaveBeenCalled(): void;
135
505
  toHaveBeenCalledTimes(expected: number): void;
136
506
  toHaveBeenCalledWith(...expectedArgs: unknown[]): void;
137
- toMatchSnapshot(snapshotName?: string): void;
507
+ toHaveTextContent(expected: string): void;
508
+ toHaveAttribute(name: string, expectedValue?: string): void;
509
+ toBeInTheDocument(): void;
138
510
  }
139
511
 
140
512
  export type Expect = <TReceived = unknown>(received: TReceived) => ExpectMatchers<TReceived>;
@@ -148,6 +520,37 @@ export type SpyOn = <TTarget extends Record<string, unknown>, TKey extends keyof
148
520
  ) => MockFunction<any[], any>;
149
521
  export type MockModule = (request: string, factoryOrExports?: unknown | (() => unknown)) => void;
150
522
  export type MockControl = () => void;
523
+ export interface RenderResult {
524
+ container: HTMLElement;
525
+ rerender(nextInput: unknown): void;
526
+ unmount(): void;
527
+ }
528
+ export interface ScreenApi {
529
+ getByText(text: string): HTMLElement;
530
+ queryByText(text: string): HTMLElement | null;
531
+ getByRole(role: string, options?: { name?: string }): HTMLElement;
532
+ queryByRole(role: string, options?: { name?: string }): HTMLElement | null;
533
+ getByLabelText(labelText: string): HTMLElement;
534
+ }
535
+ export interface FireEventApi {
536
+ click(node: Node): Event;
537
+ change(node: Node, payload?: { target?: Record<string, unknown> }): Event;
538
+ input(node: Node, payload?: { target?: Record<string, unknown> }): Event;
539
+ submit(node: Node): Event;
540
+ keyDown(node: Node, payload?: { key?: string }): Event;
541
+ }
542
+ export type Render = (input: unknown, options?: { container?: HTMLElement }) => RenderResult;
543
+ export type WaitFor = <T>(assertion: () => T | Promise<T>, options?: { timeout?: number; interval?: number }) => Promise<T>;
544
+ export type Cleanup = () => void;
545
+ export type FetchMock = MockFunction<any[], Promise<unknown>>;
546
+ export type UseFakeTimers = () => void;
547
+ export type UseRealTimers = () => void;
548
+ export type AdvanceTimersByTime = (ms: number) => void;
549
+ export type RunAllTimers = () => void;
550
+ export type FlushMicrotasks = () => Promise<void>;
551
+ export type MockFetch = (handlerOrResponse: unknown) => FetchMock;
552
+ export type RestoreFetch = () => void;
553
+ export type ResetFetchMocks = () => void;
151
554
 
152
555
  export type SuiteFn = () => void;
153
556
  export type TestFn = () => Awaitable<void>;
package/index.js CHANGED
@@ -3,7 +3,15 @@ const { collectAndRun } = require('./src/runtime');
3
3
  const { runTests } = require('./src/runner');
4
4
  const { discoverTests } = require('./src/discovery');
5
5
  const { loadConfig, initConfig, DEFAULT_CONFIG } = require('./src/config');
6
+ const { runMigrate } = require('./src/migrate');
6
7
  const { expect } = require('./src/expect');
8
+ const {
9
+ generateTestsFromSource,
10
+ buildGeneratePayload,
11
+ buildGenerateBacklogPayload,
12
+ buildGenerateHandoff,
13
+ writeGenerateArtifacts
14
+ } = require('./src/generate');
7
15
 
8
16
  module.exports = {
9
17
  main,
@@ -12,6 +20,12 @@ module.exports = {
12
20
  discoverTests,
13
21
  loadConfig,
14
22
  initConfig,
23
+ runMigrate,
15
24
  DEFAULT_CONFIG,
25
+ generateTestsFromSource,
26
+ buildGeneratePayload,
27
+ buildGenerateBacklogPayload,
28
+ buildGenerateHandoff,
29
+ writeGenerateArtifacts,
16
30
  expect
17
31
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitronai/themis",
3
- "version": "0.1.0-beta.0",
3
+ "version": "0.1.0-beta.1",
4
4
  "description": "Intent-first unit test framework for AI agents in Node.js and TypeScript, powered by an AI verdict engine",
5
5
  "license": "MIT",
6
6
  "author": "Vitron AI",