@xera-ai/core 0.1.7 → 0.4.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 (131) hide show
  1. package/bin/internal.ts +1 -0
  2. package/dist/adapter/types.d.ts +1 -1
  3. package/dist/adapter/types.d.ts.map +1 -1
  4. package/dist/artifact/meta.d.ts +2 -28
  5. package/dist/artifact/meta.d.ts.map +1 -1
  6. package/dist/artifact/status.d.ts +49 -74
  7. package/dist/artifact/status.d.ts.map +1 -1
  8. package/dist/auth/key.d.ts.map +1 -1
  9. package/dist/auth/refresh.d.ts.map +1 -1
  10. package/dist/auth/state.d.ts +5 -14
  11. package/dist/auth/state.d.ts.map +1 -1
  12. package/dist/bin/internal.js +10037 -746
  13. package/dist/bin-internal/doctor.d.ts +5 -0
  14. package/dist/bin-internal/doctor.d.ts.map +1 -0
  15. package/dist/bin-internal/eval-deterministic.d.ts +5 -0
  16. package/dist/bin-internal/eval-deterministic.d.ts.map +1 -0
  17. package/dist/bin-internal/eval-prepare.d.ts +7 -0
  18. package/dist/bin-internal/eval-prepare.d.ts.map +1 -0
  19. package/dist/bin-internal/eval-report.d.ts +5 -0
  20. package/dist/bin-internal/eval-report.d.ts.map +1 -0
  21. package/dist/bin-internal/exec.d.ts.map +1 -1
  22. package/dist/bin-internal/fetch.d.ts.map +1 -1
  23. package/dist/bin-internal/graph-backfill.d.ts +2 -0
  24. package/dist/bin-internal/graph-backfill.d.ts.map +1 -0
  25. package/dist/bin-internal/graph-query.d.ts +2 -0
  26. package/dist/bin-internal/graph-query.d.ts.map +1 -0
  27. package/dist/bin-internal/graph-record-script.d.ts +2 -0
  28. package/dist/bin-internal/graph-record-script.d.ts.map +1 -0
  29. package/dist/bin-internal/graph-record.d.ts +3 -0
  30. package/dist/bin-internal/graph-record.d.ts.map +1 -0
  31. package/dist/bin-internal/graph-snapshot.d.ts +2 -0
  32. package/dist/bin-internal/graph-snapshot.d.ts.map +1 -0
  33. package/dist/bin-internal/heal-prepare.d.ts +19 -0
  34. package/dist/bin-internal/heal-prepare.d.ts.map +1 -0
  35. package/dist/bin-internal/index.d.ts.map +1 -1
  36. package/dist/bin-internal/lint.d.ts.map +1 -1
  37. package/dist/bin-internal/normalize.d.ts.map +1 -1
  38. package/dist/bin-internal/post.d.ts.map +1 -1
  39. package/dist/bin-internal/status-cmd.d.ts.map +1 -1
  40. package/dist/bin-internal/typecheck.d.ts.map +1 -1
  41. package/dist/bin-internal/unlock.d.ts.map +1 -1
  42. package/dist/bin-internal/validate-feature.d.ts.map +1 -1
  43. package/dist/bin-internal/verify-prompts.d.ts +7 -0
  44. package/dist/bin-internal/verify-prompts.d.ts.map +1 -0
  45. package/dist/classifier/aggregate.d.ts.map +1 -1
  46. package/dist/config/define.d.ts.map +1 -1
  47. package/dist/config/load.d.ts.map +1 -1
  48. package/dist/config/schema.d.ts +38 -298
  49. package/dist/config/schema.d.ts.map +1 -1
  50. package/dist/eval/paths.d.ts +15 -0
  51. package/dist/eval/paths.d.ts.map +1 -0
  52. package/dist/eval/run-id.d.ts +6 -0
  53. package/dist/eval/run-id.d.ts.map +1 -0
  54. package/dist/eval/types.d.ts +203 -0
  55. package/dist/eval/types.d.ts.map +1 -0
  56. package/dist/graph/cost.d.ts +21 -0
  57. package/dist/graph/cost.d.ts.map +1 -0
  58. package/dist/graph/index.d.ts +8 -0
  59. package/dist/graph/index.d.ts.map +1 -0
  60. package/dist/graph/paths.d.ts +10 -0
  61. package/dist/graph/paths.d.ts.map +1 -0
  62. package/dist/graph/schema.d.ts +177 -0
  63. package/dist/graph/schema.d.ts.map +1 -0
  64. package/dist/graph/store.d.ts +14 -0
  65. package/dist/graph/store.d.ts.map +1 -0
  66. package/dist/graph/types.d.ts +151 -0
  67. package/dist/graph/types.d.ts.map +1 -0
  68. package/dist/graph/ulid.d.ts +2 -0
  69. package/dist/graph/ulid.d.ts.map +1 -0
  70. package/dist/index.d.ts +11 -11
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/jira/client.d.ts.map +1 -1
  73. package/dist/jira/fields.d.ts.map +1 -1
  74. package/dist/jira/rest-backend.d.ts.map +1 -1
  75. package/dist/reporter/jira-comment.d.ts.map +1 -1
  76. package/dist/reporter/status-writer.d.ts.map +1 -1
  77. package/dist/src/index.js +349 -321
  78. package/package.json +19 -13
  79. package/src/adapter/types.ts +5 -2
  80. package/src/artifact/meta.ts +1 -1
  81. package/src/artifact/status.ts +1 -1
  82. package/src/auth/encrypt.ts +2 -2
  83. package/src/auth/key.ts +1 -2
  84. package/src/auth/refresh.ts +5 -1
  85. package/src/auth/state.ts +2 -2
  86. package/src/bin-internal/doctor.ts +169 -0
  87. package/src/bin-internal/eval-deterministic.ts +149 -0
  88. package/src/bin-internal/eval-prepare.ts +214 -0
  89. package/src/bin-internal/eval-report.ts +177 -0
  90. package/src/bin-internal/exec.ts +28 -15
  91. package/src/bin-internal/fetch.ts +21 -10
  92. package/src/bin-internal/graph-backfill.ts +43 -0
  93. package/src/bin-internal/graph-query.ts +43 -0
  94. package/src/bin-internal/graph-record-script.ts +191 -0
  95. package/src/bin-internal/graph-record.ts +243 -0
  96. package/src/bin-internal/graph-snapshot.ts +23 -0
  97. package/src/bin-internal/heal-prepare.ts +230 -0
  98. package/src/bin-internal/index.ts +33 -11
  99. package/src/bin-internal/lint.ts +11 -4
  100. package/src/bin-internal/normalize.ts +23 -9
  101. package/src/bin-internal/post.ts +10 -4
  102. package/src/bin-internal/report.ts +3 -3
  103. package/src/bin-internal/status-cmd.ts +11 -3
  104. package/src/bin-internal/typecheck.ts +9 -3
  105. package/src/bin-internal/unlock.ts +12 -4
  106. package/src/bin-internal/validate-feature.ts +14 -5
  107. package/src/bin-internal/verify-prompts.ts +60 -0
  108. package/src/classifier/aggregate.ts +13 -6
  109. package/src/config/define.ts +3 -1
  110. package/src/config/load.ts +1 -1
  111. package/src/config/schema.ts +43 -37
  112. package/src/eval/paths.ts +32 -0
  113. package/src/eval/run-id.ts +30 -0
  114. package/src/eval/types.ts +101 -0
  115. package/src/graph/cost.ts +59 -0
  116. package/src/graph/index.ts +15 -0
  117. package/src/graph/paths.ts +27 -0
  118. package/src/graph/schema.ts +135 -0
  119. package/src/graph/store.ts +231 -0
  120. package/src/graph/types.ts +174 -0
  121. package/src/graph/ulid.ts +58 -0
  122. package/src/index.ts +11 -11
  123. package/src/jira/client.ts +4 -2
  124. package/src/jira/fields.ts +4 -2
  125. package/src/jira/mcp-backend.ts +1 -1
  126. package/src/jira/rest-backend.ts +18 -6
  127. package/src/jira/retry.ts +2 -2
  128. package/src/lock/file-lock.ts +2 -2
  129. package/src/logging/ndjson-logger.ts +2 -2
  130. package/src/reporter/jira-comment.ts +13 -7
  131. package/src/reporter/status-writer.ts +2 -2
