requ-mcp 0.1.0 → 0.5.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/README.md +107 -25
- package/dist/conductor.d.ts +14 -0
- package/dist/conductor.js +60 -0
- package/dist/conductor.js.map +1 -1
- package/dist/coverage.d.ts +28 -4
- package/dist/coverage.js +48 -6
- package/dist/coverage.js.map +1 -1
- package/dist/export-import.d.ts +10 -0
- package/dist/export-import.js +127 -0
- package/dist/export-import.js.map +1 -0
- package/dist/index.js +703 -60
- package/dist/index.js.map +1 -1
- package/dist/public/app.js +914 -0
- package/dist/public/index.html +1418 -0
- package/dist/public/style.css +458 -0
- package/dist/schema.d.ts +669 -27
- package/dist/schema.js +91 -28
- package/dist/schema.js.map +1 -1
- package/dist/sqlite-store.d.ts +43 -0
- package/dist/sqlite-store.js +210 -0
- package/dist/sqlite-store.js.map +1 -0
- package/dist/storage.d.ts +16 -4
- package/dist/storage.js +53 -19
- package/dist/storage.js.map +1 -1
- package/dist/web-api.d.ts +9 -0
- package/dist/web-api.js +789 -0
- package/dist/web-api.js.map +1 -0
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# requ-mcp
|
|
2
2
|
|
|
3
3
|
[](https://github.com/nouhouari/requ-mcp/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/requ-mcp)
|
|
5
|
+
|
|
6
|
+
📦 **Published on npm:** [npmjs.com/package/requ-mcp](https://www.npmjs.com/package/requ-mcp)
|
|
4
7
|
|
|
5
8
|
An MCP server that tracks **requirements coverage** for a project, and how it
|
|
6
9
|
**evolves across phases/releases**. It gives AI agents structured tools to
|
|
@@ -17,10 +20,42 @@ Phase (v1.0, v1.1, …) → Execution (a scenario result for a run)
|
|
|
17
20
|
At the end of a working session — or for any release — you ask the server one
|
|
18
21
|
question — *"what's our coverage?"* — and get a precise, always-current answer
|
|
19
22
|
instead of a stale spreadsheet, plus the **trend** of how coverage changed
|
|
20
|
-
release over release.
|
|
23
|
+
release over release. The server also ships a **web dashboard** (in HTTP mode)
|
|
24
|
+
that visualizes coverage and requirements in 6 interactive tabs.
|
|
21
25
|
|
|
22
26
|
## Quickstart
|
|
23
27
|
|
|
28
|
+
It's on npm — no clone or build needed. Register it with your MCP client
|
|
29
|
+
(e.g. Claude Code) once, globally, via `npx`:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"mcpServers": {
|
|
34
|
+
"requ": {
|
|
35
|
+
"command": "npx",
|
|
36
|
+
"args": ["-y", "requ-mcp"]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Or install it globally and point at the binary:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm install -g requ-mcp
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"mcpServers": {
|
|
51
|
+
"requ": { "command": "requ-mcp" }
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
<details>
|
|
57
|
+
<summary>From source instead</summary>
|
|
58
|
+
|
|
24
59
|
```bash
|
|
25
60
|
git clone https://github.com/nouhouari/requ-mcp.git
|
|
26
61
|
cd requ-mcp
|
|
@@ -29,22 +64,62 @@ npm run build # compiles to dist/
|
|
|
29
64
|
npm run smoke # optional: end-to-end self-test
|
|
30
65
|
```
|
|
31
66
|
|
|
32
|
-
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"mcpServers": {
|
|
70
|
+
"requ": { "command": "node", "args": ["/absolute/path/to/requ-mcp/dist/index.js"] }
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
</details>
|
|
75
|
+
|
|
76
|
+
## Web Dashboard
|
|
77
|
+
|
|
78
|
+
The server ships an optional **HTTP transport mode** that serves a professional web dashboard alongside the MCP endpoint. Launch with the `REQU_TRANSPORT=http` environment variable:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
REQU_TRANSPORT=http npx requ-mcp
|
|
82
|
+
# → Dashboard: http://localhost:8788/
|
|
83
|
+
# → MCP endpoint: http://localhost:8788/mcp
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Or in your MCP client config:
|
|
33
87
|
|
|
34
88
|
```json
|
|
35
89
|
{
|
|
36
90
|
"mcpServers": {
|
|
37
91
|
"requ": {
|
|
38
|
-
"command": "
|
|
39
|
-
"args": ["
|
|
92
|
+
"command": "npx",
|
|
93
|
+
"args": ["-y", "requ-mcp"],
|
|
94
|
+
"env": { "REQU_TRANSPORT": "http" }
|
|
40
95
|
}
|
|
41
96
|
}
|
|
42
97
|
}
|
|
43
98
|
```
|
|
44
99
|
|
|
45
|
-
|
|
100
|
+
**Default port:** `8788`. Override it with `REQU_PORT=9000 REQU_TRANSPORT=http npx requ-mcp`.
|
|
46
101
|
|
|
47
|
-
|
|
102
|
+
### Dashboard tabs
|
|
103
|
+
|
|
104
|
+
| Tab | Content |
|
|
105
|
+
|-----|---------|
|
|
106
|
+
| **Overview** | KPI cards (requirements, stories, scenario pass rate, verified %) + coverage trend chart + component breakdown + gaps summary + phases strip |
|
|
107
|
+
| **Requirements** | Sortable/filterable table of all requirements with inline expansion showing linked story IDs and tags |
|
|
108
|
+
| **Stories** | User stories with status, acceptance criteria count, and coverage badge; expand to see acceptance criteria and linked scenarios with pass/fail/pending icons |
|
|
109
|
+
| **Coverage** | Phase + mode selector (Cumulative / Strict), summary stats, per-component breakdown, and gaps (reqs without story / stories without scenarios / stories not covered) |
|
|
110
|
+
| **Components** | Card grid of components showing description, domain tags, requirement count, and verified percentage |
|
|
111
|
+
| **VCS** | Table of VCS refs (branches and MRs) linked to stories and requirements, with state badges and external links |
|
|
112
|
+
|
|
113
|
+
**Live updates:** The dashboard polls for KPI count changes every 5 seconds via Server-Sent Events (SSE) — no page refresh needed.
|
|
114
|
+
|
|
115
|
+
**Before init:** If the project hasn't been initialized with `init_project` yet, all API endpoints and the dashboard show a "Project not initialized" message rather than crashing.
|
|
116
|
+
|
|
117
|
+
## Usage
|
|
118
|
+
|
|
119
|
+
A typical flow, all driven through the agent:
|
|
120
|
+
|
|
121
|
+
0. `check_conductor` *(optional)* — confirm the Conductor folder exists and see its detected name before initializing.
|
|
122
|
+
1. `init_project` — points at your Conductor project (`conductorPath`); it **verifies the folder exists and is a real Conductor project** (has `features/` or a cucumber config) and reports its name before creating `.requ/`. Pass `force:true` to override.
|
|
48
123
|
2. `create_requirement` — import the requirements (with `components`).
|
|
49
124
|
3. `create_user_story` — PO authors stories, each tracing to ≥1 requirement.
|
|
50
125
|
4. **Tag scenarios** `@US-007` in your feature files — that *is* the test link.
|
|
@@ -75,6 +150,22 @@ two modes:
|
|
|
75
150
|
|
|
76
151
|
`coverage_trend` returns the summary at each phase in order — the evolution view.
|
|
77
152
|
|
|
153
|
+
### Phase planning & scope
|
|
154
|
+
|
|
155
|
+
Requirements and user stories can be **assigned a target phase** — the release
|
|
156
|
+
they're planned for — via the optional `phase` field on `create_requirement` /
|
|
157
|
+
`create_user_story` (defaults to the active phase; pass `phase: ""` to leave
|
|
158
|
+
unassigned) and `update_requirement` / `update_user_story`. This is *planning*
|
|
159
|
+
("what's in scope for v1.1?"), distinct from *execution* ("what was tested").
|
|
160
|
+
|
|
161
|
+
Phase reports are then scoped to the items planned for that phase, mirroring the
|
|
162
|
+
coverage modes:
|
|
163
|
+
|
|
164
|
+
- **cumulative** — items assigned to the target phase **or any earlier phase**.
|
|
165
|
+
- **strict** — only items assigned to **that** phase.
|
|
166
|
+
- items with **no** phase assigned are **always in scope** (so existing,
|
|
167
|
+
un-phased data behaves exactly as before until you start assigning phases).
|
|
168
|
+
|
|
78
169
|
### Components
|
|
79
170
|
|
|
80
171
|
Requirements carry a `components` array, so coverage can be sliced per
|
|
@@ -113,7 +204,8 @@ reviewable in PRs:
|
|
|
113
204
|
|
|
114
205
|
| Tool | Actor | Purpose |
|
|
115
206
|
|------|-------|---------|
|
|
116
|
-
| `init_project` | setup |
|
|
207
|
+
| `init_project` | setup | Verify the Conductor folder exists & is valid, then create `.requ/`, record Conductor + report path, optional first phase |
|
|
208
|
+
| `check_conductor` | setup | Inspect the Conductor folder (exists? valid? name? feature count?) without writing anything |
|
|
117
209
|
| `create_requirement` / `list_requirements` / `get_requirement` / `update_requirement` | server | Manage imported requirements (with `components`) |
|
|
118
210
|
| `create_user_story` | PO | Author a story (rejects unless it links ≥1 existing requirement) |
|
|
119
211
|
| `update_user_story` / `add_acceptance_criterion` / `list_user_stories` / `get_user_story` | PO | Edit stories & criteria |
|
|
@@ -150,29 +242,19 @@ doesn't exist.
|
|
|
150
242
|
npm install
|
|
151
243
|
npm run build # tsc -> dist/
|
|
152
244
|
npm run smoke # end-to-end test against the built server over stdio
|
|
153
|
-
npm run dev # run from source with tsx
|
|
245
|
+
npm run dev # run from source with tsx (stdio mode)
|
|
246
|
+
npm run start:http # run from source in HTTP mode with dashboard
|
|
154
247
|
```
|
|
155
248
|
|
|
156
|
-
##
|
|
157
|
-
|
|
158
|
-
The server talks stdio. It can be installed **once at the user level** and serve
|
|
159
|
-
any project — it resolves the target project per call:
|
|
160
|
-
|
|
161
|
-
```json
|
|
162
|
-
{
|
|
163
|
-
"mcpServers": {
|
|
164
|
-
"requ": {
|
|
165
|
-
"command": "node",
|
|
166
|
-
"args": ["/absolute/path/to/requ-mcp/dist/index.js"]
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
```
|
|
249
|
+
## How it finds the project
|
|
171
250
|
|
|
172
|
-
|
|
251
|
+
The server talks stdio and can be installed **once at the user level**
|
|
252
|
+
(see [Quickstart](#quickstart)) to serve any project — it resolves the target
|
|
253
|
+
project per call.
|
|
173
254
|
|
|
174
255
|
For each tool call, the project root (the directory containing `.requ/`) is
|
|
175
|
-
resolved in this order
|
|
256
|
+
resolved in this order (pass `REQU_ROOT` via an `env` block in the MCP config to
|
|
257
|
+
pin one explicitly):
|
|
176
258
|
|
|
177
259
|
1. The tool's explicit **`projectPath`** argument, if given (use this in monorepos).
|
|
178
260
|
2. The **`REQU_ROOT`** env var, if set at launch (a hard pin).
|
package/dist/conductor.d.ts
CHANGED
|
@@ -20,6 +20,20 @@ export interface ConductorScenario {
|
|
|
20
20
|
export interface ConductorIndex {
|
|
21
21
|
scenarios: ConductorScenario[];
|
|
22
22
|
}
|
|
23
|
+
export interface ConductorInfo {
|
|
24
|
+
path: string;
|
|
25
|
+
exists: boolean;
|
|
26
|
+
/** Looks like a Conductor/cucumber project: has features/ or a cucumber config. */
|
|
27
|
+
isConductorProject: boolean;
|
|
28
|
+
hasFeaturesDir: boolean;
|
|
29
|
+
/** The cucumber config file found at the root, if any. */
|
|
30
|
+
cucumberConfig: string | null;
|
|
31
|
+
/** Project name: package.json "name" if present, else the folder name. */
|
|
32
|
+
name: string;
|
|
33
|
+
featureFiles: number;
|
|
34
|
+
}
|
|
35
|
+
/** Inspect a candidate Conductor project directory without modifying anything. */
|
|
36
|
+
export declare function inspectConductorProject(root: string): Promise<ConductorInfo>;
|
|
23
37
|
/** Build an index of all scenarios in a Conductor project. */
|
|
24
38
|
export declare function indexConductor(conductorRoot: string): Promise<ConductorIndex>;
|
|
25
39
|
export interface ValidationResult {
|
package/dist/conductor.js
CHANGED
|
@@ -80,6 +80,66 @@ function parseFeatureFile(content, file) {
|
|
|
80
80
|
}
|
|
81
81
|
return scenarios;
|
|
82
82
|
}
|
|
83
|
+
async function dirExists(p) {
|
|
84
|
+
try {
|
|
85
|
+
return (await fs.stat(p)).isDirectory();
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async function fileExists(p) {
|
|
92
|
+
try {
|
|
93
|
+
return (await fs.stat(p)).isFile();
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const CUCUMBER_CONFIGS = [
|
|
100
|
+
"cucumber.js",
|
|
101
|
+
"cucumber.cjs",
|
|
102
|
+
"cucumber.mjs",
|
|
103
|
+
"cucumber.json",
|
|
104
|
+
"cucumber.yaml",
|
|
105
|
+
"cucumber.yml",
|
|
106
|
+
];
|
|
107
|
+
/** Inspect a candidate Conductor project directory without modifying anything. */
|
|
108
|
+
export async function inspectConductorProject(root) {
|
|
109
|
+
const exists = await dirExists(root);
|
|
110
|
+
const hasFeaturesDir = exists && (await dirExists(path.join(root, "features")));
|
|
111
|
+
let cucumberConfig = null;
|
|
112
|
+
if (exists) {
|
|
113
|
+
for (const c of CUCUMBER_CONFIGS) {
|
|
114
|
+
if (await fileExists(path.join(root, c))) {
|
|
115
|
+
cucumberConfig = c;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
let name = path.basename(root);
|
|
121
|
+
try {
|
|
122
|
+
const pkg = JSON.parse(await fs.readFile(path.join(root, "package.json"), "utf8"));
|
|
123
|
+
if (pkg && typeof pkg.name === "string" && pkg.name)
|
|
124
|
+
name = pkg.name;
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// no package.json — keep folder name
|
|
128
|
+
}
|
|
129
|
+
let featureFiles = 0;
|
|
130
|
+
if (hasFeaturesDir) {
|
|
131
|
+
featureFiles = (await walk(path.join(root, "features"), (f) => f.endsWith(".feature"))).length;
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
path: root,
|
|
135
|
+
exists,
|
|
136
|
+
isConductorProject: exists && (hasFeaturesDir || cucumberConfig !== null),
|
|
137
|
+
hasFeaturesDir,
|
|
138
|
+
cucumberConfig,
|
|
139
|
+
name,
|
|
140
|
+
featureFiles,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
83
143
|
/** Build an index of all scenarios in a Conductor project. */
|
|
84
144
|
export async function indexConductor(conductorRoot) {
|
|
85
145
|
const featureFiles = await walk(path.join(conductorRoot, "features"), (f) => f.endsWith(".feature"));
|
package/dist/conductor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conductor.js","sourceRoot":"","sources":["../src/conductor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AA0BpD,KAAK,UAAU,IAAI,CAAC,GAAW,EAAE,KAA6B;IAC5D,IAAI,OAAmC,CAAC;IACxC,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAK,GAA6B,EAAE,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QACjE,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACpB,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YAClE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC;aAAM,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,eAAe,CAAC,IAAc;IACrC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,OAAe,EAAE,IAAY;IACrD,IAAI,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC9C,IAAI,WAAW,GAAa,EAAE,CAAC;IAC/B,IAAI,WAAW,GAAa,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAwB,EAAE,CAAC;IAE1C,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAElD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,WAAW,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;YACrC,SAAS;QACX,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC3C,IAAI,EAAE,EAAE,CAAC;YACP,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACvB,WAAW,GAAG,WAAW,CAAC;YAC1B,WAAW,GAAG,EAAE,CAAC;YACjB,SAAS;QACX,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC3D,IAAI,EAAE,EAAE,CAAC;YACP,MAAM,IAAI,GAAG,CAAC,GAAG,WAAW,EAAE,GAAG,WAAW,CAAC,CAAC;YAC9C,SAAS,CAAC,IAAI,CAAC;gBACb,OAAO;gBACP,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;gBAClB,IAAI;gBACJ,IAAI;gBACJ,OAAO,EAAE,eAAe,CAAC,IAAI,CAAC;aAC/B,CAAC,CAAC;YACH,WAAW,GAAG,EAAE,CAAC;YACjB,SAAS;QACX,CAAC;QACD,yEAAyE;QACzE,WAAW,GAAG,EAAE,CAAC;IACnB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,aAAqB;IACxD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IACrG,MAAM,SAAS,GAAwB,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,SAAS,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,CAAC;AACvB,CAAC;AAQD,mEAAmE;AACnE,MAAM,UAAU,eAAe,CAAC,GAAsC,EAAE,KAAqB;IAC3F,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC;IAChG,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAC5C,4DAA4D;IAC5D,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;IAClE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,aAAa,GAAG,CAAC,IAAI,iCAAiC,GAAG,CAAC,OAAO,IAAI;YAC7E,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;SAC5D,CAAC;IACJ,CAAC;IACD,OAAO;QACL,EAAE,EAAE,KAAK;QACT,MAAM,EAAE,gBAAgB,GAAG,CAAC,IAAI,uBAAuB,GAAG,CAAC,OAAO,IAAI;QACtE,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;KACxF,CAAC;AACJ,CAAC;AAED,gEAAgE;AAChE,SAAS,OAAO,CAAC,MAAc,EAAE,IAAc,EAAE,KAAK,GAAG,CAAC;IACxD,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAC/B,OAAO,IAAI;SACR,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;SACvD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SACzB,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,WAAW,CAAC,CAAS,EAAE,CAAS;IACvC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IACnB,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IACnB,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtB,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtB,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACtD,IAAI,IAAI,GAAG,IAAI,KAAK,CAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACvE,CAAC;QACD,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,sDAAsD;AACtD,MAAM,UAAU,gBAAgB,CAAC,KAAqB;IACpD,MAAM,GAAG,GAAG,IAAI,GAAG,EAA+B,CAAC;IACnD,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACjC,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACjC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACb,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,kBAAkB,CAAC,KAAqB;IACtD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,SAAS;QAAE,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM;YAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9E,OAAO,GAAG,CAAC;AACb,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,iBAAiB,CAC/B,KAAqB,EACrB,aAA0B;IAE1B,MAAM,GAAG,GAAqE,EAAE,CAAC;IACjF,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACjC,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;YAC/B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACxG,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"conductor.js","sourceRoot":"","sources":["../src/conductor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AA0BpD,KAAK,UAAU,IAAI,CAAC,GAAW,EAAE,KAA6B;IAC5D,IAAI,OAAmC,CAAC;IACxC,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAK,GAA6B,EAAE,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QACjE,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACpB,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YAClE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC;aAAM,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,eAAe,CAAC,IAAc;IACrC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,OAAe,EAAE,IAAY;IACrD,IAAI,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC9C,IAAI,WAAW,GAAa,EAAE,CAAC;IAC/B,IAAI,WAAW,GAAa,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAwB,EAAE,CAAC;IAE1C,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAElD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,WAAW,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;YACrC,SAAS;QACX,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC3C,IAAI,EAAE,EAAE,CAAC;YACP,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACvB,WAAW,GAAG,WAAW,CAAC;YAC1B,WAAW,GAAG,EAAE,CAAC;YACjB,SAAS;QACX,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC3D,IAAI,EAAE,EAAE,CAAC;YACP,MAAM,IAAI,GAAG,CAAC,GAAG,WAAW,EAAE,GAAG,WAAW,CAAC,CAAC;YAC9C,SAAS,CAAC,IAAI,CAAC;gBACb,OAAO;gBACP,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;gBAClB,IAAI;gBACJ,IAAI;gBACJ,OAAO,EAAE,eAAe,CAAC,IAAI,CAAC;aAC/B,CAAC,CAAC;YACH,WAAW,GAAG,EAAE,CAAC;YACjB,SAAS;QACX,CAAC;QACD,yEAAyE;QACzE,WAAW,GAAG,EAAE,CAAC;IACnB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,CAAS;IAChC,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,CAAS;IACjC,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,gBAAgB,GAAG;IACvB,aAAa;IACb,cAAc;IACd,cAAc;IACd,eAAe;IACf,eAAe;IACf,cAAc;CACf,CAAC;AAeF,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,IAAY;IACxD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IAEhF,IAAI,cAAc,GAAkB,IAAI,CAAC;IACzC,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC;YACjC,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzC,cAAc,GAAG,CAAC,CAAC;gBACnB,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACnF,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI;YAAE,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,qCAAqC;IACvC,CAAC;IAED,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,cAAc,EAAE,CAAC;QACnB,YAAY,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACjG,CAAC;IAED,OAAO;QACL,IAAI,EAAE,IAAI;QACV,MAAM;QACN,kBAAkB,EAAE,MAAM,IAAI,CAAC,cAAc,IAAI,cAAc,KAAK,IAAI,CAAC;QACzE,cAAc;QACd,cAAc;QACd,IAAI;QACJ,YAAY;KACb,CAAC;AACJ,CAAC;AAED,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,aAAqB;IACxD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IACrG,MAAM,SAAS,GAAwB,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,SAAS,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,CAAC;AACvB,CAAC;AAQD,mEAAmE;AACnE,MAAM,UAAU,eAAe,CAAC,GAAsC,EAAE,KAAqB;IAC3F,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC;IAChG,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAC5C,4DAA4D;IAC5D,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;IAClE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,aAAa,GAAG,CAAC,IAAI,iCAAiC,GAAG,CAAC,OAAO,IAAI;YAC7E,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;SAC5D,CAAC;IACJ,CAAC;IACD,OAAO;QACL,EAAE,EAAE,KAAK;QACT,MAAM,EAAE,gBAAgB,GAAG,CAAC,IAAI,uBAAuB,GAAG,CAAC,OAAO,IAAI;QACtE,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;KACxF,CAAC;AACJ,CAAC;AAED,gEAAgE;AAChE,SAAS,OAAO,CAAC,MAAc,EAAE,IAAc,EAAE,KAAK,GAAG,CAAC;IACxD,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAC/B,OAAO,IAAI;SACR,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;SACvD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SACzB,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,WAAW,CAAC,CAAS,EAAE,CAAS;IACvC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IACnB,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IACnB,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtB,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtB,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACtD,IAAI,IAAI,GAAG,IAAI,KAAK,CAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACvE,CAAC;QACD,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,sDAAsD;AACtD,MAAM,UAAU,gBAAgB,CAAC,KAAqB;IACpD,MAAM,GAAG,GAAG,IAAI,GAAG,EAA+B,CAAC;IACnD,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACjC,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACjC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACb,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,kBAAkB,CAAC,KAAqB;IACtD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,SAAS;QAAE,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM;YAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9E,OAAO,GAAG,CAAC;AACb,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,iBAAiB,CAC/B,KAAqB,EACrB,aAA0B;IAE1B,MAAM,GAAG,GAAqE,EAAE,CAAC;IACjF,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACjC,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;YAC/B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACxG,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
package/dist/coverage.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type CoverageMode, type Execution, type Phase, type Requirement, type TestStatus, type UserStory } from "./schema.js";
|
|
1
|
+
import { type CoverageMode, type Execution, type Phase, type Requirement, type TestStatus, type UserStory, type VcsRef } from "./schema.js";
|
|
2
2
|
import type { ConductorScenario } from "./conductor.js";
|
|
3
3
|
/**
|
|
4
4
|
* Phase-aware, story-level coverage rollup.
|
|
@@ -19,6 +19,16 @@ import type { ConductorScenario } from "./conductor.js";
|
|
|
19
19
|
*/
|
|
20
20
|
export type StatusMap = Map<string, TestStatus>;
|
|
21
21
|
export type ScenariosByStory = Map<string, ConductorScenario[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Whether a requirement/story is in scope for a phase report.
|
|
24
|
+
*
|
|
25
|
+
* Mirrors the execution cumulative/strict model:
|
|
26
|
+
* - unassigned (no phase) → always in scope (backward-compatible),
|
|
27
|
+
* - strict → only items assigned to the target phase,
|
|
28
|
+
* - cumulative → items assigned to the target phase or any earlier phase.
|
|
29
|
+
* An item whose phase id is unknown (not in `phases`) is treated as unassigned.
|
|
30
|
+
*/
|
|
31
|
+
export declare function inScope(itemPhase: string | undefined, targetPhaseId: string | null, phases: Phase[], mode: CoverageMode): boolean;
|
|
22
32
|
export declare function resolveStatuses(executionsByPhase: Map<string, Execution[]>, phases: Phase[], targetPhaseId: string | null, mode: CoverageMode): StatusMap;
|
|
23
33
|
export interface ScenarioCoverage {
|
|
24
34
|
feature: string;
|
|
@@ -38,6 +48,16 @@ export interface StoryCoverage {
|
|
|
38
48
|
tested: boolean;
|
|
39
49
|
/** Covered = tested AND every tagged scenario passes. */
|
|
40
50
|
covered: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Merged-MR is a SEPARATE dimension from `covered` (it does not affect it):
|
|
53
|
+
* the merge-request VcsRef (kind="mr") referencing this story, preferring a
|
|
54
|
+
* state="merged" ref. Optional / backward-compatible.
|
|
55
|
+
*/
|
|
56
|
+
mergedMr?: {
|
|
57
|
+
ref: string;
|
|
58
|
+
state: string;
|
|
59
|
+
url: string;
|
|
60
|
+
};
|
|
41
61
|
}
|
|
42
62
|
export interface RequirementCoverage {
|
|
43
63
|
id: string;
|
|
@@ -77,8 +97,12 @@ export interface CoverageReport {
|
|
|
77
97
|
byComponent: ComponentCoverage[];
|
|
78
98
|
summary: CoverageSummary;
|
|
79
99
|
}
|
|
80
|
-
export declare function computeStoryCoverage(story: UserStory, scenariosByStory: ScenariosByStory, status: StatusMap
|
|
81
|
-
|
|
100
|
+
export declare function computeStoryCoverage(story: UserStory, scenariosByStory: ScenariosByStory, status: StatusMap, mergedMr?: {
|
|
101
|
+
ref: string;
|
|
102
|
+
state: string;
|
|
103
|
+
url: string;
|
|
104
|
+
}): StoryCoverage;
|
|
105
|
+
export declare function buildReport(requirements: Requirement[], stories: UserStory[], scenariosByStory: ScenariosByStory, status: StatusMap, phaseId: string | null, mode: CoverageMode, vcsRefs?: VcsRef[], phases?: Phase[]): CoverageReport;
|
|
82
106
|
export interface TrendPoint {
|
|
83
107
|
phase: string;
|
|
84
108
|
phaseName: string;
|
|
@@ -106,4 +130,4 @@ export interface Gaps {
|
|
|
106
130
|
pending: string[];
|
|
107
131
|
}[];
|
|
108
132
|
}
|
|
109
|
-
export declare function findGaps(requirements: Requirement[], stories: UserStory[], scenariosByStory: ScenariosByStory, status: StatusMap, phaseId: string | null, mode: CoverageMode): Gaps;
|
|
133
|
+
export declare function findGaps(requirements: Requirement[], stories: UserStory[], scenariosByStory: ScenariosByStory, status: StatusMap, phaseId: string | null, mode: CoverageMode, phases?: Phase[]): Gaps;
|
package/dist/coverage.js
CHANGED
|
@@ -1,4 +1,26 @@
|
|
|
1
1
|
import { testKey, } from "./schema.js";
|
|
2
|
+
/**
|
|
3
|
+
* Whether a requirement/story is in scope for a phase report.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors the execution cumulative/strict model:
|
|
6
|
+
* - unassigned (no phase) → always in scope (backward-compatible),
|
|
7
|
+
* - strict → only items assigned to the target phase,
|
|
8
|
+
* - cumulative → items assigned to the target phase or any earlier phase.
|
|
9
|
+
* An item whose phase id is unknown (not in `phases`) is treated as unassigned.
|
|
10
|
+
*/
|
|
11
|
+
export function inScope(itemPhase, targetPhaseId, phases, mode) {
|
|
12
|
+
if (!itemPhase)
|
|
13
|
+
return true;
|
|
14
|
+
if (!targetPhaseId)
|
|
15
|
+
return true;
|
|
16
|
+
if (mode === "strict")
|
|
17
|
+
return itemPhase === targetPhaseId;
|
|
18
|
+
const itemOrder = phases.find((p) => p.id === itemPhase)?.order;
|
|
19
|
+
const targetOrder = phases.find((p) => p.id === targetPhaseId)?.order;
|
|
20
|
+
if (itemOrder === undefined || targetOrder === undefined)
|
|
21
|
+
return true;
|
|
22
|
+
return itemOrder <= targetOrder;
|
|
23
|
+
}
|
|
2
24
|
export function resolveStatuses(executionsByPhase, phases, targetPhaseId, mode) {
|
|
3
25
|
const out = new Map();
|
|
4
26
|
if (!targetPhaseId)
|
|
@@ -16,10 +38,25 @@ export function resolveStatuses(executionsByPhase, phases, targetPhaseId, mode)
|
|
|
16
38
|
}
|
|
17
39
|
return out;
|
|
18
40
|
}
|
|
41
|
+
/** Build a story-id → best MR reference map (prefers a merged MR). */
|
|
42
|
+
function mergedMrByStory(vcsRefs) {
|
|
43
|
+
const out = new Map();
|
|
44
|
+
const mrs = vcsRefs.filter((r) => r.kind === "mr");
|
|
45
|
+
for (const mr of mrs) {
|
|
46
|
+
for (const storyId of mr.storyIds) {
|
|
47
|
+
const current = out.get(storyId);
|
|
48
|
+
// Prefer a merged ref; otherwise keep the first seen.
|
|
49
|
+
if (!current || (current.state !== "merged" && mr.state === "merged")) {
|
|
50
|
+
out.set(storyId, { ref: mr.ref, state: mr.state, url: mr.url });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
19
56
|
function pct(num, den) {
|
|
20
57
|
return den === 0 ? 0 : Math.round((num / den) * 1000) / 10;
|
|
21
58
|
}
|
|
22
|
-
export function computeStoryCoverage(story, scenariosByStory, status) {
|
|
59
|
+
export function computeStoryCoverage(story, scenariosByStory, status, mergedMr) {
|
|
23
60
|
const scs = scenariosByStory.get(story.id) ?? [];
|
|
24
61
|
let passing = 0;
|
|
25
62
|
let failing = 0;
|
|
@@ -45,10 +82,15 @@ export function computeStoryCoverage(story, scenariosByStory, status) {
|
|
|
45
82
|
pending,
|
|
46
83
|
tested: scs.length > 0,
|
|
47
84
|
covered: scs.length > 0 && passing === scs.length,
|
|
85
|
+
...(mergedMr ? { mergedMr } : {}),
|
|
48
86
|
};
|
|
49
87
|
}
|
|
50
|
-
export function buildReport(requirements, stories, scenariosByStory, status, phaseId, mode) {
|
|
51
|
-
|
|
88
|
+
export function buildReport(requirements, stories, scenariosByStory, status, phaseId, mode, vcsRefs = [], phases = []) {
|
|
89
|
+
// Scope to the items planned for this phase (unassigned items always count).
|
|
90
|
+
requirements = requirements.filter((r) => inScope(r.phase, phaseId, phases, mode));
|
|
91
|
+
stories = stories.filter((s) => inScope(s.phase, phaseId, phases, mode));
|
|
92
|
+
const mrByStory = mergedMrByStory(vcsRefs);
|
|
93
|
+
const storyCov = stories.map((s) => computeStoryCoverage(s, scenariosByStory, status, mrByStory.get(s.id)));
|
|
52
94
|
const storyById = new Map(storyCov.map((s) => [s.id, s]));
|
|
53
95
|
const storiesByReq = new Map();
|
|
54
96
|
for (const s of stories) {
|
|
@@ -127,12 +169,12 @@ export function buildTrend(requirements, stories, scenariosByStory, executionsBy
|
|
|
127
169
|
.sort((a, b) => a.order - b.order)
|
|
128
170
|
.map((p) => {
|
|
129
171
|
const status = resolveStatuses(executionsByPhase, phases, p.id, mode);
|
|
130
|
-
const report = buildReport(requirements, stories, scenariosByStory, status, p.id, mode);
|
|
172
|
+
const report = buildReport(requirements, stories, scenariosByStory, status, p.id, mode, [], phases);
|
|
131
173
|
return { phase: p.id, phaseName: p.name, order: p.order, summary: report.summary };
|
|
132
174
|
});
|
|
133
175
|
}
|
|
134
|
-
export function findGaps(requirements, stories, scenariosByStory, status, phaseId, mode) {
|
|
135
|
-
const report = buildReport(requirements, stories, scenariosByStory, status, phaseId, mode);
|
|
176
|
+
export function findGaps(requirements, stories, scenariosByStory, status, phaseId, mode, phases = []) {
|
|
177
|
+
const report = buildReport(requirements, stories, scenariosByStory, status, phaseId, mode, [], phases);
|
|
136
178
|
const requirementsWithoutStory = report.requirements
|
|
137
179
|
.filter((r) => r.status === "active" && !r.hasStory)
|
|
138
180
|
.map((r) => ({ id: r.id, title: r.title, priority: r.priority, components: r.components }));
|
package/dist/coverage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../src/coverage.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,
|
|
1
|
+
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../src/coverage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared export/import logic — used by both MCP tools and REST routes.
|
|
3
|
+
*/
|
|
4
|
+
import type { Store } from "./storage.js";
|
|
5
|
+
import type { SqliteStore } from "./sqlite-store.js";
|
|
6
|
+
import type { ExportPayload, ImportReport } from "./schema.js";
|
|
7
|
+
type AnyStore = Store | SqliteStore;
|
|
8
|
+
export declare function buildExport(store: AnyStore): Promise<ExportPayload>;
|
|
9
|
+
export declare function applyImport(store: AnyStore, payload: ExportPayload): Promise<ImportReport>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export async function buildExport(store) {
|
|
2
|
+
const [config, components, requirements, stories, phases, vcsRefs, executionsByPhase] = await Promise.all([
|
|
3
|
+
store.readConfig().catch(() => null),
|
|
4
|
+
store.listComponents(),
|
|
5
|
+
store.listRequirements(),
|
|
6
|
+
store.listStories(),
|
|
7
|
+
store.listPhases(),
|
|
8
|
+
store.listVcsRefs(),
|
|
9
|
+
store.readAllExecutions(),
|
|
10
|
+
]);
|
|
11
|
+
// Convert Map<phaseId, Execution[]> to plain object
|
|
12
|
+
const executions = {};
|
|
13
|
+
for (const [phaseId, runs] of executionsByPhase.entries()) {
|
|
14
|
+
executions[phaseId] = runs;
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
version: "1",
|
|
18
|
+
exportedAt: new Date().toISOString(),
|
|
19
|
+
source: config ? { name: config.name } : undefined,
|
|
20
|
+
data: { components, requirements, stories, phases, executions, vcsRefs },
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export async function applyImport(store, payload) {
|
|
24
|
+
const report = {
|
|
25
|
+
imported: {},
|
|
26
|
+
skipped: {},
|
|
27
|
+
errors: [],
|
|
28
|
+
};
|
|
29
|
+
const inc = (key) => { report.imported[key] = (report.imported[key] ?? 0) + 1; };
|
|
30
|
+
const skip = (key, id) => {
|
|
31
|
+
(report.skipped[key] ??= []).push(id);
|
|
32
|
+
};
|
|
33
|
+
// Fetch existing IDs for all entity types in parallel
|
|
34
|
+
const [existingComponents, existingRequirements, existingStories, existingPhases, existingVcsRefs, existingExecutionsByPhase,] = await Promise.all([
|
|
35
|
+
store.listComponents(),
|
|
36
|
+
store.listRequirements(),
|
|
37
|
+
store.listStories(),
|
|
38
|
+
store.listPhases(),
|
|
39
|
+
store.listVcsRefs(),
|
|
40
|
+
store.readAllExecutions(),
|
|
41
|
+
]);
|
|
42
|
+
const existingComponentIds = new Set(existingComponents.map(x => x.id));
|
|
43
|
+
const existingRequirementIds = new Set(existingRequirements.map(x => x.id));
|
|
44
|
+
const existingStoryIds = new Set(existingStories.map(x => x.id));
|
|
45
|
+
const existingPhaseIds = new Set(existingPhases.map(x => x.id));
|
|
46
|
+
const existingVcsRefIds = new Set(existingVcsRefs.map(x => x.id));
|
|
47
|
+
const { data } = payload;
|
|
48
|
+
// --- Components ---
|
|
49
|
+
for (const comp of data.components) {
|
|
50
|
+
if (existingComponentIds.has(comp.id)) {
|
|
51
|
+
skip("components", comp.id);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
await store.writeComponent(comp);
|
|
55
|
+
existingComponentIds.add(comp.id);
|
|
56
|
+
inc("components");
|
|
57
|
+
}
|
|
58
|
+
// --- Requirements ---
|
|
59
|
+
for (const req of data.requirements) {
|
|
60
|
+
if (existingRequirementIds.has(req.id)) {
|
|
61
|
+
skip("requirements", req.id);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
await store.writeRequirement(req);
|
|
65
|
+
existingRequirementIds.add(req.id);
|
|
66
|
+
inc("requirements");
|
|
67
|
+
}
|
|
68
|
+
// --- Stories ---
|
|
69
|
+
for (const story of data.stories) {
|
|
70
|
+
if (existingStoryIds.has(story.id)) {
|
|
71
|
+
skip("stories", story.id);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
// FK check: all referenced requirements must exist (in DB or just imported)
|
|
75
|
+
const missingReqs = story.requirements.filter(rid => !existingRequirementIds.has(rid));
|
|
76
|
+
if (missingReqs.length > 0) {
|
|
77
|
+
report.errors.push(`Story ${story.id} references unknown requirement(s): ${missingReqs.join(", ")}`);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
await store.writeStory(story);
|
|
81
|
+
existingStoryIds.add(story.id);
|
|
82
|
+
inc("stories");
|
|
83
|
+
}
|
|
84
|
+
// --- Phases ---
|
|
85
|
+
for (const phase of data.phases) {
|
|
86
|
+
if (existingPhaseIds.has(phase.id)) {
|
|
87
|
+
skip("phases", phase.id);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
await store.writePhase(phase);
|
|
91
|
+
existingPhaseIds.add(phase.id);
|
|
92
|
+
inc("phases");
|
|
93
|
+
}
|
|
94
|
+
// --- Executions (keyed by phaseId) ---
|
|
95
|
+
for (const [phaseId, runs] of Object.entries(data.executions)) {
|
|
96
|
+
if (!existingPhaseIds.has(phaseId)) {
|
|
97
|
+
report.errors.push(`Executions reference unknown phase "${phaseId}" — skipped ${runs.length} execution(s)`);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
// Build a set of existing execution keys for this phase to avoid duplicates
|
|
101
|
+
const existingForPhase = existingExecutionsByPhase.get(phaseId) ?? [];
|
|
102
|
+
const existingKeys = new Set(existingForPhase.map(e => `${e.feature}::${e.name}`));
|
|
103
|
+
const newRuns = runs.filter(e => !existingKeys.has(`${e.feature}::${e.name}`));
|
|
104
|
+
const skippedCount = runs.length - newRuns.length;
|
|
105
|
+
if (skippedCount > 0) {
|
|
106
|
+
(report.skipped["executions"] ??= []).push(...runs
|
|
107
|
+
.filter(e => existingKeys.has(`${e.feature}::${e.name}`))
|
|
108
|
+
.map(e => `${phaseId}::${e.feature}::${e.name}`));
|
|
109
|
+
}
|
|
110
|
+
if (newRuns.length > 0) {
|
|
111
|
+
await store.appendExecutions(phaseId, newRuns);
|
|
112
|
+
report.imported["executions"] = (report.imported["executions"] ?? 0) + newRuns.length;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// --- VCS Refs ---
|
|
116
|
+
for (const ref of data.vcsRefs) {
|
|
117
|
+
if (existingVcsRefIds.has(ref.id)) {
|
|
118
|
+
skip("vcsRefs", ref.id);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
await store.writeVcsRef(ref);
|
|
122
|
+
existingVcsRefIds.add(ref.id);
|
|
123
|
+
inc("vcsRefs");
|
|
124
|
+
}
|
|
125
|
+
return report;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=export-import.js.map
|