@xera-ai/skills 0.9.8 → 0.11.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/CHANGELOG.md +53 -0
- package/package.json +1 -1
- package/xera-coverage.md +127 -0
- package/xera-fill-gap.md +111 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# @xera-ai/skills
|
|
2
2
|
|
|
3
|
+
## 0.11.0
|
|
4
|
+
|
|
5
|
+
## 0.10.0
|
|
6
|
+
|
|
7
|
+
### Minor Changes
|
|
8
|
+
|
|
9
|
+
- [#64](https://github.com/xera-ai/xera/pull/64) [`c5aca3c`](https://github.com/xera-ai/xera/commit/c5aca3c95362ca99de6b072e68173933a4a23035) Thanks [@thanhtrinity](https://github.com/thanhtrinity)! - v0.8 — Coverage gap & AC matrix
|
|
10
|
+
|
|
11
|
+
QA teams now get an actionable "where to write tests next" surface built on top of the v0.6 project knowledge graph.
|
|
12
|
+
|
|
13
|
+
**New skills:**
|
|
14
|
+
|
|
15
|
+
- `/xera-coverage` — area-level + AC-level coverage report. Areas classify as UNCOVERED (no POM covers it), STALE (POM exists but no PASS in 30d), or COVERED. Risk-weighted gap list with `--why` drill-down. AC backfill auto-orchestrates on first invocation to map legacy scenarios → ACs via `map-ac-to-scenarios.md` prompt.
|
|
16
|
+
- `/xera-fill-gap <area>` and `/xera-fill-gap --ticket <TICKET>` — AI-drafted Gherkin scenarios for UNCOVERED areas or unsatisfied ACs. Atomic boundary — produces `.xera/<TICKET>/feature.draft.md`, user iterates and invokes `/xera-script` when ready.
|
|
17
|
+
|
|
18
|
+
**HTML viewer Coverage tab** (`/xera-coverage --viewer`):
|
|
19
|
+
|
|
20
|
+
- Map sub-tab — vis-network recolors area nodes by status (red/amber/green)
|
|
21
|
+
- List sub-tab — sortable area table + per-ticket AC gap matrix
|
|
22
|
+
- Trend sub-tab — inline SVG line chart of UNCOVERED+STALE count over time
|
|
23
|
+
|
|
24
|
+
**Graph schema additions:**
|
|
25
|
+
|
|
26
|
+
- New node kind `ACNode` (id = `${ticketId}#ac-${index}`)
|
|
27
|
+
- New edge kind `satisfies` (Scenario → AC, eager from `/xera-script` or lazy from backfill)
|
|
28
|
+
- New `Snapshot` projections: `acNodes`, `classifications`
|
|
29
|
+
- New event types `coverage.snapshot` (history for Trend) and `ac-coverage.backfilled` (materializes satisfies edges idempotently)
|
|
30
|
+
|
|
31
|
+
**Config additions** (`xera.config.ts`):
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
coverage: {
|
|
35
|
+
staleAfterDays: 30, // default
|
|
36
|
+
criticalAreas: [], // boost ×2 in risk formula
|
|
37
|
+
autoSnapshotOnCoverage: true, // emit trend snapshots
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Doctor checks added:**
|
|
42
|
+
|
|
43
|
+
- Warns when `coverage.staleAfterDays > 90`
|
|
44
|
+
- Warns when `criticalAreas` slug is missing from snapshot
|
|
45
|
+
- Warns when a ticket has ACs but no `ACNode` materialized
|
|
46
|
+
|
|
47
|
+
**Internals:**
|
|
48
|
+
|
|
49
|
+
- 5 new xera-internal subcommands: `coverage-prepare`, `ac-coverage-backfill-{prepare,finalize}`, `fill-gap-{prepare,finalize}`
|
|
50
|
+
- 2 new prompt templates: `map-ac-to-scenarios.md`, `propose-scenarios.md` (in-scope prompt count now 11)
|
|
51
|
+
- New `packages/core/src/coverage/` module (pure functions: status, risk, report, why)
|
|
52
|
+
- 6 golden fixtures in `fixtures/golden-coverage/` covering UNCOVERED, STALE, COVERED, critical-boost, bug-history, AC gap scenarios
|
|
53
|
+
|
|
54
|
+
See full spec at `docs/superpowers/specs/2026-05-17-xera-v08-coverage-gap-design.md`.
|
|
55
|
+
|
|
3
56
|
## 0.9.8
|
|
4
57
|
|
|
5
58
|
## 0.9.7
|
package/package.json
CHANGED
package/xera-coverage.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: xera-coverage
|
|
3
|
+
description: Show area-level and AC-level coverage report for the current xera project; sort by risk; drill-down via --why; optional HTML viewer (v0.8.1+). Available v0.8.0+.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The user invoked `/xera-coverage [--why <area-or-TICKET>] [--all] [--json] [--viewer]`. Read flag arguments and forward to the binary.
|
|
7
|
+
|
|
8
|
+
This skill walks the project knowledge graph (`.xera/graph/`) to identify untested areas and unsatisfied acceptance criteria. It does NOT modify graph state or run tests — strictly read-only reporting plus an optional snapshot event for trend history.
|
|
9
|
+
|
|
10
|
+
## Step 1 — Verify project layout
|
|
11
|
+
|
|
12
|
+
Confirm the cwd is a xera project: `xera.config.ts` exists. If not, surface:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
xera.config.ts not found — this command must run inside a xera project.
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
And STOP.
|
|
19
|
+
|
|
20
|
+
## Step 2 — Run coverage-prepare
|
|
21
|
+
|
|
22
|
+
Pass through the user's flags:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
bun run xera:coverage-prepare [--why <id>] [--all] [--json] [--no-emit-event]
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Flag handling:
|
|
29
|
+
|
|
30
|
+
- **`--why <id>`** — binary prints drill-down to stdout, no files written. Return that output to the user; do not continue to Step 3.
|
|
31
|
+
- **`--json`** — binary prints `report.json` to stdout. Return as-is.
|
|
32
|
+
- **No flag (default), or `--all`** — binary writes `.xera/coverage/report.json` and `.xera/coverage/report.md`, plus emits a `coverage.snapshot` event (unless config disables it).
|
|
33
|
+
|
|
34
|
+
Exit codes:
|
|
35
|
+
|
|
36
|
+
- `0` — report generated.
|
|
37
|
+
- `1` — unknown flag passed.
|
|
38
|
+
- `2` — `xera.config.ts` missing or invalid; surface stderr and STOP.
|
|
39
|
+
- `4` — internal error; surface stderr and STOP.
|
|
40
|
+
|
|
41
|
+
## Step 3 — Detect + run AC backfill if needed
|
|
42
|
+
|
|
43
|
+
Read `.xera/coverage/report.json`. If `acBackfillNeeded === true`:
|
|
44
|
+
|
|
45
|
+
### 3a — Assemble unmapped context
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
bun run xera:ac-coverage-backfill-prepare
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
This writes `.xera/coverage/ac-backfill-input.json` listing tickets that have ACs + scenarios but no `satisfies` edges yet.
|
|
52
|
+
|
|
53
|
+
If the input file is `{ "tickets": [] }`, skip to Step 4 — there's nothing to backfill (the `acBackfillNeeded` flag in report.json may be a leftover stale state; re-running `coverage-prepare` will refresh it).
|
|
54
|
+
|
|
55
|
+
### 3b — Invoke the AC-mapping prompt
|
|
56
|
+
|
|
57
|
+
Mint a fresh per-invocation nonce:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
bun -e "console.log('XR_' + crypto.randomUUID().replace(/-/g,'').slice(0,12))"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Capture the single-line output as the nonce.
|
|
64
|
+
|
|
65
|
+
Read `.xera/coverage/ac-backfill-input.json` and `node_modules/@xera-ai/prompts/map-ac-to-scenarios.md`. Generate the AC mapping decisions following that prompt's rules. Wrap the input JSON between two identical `<NONCE>` tags before feeding it to your generation context.
|
|
66
|
+
|
|
67
|
+
Write the prompt output to `.xera/coverage/ac-backfill-decisions.json`. The output schema is:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"mappings": [
|
|
72
|
+
{ "scenarioId": "<id>", "satisfiesAcs": [<indices>], "confidence": <0-1> }
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 3c — Materialize the satisfies edges
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
bun run xera:ac-coverage-backfill-finalize
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
This validates the decisions JSON and emits one `ac-coverage.backfilled` event per ticket. Each event materializes the `satisfies` edges in the graph snapshot.
|
|
84
|
+
|
|
85
|
+
### 3d — Re-run coverage-prepare
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
bun run xera:coverage-prepare --no-emit-event
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
This regenerates `.xera/coverage/report.json` with the newly materialized `satisfies` edges. After this, `acBackfillNeeded` should be `false` (or only `true` for tickets the AI declined to map — those are an AI quality issue and need a human eye).
|
|
92
|
+
|
|
93
|
+
## Step 4 — Print report.md
|
|
94
|
+
|
|
95
|
+
Read `.xera/coverage/report.md` and print it verbatim to the terminal.
|
|
96
|
+
|
|
97
|
+
## Step 5 — Handle --viewer
|
|
98
|
+
|
|
99
|
+
If the user passed `--viewer`, run:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
bun run xera:graph-render --include-coverage
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
This regenerates `.xera/graph.html` with a top-level Coverage tab (Map / List / Trend). Print the path so the user knows where to open it:
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
Coverage HTML viewer ready: .xera/graph.html
|
|
109
|
+
Open in any browser. The Coverage tab is at the top right.
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Step 6 — Print next-step hints
|
|
113
|
+
|
|
114
|
+
After the report (skip for `--why` and `--json` runs):
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
Next:
|
|
118
|
+
/xera-coverage --why <area-or-TICKET> full breakdown
|
|
119
|
+
/xera-coverage --viewer HTML viewer (v0.8.1)
|
|
120
|
+
/xera-fill-gap <area> draft scenarios (v0.8.2)
|
|
121
|
+
/xera-fill-gap --ticket <TICKET> draft AC gap scenarios (v0.8.2)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Edge cases
|
|
125
|
+
|
|
126
|
+
- Graph snapshot not present yet: `loadAllEvents` returns `[]` → empty report. That's fine; surface "no events yet, run /xera-fetch on a ticket first" hint after Step 6.
|
|
127
|
+
- Config has invalid `coverage.criticalAreas` slug → binary exits 2 with parse error; surface and STOP.
|
package/xera-fill-gap.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: xera-fill-gap
|
|
3
|
+
description: Generative — draft Gherkin scenarios for an UNCOVERED area or the unsatisfied ACs of a specific ticket. Use when you want AI to fill a coverage gap. Available v0.8.2+.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The user invoked one of:
|
|
7
|
+
- `/xera-fill-gap <area>` (area mode — fill an UNCOVERED area)
|
|
8
|
+
- `/xera-fill-gap --ticket <TICKET>` (ticket mode — fill unsatisfied ACs of a specific ticket)
|
|
9
|
+
|
|
10
|
+
If neither is provided, ask.
|
|
11
|
+
|
|
12
|
+
This skill does NOT modify graph state, run tests, or auto-chain into `/xera-script`. It produces draft `.feature` files that the user reviews; the user invokes `/xera-script` separately when ready.
|
|
13
|
+
|
|
14
|
+
## Step 1 — Verify project layout
|
|
15
|
+
|
|
16
|
+
Confirm `xera.config.ts` exists in cwd. If not, say `xera.config.ts not found — run this inside a xera project.` and STOP.
|
|
17
|
+
|
|
18
|
+
## Step 2 — Assemble context
|
|
19
|
+
|
|
20
|
+
Run:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
bun run xera:fill-gap-prepare {{--area <slug> | --ticket <TICKET>}}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Exit codes:
|
|
27
|
+
- `0` — context written
|
|
28
|
+
- `1` — invalid flags (shouldn't happen if you pass-through user input)
|
|
29
|
+
- `2` — area has no tickets / ticket has no unsatisfied ACs. Surface the stderr and STOP.
|
|
30
|
+
|
|
31
|
+
The output is `.xera/coverage/<scope>/context.json` where `<scope>` is the area slug or ticket ID.
|
|
32
|
+
|
|
33
|
+
## Step 3 — Invoke the propose-scenarios prompt
|
|
34
|
+
|
|
35
|
+
Mint a fresh per-invocation nonce:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
bun -e "console.log('XR_' + crypto.randomUUID().replace(/-/g,'').slice(0,12))"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Capture the single-line output as the nonce.
|
|
42
|
+
|
|
43
|
+
Read `.xera/coverage/<scope>/context.json` and `node_modules/@xera-ai/prompts/propose-scenarios.md`. Generate scenario proposals following that prompt's rules. Wrap the context JSON between two identical `<NONCE>` tags before feeding it to your generation context.
|
|
44
|
+
|
|
45
|
+
Write the prompt output to `.xera/coverage/<scope>/proposals.json`. Schema:
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"proposals": [
|
|
50
|
+
{
|
|
51
|
+
"id": "P1", "ticketId": "<id>", "title": "<title>",
|
|
52
|
+
"rationale": "<one sentence>",
|
|
53
|
+
"gherkin": "Scenario: ...\n Given ...\n When ...\n Then ...",
|
|
54
|
+
"satisfiesAcs": [<indices or empty>]
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Step 4 — Present proposals to user
|
|
61
|
+
|
|
62
|
+
Read the proposals and print them in a numbered list:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
3 candidate scenarios for `<scope>`:
|
|
66
|
+
|
|
67
|
+
[P1] PROJ-101 · "Customer pays with Apple Pay"
|
|
68
|
+
Why: Ticket adds Apple Pay; no scenario tests this path.
|
|
69
|
+
Preview: Given user is on /checkout · When they select Apple Pay · Then ...
|
|
70
|
+
|
|
71
|
+
[P2] PROJ-101 · "Apple Pay declined with no second attempt"
|
|
72
|
+
Why: ...
|
|
73
|
+
Preview: ...
|
|
74
|
+
|
|
75
|
+
...
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Ask the user: `Pick proposals to draft [comma-separated IDs / all / none]:`
|
|
79
|
+
|
|
80
|
+
- **none** — STOP. Mention the proposals.json file path so the user can review later.
|
|
81
|
+
- **all** — accept every proposal in proposals.json.
|
|
82
|
+
- **comma-separated IDs** (e.g. `P1, P3`) — accept the named subset.
|
|
83
|
+
|
|
84
|
+
## Step 5 — Finalize each accepted proposal
|
|
85
|
+
|
|
86
|
+
For each accepted proposal ID, run:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
bun run xera:fill-gap-finalize --accept <id> --ticket <proposal.ticketId> --source .xera/coverage/<scope>/proposals.json
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
If the binary returns exit 3 (`feature.draft.md` already exists), prompt the user: `Overwrite existing draft for <TICKET>? (y/N)`. If yes, re-run with `--force`.
|
|
93
|
+
|
|
94
|
+
Collect the list of written `.xera/<TICKET>/feature.draft.md` paths.
|
|
95
|
+
|
|
96
|
+
## Step 6 — Print next-step summary
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
Drafted N scenario(s):
|
|
100
|
+
- .xera/PROJ-101/feature.draft.md
|
|
101
|
+
- ...
|
|
102
|
+
|
|
103
|
+
Next:
|
|
104
|
+
Review each feature.draft.md, edit as needed, then run /xera-script <TICKET> when ready.
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Edge cases
|
|
108
|
+
|
|
109
|
+
- Graph snapshot not present yet — `fill-gap-prepare` will return exit 2; surface message + suggest `/xera-fetch` first.
|
|
110
|
+
- All proposals declined — STOP, no files written, no graph events emitted (the prompt run leaves only `.xera/coverage/<scope>/proposals.json` on disk, which is fine and reviewable).
|
|
111
|
+
- Mixed acceptance / overwrite conflict — handle one at a time; don't abort all on first --force prompt.
|