@xera-ai/web 0.1.7 → 0.2.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 (44) hide show
  1. package/dist/index.js +71 -71
  2. package/package.json +10 -7
  3. package/src/generator/lint.ts +2 -2
  4. package/src/generator/pom-scan.ts +1 -1
  5. package/src/index.ts +7 -7
  6. package/dist/core/src/adapter/types.d.ts +0 -69
  7. package/dist/core/src/artifact/hash.d.ts +0 -3
  8. package/dist/core/src/artifact/meta.d.ts +0 -45
  9. package/dist/core/src/artifact/paths.d.ts +0 -24
  10. package/dist/core/src/artifact/status.d.ts +0 -95
  11. package/dist/core/src/auth/encrypt.d.ts +0 -3
  12. package/dist/core/src/auth/key.d.ts +0 -2
  13. package/dist/core/src/auth/refresh.d.ts +0 -8
  14. package/dist/core/src/auth/state.d.ts +0 -23
  15. package/dist/core/src/config/define.d.ts +0 -2
  16. package/dist/core/src/config/load.d.ts +0 -2
  17. package/dist/core/src/config/schema.d.ts +0 -325
  18. package/dist/core/src/index.d.ts +0 -19
  19. package/dist/core/src/jira/client.d.ts +0 -10
  20. package/dist/core/src/jira/fields.d.ts +0 -6
  21. package/dist/core/src/jira/mcp-backend.d.ts +0 -2
  22. package/dist/core/src/jira/rest-backend.d.ts +0 -7
  23. package/dist/core/src/jira/retry.d.ts +0 -7
  24. package/dist/core/src/jira/types.d.ts +0 -28
  25. package/dist/core/src/lock/file-lock.d.ts +0 -11
  26. package/dist/core/src/logging/ndjson-logger.d.ts +0 -10
  27. package/dist/{web/src/adapter.d.ts → adapter.d.ts} +0 -0
  28. package/dist/{web/src/auth-setup → auth-setup}/define.d.ts +0 -0
  29. package/dist/{web/src/auth-setup → auth-setup}/playwright-state.d.ts +0 -0
  30. package/dist/{web/src/auth-setup → auth-setup}/runner.d.ts +0 -0
  31. package/dist/{web/src/executor → executor}/index.d.ts +0 -0
  32. package/dist/{web/src/executor → executor}/playwright-args.d.ts +0 -0
  33. package/dist/{web/src/generator → generator}/gherkin-validate.d.ts +0 -0
  34. package/dist/{web/src/generator → generator}/lint.d.ts +0 -0
  35. package/dist/{web/src/generator → generator}/pom-scan.d.ts +0 -0
  36. package/dist/{web/src/generator → generator}/promote.d.ts +0 -0
  37. package/dist/{web/src/generator → generator}/selector-rules.d.ts +0 -0
  38. package/dist/{web/src/generator → generator}/typecheck.d.ts +0 -0
  39. package/dist/{web/src/index.d.ts → index.d.ts} +7 -7
  40. /package/dist/{web/src/trace-normalizer → trace-normalizer}/normalize.d.ts +0 -0
  41. /package/dist/{web/src/trace-normalizer → trace-normalizer}/parse.d.ts +0 -0
  42. /package/dist/{web/src/trace-normalizer → trace-normalizer}/scrub-rules.d.ts +0 -0
  43. /package/dist/{web/src/trace-normalizer → trace-normalizer}/scrub.d.ts +0 -0
  44. /package/dist/{web/src/trace-normalizer → trace-normalizer}/unzip.d.ts +0 -0
package/dist/index.js CHANGED
@@ -304,6 +304,20 @@ var WebAdapter = {
304
304
  function defineAuthSetup(fn) {
305
305
  return fn;
306
306
  }
307
+ // src/auth-setup/playwright-state.ts
308
+ import { mkdirSync, writeFileSync as writeFileSync2 } from "fs";
309
+ import { join as join4 } from "path";
310
+ import { readAuthState } from "@xera-ai/core";
311
+ function stagePlaywrightState(authDir, role) {
312
+ const entry = readAuthState(authDir, role);
313
+ if (!entry)
314
+ throw new Error(`No auth state for role "${role}" in ${authDir}`);
315
+ const cacheDir = join4(authDir, ".cache");
316
+ mkdirSync(cacheDir, { recursive: true });
317
+ const stagedPath = join4(cacheDir, `${role}.json`);
318
+ writeFileSync2(stagedPath, JSON.stringify(entry.payload));
319
+ return stagedPath;
320
+ }
307
321
  // src/auth-setup/runner.ts
308
322
  import { pathToFileURL } from "url";
309
323
  import { writeAuthState } from "@xera-ai/core";
@@ -331,20 +345,6 @@ async function runAuthSetup(input) {
331
345
  await context.close();
332
346
  }
333
347
  }
334
- // src/auth-setup/playwright-state.ts
335
- import { mkdirSync, writeFileSync as writeFileSync2 } from "fs";
336
- import { join as join4 } from "path";
337
- import { readAuthState } from "@xera-ai/core";
338
- function stagePlaywrightState(authDir, role) {
339
- const entry = readAuthState(authDir, role);
340
- if (!entry)
341
- throw new Error(`No auth state for role "${role}" in ${authDir}`);
342
- const cacheDir = join4(authDir, ".cache");
343
- mkdirSync(cacheDir, { recursive: true });
344
- const stagedPath = join4(cacheDir, `${role}.json`);
345
- writeFileSync2(stagedPath, JSON.stringify(entry.payload));
346
- return stagedPath;
347
- }
348
348
  // src/generator/gherkin-validate.ts
349
349
  import { AstBuilder, GherkinClassicTokenMatcher, Parser } from "@cucumber/gherkin";
350
350
  import { IdGenerator } from "@cucumber/messages";
