@xera-ai/core 0.4.2 → 0.4.4
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 +725 -290
- package/dist/bin-internal/disputes.d.ts +2 -0
- package/dist/bin-internal/disputes.d.ts.map +1 -0
- package/dist/bin-internal/doctor.d.ts +1 -1
- package/dist/bin-internal/doctor.d.ts.map +1 -1
- package/dist/bin-internal/exec.d.ts.map +1 -1
- package/dist/bin-internal/graph-record-script.d.ts.map +1 -1
- package/dist/bin-internal/graph-render.d.ts +2 -0
- package/dist/bin-internal/graph-render.d.ts.map +1 -0
- package/dist/bin-internal/index.d.ts.map +1 -1
- package/dist/graph/index.d.ts +2 -0
- package/dist/graph/index.d.ts.map +1 -1
- package/dist/graph/render.d.ts +50 -0
- package/dist/graph/render.d.ts.map +1 -0
- package/dist/graph/store.d.ts.map +1 -1
- package/dist/graph/types.d.ts +1 -0
- package/dist/graph/types.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/package.json +1 -1
- package/src/bin-internal/disputes.ts +88 -0
- package/src/bin-internal/doctor.ts +13 -1
- package/src/bin-internal/exec.ts +3 -0
- package/src/bin-internal/graph-record-script.ts +37 -8
- package/src/bin-internal/graph-render.ts +70 -0
- package/src/bin-internal/index.ts +4 -0
- package/src/config/schema.ts +1 -1
- package/src/graph/index.ts +2 -0
- package/src/graph/render.ts +324 -0
- package/src/graph/store.ts +8 -1
- package/src/graph/templates/LICENSE-vis-network.txt +176 -0
- package/src/graph/templates/graph.css +88 -0
- package/src/graph/templates/graph.html.template +31 -0
- package/src/graph/templates/graph.js +101 -0
- package/src/graph/templates/vis-network.min.js +25000 -0
- package/src/graph/types.ts +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"disputes.d.ts","sourceRoot":"","sources":["../../src/bin-internal/disputes.ts"],"names":[],"mappings":"AAoDA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAmCjE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/bin-internal/doctor.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA8GD,wBAAsB,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/bin-internal/doctor.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA8GD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CA6DtF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/bin-internal/exec.ts"],"names":[],"mappings":"AAWA,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/bin-internal/exec.ts"],"names":[],"mappings":"AAWA,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAwH7D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-record-script.d.ts","sourceRoot":"","sources":["../../src/bin-internal/graph-record-script.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"graph-record-script.d.ts","sourceRoot":"","sources":["../../src/bin-internal/graph-record-script.ts"],"names":[],"mappings":"AAqIA,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsFxF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-render.d.ts","sourceRoot":"","sources":["../../src/bin-internal/graph-render.ts"],"names":[],"mappings":"AAkBA,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAmDpE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bin-internal/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bin-internal/index.ts"],"names":[],"mappings":"AAsDA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAczD"}
|
package/dist/graph/index.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export { enrichTicket } from './enrich';
|
|
|
7
7
|
export type { ImpactEdge, ImpactOpts, ImpactReport, ImpactScenario, } from './impact';
|
|
8
8
|
export { renderImpactMarkdown, riskScore, walkImpact, } from './impact';
|
|
9
9
|
export { currentYyyyMm, graphPaths } from './paths';
|
|
10
|
+
export type { GraphStats, RenderHtmlInput, RenderOpts, VisEdge, VisNode } from './render';
|
|
11
|
+
export { renderHtml, transformForVisNetwork } from './render';
|
|
10
12
|
export { EventSchema, safeParseEvent } from './schema';
|
|
11
13
|
export { buildSimilarityPrompt } from './similarity';
|
|
12
14
|
export { appendEvents, computeEventsHash, deriveSnapshot, isSnapshotStale, loadAllEvents, loadSnapshot, writeSnapshot, } from './store';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,cAAc,EACd,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACnD,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,cAAc,GACf,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,oBAAoB,EACpB,SAAS,EACT,UAAU,GACX,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,aAAa,EACb,YAAY,EACZ,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,cAAc,EACd,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACnD,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,cAAc,GACf,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,oBAAoB,EACpB,SAAS,EACT,UAAU,GACX,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACpD,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1F,OAAO,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,aAAa,EACb,YAAY,EACZ,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Snapshot } from './types';
|
|
2
|
+
export interface VisNode {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
group: 'Ticket' | 'Scenario' | 'POM' | 'SUTArea' | 'Failure';
|
|
6
|
+
color?: string;
|
|
7
|
+
shape?: string;
|
|
8
|
+
size?: number;
|
|
9
|
+
title?: string;
|
|
10
|
+
borderWidth?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface VisEdge {
|
|
13
|
+
id?: string;
|
|
14
|
+
from: string;
|
|
15
|
+
to: string;
|
|
16
|
+
label?: string;
|
|
17
|
+
color?: string;
|
|
18
|
+
dashes?: boolean;
|
|
19
|
+
width?: number;
|
|
20
|
+
arrows?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface GraphStats {
|
|
23
|
+
tickets: number;
|
|
24
|
+
scenarios: number;
|
|
25
|
+
poms: number;
|
|
26
|
+
areas: number;
|
|
27
|
+
failures: number;
|
|
28
|
+
edges: number;
|
|
29
|
+
}
|
|
30
|
+
export interface RenderOpts {
|
|
31
|
+
since?: string;
|
|
32
|
+
ticketId?: string;
|
|
33
|
+
depth?: 1 | 2 | 3;
|
|
34
|
+
performanceMode?: 'full' | 'ticket-only' | 'text-fallback';
|
|
35
|
+
}
|
|
36
|
+
export declare function transformForVisNetwork(snap: Snapshot, opts: RenderOpts): {
|
|
37
|
+
nodes: VisNode[];
|
|
38
|
+
edges: VisEdge[];
|
|
39
|
+
stats: GraphStats;
|
|
40
|
+
};
|
|
41
|
+
export interface RenderHtmlInput {
|
|
42
|
+
data: {
|
|
43
|
+
nodes: VisNode[];
|
|
44
|
+
edges: VisEdge[];
|
|
45
|
+
};
|
|
46
|
+
stats: GraphStats;
|
|
47
|
+
generatedAt: string;
|
|
48
|
+
}
|
|
49
|
+
export declare function renderHtml(input: RenderHtmlInput): string;
|
|
50
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/graph/render.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAc,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEpD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,GAAG,UAAU,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,CAAC;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,eAAe,CAAC;CAC5D;AAmKD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,UAAU,GACf;IACD,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;CACnB,CA4EA;AAcD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE;QAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAAC,KAAK,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;IAC7C,KAAK,EAAE,UAAU,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAgBzD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/graph/store.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAEV,KAAK,EAIL,QAAQ,EAET,MAAM,SAAS,CAAC;AAGjB,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,aAAa,GAAG,MAAM,CAa3F;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,EAAE,CAyCvD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAIzD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/graph/store.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAEV,KAAK,EAIL,QAAQ,EAET,MAAM,SAAS,CAAC;AAGjB,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,aAAa,GAAG,MAAM,CAa3F;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,EAAE,CAyCvD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAIzD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,CAuHxD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAMpE;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAQ9D;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAKzD"}
|
package/dist/graph/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/graph/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/graph/types.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.js
CHANGED
|
@@ -327,7 +327,7 @@ var ReportingSchema = z4.object({
|
|
|
327
327
|
var RunSchema = z4.object({
|
|
328
328
|
autoImpact: z4.object({
|
|
329
329
|
enabled: z4.boolean().default(true),
|
|
330
|
-
threshold: z4.number().nonnegative().default(
|
|
330
|
+
threshold: z4.number().nonnegative().default(8)
|
|
331
331
|
}).prefault({})
|
|
332
332
|
}).prefault({});
|
|
333
333
|
var XeraConfigSchema = z4.object({
|
package/package.json
CHANGED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { loadAllEvents } from '../graph/store';
|
|
2
|
+
import type { ClassificationDisputedPayload, Event } from '../graph/types';
|
|
3
|
+
|
|
4
|
+
function parseDuration(s: string): number {
|
|
5
|
+
// accepts "7d", "30d", "1h", "5m" — returns ms; returns 0 for invalid input
|
|
6
|
+
const match = s.match(/^(\d+)([dhm])$/);
|
|
7
|
+
if (!match) return 0;
|
|
8
|
+
const n = Number.parseInt(match[1]!, 10);
|
|
9
|
+
const unit = match[2]!;
|
|
10
|
+
if (unit === 'd') return n * 86400 * 1000;
|
|
11
|
+
if (unit === 'h') return n * 3600 * 1000;
|
|
12
|
+
if (unit === 'm') return n * 60 * 1000;
|
|
13
|
+
return 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface DisputeRow {
|
|
17
|
+
ts: string;
|
|
18
|
+
runId: string;
|
|
19
|
+
scenarioId: string;
|
|
20
|
+
originalClassification: string;
|
|
21
|
+
disputedTo: string;
|
|
22
|
+
qaActor: string;
|
|
23
|
+
qaReason?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function eventToRow(e: Event & { type: 'classification.disputed' }): DisputeRow {
|
|
27
|
+
const p = e.payload as ClassificationDisputedPayload;
|
|
28
|
+
const row: DisputeRow = {
|
|
29
|
+
ts: e.ts,
|
|
30
|
+
runId: p.runId,
|
|
31
|
+
scenarioId: p.scenarioId,
|
|
32
|
+
originalClassification: p.originalClassification,
|
|
33
|
+
disputedTo: p.disputedTo,
|
|
34
|
+
qaActor: p.qaActor,
|
|
35
|
+
};
|
|
36
|
+
if (p.qaReason) row.qaReason = p.qaReason;
|
|
37
|
+
return row;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function renderText(rows: DisputeRow[]): string {
|
|
41
|
+
if (rows.length === 0) return 'No disputes recorded.\n';
|
|
42
|
+
const lines: string[] = [];
|
|
43
|
+
lines.push(`${rows.length} dispute(s):`);
|
|
44
|
+
for (const r of rows) {
|
|
45
|
+
lines.push(
|
|
46
|
+
` ${r.ts} | ${r.scenarioId} | ${r.originalClassification} → ${r.disputedTo} | ${r.qaActor}`,
|
|
47
|
+
);
|
|
48
|
+
if (r.qaReason) lines.push(` reason: ${r.qaReason}`);
|
|
49
|
+
}
|
|
50
|
+
return `${lines.join('\n')}\n`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function disputesCmd(argv: string[]): Promise<number> {
|
|
54
|
+
let since: string | undefined;
|
|
55
|
+
let format: 'text' | 'json' = 'text';
|
|
56
|
+
for (let i = 0; i < argv.length; i++) {
|
|
57
|
+
if (argv[i] === '--since') {
|
|
58
|
+
since = argv[++i];
|
|
59
|
+
} else if (argv[i] === '--format') {
|
|
60
|
+
const v = argv[++i];
|
|
61
|
+
if (v === 'json' || v === 'text') format = v;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const repoRoot = process.cwd();
|
|
66
|
+
const events = loadAllEvents(repoRoot);
|
|
67
|
+
const disputes = events.filter(
|
|
68
|
+
(e): e is Event & { type: 'classification.disputed' } => e.type === 'classification.disputed',
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
let cutoffMs: number | undefined;
|
|
72
|
+
if (since) {
|
|
73
|
+
const sinceMs = parseDuration(since);
|
|
74
|
+
if (sinceMs > 0) cutoffMs = Date.now() - sinceMs;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const rows = disputes
|
|
78
|
+
.filter((e) => cutoffMs === undefined || Date.parse(e.ts) >= cutoffMs)
|
|
79
|
+
.map(eventToRow)
|
|
80
|
+
.sort((a, b) => (a.ts < b.ts ? 1 : -1));
|
|
81
|
+
|
|
82
|
+
if (format === 'json') {
|
|
83
|
+
process.stdout.write(JSON.stringify(rows, null, 2));
|
|
84
|
+
} else {
|
|
85
|
+
process.stdout.write(renderText(rows));
|
|
86
|
+
}
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
@@ -117,8 +117,9 @@ 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
|
-
export async function doctorCmd(
|
|
120
|
+
export async function doctorCmd(argv: string[], opts: DoctorOpts = {}): Promise<number> {
|
|
121
121
|
const repoRoot = opts.cwd ?? process.cwd();
|
|
122
|
+
const autoEnrich = argv.includes('--auto-enrich');
|
|
122
123
|
const results: CheckResult[] = [
|
|
123
124
|
...checkGoldenEvalDir(repoRoot),
|
|
124
125
|
...checkRubricPrompt(repoRoot),
|
|
@@ -156,6 +157,17 @@ export async function doctorCmd(_argv: string[], opts: DoctorOpts = {}): Promise
|
|
|
156
157
|
console.log(` These won't participate in v0.6.1+ features (TEST_OUTDATED, /xera-impact).`);
|
|
157
158
|
console.log(` Run: bun run xera:graph-backfill`);
|
|
158
159
|
console.log(` (Use --dry-run to preview.)`);
|
|
160
|
+
if (autoEnrich) {
|
|
161
|
+
console.log('[doctor] --auto-enrich: running backfill for unbackfilled tickets...');
|
|
162
|
+
// Lazy import to avoid circular deps
|
|
163
|
+
const { graphBackfillCmd } = await import('./graph-backfill');
|
|
164
|
+
const exitCode = await graphBackfillCmd([]);
|
|
165
|
+
if (exitCode === 0) {
|
|
166
|
+
console.log(`[doctor] auto-enrich: backfilled ${unbackfilled.length} tickets`);
|
|
167
|
+
} else {
|
|
168
|
+
console.error('[doctor] auto-enrich: backfill failed');
|
|
169
|
+
}
|
|
170
|
+
}
|
|
159
171
|
}
|
|
160
172
|
}
|
|
161
173
|
}
|
package/src/bin-internal/exec.ts
CHANGED
|
@@ -15,6 +15,8 @@ export async function execCmd(argv: string[]): Promise<number> {
|
|
|
15
15
|
console.error('[xera:exec] usage: exec <TICKET>');
|
|
16
16
|
return 1;
|
|
17
17
|
}
|
|
18
|
+
const grepIdx = argv.indexOf('--grep');
|
|
19
|
+
const grep = grepIdx > -1 ? argv[grepIdx + 1] : undefined;
|
|
18
20
|
const cwd = process.cwd();
|
|
19
21
|
const config = await loadConfig(cwd);
|
|
20
22
|
const paths = resolveArtifactPaths(cwd, ticket);
|
|
@@ -117,6 +119,7 @@ export async function execCmd(argv: string[]): Promise<number> {
|
|
|
117
119
|
// path to read.
|
|
118
120
|
PLAYWRIGHT_JSON_OUTPUT_NAME: reportJsonPath,
|
|
119
121
|
},
|
|
122
|
+
...(grep && { grep }),
|
|
120
123
|
});
|
|
121
124
|
log.log({ step: 'exec.done', runId, exit: r.exitCode, ms: Date.now() - t0 });
|
|
122
125
|
|
|
@@ -30,18 +30,49 @@ const mk = <T extends Event['type']>(
|
|
|
30
30
|
payload,
|
|
31
31
|
}) as Event;
|
|
32
32
|
|
|
33
|
+
const P0_KEYWORDS = [
|
|
34
|
+
'log in',
|
|
35
|
+
'login',
|
|
36
|
+
'sign in',
|
|
37
|
+
'signin',
|
|
38
|
+
'sign up',
|
|
39
|
+
'signup',
|
|
40
|
+
'auth',
|
|
41
|
+
'authentic',
|
|
42
|
+
'payment',
|
|
43
|
+
'pay ',
|
|
44
|
+
'checkout',
|
|
45
|
+
'purchase',
|
|
46
|
+
'charge',
|
|
47
|
+
'password',
|
|
48
|
+
'credential',
|
|
49
|
+
'admin',
|
|
50
|
+
'permission',
|
|
51
|
+
'role',
|
|
52
|
+
'must ',
|
|
53
|
+
'critical',
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
function inferPriority(name: string, gherkin: string): 'p0' | 'p1' {
|
|
57
|
+
const haystack = `${name} ${gherkin}`.toLowerCase();
|
|
58
|
+
for (const kw of P0_KEYWORDS) {
|
|
59
|
+
if (haystack.includes(kw)) return 'p0';
|
|
60
|
+
}
|
|
61
|
+
return 'p1';
|
|
62
|
+
}
|
|
63
|
+
|
|
33
64
|
function parseFeature(
|
|
34
65
|
text: string,
|
|
35
66
|
): Array<{ name: string; priority: 'p0' | 'p1' | 'p2'; gherkin: string }> {
|
|
36
67
|
const scenarios: Array<{ name: string; priority: 'p0' | 'p1' | 'p2'; gherkin: string }> = [];
|
|
37
68
|
const lines = text.split('\n');
|
|
38
|
-
let
|
|
69
|
+
let explicitTag: 'p0' | 'p1' | 'p2' | null = null;
|
|
39
70
|
let i = 0;
|
|
40
71
|
while (i < lines.length) {
|
|
41
72
|
const line = lines[i]!.trim();
|
|
42
73
|
if (line.startsWith('@')) {
|
|
43
74
|
const tag = line.slice(1).split(/\s+/)[0]!.toLowerCase();
|
|
44
|
-
if (tag === 'p0' || tag === 'p1' || tag === 'p2')
|
|
75
|
+
if (tag === 'p0' || tag === 'p1' || tag === 'p2') explicitTag = tag;
|
|
45
76
|
i++;
|
|
46
77
|
continue;
|
|
47
78
|
}
|
|
@@ -55,12 +86,10 @@ function parseFeature(
|
|
|
55
86
|
!lines[i]!.trim().startsWith('@')
|
|
56
87
|
)
|
|
57
88
|
i++;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
});
|
|
63
|
-
currentTagPriority = 'p1';
|
|
89
|
+
const gherkin = lines.slice(start, i).join('\n');
|
|
90
|
+
const priority = explicitTag !== null ? explicitTag : inferPriority(name, gherkin);
|
|
91
|
+
scenarios.push({ name, priority, gherkin });
|
|
92
|
+
explicitTag = null;
|
|
64
93
|
continue;
|
|
65
94
|
}
|
|
66
95
|
i++;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { mkdirSync, renameSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import type { RenderOpts } from '../graph/render';
|
|
4
|
+
import { renderHtml, transformForVisNetwork } from '../graph/render';
|
|
5
|
+
import { deriveSnapshot, loadAllEvents } from '../graph/store';
|
|
6
|
+
|
|
7
|
+
function parseDepth(s: string | undefined): 1 | 2 | 3 {
|
|
8
|
+
const n = s ? Number.parseInt(s, 10) : 2;
|
|
9
|
+
if (n === 1 || n === 3) return n;
|
|
10
|
+
return 2;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function decidePerformanceMode(nodeCount: number): 'full' | 'ticket-only' | 'text-fallback' {
|
|
14
|
+
if (nodeCount > 2000) return 'text-fallback';
|
|
15
|
+
if (nodeCount > 500) return 'ticket-only';
|
|
16
|
+
return 'full';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function graphRenderCmd(argv: string[]): Promise<number> {
|
|
20
|
+
let outPath: string | undefined;
|
|
21
|
+
let ticketId: string | undefined;
|
|
22
|
+
let since: string | undefined;
|
|
23
|
+
let depth: 1 | 2 | 3 = 2;
|
|
24
|
+
|
|
25
|
+
for (let i = 0; i < argv.length; i++) {
|
|
26
|
+
if (argv[i] === '--out') outPath = argv[++i];
|
|
27
|
+
else if (argv[i] === '--ticket') ticketId = argv[++i];
|
|
28
|
+
else if (argv[i] === '--since') since = argv[++i];
|
|
29
|
+
else if (argv[i] === '--depth') depth = parseDepth(argv[++i]);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const repoRoot = process.cwd();
|
|
33
|
+
const finalPath = outPath ?? join(repoRoot, '.xera/graph.html');
|
|
34
|
+
|
|
35
|
+
const snap = deriveSnapshot(loadAllEvents(repoRoot));
|
|
36
|
+
const totalNodeCount =
|
|
37
|
+
Object.keys(snap.tickets).length +
|
|
38
|
+
Object.keys(snap.scenarios).length +
|
|
39
|
+
Object.keys(snap.poms).length +
|
|
40
|
+
Object.keys(snap.areas).length;
|
|
41
|
+
const performanceMode = decidePerformanceMode(totalNodeCount);
|
|
42
|
+
|
|
43
|
+
if (performanceMode === 'text-fallback') {
|
|
44
|
+
const txtPath = finalPath.replace(/\.html$/, '.txt');
|
|
45
|
+
mkdirSync(dirname(txtPath), { recursive: true });
|
|
46
|
+
writeFileSync(
|
|
47
|
+
txtPath,
|
|
48
|
+
`Graph too large for HTML viewer (${totalNodeCount} nodes). Use 'xera:graph-query --format text' instead.\n`,
|
|
49
|
+
);
|
|
50
|
+
console.log(`[graph-render] graph too large (${totalNodeCount} nodes); wrote ${txtPath}`);
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const opts: RenderOpts = { depth, performanceMode };
|
|
55
|
+
if (ticketId) opts.ticketId = ticketId;
|
|
56
|
+
if (since) opts.since = since;
|
|
57
|
+
|
|
58
|
+
const data = transformForVisNetwork(snap, opts);
|
|
59
|
+
const html = renderHtml({ data, stats: data.stats, generatedAt: new Date().toISOString() });
|
|
60
|
+
|
|
61
|
+
mkdirSync(dirname(finalPath), { recursive: true });
|
|
62
|
+
const tmpPath = `${finalPath}.tmp`;
|
|
63
|
+
writeFileSync(tmpPath, html);
|
|
64
|
+
renameSync(tmpPath, finalPath);
|
|
65
|
+
|
|
66
|
+
console.log(
|
|
67
|
+
`[graph-render] wrote ${finalPath} (${data.stats.tickets} tickets · ${data.stats.scenarios} scenarios · ${html.length} bytes)`,
|
|
68
|
+
);
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { disputesCmd } from './disputes';
|
|
1
2
|
import { doctorCmd } from './doctor';
|
|
2
3
|
import { evalDeterministicCmd } from './eval-deterministic';
|
|
3
4
|
import { evalPrepareCmd } from './eval-prepare';
|
|
@@ -8,6 +9,7 @@ import { graphBackfillCmd } from './graph-backfill';
|
|
|
8
9
|
import { graphEnrichCmd } from './graph-enrich';
|
|
9
10
|
import { graphQueryCmd } from './graph-query';
|
|
10
11
|
import { graphRecordCmd } from './graph-record';
|
|
12
|
+
import { graphRenderCmd } from './graph-render';
|
|
11
13
|
import { graphSnapshotCmd } from './graph-snapshot';
|
|
12
14
|
import { healPrepareCmd } from './heal-prepare';
|
|
13
15
|
import { impactPrepareCmd } from './impact-prepare';
|
|
@@ -23,6 +25,7 @@ import { validateFeatureCmd } from './validate-feature';
|
|
|
23
25
|
import { verifyPromptsCmd } from './verify-prompts';
|
|
24
26
|
|
|
25
27
|
const COMMANDS: Record<string, (argv: string[]) => Promise<number>> = {
|
|
28
|
+
disputes: disputesCmd,
|
|
26
29
|
doctor: doctorCmd,
|
|
27
30
|
'eval-deterministic': evalDeterministicCmd,
|
|
28
31
|
'eval-prepare': evalPrepareCmd,
|
|
@@ -31,6 +34,7 @@ const COMMANDS: Record<string, (argv: string[]) => Promise<number>> = {
|
|
|
31
34
|
fetch: fetchCmd,
|
|
32
35
|
'graph-backfill': graphBackfillCmd,
|
|
33
36
|
'graph-enrich': graphEnrichCmd,
|
|
37
|
+
'graph-render': graphRenderCmd,
|
|
34
38
|
'graph-query': graphQueryCmd,
|
|
35
39
|
'graph-record': graphRecordCmd,
|
|
36
40
|
'graph-snapshot': graphSnapshotCmd,
|
package/src/config/schema.ts
CHANGED
package/src/graph/index.ts
CHANGED
|
@@ -26,6 +26,8 @@ export {
|
|
|
26
26
|
walkImpact,
|
|
27
27
|
} from './impact';
|
|
28
28
|
export { currentYyyyMm, graphPaths } from './paths';
|
|
29
|
+
export type { GraphStats, RenderHtmlInput, RenderOpts, VisEdge, VisNode } from './render';
|
|
30
|
+
export { renderHtml, transformForVisNetwork } from './render';
|
|
29
31
|
export { EventSchema, safeParseEvent } from './schema';
|
|
30
32
|
export { buildSimilarityPrompt } from './similarity';
|
|
31
33
|
export {
|