@xera-ai/core 0.12.3 → 0.13.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.
@@ -11038,7 +11038,8 @@ async function fetchCmd(argv, opts = {}) {
11038
11038
  const body = renderStoryBody(t);
11039
11039
  const storyHash = hashString(body);
11040
11040
  const acLines = parseAcLines(t.acceptanceCriteria);
11041
- const full = renderStory(t.key, t.summary, storyHash, acLines, body);
11041
+ const acSource = acLines.length > 0 ? "jira-field" : "none";
11042
+ const full = renderStory(t.key, t.summary, storyHash, acLines, acSource, body);
11042
11043
  mkdirSync12(dirname5(paths.storyPath), { recursive: true });
11043
11044
  writeFileSync13(paths.storyPath, full);
11044
11045
  const existing = readMeta(paths.metaPath);
@@ -11083,7 +11084,7 @@ function renderStoryBody(t) {
11083
11084
  return lines.join(`
11084
11085
  `);
11085
11086
  }
11086
- function renderStory(key, summary, storyHash, acLines, body) {
11087
+ function renderStory(key, summary, storyHash, acLines, acSource, body) {
11087
11088
  const yamlLines = [
11088
11089
  "---",
11089
11090
  `ticketId: ${key}`,
@@ -11095,6 +11096,7 @@ function renderStory(key, summary, storyHash, acLines, body) {
11095
11096
  for (const ac of acLines)
11096
11097
  yamlLines.push(` - ${JSON.stringify(ac)}`);
11097
11098
  }
11099
+ yamlLines.push(`acceptanceCriteriaSource: ${acSource}`);
11098
11100
  yamlLines.push("---", "");
11099
11101
  return yamlLines.join(`
11100
11102
  `) + body;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xera-ai/core",
3
- "version": "0.12.3",
3
+ "version": "0.13.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.12.3",
35
- "@xera-ai/http": "^0.12.3",
34
+ "@xera-ai/web": "^0.13.1",
35
+ "@xera-ai/http": "^0.13.1",
36
36
  "@playwright/test": "1.60.0",
37
37
  "dotenv": "^16.0.0",
38
38
  "fflate": "0.8.3",
@@ -47,7 +47,11 @@ export async function fetchCmd(argv: string[], opts: FetchCmdOpts = {}): Promise
47
47
  const body = renderStoryBody(t);
48
48
  const storyHash = hashString(body);
49
49
  const acLines = parseAcLines(t.acceptanceCriteria);
50
- const full = renderStory(t.key, t.summary, storyHash, acLines, body);
50
+ // Track where AC came from so /xera-fetch step 3.5 (cognitive body-extraction)
51
+ // and `xera doctor --strict <TICKET>` can act on accurate provenance.
52
+ // `body-extraction` is set later by the skill if it finds AC in the description.
53
+ const acSource: 'jira-field' | 'none' = acLines.length > 0 ? 'jira-field' : 'none';
54
+ const full = renderStory(t.key, t.summary, storyHash, acLines, acSource, body);
51
55
  mkdirSync(dirname(paths.storyPath), { recursive: true });
52
56
  writeFileSync(paths.storyPath, full);
53
57
 
@@ -112,6 +116,7 @@ function renderStory(
112
116
  summary: string,
113
117
  storyHash: string,
114
118
  acLines: string[],
119
+ acSource: 'jira-field' | 'none',
115
120
  body: string,
116
121
  ): string {
117
122
  const yamlLines = [
@@ -124,6 +129,7 @@ function renderStory(
124
129
  yamlLines.push('acceptanceCriteria:');
125
130
  for (const ac of acLines) yamlLines.push(` - ${JSON.stringify(ac)}`);
126
131
  }
132
+ yamlLines.push(`acceptanceCriteriaSource: ${acSource}`);
127
133
  yamlLines.push('---', '');
128
134
  return yamlLines.join('\n') + body;
129
135
  }
@@ -50,6 +50,11 @@ interface StoryFrontmatter {
50
50
  summary: string;
51
51
  storyHash: string;
52
52
  acceptanceCriteria?: string[];
53
+ // Where AC came from. Set by `xera-internal fetch` ('jira-field' | 'none') and
54
+ // upgraded by /xera-fetch step 4 to 'body-extraction' when the skill extracts
55
+ // AC out of the description body. Optional for backward compat with
56
+ // pre-existing story.md files.
57
+ acceptanceCriteriaSource?: 'jira-field' | 'body-extraction' | 'none';
53
58
  linked_issues?: Array<{
54
59
  ticketId: string;
55
60
  relation: 'blocks' | 'duplicates' | 'relates' | 'supersedes';