@@ -1,6 +1,9 @@
1
- import type { JiraClient, JiraFieldMap, JiraTicket } from './types';
1
+ import type { JiraClient, JiraTicket } from './types';
2
2
 
3
- interface RestCreds { email: string; apiToken: string; }
3
+ interface RestCreds {
4
+ email: string;
5
+ apiToken: string;
6
+ }
4
7
 
5
8
  export function createRestBackend(baseUrl: string, creds: RestCreds): JiraClient {
6
9
  const authHeader = `Basic ${Buffer.from(`${creds.email}:${creds.apiToken}`).toString('base64')}`;
@@ -17,7 +20,9 @@ export function createRestBackend(baseUrl: string, creds: RestCreds): JiraClient
17
20
  },
18
21
  });
19
22
  if (!r.ok && r.status !== 201) {
20
- throw new Error(`Jira REST ${init?.method ?? 'GET'} ${path} failed: ${r.status} ${await r.text()}`);
23
+ throw new Error(
24
+ `Jira REST ${init?.method ?? 'GET'} ${path} failed: ${r.status} ${await r.text()}`,
25
+ );
21
26
  }
22
27
  return r;
23
28
  }
@@ -32,7 +37,10 @@ export function createRestBackend(baseUrl: string, creds: RestCreds): JiraClient
32
37
  const json = (await r.json()) as { key: string; fields: Record<string, unknown> };
