@xera-ai/core 0.8.0 → 0.8.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.
@@ -8395,16 +8395,19 @@ function checkRootScripts(repoRoot) {
8395
8395
  const missing = REQUIRED_SCRIPTS.filter((s) => typeof scripts[s] !== "string");
8396
8396
  return missing.map((s) => ({ ok: false, message: `root package.json missing script: ${s}` }));
8397
8397
  }
8398
+ function isXeraMonorepo(repoRoot) {
8399
+ return existsSync9(join8(repoRoot, "packages/skills")) && existsSync9(join8(repoRoot, "packages/prompts"));
8400
+ }
8398
8401
  async function doctorCmd(argv, opts = {}) {
8399
8402
  const repoRoot = opts.cwd ?? process.cwd();
8400
8403
  const autoEnrich = argv.includes("--auto-enrich");
8401
- const results = [
8404
+ const results = isXeraMonorepo(repoRoot) ? [
8402
8405
  ...checkGoldenEvalDir(repoRoot),
8403
8406
  ...checkRubricPrompt(repoRoot),
8404
8407
  ...checkEvalSkill(repoRoot),
8405
8408
  ...checkPromptInjectionPreamble(repoRoot),
8406
8409
  ...checkRootScripts(repoRoot)
8407
- ];
8410
+ ] : [];
8408
8411
  const cost = summarizeCost(repoRoot, 7);
8409
8412
  if (cost.totalCalls > 0) {
8410
8413
  console.log("");
@@ -9565,9 +9568,12 @@ async function fetchCmd(argv, opts = {}) {
9565
9568
  } : { story: config.jira.fields.story };
9566
9569
  t = await client.fetchTicket(ticket, fieldMap);
9567
9570
  }
9568
- const story = renderStory(t);
9571
+ const body = renderStoryBody(t);
9572
+ const storyHash = hashString(body);
9573
+ const acLines = parseAcLines(t.acceptanceCriteria);
9574
+ const full = renderStory(t.key, t.summary, storyHash, acLines, body);
9569
9575
  mkdirSync10(dirname5(paths.storyPath), { recursive: true });
9570
- writeFileSync9(paths.storyPath, story);
9576
+ writeFileSync9(paths.storyPath, full);
9571
9577
  const existing = readMeta(paths.metaPath);
9572
9578
  writeMeta(paths.metaPath, {
9573
9579
  ticket,
@@ -9575,13 +9581,19 @@ async function fetchCmd(argv, opts = {}) {
9575
9581
  xera_version: "0.1.0",
9576
9582
  prompts_version: "1.0.0",
9577
9583
  ...existing ?? {},
9578
- story_hash: hashString(story),
9584
+ story_hash: storyHash,
9579
9585
  fetched_at: new Date().toISOString()
9580
9586
  });
9581
9587
  console.log(`[xera:fetch] wrote ${paths.storyPath}`);
9582
9588
  return 0;
9583
9589
  }
9584
- function renderStory(t) {
9590
+ function parseAcLines(raw) {
9591
+ if (!raw?.trim())
9592
+ return [];
9593
+ return raw.trim().split(`
9594
+ `).map((l) => l.replace(/^[\s\-*]+/, "").trim()).filter(Boolean);
9595
+ }
9596
+ function renderStoryBody(t) {
9585
9597
  const lines = [];
9586
9598
  lines.push(`# ${t.key}: ${t.summary}`, "");
9587
9599
  const story = t.story.trim();
@@ -9604,6 +9616,22 @@ function renderStory(t) {
9604
9616
  return lines.join(`
9605
9617
  `);
9606
9618
  }
9619
+ function renderStory(key, summary, storyHash, acLines, body) {
9620
+ const yamlLines = [
9621
+ "---",
9622
+ `ticketId: ${key}`,
9623
+ `summary: ${JSON.stringify(summary)}`,
9624
+ `storyHash: ${storyHash}`
9625
+ ];
9626
+ if (acLines.length > 0) {
9627
+ yamlLines.push("acceptanceCriteria:");
9628
+ for (const ac of acLines)
9629
+ yamlLines.push(` - ${JSON.stringify(ac)}`);
9630
+ }
9631
+ yamlLines.push("---", "");
9632
+ return yamlLines.join(`
9633
+ `) + body;
9634
+ }
9607
9635
 
9608
9636
  // src/bin-internal/index.ts
9609
9637
  init_graph_backfill();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xera-ai/core",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -31,8 +31,8 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "zod": "4.4.3",
34
- "@xera-ai/web": "^0.8.0",
35
- "@xera-ai/http": "^0.8.0",
34
+ "@xera-ai/web": "^0.8.1",
35
+ "@xera-ai/http": "^0.8.1",
36
36
  "@playwright/test": "1.60.0",
37
37
  "fflate": "0.8.3",
38
38
  "yaml": "2.9.0"
@@ -117,16 +117,24 @@ function checkRootScripts(repoRoot: string): CheckResult[] {
117
117
  return missing.map((s) => ({ ok: false, message: `root package.json missing script: ${s}` }));
118
118
  }
119
119
 
120
+ function isXeraMonorepo(repoRoot: string): boolean {
121
+ return (
122
+ existsSync(join(repoRoot, 'packages/skills')) && existsSync(join(repoRoot, 'packages/prompts'))
123
+ );
124
+ }
125
+
120
126
  export async function doctorCmd(argv: string[], opts: DoctorOpts = {}): Promise<number> {
121
127
  const repoRoot = opts.cwd ?? process.cwd();
122
128
  const autoEnrich = argv.includes('--auto-enrich');
123
- const results: CheckResult[] = [
124
- ...checkGoldenEvalDir(repoRoot),
125
- ...checkRubricPrompt(repoRoot),
126
- ...checkEvalSkill(repoRoot),
127
- ...checkPromptInjectionPreamble(repoRoot),
128
- ...checkRootScripts(repoRoot),
129
- ];
129
+ const results: CheckResult[] = isXeraMonorepo(repoRoot)
130
+ ? [
131
+ ...checkGoldenEvalDir(repoRoot),
132
+ ...checkRubricPrompt(repoRoot),
133
+ ...checkEvalSkill(repoRoot),
134
+ ...checkPromptInjectionPreamble(repoRoot),
135
+ ...checkRootScripts(repoRoot),
136
+ ]
137
+ : [];
130
138
  // Cost summary (past 7 days)
131
139
  const cost = summarizeCost(repoRoot, 7);
132
140
  if (cost.totalCalls > 0) {
@@ -43,9 +43,12 @@ export async function fetchCmd(argv: string[], opts: FetchCmdOpts = {}): Promise
43
43
  t = await client.fetchTicket(ticket, fieldMap);
44
44
  }
45
45
 
46
- const story = renderStory(t);
46
+ const body = renderStoryBody(t);
47
+ const storyHash = hashString(body);
48
+ const acLines = parseAcLines(t.acceptanceCriteria);
49
+ const full = renderStory(t.key, t.summary, storyHash, acLines, body);
47
50
  mkdirSync(dirname(paths.storyPath), { recursive: true });
48
- writeFileSync(paths.storyPath, story);
51
+ writeFileSync(paths.storyPath, full);
49
52
 
50
53
  const existing = readMeta(paths.metaPath);
51
54
  writeMeta(paths.metaPath, {
@@ -55,7 +58,7 @@ export async function fetchCmd(argv: string[], opts: FetchCmdOpts = {}): Promise
55
58
  prompts_version: '1.0.0',
56
59
  ...(existing ?? {}),
57
60
  // Re-stamp the just-fetched fields:
58
- story_hash: hashString(story),
61
+ story_hash: storyHash,
59
62
  fetched_at: new Date().toISOString(),
60
63
  });
61
64
 
@@ -63,7 +66,16 @@ export async function fetchCmd(argv: string[], opts: FetchCmdOpts = {}): Promise
63
66
  return 0;
64
67
  }
65
68
 
66
- function renderStory(t: JiraTicket): string {
69
+ function parseAcLines(raw: string | undefined): string[] {
70
+ if (!raw?.trim()) return [];
71
+ return raw
72
+ .trim()
73
+ .split('\n')
74
+ .map((l) => l.replace(/^[\s\-*]+/, '').trim())
75
+ .filter(Boolean);
76
+ }
77
+
78
+ function renderStoryBody(t: JiraTicket): string {
67
79
  const lines: string[] = [];
68
80
  lines.push(`# ${t.key}: ${t.summary}`, '');
69
81
 
@@ -93,3 +105,24 @@ function renderStory(t: JiraTicket): string {
93
105
  }
94
106
  return lines.join('\n');
95
107
  }
108
+
109
+ function renderStory(
110
+ key: string,
111
+ summary: string,
112
+ storyHash: string,
113
+ acLines: string[],
114
+ body: string,
115
+ ): string {
116
+ const yamlLines = [
117
+ '---',
118
+ `ticketId: ${key}`,
119
+ `summary: ${JSON.stringify(summary)}`,
120
+ `storyHash: ${storyHash}`,
121
+ ];
122
+ if (acLines.length > 0) {
123
+ yamlLines.push('acceptanceCriteria:');
124
+ for (const ac of acLines) yamlLines.push(` - ${JSON.stringify(ac)}`);
125
+ }
126
+ yamlLines.push('---', '');
127
+ return yamlLines.join('\n') + body;
128
+ }