@@ -368,47 +368,9 @@ function validateGherkin(content) {
368
368
  return { ok: false, errors };
369
369
  }
370
370
  }
371
- // src/generator/typecheck.ts
372
- import { spawnSync } from "child_process";
373
- import { existsSync as existsSync2 } from "fs";
374
- import { dirname, join as join5 } from "path";
375
- function findNearestTsconfig(start) {
376
- let dir = start;
377
- while (true) {
378
- const candidate = join5(dir, "tsconfig.json");
379
- if (existsSync2(candidate))
380
- return candidate;
381
- const parent = dirname(dir);
382
- if (parent === dir)
383
- return null;
384
- dir = parent;
385
- }
386
- }
387
- async function typecheckTicket(ticketDir) {
388
- const tsconfig = findNearestTsconfig(ticketDir);
389
- if (!tsconfig) {
390
- return {
391
- ok: false,
392
- errors: [
393
- `No tsconfig.json found walking up from ${ticketDir}. Run \`xera init\` to scaffold one at the project root.`
394
- ]
395
- };
396
- }
397
- const proc = spawnSync("npx", ["tsc", "--noEmit", "-p", tsconfig], { encoding: "utf8" });
398
- if (proc.status === 0)
399
- return { ok: true, errors: [] };
400
- const out = `${proc.stdout ?? ""}${proc.stderr ?? ""}`;
401
- const allErrors = out.split(`
402
- `).filter((line) => /error TS\d+/.test(line));
403
- const ticketErrors = allErrors.filter((line) => line.includes(ticketDir));
404
- return {
405
- ok: false,
406
- errors: ticketErrors.length > 0 ? ticketErrors : allErrors
407
- };
408
- }
409
371
  // src/generator/lint.ts
410
- import { existsSync as existsSync3, readFileSync as readFileSync3, readdirSync } from "fs";
411
- import { join as join6 } from "path";
372
+ import { existsSync as existsSync2, readdirSync, readFileSync as readFileSync3 } from "fs";
373
+ import { join as join5 } from "path";
412
374
 
413
375
  // src/generator/selector-rules.ts
414
376
  var AUTO_CLASS_RE = /\.(?:Mui|css|ant|chakra|MuiButton)[A-Za-z]*-[A-Za-z0-9_]*-[A-Za-z0-9_]{3,}/;