33
38
  const f = json.fields;
34
39
  const attachments = Array.isArray(f.attachment)
35
- ? (f.attachment as Array<{ filename: string; content: string }>).map(a => ({ filename: a.filename, url: a.content }))
40
+ ? (f.attachment as Array<{ filename: string; content: string }>).map((a) => ({
41
+ filename: a.filename,
42
+ url: a.content,
43
+ }))
36
44
  : [];
37
45
  const ticket: JiraTicket = {
38
46
  key: json.key,
@@ -50,7 +58,11 @@ export function createRestBackend(baseUrl: string, creds: RestCreds): JiraClient
50
58
  const r = await req(`/rest/api/3/issue/${encodeURIComponent(key)}/comment`, {
51
59
  method: 'POST',
52
60
  body: JSON.stringify({
53
- body: { type: 'doc', version: 1, content: [{ type: 'paragraph', content: [{ type: 'text', text: body }] }] },
61
+ body: {
62
+ type: 'doc',
63
+ version: 1,
64
+ content: [{ type: 'paragraph', content: [{ type: 'text', text: body }] }],
65
+ },
54
66
  }),
55
67
  });
56
68
  const json = (await r.json()) as { id: string };
@@ -59,7 +71,7 @@ export function createRestBackend(baseUrl: string, creds: RestCreds): JiraClient
59
71
  async transitionStatus(key, statusName) {
60
72
  const tr = await req(`/rest/api/3/issue/${encodeURIComponent(key)}/transitions`);
61
73
  const json = (await tr.json()) as { transitions: Array<{ id: string; name: string }> };
62
- const t = json.transitions.find(x => x.name === statusName);
74
+ const t = json.transitions.find((x) => x.name === statusName);
63
75
  if (!t) throw new Error(`No transition named "${statusName}" available for ${key}`);
64
76
  await req(`/rest/api/3/issue/${encodeURIComponent(key)}/transitions`, {
65
77
  method: 'POST',
package/src/jira/retry.ts CHANGED
@@ -16,8 +16,8 @@ export async function withRetry<T>(fn: () => Promise<T>, opts: RetryOptions): Pr
16
16
  if (opts.shouldRetry && !opts.shouldRetry(err)) throw err;
17
17
  attempt++;
18
18
  if (attempt >= opts.maxAttempts) break;
19
- const delay = opts.baseMs * Math.pow(opts.factor, attempt - 1);
20
- await new Promise(r => setTimeout(r, delay));
19
+ const delay = opts.baseMs * opts.factor ** (attempt - 1);
20
+ await new Promise((r) => setTimeout(r, delay));
21
21
  }
22
22
  }
23
23
  throw lastErr;
@@ -1,6 +1,6 @@
1
- import { existsSync, readFileSync, writeFileSync, unlinkSync, mkdirSync } from 'node:fs';
2
- import { dirname } from 'node:path';
1
+ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
3
2
  import { hostname } from 'node:os';
3
+ import { dirname } from 'node:path';
4
4
 
5
5
  export interface LockData {
6
6
  pid: number;
@@ -1,4 +1,4 @@
1
- import { appendFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';
1
+ import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
2
2
  import { dirname } from 'node:path';
3
3
 
4
4
  export interface LogEntry {
@@ -20,6 +20,6 @@ export class NdjsonLogger {
20
20
  if (!existsSync(path)) return [];
21
21
  const txt = readFileSync(path, 'utf8').trim();
22
22
  if (!txt) return [];
23
- return txt.split('\n').map(line => JSON.parse(line) as LogEntry);
23
+ return txt.split('\n').map((line) => JSON.parse(line) as LogEntry);
24
24
  }
25
25
  }
@@ -8,24 +8,30 @@ export interface JiraCommentInput extends ClassifyOutput {
8
8
  }
9
9
 
10
10
  export function buildJiraComment(input: JiraCommentInput): string {
11
- const passed = input.scenarios.filter(s => s.outcome === 'PASS').length;
11
+ const passed = input.scenarios.filter((s) => s.outcome === 'PASS').length;
12
12
  const total = input.scenarios.length;
13
13
  const icon = input.overall === 'PASS' ? '🟢' : '🔴';
14
14
  const header = `## ${icon} xera test ${input.overall === 'PASS' ? 'PASSED' : 'FAILED'} — ${input.ticket} (run ${input.runId})`;
15
15
  const meta = `**Classification:** ${input.overall} (confidence: ${input.overallConfidence})\n**Scenarios:** ${passed} / ${total} passed`;
16
16
 
17
17
  const failingBlocks = input.scenarios
18
- .filter(s => s.outcome === 'FAIL')
19
- .map(s => `### Scenario: ${s.name}\n- **Classification:** ${s.class} (confidence: ${s.confidence})\n- **Diagnosis:** ${s.rationale}`)
18
+ .filter((s) => s.outcome === 'FAIL')
19
+ .map(
20
+ (s) =>
21
+ `### Scenario: ${s.name}\n- **Classification:** ${s.class} (confidence: ${s.confidence})\n- **Diagnosis:** ${s.rationale}`,
22
+ )
20
23
  .join('\n\n');
21
24
 
22
25
  const reproduce = `### Reproduce locally\n\n\`\`\`\nbunx xera-internal exec ${input.ticket} --replay=${input.runId}\n\`\`\``;
23
26
 
24
- const next = input.overall === 'PASS'
25
- ? ''
26
- : `### Suggested next action\n- Review the failing scenarios above.\n- Re-run after changes: open Claude Code and run \`/xera-run ${input.ticket}\`.\n\n`;
27
+ const next =
28
+ input.overall === 'PASS'
29
+ ? ''
30
+ : `### Suggested next action\n- Review the failing scenarios above.\n- Re-run after changes: open Claude Code and run \`/xera-run ${input.ticket}\`.\n\n`;
27
31
 
28
32
  const footer = `---\nxera v${input.xeraVersion} • prompts v${input.promptsVersion}`;
29
33
 
30
- return [header, '', meta, '', failingBlocks, '', next, reproduce, '', footer].filter(Boolean).join('\n');
34
+ return [header, '', meta, '', failingBlocks, '', next, reproduce, '', footer]
35
+ .filter(Boolean)
36
+ .join('\n');
31
37
  }
@@ -1,6 +1,6 @@
1
- import type { ClassifyOutput } from '../classifier/types';
2
1
  import { existsSync } from 'node:fs';
3
- import { readStatus, writeStatus, appendHistory, type StatusJson } from '../artifact/status';
2
+ import { appendHistory, readStatus, type StatusJson, writeStatus } from '../artifact/status';
3
+ import type { ClassifyOutput } from '../classifier/types';
4
4
 
5
5
  export interface StatusWriterInput {
6
6
  ticket: string;