@xera-ai/core 0.12.2 → 0.13.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.
package/dist/bin/internal.js
CHANGED
|
@@ -8268,11 +8268,14 @@ function readStoryFrontmatter(repoRoot, ticket) {
|
|
|
8268
8268
|
}
|
|
8269
8269
|
function readGraphInput(repoRoot, ticket) {
|
|
8270
8270
|
const path = join10(repoRoot, ".xera", ticket, "graph-input.json");
|
|
8271
|
-
if (!existsSync8(path))
|
|
8271
|
+
if (!existsSync8(path)) {
|
|
8272
|
+
console.warn(`[graph-record fetch] graph-input.json missing for ${ticket} \u2014 modifiesAreas=[] (run step 5 of /xera-fetch to populate)`);
|
|
8272
8273
|
return { modifiesAreas: [] };
|
|
8274
|
+
}
|
|
8273
8275
|
try {
|
|
8274
8276
|
return JSON.parse(readFileSync7(path, "utf8"));
|
|
8275
|
-
} catch {
|
|
8277
|
+
} catch (err) {
|
|
8278
|
+
console.warn(`[graph-record fetch] graph-input.json invalid JSON for ${ticket} at ${path} \u2014 modifiesAreas=[] (${err.message})`);
|
|
8276
8279
|
return { modifiesAreas: [] };
|
|
8277
8280
|
}
|
|
8278
8281
|
}
|
|
@@ -11035,7 +11038,8 @@ async function fetchCmd(argv, opts = {}) {
|
|
|
11035
11038
|
const body = renderStoryBody(t);
|
|
11036
11039
|
const storyHash = hashString(body);
|
|
11037
11040
|
const acLines = parseAcLines(t.acceptanceCriteria);
|
|
11038
|
-
const
|
|
11041
|
+
const acSource = acLines.length > 0 ? "jira-field" : "none";
|
|
11042
|
+
const full = renderStory(t.key, t.summary, storyHash, acLines, acSource, body);
|
|
11039
11043
|
mkdirSync12(dirname5(paths.storyPath), { recursive: true });
|
|
11040
11044
|
writeFileSync13(paths.storyPath, full);
|
|
11041
11045
|
const existing = readMeta(paths.metaPath);
|
|
@@ -11080,7 +11084,7 @@ function renderStoryBody(t) {
|
|
|
11080
11084
|
return lines.join(`
|
|
11081
11085
|
`);
|
|
11082
11086
|
}
|
|
11083
|
-
function renderStory(key, summary, storyHash, acLines, body) {
|
|
11087
|
+
function renderStory(key, summary, storyHash, acLines, acSource, body) {
|
|
11084
11088
|
const yamlLines = [
|
|
11085
11089
|
"---",
|
|
11086
11090
|
`ticketId: ${key}`,
|
|
@@ -11092,6 +11096,7 @@ function renderStory(key, summary, storyHash, acLines, body) {
|
|
|
11092
11096
|
for (const ac of acLines)
|
|
11093
11097
|
yamlLines.push(` - ${JSON.stringify(ac)}`);
|
|
11094
11098
|
}
|
|
11099
|
+
yamlLines.push(`acceptanceCriteriaSource: ${acSource}`);
|
|
11095
11100
|
yamlLines.push("---", "");
|
|
11096
11101
|
return yamlLines.join(`
|
|
11097
11102
|
`) + body;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xera-ai/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
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.
|
|
35
|
-
"@xera-ai/http": "^0.
|
|
34
|
+
"@xera-ai/web": "^0.13.0",
|
|
35
|
+
"@xera-ai/http": "^0.13.0",
|
|
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
|
-
|
|
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';
|
|
@@ -125,10 +130,18 @@ function readStoryFrontmatter(repoRoot: string, ticket: string): StoryFrontmatte
|
|
|
125
130
|
|
|
126
131
|
function readGraphInput(repoRoot: string, ticket: string): { modifiesAreas: string[] } {
|
|
127
132
|
const path = join(repoRoot, '.xera', ticket, 'graph-input.json');
|
|
128
|
-
if (!existsSync(path))
|
|
133
|
+
if (!existsSync(path)) {
|
|
134
|
+
console.warn(
|
|
135
|
+
`[graph-record fetch] graph-input.json missing for ${ticket} — modifiesAreas=[] (run step 5 of /xera-fetch to populate)`,
|
|
136
|
+
);
|
|
137
|
+
return { modifiesAreas: [] };
|
|
138
|
+
}
|
|
129
139
|
try {
|
|
130
140
|
return JSON.parse(readFileSync(path, 'utf8'));
|
|
131
|
-
} catch {
|
|
141
|
+
} catch (err) {
|
|
142
|
+
console.warn(
|
|
143
|
+
`[graph-record fetch] graph-input.json invalid JSON for ${ticket} at ${path} — modifiesAreas=[] (${(err as Error).message})`,
|
|
144
|
+
);
|
|
132
145
|
return { modifiesAreas: [] };
|
|
133
146
|
}
|
|
134
147
|
}
|