@@ -456,11 +418,11 @@ function lintSelectors(source) {
456
418
 
457
419
  // src/generator/lint.ts
458
420
  function listTsFiles(dir) {
459
- if (!existsSync3(dir))
421
+ if (!existsSync2(dir))
460
422
  return [];
461
423
  const out = [];
462
424
  for (const name of readdirSync(dir, { withFileTypes: true })) {
463
- const full = join6(dir, name.name);
425
+ const full = join5(dir, name.name);
464
426
  if (name.isDirectory())
465
427
  out.push(...listTsFiles(full));
466
428
  else if (name.name.endsWith(".ts"))
@@ -480,18 +442,18 @@ async function lintTicket(ticketDir) {
480
442
  return { ok: warnings.length === 0, warnings };
481
443
  }
482
444
  // src/generator/pom-scan.ts
483
- import { existsSync as existsSync4, readFileSync as readFileSync4, readdirSync as readdirSync2 } from "fs";
484
- import { join as join7 } from "path";
445
+ import { existsSync as existsSync3, readdirSync as readdirSync2, readFileSync as readFileSync4 } from "fs";
446
+ import { join as join6 } from "path";
485
447
  var CLASS_RE = /export\s+class\s+([A-Z][A-Za-z0-9_]*)/g;
486
448
  function scanSharedPoms(repoRoot) {
487
- const dir = join7(repoRoot, "shared", "page-objects");
488
- if (!existsSync4(dir))
449
+ const dir = join6(repoRoot, "shared", "page-objects");
450
+ if (!existsSync3(dir))
489
451
  return [];
490
452
  const found = [];
491
453
  for (const entry of readdirSync2(dir, { withFileTypes: true })) {
492
454
  if (!entry.isFile() || !entry.name.endsWith(".ts"))
493
455
  continue;
494
- const path = join7(dir, entry.name);
456
+ const path = join6(dir, entry.name);
495
457
  const src = readFileSync4(path, "utf8");
496
458
  for (const m of src.matchAll(CLASS_RE)) {
497
459
  found.push({ className: m[1], absolutePath: path });
@@ -500,28 +462,66 @@ function scanSharedPoms(repoRoot) {
500
462
  return found;
501
463
  }
502
464
  // src/generator/promote.ts
503
- import { existsSync as existsSync5, readFileSync as readFileSync5, renameSync, writeFileSync as writeFileSync3 } from "fs";
504
- import { join as join8 } from "path";
465
+ import { existsSync as existsSync4, readFileSync as readFileSync5, renameSync, writeFileSync as writeFileSync3 } from "fs";
466
+ import { join as join7 } from "path";
505
467
  async function promotePom(input) {
506
- const fromDir = join8(input.repoRoot, ".xera", input.ticket, "page-objects");
507
- const toDir = join8(input.repoRoot, "shared", "page-objects");
468
+ const fromDir = join7(input.repoRoot, ".xera", input.ticket, "page-objects");
469
+ const toDir = join7(input.repoRoot, "shared", "page-objects");
508
470
  const file = `${input.className}.ts`;
509
- const fromPath = join8(fromDir, file);
510
- const toPath = join8(toDir, file);
511
- if (!existsSync5(fromPath)) {
471
+ const fromPath = join7(fromDir, file);
472
+ const toPath = join7(toDir, file);
473
+ if (!existsSync4(fromPath)) {
512
474
  throw new Error(`POM ${file} not found at ${fromPath}`);
513
475
  }
514
- if (existsSync5(toPath)) {
476
+ if (existsSync4(toPath)) {
515
477
  throw new Error(`POM ${file} already exists at ${toPath}. Reconcile manually before promoting.`);
516
478
  }
517
479
  renameSync(fromPath, toPath);
518
- const specPath = join8(input.repoRoot, ".xera", input.ticket, "spec.ts");
519
- if (existsSync5(specPath)) {
480
+ const specPath = join7(input.repoRoot, ".xera", input.ticket, "spec.ts");
481
+ if (existsSync4(specPath)) {
520
482
  const src = readFileSync5(specPath, "utf8");
521
483
  const updated = src.replace(new RegExp(`from\\s+['"]\\./page-objects/${input.className}['"]`, "g"), `from '../../shared/page-objects/${input.className}'`);
522
484
  writeFileSync3(specPath, updated);
523
485
  }
524
486
  }
487
+ // src/generator/typecheck.ts
488
+ import { spawnSync } from "child_process";
489
+ import { existsSync as existsSync5 } from "fs";
490
+ import { dirname, join as join8 } from "path";
491
+ function findNearestTsconfig(start) {
492
+ let dir = start;
493
+ while (true) {
494
+ const candidate = join8(dir, "tsconfig.json");
495
+ if (existsSync5(candidate))
496
+ return candidate;
497
+ const parent = dirname(dir);
498
+ if (parent === dir)
499
+ return null;
500
+ dir = parent;
501
+ }
502
+ }
503
+ async function typecheckTicket(ticketDir) {
504
+ const tsconfig = findNearestTsconfig(ticketDir);
505
+ if (!tsconfig) {
506
+ return {
507
+ ok: false,
508
+ errors: [
509
+ `No tsconfig.json found walking up from ${ticketDir}. Run \`xera init\` to scaffold one at the project root.`
510
+ ]
511
+ };
512
+ }
513
+ const proc = spawnSync("npx", ["tsc", "--noEmit", "-p", tsconfig], { encoding: "utf8" });
514
+ if (proc.status === 0)
515
+ return { ok: true, errors: [] };
516
+ const out = `${proc.stdout ?? ""}${proc.stderr ?? ""}`;
517
+ const allErrors = out.split(`
518
+ `).filter((line) => /error TS\d+/.test(line));
519
+ const ticketErrors = allErrors.filter((line) => line.includes(ticketDir));
520
+ return {
521
+ ok: false,
522
+ errors: ticketErrors.length > 0 ? ticketErrors : allErrors
523
+ };
524
+ }
525
525
  export {
526
526
  validateGherkin,
527
527
  unzipTrace,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xera-ai/web",
3
- "version": "0.1.7",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -11,16 +11,19 @@
11
11
  "types": "./dist/index.d.ts"
12
12
  }
13
13
  },
14
- "files": ["dist", "src"],
14
+ "files": [
15
+ "dist",
16
+ "src"
17
+ ],
15
18
  "scripts": {
16
19
  "build": "bun build ./src/index.ts --outdir ./dist --target bun --external @playwright/test --external @xera-ai/core --external @cucumber/gherkin --external @cucumber/messages --external fflate",
17
20
  "typecheck": "tsc --noEmit"
18
21
  },
19
22
  "dependencies": {
20
- "@cucumber/gherkin": "30.0.4",
21
- "@cucumber/messages": "27.0.2",
22
- "@playwright/test": "1.48.0",
23
- "@xera-ai/core": "^0.1.5",
24
- "fflate": "0.8.2"
23
+ "@cucumber/gherkin": "39.1.0",
24
+ "@cucumber/messages": "32.3.1",
25
+ "@playwright/test": "1.60.0",
26
+ "@xera-ai/core": "^0.4.0",
27
+ "fflate": "0.8.3"
25
28
  }
26
29
  }
@@ -1,6 +1,6 @@
1
- import { existsSync, readFileSync, readdirSync } from 'node:fs';
1
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
- import { type SelectorWarning, lintSelectors } from './selector-rules';
3
+ import { lintSelectors, type SelectorWarning } from './selector-rules';
4
4
 
5
5
  export interface LintResult {
6
6
  ok: boolean;
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync, readdirSync } from 'node:fs';
1
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
 
4
4
  const CLASS_RE = /export\s+class\s+([A-Z][A-Za-z0-9_]*)/g;
package/src/index.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  export * from './adapter';
2
2
  export * from './auth-setup/define';
3
- export * from './auth-setup/runner';
4
3
  export * from './auth-setup/playwright-state';
4
+ export * from './auth-setup/runner';
5
5
  export * from './executor';
6
6
  export * from './executor/playwright-args';
7
+ export * from './generator/gherkin-validate';
8
+ export * from './generator/lint';
9
+ export * from './generator/pom-scan';
10
+ export * from './generator/promote';
11
+ export * from './generator/selector-rules';
12
+ export * from './generator/typecheck';
7
13
  export * from './trace-normalizer/normalize';
8
14
  export * from './trace-normalizer/parse';
9
15
  export * from './trace-normalizer/scrub';
10
16
  export * from './trace-normalizer/scrub-rules';
11
17
  export * from './trace-normalizer/unzip';
12
- export * from './generator/gherkin-validate';
13
- export * from './generator/typecheck';
14
- export * from './generator/lint';
15
- export * from './generator/selector-rules';
16
- export * from './generator/pom-scan';
17
- export * from './generator/promote';
@@ -1,69 +0,0 @@
1
- import type { Classification } from '../artifact/status';
2
- import type { XeraConfig } from '../config/schema';
3
- export interface GenerateInput {
4
- ticketDir: string;
5
- feature: string;
6
- story: string;
7
- config: XeraConfig;
8
- }
9
- export interface GenerateResult {
10
- artifacts: string[];
11
- warnings: string[];
12
- }
13
- export interface ExecuteInput {
14
- ticketDir: string;
15
- config: XeraConfig;
16
- runId: string;
17
- env: string;
18
- }
19
- export interface ScenarioResult {
20
- name: string;
21
- outcome: 'PASS' | 'FAIL' | 'SKIPPED';
22
- failure?: {
23
- step?: string;
24
- errorMessage?: string;
25
- domSnapshotAtFailure?: string;
26
- networkAtFailure?: Array<{
27
- method: string;
28
- url: string;
29
- status: number;
30
- }>;
31
- consoleAtFailure?: string[];
32
- screenshotPath?: string;
33
- };
34
- }
35
- export interface RunResult {
36
- runId: string;
37
- outcome: 'PASS' | 'FAIL';
38
- scenarios: ScenarioResult[];
39
- artifactsDir: string;
40
- rawReportPath: string;
41
- normalizedReportPath: string;
42
- }
43
- export interface ClassifyContext {
44
- history: Array<{
45
- ts: string;
46
- result: 'PASS' | 'FAIL';
47
- class: Classification;
48
- }>;
49
- storyHashChanged: boolean;
50
- specHashChanged: boolean;
51
- }
52
- export interface DoctorReport {
53
- ok: boolean;
54
- checks: Array<{
55
- name: string;
56
- ok: boolean;
57
- message?: string;
58
- }>;
59
- }
60
- export interface TestAdapter {
61
- readonly id: string;
62
- generate(input: GenerateInput): Promise<GenerateResult>;
63
- execute(input: ExecuteInput): Promise<RunResult>;
64
- classify?(run: RunResult, ctx: ClassifyContext): Partial<{
65
- class: Classification;
66
- rationale: string;
67
- }>;
68
- doctor(): Promise<DoctorReport>;
69
- }
@@ -1,3 +0,0 @@
1
- export declare function hashString(s: string): string;
2
- export declare function hashFile(path: string): string;
3
- export declare function hashFileIfExists(path: string): string | null;
@@ -1,45 +0,0 @@
1
- import { z } from 'zod';
2
- export declare const MetaJsonSchema: z.ZodObject<{
3
- ticket: z.ZodString;
4
- adapter: z.ZodString;
5
- xera_version: z.ZodString;
6
- prompts_version: z.ZodString;
7
- fetched_at: z.ZodOptional<z.ZodString>;
8
- story_hash: z.ZodOptional<z.ZodString>;
9
- feature_generated_at: z.ZodOptional<z.ZodString>;
10
- feature_generated_from_story_hash: z.ZodOptional<z.ZodString>;
11
- feature_hash: z.ZodOptional<z.ZodString>;
12
- script_generated_at: z.ZodOptional<z.ZodString>;
13
- script_generated_from_feature_hash: z.ZodOptional<z.ZodString>;
14
- script_warnings: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
15
- }, "strip", z.ZodTypeAny, {
16
- ticket: string;
17
- adapter: string;
18
- xera_version: string;
19
- prompts_version: string;
20
- fetched_at?: string | undefined;
21
- story_hash?: string | undefined;
22
- feature_generated_at?: string | undefined;
23
- feature_generated_from_story_hash?: string | undefined;
24
- feature_hash?: string | undefined;
25
- script_generated_at?: string | undefined;
26
- script_generated_from_feature_hash?: string | undefined;
27
- script_warnings?: string[] | undefined;
28
- }, {
29
- ticket: string;
30
- adapter: string;
31
- xera_version: string;
32
- prompts_version: string;
33
- fetched_at?: string | undefined;
34
- story_hash?: string | undefined;
35
- feature_generated_at?: string | undefined;
36
- feature_generated_from_story_hash?: string | undefined;
37
- feature_hash?: string | undefined;
38
- script_generated_at?: string | undefined;
39
- script_generated_from_feature_hash?: string | undefined;
40
- script_warnings?: string[] | undefined;
41
- }>;
42
- export type MetaJson = z.infer<typeof MetaJsonSchema>;
43
- export declare function readMeta(path: string): MetaJson | null;
44
- export declare function writeMeta(path: string, meta: MetaJson): void;
45
- export declare function updateMeta(path: string, patch: Partial<MetaJson>): MetaJson;
@@ -1,24 +0,0 @@
1
- export interface RunPaths {
2
- runDir: string;
3
- reportJsonPath: string;
4
- tracePath: string;
5
- normalizedPath: string;
6
- screenshotsDir: string;
7
- videoDir: string;
8
- }
9
- export interface ArtifactPaths {
10
- ticketDir: string;
11
- storyPath: string;
12
- featurePath: string;
13
- specPath: string;
14
- pageObjectsDir: string;
15
- runsDir: string;
16
- metaPath: string;
17
- statusPath: string;
18
- logPath: string;
19
- lockPath: string;
20
- authDir: string;
21
- runPath: (runId: string) => RunPaths;
22
- }
23
- export declare function resolveArtifactPaths(repoRoot: string, ticket: string): ArtifactPaths;
24
- export declare function generateRunId(now?: Date): string;
@@ -1,95 +0,0 @@
1
- import { z } from 'zod';
2
- declare const ClassificationEnum: z.ZodEnum<["PASS", "REAL_BUG", "SELECTOR_DRIFT", "FLAKY", "TEST_BUG"]>;
3
- export declare const HistoryEntrySchema: z.ZodObject<{
4
- ts: z.ZodString;
5
- result: z.ZodEnum<["PASS", "FAIL"]>;
6
- class: z.ZodEnum<["PASS", "REAL_BUG", "SELECTOR_DRIFT", "FLAKY", "TEST_BUG"]>;
7
- }, "strip", z.ZodTypeAny, {
8
- ts: string;
9
- result: "PASS" | "FAIL";
10
- class: "PASS" | "REAL_BUG" | "SELECTOR_DRIFT" | "FLAKY" | "TEST_BUG";
11
- }, {
12
- ts: string;
13
- result: "PASS" | "FAIL";
14
- class: "PASS" | "REAL_BUG" | "SELECTOR_DRIFT" | "FLAKY" | "TEST_BUG";
15
- }>;
16
- export declare const StatusJsonSchema: z.ZodObject<{
17
- ticket: z.ZodString;
18
- lastRun: z.ZodString;
19
- result: z.ZodEnum<["PASS", "FAIL"]>;
20
- classification: z.ZodEnum<["PASS", "REAL_BUG", "SELECTOR_DRIFT", "FLAKY", "TEST_BUG"]>;
21
- confidence: z.ZodEnum<["low", "medium", "high"]>;
22
- scenarios: z.ZodObject<{
23
- total: z.ZodNumber;
24
- passed: z.ZodNumber;
25
- failed: z.ZodNumber;
26
- skipped: z.ZodNumber;
27
- }, "strip", z.ZodTypeAny, {
28
- total: number;
29
- passed: number;
30
- failed: number;
31
- skipped: number;
32
- }, {
33
- total: number;
34
- passed: number;
35
- failed: number;
36
- skipped: number;
37
- }>;
38
- history: z.ZodDefault<z.ZodArray<z.ZodObject<{
39
- ts: z.ZodString;
40
- result: z.ZodEnum<["PASS", "FAIL"]>;
41
- class: z.ZodEnum<["PASS", "REAL_BUG", "SELECTOR_DRIFT", "FLAKY", "TEST_BUG"]>;
42
- }, "strip", z.ZodTypeAny, {
43
- ts: string;
44
- result: "PASS" | "FAIL";
45
- class: "PASS" | "REAL_BUG" | "SELECTOR_DRIFT" | "FLAKY" | "TEST_BUG";
46
- }, {
47
- ts: string;
48
- result: "PASS" | "FAIL";
49
- class: "PASS" | "REAL_BUG" | "SELECTOR_DRIFT" | "FLAKY" | "TEST_BUG";
50
- }>, "many">>;
51
- last_jira_comment_id: z.ZodOptional<z.ZodString>;
52
- }, "strip", z.ZodTypeAny, {
53
- result: "PASS" | "FAIL";
54
- ticket: string;
55
- lastRun: string;
56
- classification: "PASS" | "REAL_BUG" | "SELECTOR_DRIFT" | "FLAKY" | "TEST_BUG";
57
- confidence: "low" | "medium" | "high";
58
- scenarios: {
59
- total: number;
60
- passed: number;
61
- failed: number;
62
- skipped: number;
63
- };
64
- history: {
65
- ts: string;
66
- result: "PASS" | "FAIL";
67
- class: "PASS" | "REAL_BUG" | "SELECTOR_DRIFT" | "FLAKY" | "TEST_BUG";
68
- }[];
69
- last_jira_comment_id?: string | undefined;
70
- }, {
71
- result: "PASS" | "FAIL";
72
- ticket: string;
73
- lastRun: string;
74
- classification: "PASS" | "REAL_BUG" | "SELECTOR_DRIFT" | "FLAKY" | "TEST_BUG";
75
- confidence: "low" | "medium" | "high";
76
- scenarios: {
77
- total: number;
78
- passed: number;
79
- failed: number;
80
- skipped: number;
81
- };
82
- history?: {
83
- ts: string;
84
- result: "PASS" | "FAIL";
85
- class: "PASS" | "REAL_BUG" | "SELECTOR_DRIFT" | "FLAKY" | "TEST_BUG";
86
- }[] | undefined;
87
- last_jira_comment_id?: string | undefined;
88
- }>;
89
- export type StatusJson = z.infer<typeof StatusJsonSchema>;
90
- export type HistoryEntry = z.infer<typeof HistoryEntrySchema>;
91
- export type Classification = z.infer<typeof ClassificationEnum>;
92
- export declare function readStatus(path: string): StatusJson | null;
93
- export declare function writeStatus(path: string, status: StatusJson): void;
94
- export declare function appendHistory(path: string, entry: HistoryEntry): StatusJson;
95
- export {};
@@ -1,3 +0,0 @@
1
- export declare function generateKey(): string;
2
- export declare function encrypt(plaintext: string, keyHex: string): string;
3
- export declare function decrypt(ciphertext: string, keyHex: string): string;
@@ -1,2 +0,0 @@
1
- export declare const AUTH_KEY_ENV = "XERA_AUTH_KEY";
2
- export declare function resolveAuthKey(): string;
@@ -1,8 +0,0 @@
1
- import type { AuthStateEntry } from './state';
2
- export type { AuthStateEntry } from './state';
3
- export declare function parseDuration(d: string): number;
4
- export interface RefreshPolicy {
5
- ttl: string;
6
- refreshBuffer: string;
7
- }
8
- export declare function needsRefresh(entry: AuthStateEntry | null, policy: RefreshPolicy, now?: Date): boolean;
@@ -1,23 +0,0 @@
1
- import { z } from 'zod';
2
- export declare const AuthStateEntrySchema: z.ZodObject<{
3
- role: z.ZodString;
4
- strategy: z.ZodEnum<["storageState", "apiToken"]>;
5
- created_at: z.ZodString;
6
- expires_at: z.ZodString;
7
- payload: z.ZodRecord<z.ZodString, z.ZodUnknown>;
8
- }, "strip", z.ZodTypeAny, {
9
- strategy: "storageState" | "apiToken";
10
- role: string;
11
- created_at: string;
12
- expires_at: string;
13
- payload: Record<string, unknown>;
14
- }, {
15
- strategy: "storageState" | "apiToken";
16
- role: string;
17
- created_at: string;
18
- expires_at: string;
19
- payload: Record<string, unknown>;
20
- }>;
21
- export type AuthStateEntry = z.infer<typeof AuthStateEntrySchema>;
22
- export declare function writeAuthState(authDir: string, entry: AuthStateEntry): void;
23
- export declare function readAuthState(authDir: string, role: string): AuthStateEntry | null;
@@ -1,2 +0,0 @@
1
- import type { XeraConfig } from './schema';
2
- export declare function defineConfig(config: XeraConfig): XeraConfig;
@@ -1,2 +0,0 @@
1
- import { type XeraConfig } from './schema';
2
- export declare function loadConfig(cwd: string): Promise<XeraConfig>;
@@ -1,325 +0,0 @@
1
- import { z } from 'zod';
2
- export declare const XeraConfigSchema: z.ZodObject<{
3
- jira: z.ZodObject<{
4
- baseUrl: z.ZodString;
5
- projectKeys: z.ZodArray<z.ZodString, "many">;
6
- fields: z.ZodObject<{
7
- story: z.ZodString;
8
- acceptanceCriteria: z.ZodOptional<z.ZodString>;
9
- attachments: z.ZodDefault<z.ZodString>;
10
- }, "strip", z.ZodTypeAny, {
11
- story: string;
12
- attachments: string;
13
- acceptanceCriteria?: string | undefined;
14
- }, {
15
- story: string;
16
- acceptanceCriteria?: string | undefined;
17
- attachments?: string | undefined;
18
- }>;
19
- }, "strip", z.ZodTypeAny, {
20
- baseUrl: string;
21
- projectKeys: string[];
22
- fields: {
23
- story: string;
24
- attachments: string;
25
- acceptanceCriteria?: string | undefined;
26
- };
27
- }, {
28
- baseUrl: string;
29
- projectKeys: string[];
30
- fields: {
31
- story: string;
32
- acceptanceCriteria?: string | undefined;
33
- attachments?: string | undefined;
34
- };
35
- }>;
36
- web: z.ZodEffects<z.ZodObject<{
37
- baseUrl: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodString>, Record<string, string>, Record<string, string>>;
38
- defaultEnv: z.ZodString;
39
- auth: z.ZodDefault<z.ZodObject<{
40
- strategy: z.ZodDefault<z.ZodEnum<["storageState", "apiToken", "none"]>>;
41
- ttl: z.ZodDefault<z.ZodString>;
42
- refreshBuffer: z.ZodDefault<z.ZodString>;
43
- setupScript: z.ZodOptional<z.ZodString>;
44
- roles: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
45
- envEmail: z.ZodString;
46
- envPassword: z.ZodString;
47
- }, "strip", z.ZodTypeAny, {
48
- envEmail: string;
49
- envPassword: string;
50
- }, {
51
- envEmail: string;
52
- envPassword: string;
53
- }>>>;
54
- }, "strip", z.ZodTypeAny, {
55
- strategy: "storageState" | "apiToken" | "none";
56
- ttl: string;
57
- refreshBuffer: string;
58
- roles: Record<string, {
59
- envEmail: string;
60
- envPassword: string;
61
- }>;
62
- setupScript?: string | undefined;
63
- }, {
64
- strategy?: "storageState" | "apiToken" | "none" | undefined;
65
- ttl?: string | undefined;
66
- refreshBuffer?: string | undefined;
67
- setupScript?: string | undefined;
68
- roles?: Record<string, {
69
- envEmail: string;
70
- envPassword: string;
71
- }> | undefined;
72
- }>>;
73
- testData: z.ZodDefault<z.ZodObject<{
74
- users: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
75
- fromAuth: z.ZodString;
76
- }, "strip", z.ZodTypeAny, {
77
- fromAuth: string;
78
- }, {
79
- fromAuth: string;
80
- }>>>;
81
- }, "strip", z.ZodTypeAny, {
82
- users: Record<string, {
83
- fromAuth: string;
84
- }>;
85
- }, {
86
- users?: Record<string, {
87
- fromAuth: string;
88
- }> | undefined;
89
- }>>;
90
- }, "strip", z.ZodTypeAny, {
91
- baseUrl: Record<string, string>;
92
- defaultEnv: string;
93
- auth: {
94
- strategy: "storageState" | "apiToken" | "none";
95
- ttl: string;
96
- refreshBuffer: string;
97
- roles: Record<string, {
98
- envEmail: string;
99
- envPassword: string;
100
- }>;
101
- setupScript?: string | undefined;
102
- };
103
- testData: {
104
- users: Record<string, {
105
- fromAuth: string;
106
- }>;
107
- };
108
- }, {
109
- baseUrl: Record<string, string>;
110
- defaultEnv: string;
111
- auth?: {
112
- strategy?: "storageState" | "apiToken" | "none" | undefined;
113
- ttl?: string | undefined;
114
- refreshBuffer?: string | undefined;
115
- setupScript?: string | undefined;
116
- roles?: Record<string, {
117
- envEmail: string;
118
- envPassword: string;
119
- }> | undefined;
120
- } | undefined;
121
- testData?: {
122
- users?: Record<string, {
123
- fromAuth: string;
124
- }> | undefined;
125
- } | undefined;
126
- }>, {
127
- baseUrl: Record<string, string>;
128
- defaultEnv: string;
129
- auth: {
130
- strategy: "storageState" | "apiToken" | "none";
131
- ttl: string;
132
- refreshBuffer: string;
133
- roles: Record<string, {
134
- envEmail: string;
135
- envPassword: string;
136
- }>;
137
- setupScript?: string | undefined;
138
- };
139
- testData: {
140
- users: Record<string, {
141
- fromAuth: string;
142
- }>;
143
- };
144
- }, {
145
- baseUrl: Record<string, string>;
146
- defaultEnv: string;
147
- auth?: {
148
- strategy?: "storageState" | "apiToken" | "none" | undefined;
149
- ttl?: string | undefined;
150
- refreshBuffer?: string | undefined;
151
- setupScript?: string | undefined;
152
- roles?: Record<string, {
153
- envEmail: string;
154
- envPassword: string;
155
- }> | undefined;
156
- } | undefined;
157
- testData?: {
158
- users?: Record<string, {
159
- fromAuth: string;
160
- }> | undefined;
161
- } | undefined;
162
- }>;
163
- ai: z.ZodDefault<z.ZodObject<{
164
- livePageSnapshot: z.ZodDefault<z.ZodBoolean>;
165
- confidenceThreshold: z.ZodDefault<z.ZodEnum<["low", "medium", "high"]>>;
166
- maxRetries: z.ZodDefault<z.ZodObject<{
167
- typecheck: z.ZodDefault<z.ZodNumber>;
168
- lint: z.ZodDefault<z.ZodNumber>;
169
- validateFeature: z.ZodDefault<z.ZodNumber>;
170
- }, "strip", z.ZodTypeAny, {
171
- typecheck: number;
172
- lint: number;
173
- validateFeature: number;
174
- }, {
175
- typecheck?: number | undefined;
176
- lint?: number | undefined;
177
- validateFeature?: number | undefined;
178
- }>>;
179
- }, "strip", z.ZodTypeAny, {
180
- livePageSnapshot: boolean;
181
- confidenceThreshold: "low" | "medium" | "high";
182
- maxRetries: {
183
- typecheck: number;
184
- lint: number;
185
- validateFeature: number;
186
- };
187
- }, {
188
- livePageSnapshot?: boolean | undefined;
189
- confidenceThreshold?: "low" | "medium" | "high" | undefined;
190
- maxRetries?: {
191
- typecheck?: number | undefined;
192
- lint?: number | undefined;
193
- validateFeature?: number | undefined;
194
- } | undefined;
195
- }>>;
196
- reporting: z.ZodDefault<z.ZodObject<{
197
- language: z.ZodDefault<z.ZodEnum<["en", "vi"]>>;
198
- postToJira: z.ZodDefault<z.ZodBoolean>;
199
- transition: z.ZodDefault<z.ZodObject<{
200
- onPass: z.ZodDefault<z.ZodNullable<z.ZodString>>;
201
- onFail: z.ZodDefault<z.ZodNullable<z.ZodString>>;
202
- }, "strip", z.ZodTypeAny, {
203
- onPass: string | null;
204
- onFail: string | null;
205
- }, {
206
- onPass?: string | null | undefined;
207
- onFail?: string | null | undefined;
208
- }>>;
209
- artifactLinks: z.ZodDefault<z.ZodEnum<["git", "local"]>>;
210
- }, "strip", z.ZodTypeAny, {
211
- language: "en" | "vi";
212
- postToJira: boolean;
213
- transition: {
214
- onPass: string | null;
215
- onFail: string | null;
216
- };
217
- artifactLinks: "git" | "local";
218
- }, {
219
- language?: "en" | "vi" | undefined;
220
- postToJira?: boolean | undefined;
221
- transition?: {
222
- onPass?: string | null | undefined;
223
- onFail?: string | null | undefined;
224
- } | undefined;
225
- artifactLinks?: "git" | "local" | undefined;
226
- }>>;
227
- adapters: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
228
- }, "strip", z.ZodTypeAny, {
229
- jira: {
230
- baseUrl: string;
231
- projectKeys: string[];
232
- fields: {
233
- story: string;
234
- attachments: string;
235
- acceptanceCriteria?: string | undefined;
236
- };
237
- };
238
- web: {
239
- baseUrl: Record<string, string>;
240
- defaultEnv: string;
241
- auth: {
242
- strategy: "storageState" | "apiToken" | "none";
243
- ttl: string;
244
- refreshBuffer: string;
245
- roles: Record<string, {
246
- envEmail: string;
247
- envPassword: string;
248
- }>;
249
- setupScript?: string | undefined;
250
- };
251
- testData: {
252
- users: Record<string, {
253
- fromAuth: string;
254
- }>;
255
- };
256
- };
257
- ai: {
258
- livePageSnapshot: boolean;
259
- confidenceThreshold: "low" | "medium" | "high";
260
- maxRetries: {
261
- typecheck: number;
262
- lint: number;
263
- validateFeature: number;
264
- };
265
- };
266
- reporting: {
267
- language: "en" | "vi";
268
- postToJira: boolean;
269
- transition: {
270
- onPass: string | null;
271
- onFail: string | null;
272
- };
273
- artifactLinks: "git" | "local";
274
- };
275
- adapters: string[];
276
- }, {
277
- jira: {
278
- baseUrl: string;
279
- projectKeys: string[];
280
- fields: {
281
- story: string;
282
- acceptanceCriteria?: string | undefined;
283
- attachments?: string | undefined;
284
- };
285
- };
286
- web: {
287
- baseUrl: Record<string, string>;
288
- defaultEnv: string;
289
- auth?: {
290
- strategy?: "storageState" | "apiToken" | "none" | undefined;
291
- ttl?: string | undefined;
292
- refreshBuffer?: string | undefined;
293
- setupScript?: string | undefined;
294
- roles?: Record<string, {
295
- envEmail: string;
296
- envPassword: string;
297
- }> | undefined;
298
- } | undefined;
299
- testData?: {
300
- users?: Record<string, {
301
- fromAuth: string;
302
- }> | undefined;
303
- } | undefined;
304
- };
305
- ai?: {
306
- livePageSnapshot?: boolean | undefined;
307
- confidenceThreshold?: "low" | "medium" | "high" | undefined;
308
- maxRetries?: {
309
- typecheck?: number | undefined;
310
- lint?: number | undefined;
311
- validateFeature?: number | undefined;
312
- } | undefined;
313
- } | undefined;
314
- reporting?: {
315
- language?: "en" | "vi" | undefined;
316
- postToJira?: boolean | undefined;
317
- transition?: {
318
- onPass?: string | null | undefined;
319
- onFail?: string | null | undefined;
320
- } | undefined;
321
- artifactLinks?: "git" | "local" | undefined;
322
- } | undefined;
323
- adapters?: string[] | undefined;
324
- }>;
325
- export type XeraConfig = z.infer<typeof XeraConfigSchema>;
@@ -1,19 +0,0 @@
1
- export declare const VERSION = "0.1.0";
2
- export type * from './adapter/types';
3
- export * from './config/schema';
4
- export * from './config/define';
5
- export * from './config/load';
6
- export * from './artifact/paths';
7
- export * from './artifact/hash';
8
- export * from './artifact/meta';
9
- export * from './artifact/status';
10
- export * from './logging/ndjson-logger';
11
- export * from './lock/file-lock';
12
- export * from './jira/types';
13
- export * from './jira/client';
14
- export * from './jira/fields';
15
- export * from './jira/retry';
16
- export * from './auth/encrypt';
17
- export * from './auth/key';
18
- export * from './auth/state';
19
- export * from './auth/refresh';
@@ -1,10 +0,0 @@
1
- import type { JiraClient } from './types';
2
- export interface CreateJiraClientOptions {
3
- baseUrl: string;
4
- preferMcp?: boolean;
5
- rest?: {
6
- email: string;
7
- apiToken: string;
8
- };
9
- }
10
- export declare function createJiraClient(opts: CreateJiraClientOptions): Promise<JiraClient>;
@@ -1,6 +0,0 @@
1
- export interface JiraFieldInfo {
2
- id: string;
3
- name: string;
4
- hasContent: boolean;
5
- }
6
- export declare function rankStoryCandidates(fields: JiraFieldInfo[]): JiraFieldInfo[];
@@ -1,2 +0,0 @@
1
- import type { JiraClient } from './types';
2
- export declare function createMcpBackend(_baseUrl: string): Promise<JiraClient | null>;
@@ -1,7 +0,0 @@
1
- import type { JiraClient } from './types';
2
- interface RestCreds {
3
- email: string;
4
- apiToken: string;
5
- }
6
- export declare function createRestBackend(baseUrl: string, creds: RestCreds): JiraClient;
7
- export {};
@@ -1,7 +0,0 @@
1
- export interface RetryOptions {
2
- maxAttempts: number;
3
- baseMs: number;
4
- factor: number;
5
- shouldRetry?: (err: unknown) => boolean;
6
- }
7
- export declare function withRetry<T>(fn: () => Promise<T>, opts: RetryOptions): Promise<T>;
@@ -1,28 +0,0 @@
1
- export interface JiraTicket {
2
- key: string;
3
- summary: string;
4
- story: string;
5
- acceptanceCriteria?: string;
6
- attachments: Array<{
7
- filename: string;
8
- url: string;
9
- }>;
10
- raw: Record<string, unknown>;
11
- }
12
- export interface JiraFieldMap {
13
- story: string;
14
- acceptanceCriteria?: string;
15
- }
16
- export interface JiraClient {
17
- readonly backend: 'mcp' | 'rest';
18
- fetchTicket(key: string, fields: JiraFieldMap): Promise<JiraTicket>;
19
- postComment(key: string, body: string): Promise<{
20
- id: string;
21
- }>;
22
- transitionStatus(key: string, statusName: string): Promise<void>;
23
- listFields(sampleKey: string): Promise<Array<{
24
- id: string;
25
- name: string;
26
- hasContent: boolean;
27
- }>>;
28
- }
@@ -1,11 +0,0 @@
1
- export interface LockData {
2
- pid: number;
3
- hostname: string;
4
- started_at: string;
5
- run_id: string;
6
- }
7
- export declare function acquireLock(path: string, runId: string): boolean;
8
- export declare function releaseLock(path: string): void;
9
- export declare function readLock(path: string): LockData | null;
10
- export declare function isLockStale(path: string): boolean;
11
- export declare function forceUnlock(path: string): void;
@@ -1,10 +0,0 @@
1
- export interface LogEntry {
2
- ts: string;
3
- [key: string]: unknown;
4
- }
5
- export declare class NdjsonLogger {
6
- private readonly path;
7
- constructor(path: string);
8
- log(payload: Record<string, unknown>): void;
9
- static readAll(path: string): LogEntry[];
10
- }
File without changes
File without changes
File without changes
@@ -1,17 +1,17 @@
1
1
  export * from './adapter';
2
2
  export * from './auth-setup/define';
3
- export * from './auth-setup/runner';
4
3
  export * from './auth-setup/playwright-state';
4
+ export * from './auth-setup/runner';
5
5
  export * from './executor';
6
6
  export * from './executor/playwright-args';
7
+ export * from './generator/gherkin-validate';
8
+ export * from './generator/lint';
9
+ export * from './generator/pom-scan';
10
+ export * from './generator/promote';
11
+ export * from './generator/selector-rules';
12
+ export * from './generator/typecheck';
7
13
  export * from './trace-normalizer/normalize';
8
14
  export * from './trace-normalizer/parse';
9
15
  export * from './trace-normalizer/scrub';
10
16
  export * from './trace-normalizer/scrub-rules';
11
17
  export * from './trace-normalizer/unzip';
12
- export * from './generator/gherkin-validate';
13
- export * from './generator/typecheck';
14
- export * from './generator/lint';
15
- export * from './generator/selector-rules';
16
- export * from './generator/pom-scan';
17
- export * from './generator/promote';