@sdd-method/sdd-cli 0.17.0 → 0.21.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/lib/catalogue/build.d.ts.map +1 -1
- package/dist/lib/catalogue/build.js +92 -5
- package/dist/lib/catalogue/build.js.map +1 -1
- package/dist/lib/catalogue/builders/c4-containers.d.ts.map +1 -1
- package/dist/lib/catalogue/builders/c4-containers.js +15 -0
- package/dist/lib/catalogue/builders/c4-containers.js.map +1 -1
- package/dist/lib/catalogue/builders/capability-spec-walker.d.ts +55 -0
- package/dist/lib/catalogue/builders/capability-spec-walker.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/capability-spec-walker.js +99 -0
- package/dist/lib/catalogue/builders/capability-spec-walker.js.map +1 -0
- package/dist/lib/catalogue/builders/capability-spec.d.ts +51 -0
- package/dist/lib/catalogue/builders/capability-spec.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/capability-spec.js +276 -0
- package/dist/lib/catalogue/builders/capability-spec.js.map +1 -0
- package/dist/lib/catalogue/builders/contracts.d.ts.map +1 -1
- package/dist/lib/catalogue/builders/contracts.js +88 -41
- package/dist/lib/catalogue/builders/contracts.js.map +1 -1
- package/dist/lib/catalogue/builders/feature-grounding-walker.d.ts +68 -0
- package/dist/lib/catalogue/builders/feature-grounding-walker.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/feature-grounding-walker.js +254 -0
- package/dist/lib/catalogue/builders/feature-grounding-walker.js.map +1 -0
- package/dist/lib/catalogue/builders/feature-grounding.d.ts +53 -0
- package/dist/lib/catalogue/builders/feature-grounding.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/feature-grounding.js +312 -0
- package/dist/lib/catalogue/builders/feature-grounding.js.map +1 -0
- package/dist/lib/catalogue/builders/index.d.ts +6 -0
- package/dist/lib/catalogue/builders/index.d.ts.map +1 -1
- package/dist/lib/catalogue/builders/index.js +3 -0
- package/dist/lib/catalogue/builders/index.js.map +1 -1
- package/dist/lib/catalogue/builders/integrations.d.ts.map +1 -1
- package/dist/lib/catalogue/builders/integrations.js +69 -14
- package/dist/lib/catalogue/builders/integrations.js.map +1 -1
- package/dist/lib/catalogue/builders/service-contract-consumes.d.ts +24 -0
- package/dist/lib/catalogue/builders/service-contract-consumes.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/service-contract-consumes.js +173 -0
- package/dist/lib/catalogue/builders/service-contract-consumes.js.map +1 -0
- package/dist/lib/catalogue/canonical-schema.yaml +7 -7
- package/dist/lib/catalogue/feature-grounding-aliases-loader.d.ts +36 -0
- package/dist/lib/catalogue/feature-grounding-aliases-loader.d.ts.map +1 -0
- package/dist/lib/catalogue/feature-grounding-aliases-loader.js +65 -0
- package/dist/lib/catalogue/feature-grounding-aliases-loader.js.map +1 -0
- package/dist/lib/catalogue/service-contract-aliases-loader.d.ts +60 -0
- package/dist/lib/catalogue/service-contract-aliases-loader.d.ts.map +1 -0
- package/dist/lib/catalogue/service-contract-aliases-loader.js +109 -0
- package/dist/lib/catalogue/service-contract-aliases-loader.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walker for `feature-grounding.md` files per ADR 0143 (schema 2.5.0).
|
|
3
|
+
*
|
|
4
|
+
* Reads markdown tables of the canonical shape:
|
|
5
|
+
*
|
|
6
|
+
* | Feature | UI Components | API Routes | Backend Handlers | Data Entities | Evidence |
|
|
7
|
+
* |---|---|---|---|---|---|
|
|
8
|
+
* | `oauth2-login` | ... | BFF `GET /login` | `AuthHandler.handle...()` | Token | `auth-handler.ts` |
|
|
9
|
+
*
|
|
10
|
+
* Path conventions (per ADR 0143 §4.3):
|
|
11
|
+
* - platform-profile: `docs/domains/<dom>/design/<capability>/feature-grounding.md`
|
|
12
|
+
* - integration-product: `docs/design/integration/feature-grounding.md`
|
|
13
|
+
*
|
|
14
|
+
* Tolerant of column re-ordering and missing optional columns. The only
|
|
15
|
+
* required column is `Feature`. Lines inside ```fenced``` code blocks
|
|
16
|
+
* are skipped. Recovery is row-local — a malformed row emits a finding
|
|
17
|
+
* and the walker continues with the next row.
|
|
18
|
+
*/
|
|
19
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
20
|
+
import { join, relative, sep } from "node:path";
|
|
21
|
+
const DOMAINS_DIR_REL = join("docs", "domains");
|
|
22
|
+
const PLATFORM_LEAF = "feature-grounding.md";
|
|
23
|
+
/**
|
|
24
|
+
* Find all `docs/domains/<dom>/design/<capability>/feature-grounding.md`
|
|
25
|
+
* files under the SDD root. Sorted for deterministic output.
|
|
26
|
+
*/
|
|
27
|
+
export async function findPlatformGroundingFiles(sddPath) {
|
|
28
|
+
const out = [];
|
|
29
|
+
const domainsDir = join(sddPath, DOMAINS_DIR_REL);
|
|
30
|
+
let domains;
|
|
31
|
+
try {
|
|
32
|
+
domains = await readdir(domainsDir, { withFileTypes: true });
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
for (const d of domains) {
|
|
38
|
+
if (!d.isDirectory())
|
|
39
|
+
continue;
|
|
40
|
+
const designDir = join(domainsDir, d.name, "design");
|
|
41
|
+
let caps;
|
|
42
|
+
try {
|
|
43
|
+
caps = await readdir(designDir, { withFileTypes: true });
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
for (const c of caps) {
|
|
49
|
+
if (!c.isDirectory())
|
|
50
|
+
continue;
|
|
51
|
+
const candidate = join(designDir, c.name, PLATFORM_LEAF);
|
|
52
|
+
try {
|
|
53
|
+
await readFile(candidate, "utf-8");
|
|
54
|
+
out.push(candidate);
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
const code = err.code;
|
|
58
|
+
if (code === "ENOENT")
|
|
59
|
+
continue;
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return out.sort();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Find the single integration-product feature-grounding.md, if any.
|
|
68
|
+
* Path: `docs/design/integration/feature-grounding.md`.
|
|
69
|
+
*/
|
|
70
|
+
export async function findIntegrationGroundingFile(sddPath) {
|
|
71
|
+
const candidate = join(sddPath, "docs", "design", "integration", PLATFORM_LEAF);
|
|
72
|
+
try {
|
|
73
|
+
await readFile(candidate, "utf-8");
|
|
74
|
+
return candidate;
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
const code = err.code;
|
|
78
|
+
if (code === "ENOENT")
|
|
79
|
+
return null;
|
|
80
|
+
throw err;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Resolve the capability id from a platform-profile grounding file's
|
|
85
|
+
* absolute path. Returns the parent folder name. Callers verify the
|
|
86
|
+
* id resolves against `capabilities.csv` and emit findings on miss.
|
|
87
|
+
*/
|
|
88
|
+
export function capabilityIdFromPath(absPath, sddPath) {
|
|
89
|
+
const rel = relative(sddPath, absPath);
|
|
90
|
+
const parts = rel.split(sep);
|
|
91
|
+
// Expected: ["docs", "domains", "<dom>", "design", "<capability>", "feature-grounding.md"]
|
|
92
|
+
if (parts.length < 6)
|
|
93
|
+
return "";
|
|
94
|
+
return parts[parts.length - 2] ?? "";
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Parse the markdown content of a feature-grounding.md file and return
|
|
98
|
+
* the rows from its first valid feature table. A "valid table" has a
|
|
99
|
+
* header row whose first non-empty cell normalises to `feature`.
|
|
100
|
+
* Returns an empty array if no such table is found (caller logs a
|
|
101
|
+
* coverage finding).
|
|
102
|
+
*/
|
|
103
|
+
export function parseGroundingTable(text) {
|
|
104
|
+
const lines = text.split(/\r?\n/);
|
|
105
|
+
let inFence = false;
|
|
106
|
+
let i = 0;
|
|
107
|
+
while (i < lines.length) {
|
|
108
|
+
const raw = lines[i] ?? "";
|
|
109
|
+
if (isFenceToggle(raw)) {
|
|
110
|
+
inFence = !inFence;
|
|
111
|
+
i++;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (inFence) {
|
|
115
|
+
i++;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (!isTableRowLine(raw)) {
|
|
119
|
+
i++;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
// Candidate header row. Need a separator row right after.
|
|
123
|
+
const next = lines[i + 1] ?? "";
|
|
124
|
+
if (!isSeparatorRowLine(next)) {
|
|
125
|
+
i++;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
const headers = splitTableRow(raw).map(normaliseHeader);
|
|
129
|
+
if (headers.length === 0 || headers[0] !== "feature") {
|
|
130
|
+
i++;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
// Found the table. Walk body rows until non-table line.
|
|
134
|
+
return parseBodyRows(lines, i + 2, headers);
|
|
135
|
+
}
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
function parseBodyRows(lines, startIdx, headers) {
|
|
139
|
+
const rows = [];
|
|
140
|
+
let inFence = false;
|
|
141
|
+
for (let i = startIdx; i < lines.length; i++) {
|
|
142
|
+
const raw = lines[i] ?? "";
|
|
143
|
+
if (isFenceToggle(raw)) {
|
|
144
|
+
inFence = !inFence;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (inFence)
|
|
148
|
+
continue;
|
|
149
|
+
if (!isTableRowLine(raw)) {
|
|
150
|
+
// Allow a single blank line inside the table; anything else ends it.
|
|
151
|
+
if (raw.trim() === "")
|
|
152
|
+
continue;
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
const cells = splitTableRow(raw);
|
|
156
|
+
const featureCell = cells[0] ?? "";
|
|
157
|
+
const slug = extractSlug(featureCell);
|
|
158
|
+
if (slug === "") {
|
|
159
|
+
// Skip rows whose first cell isn't a recognisable slug — caller logs.
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const cellMap = new Map();
|
|
163
|
+
for (let c = 1; c < headers.length; c++) {
|
|
164
|
+
const header = headers[c] ?? "";
|
|
165
|
+
if (header === "")
|
|
166
|
+
continue;
|
|
167
|
+
cellMap.set(header, (cells[c] ?? "").trim());
|
|
168
|
+
}
|
|
169
|
+
rows.push({ slug, cells: cellMap, lineNumber: i + 1 });
|
|
170
|
+
}
|
|
171
|
+
return rows;
|
|
172
|
+
}
|
|
173
|
+
/** A line is a table row if it has at least one unescaped `|`. */
|
|
174
|
+
function isTableRowLine(raw) {
|
|
175
|
+
const trimmed = raw.trim();
|
|
176
|
+
if (!trimmed.startsWith("|") && !trimmed.includes("|"))
|
|
177
|
+
return false;
|
|
178
|
+
// Heuristic: a row must contain at least two | characters.
|
|
179
|
+
return (trimmed.match(/\|/g)?.length ?? 0) >= 2;
|
|
180
|
+
}
|
|
181
|
+
/** Separator row: `|---|---|...|`, possibly with `:` alignment markers. */
|
|
182
|
+
function isSeparatorRowLine(raw) {
|
|
183
|
+
const trimmed = raw.trim();
|
|
184
|
+
if (!trimmed.startsWith("|"))
|
|
185
|
+
return false;
|
|
186
|
+
return /^\|(\s*:?-+:?\s*\|)+\s*$/.test(trimmed);
|
|
187
|
+
}
|
|
188
|
+
function isFenceToggle(raw) {
|
|
189
|
+
const trimmed = raw.trimStart();
|
|
190
|
+
return trimmed.startsWith("```") || trimmed.startsWith("~~~");
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Split a `| a | b | c |` row into cells. Strips leading/trailing
|
|
194
|
+
* empty cells caused by the bookend pipes. Does NOT split inside
|
|
195
|
+
* backtick spans — `` `foo|bar` `` stays as one cell.
|
|
196
|
+
*/
|
|
197
|
+
function splitTableRow(raw) {
|
|
198
|
+
const cells = [];
|
|
199
|
+
let current = "";
|
|
200
|
+
let inTick = false;
|
|
201
|
+
// Skip the opening pipe if present.
|
|
202
|
+
let trimmed = raw.trim();
|
|
203
|
+
if (trimmed.startsWith("|"))
|
|
204
|
+
trimmed = trimmed.slice(1);
|
|
205
|
+
if (trimmed.endsWith("|"))
|
|
206
|
+
trimmed = trimmed.slice(0, -1);
|
|
207
|
+
for (const ch of trimmed) {
|
|
208
|
+
if (ch === "`") {
|
|
209
|
+
inTick = !inTick;
|
|
210
|
+
current += ch;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (ch === "|" && !inTick) {
|
|
214
|
+
cells.push(current);
|
|
215
|
+
current = "";
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
current += ch;
|
|
219
|
+
}
|
|
220
|
+
cells.push(current);
|
|
221
|
+
return cells;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Normalise a header cell to a key form: lowercase, trimmed, spaces
|
|
225
|
+
* and `/` collapsed to `_`. Backticks stripped. e.g. "API Routes" →
|
|
226
|
+
* "api_routes", "UI / UX" → "ui_ux".
|
|
227
|
+
*/
|
|
228
|
+
function normaliseHeader(cell) {
|
|
229
|
+
return cell
|
|
230
|
+
.replace(/`/g, "")
|
|
231
|
+
.trim()
|
|
232
|
+
.toLowerCase()
|
|
233
|
+
.replace(/[\s/]+/g, "_");
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Extract the slug from the first cell. Recognises:
|
|
237
|
+
* - `` `slug` `` → "slug"
|
|
238
|
+
* - `` `slug` (description) `` → "slug"
|
|
239
|
+
* - plain `slug-name` → "slug-name"
|
|
240
|
+
* Returns "" if no valid slug pattern matches.
|
|
241
|
+
*/
|
|
242
|
+
function extractSlug(cell) {
|
|
243
|
+
const trimmed = cell.trim();
|
|
244
|
+
// Backticked form first — the canonical shape.
|
|
245
|
+
const tickMatch = trimmed.match(/^`([a-z0-9][a-z0-9-]*)`/i);
|
|
246
|
+
if (tickMatch)
|
|
247
|
+
return tickMatch[1] ?? "";
|
|
248
|
+
// Plain kebab-case fallback.
|
|
249
|
+
const plainMatch = trimmed.match(/^([a-z][a-z0-9-]*)$/i);
|
|
250
|
+
if (plainMatch)
|
|
251
|
+
return plainMatch[1] ?? "";
|
|
252
|
+
return "";
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=feature-grounding-walker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-grounding-walker.js","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/feature-grounding-walker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature-grounding extractor per ADR 0143 (schema 2.5.0).
|
|
3
|
+
*
|
|
4
|
+
* Walks `docs/domains/<dom>/design/<capability>/feature-grounding.md`
|
|
5
|
+
* (platform-profile) and `docs/design/integration/feature-grounding.md`
|
|
6
|
+
* (integration-product), parses the canonical markdown table, and
|
|
7
|
+
* emits four catalogue contributions:
|
|
8
|
+
*
|
|
9
|
+
* - `features.csv` rows with `source: feature-grounding`.
|
|
10
|
+
* - `capability_feature.csv` rows (1:1 with each feature row).
|
|
11
|
+
* - `feature_repo.csv` rows derived from file-path references in
|
|
12
|
+
* the Evidence column.
|
|
13
|
+
* - `feature_service.csv` rows derived from class names / file
|
|
14
|
+
* basenames / route fragments in API Routes / Backend Handlers
|
|
15
|
+
* / Evidence columns, resolved via `services.csv` + the optional
|
|
16
|
+
* per-SDD alias map.
|
|
17
|
+
*
|
|
18
|
+
* Resolution failures (unresolved capability, service, repo) emit
|
|
19
|
+
* findings but never break FK validation — only confidently-resolved
|
|
20
|
+
* rows are emitted.
|
|
21
|
+
*
|
|
22
|
+
* Precedence per ADR 0143 §4.4: feature-tree and feature-spec rows
|
|
23
|
+
* win on id collision; grounding rows are skipped with a divergence
|
|
24
|
+
* finding.
|
|
25
|
+
*/
|
|
26
|
+
import type { CatalogueRow } from "../csv-writer.js";
|
|
27
|
+
import type { FindingsLog } from "../findings.js";
|
|
28
|
+
import type { LoadedAliases } from "../feature-grounding-aliases-loader.js";
|
|
29
|
+
export interface FeatureGroundingInputs {
|
|
30
|
+
readonly sddPath: string;
|
|
31
|
+
readonly findings: FindingsLog;
|
|
32
|
+
readonly profile: string;
|
|
33
|
+
/** Product id, used for integration-product capability resolution. */
|
|
34
|
+
readonly productId: string;
|
|
35
|
+
/** Set of capability ids known from capabilities.csv (for path resolution). */
|
|
36
|
+
readonly knownCapabilityIds: ReadonlySet<string>;
|
|
37
|
+
/** Set of service ids known from services.csv (for service-edge resolution). */
|
|
38
|
+
readonly knownServiceIds: ReadonlySet<string>;
|
|
39
|
+
/** Set of canonical_repo_keys known from repositories.csv. */
|
|
40
|
+
readonly knownRepoKeys: ReadonlySet<string>;
|
|
41
|
+
/** Already-emitted feature ids from earlier sources — grounding rows lose on collision. */
|
|
42
|
+
readonly existingFeatureIds: ReadonlySet<string>;
|
|
43
|
+
/** Optional alias map for display-name → canonical-id translation. */
|
|
44
|
+
readonly aliases: LoadedAliases | null;
|
|
45
|
+
}
|
|
46
|
+
export interface FeatureGroundingResult {
|
|
47
|
+
readonly featureRows: CatalogueRow[];
|
|
48
|
+
readonly capabilityFeatureRows: CatalogueRow[];
|
|
49
|
+
readonly featureRepoRows: CatalogueRow[];
|
|
50
|
+
readonly featureServiceRows: CatalogueRow[];
|
|
51
|
+
}
|
|
52
|
+
export declare function buildFeatureGrounding(inputs: FeatureGroundingInputs): Promise<FeatureGroundingResult>;
|
|
53
|
+
//# sourceMappingURL=feature-grounding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-grounding.d.ts","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/feature-grounding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAsB5E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,sEAAsE;IACtE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,+EAA+E;IAC/E,QAAQ,CAAC,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjD,gFAAgF;IAChF,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC9C,8DAA8D;IAC9D,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5C,2FAA2F;IAC3F,QAAQ,CAAC,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjD,sEAAsE;IACtE,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,WAAW,EAAE,YAAY,EAAE,CAAC;IACrC,QAAQ,CAAC,qBAAqB,EAAE,YAAY,EAAE,CAAC;IAC/C,QAAQ,CAAC,eAAe,EAAE,YAAY,EAAE,CAAC;IACzC,QAAQ,CAAC,kBAAkB,EAAE,YAAY,EAAE,CAAC;CAC7C;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,sBAAsB,CAAC,CAiIjC"}
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature-grounding extractor per ADR 0143 (schema 2.5.0).
|
|
3
|
+
*
|
|
4
|
+
* Walks `docs/domains/<dom>/design/<capability>/feature-grounding.md`
|
|
5
|
+
* (platform-profile) and `docs/design/integration/feature-grounding.md`
|
|
6
|
+
* (integration-product), parses the canonical markdown table, and
|
|
7
|
+
* emits four catalogue contributions:
|
|
8
|
+
*
|
|
9
|
+
* - `features.csv` rows with `source: feature-grounding`.
|
|
10
|
+
* - `capability_feature.csv` rows (1:1 with each feature row).
|
|
11
|
+
* - `feature_repo.csv` rows derived from file-path references in
|
|
12
|
+
* the Evidence column.
|
|
13
|
+
* - `feature_service.csv` rows derived from class names / file
|
|
14
|
+
* basenames / route fragments in API Routes / Backend Handlers
|
|
15
|
+
* / Evidence columns, resolved via `services.csv` + the optional
|
|
16
|
+
* per-SDD alias map.
|
|
17
|
+
*
|
|
18
|
+
* Resolution failures (unresolved capability, service, repo) emit
|
|
19
|
+
* findings but never break FK validation — only confidently-resolved
|
|
20
|
+
* rows are emitted.
|
|
21
|
+
*
|
|
22
|
+
* Precedence per ADR 0143 §4.4: feature-tree and feature-spec rows
|
|
23
|
+
* win on id collision; grounding rows are skipped with a divergence
|
|
24
|
+
* finding.
|
|
25
|
+
*/
|
|
26
|
+
import { readFile } from "node:fs/promises";
|
|
27
|
+
import { relative } from "node:path";
|
|
28
|
+
import { capabilityIdFromPath, findIntegrationGroundingFile, findPlatformGroundingFiles, parseGroundingTable, } from "./feature-grounding-walker.js";
|
|
29
|
+
const DESCRIPTION_MAX = 500;
|
|
30
|
+
/** Columns the service-name resolver scans for class names / route fragments. */
|
|
31
|
+
const SERVICE_RESOLUTION_COLUMNS = [
|
|
32
|
+
"ui_components",
|
|
33
|
+
"api_routes",
|
|
34
|
+
"backend_handlers",
|
|
35
|
+
"evidence",
|
|
36
|
+
];
|
|
37
|
+
/** Columns the repo-name resolver scans for file-path references. */
|
|
38
|
+
const REPO_RESOLUTION_COLUMNS = ["evidence", "ui_components"];
|
|
39
|
+
export async function buildFeatureGrounding(inputs) {
|
|
40
|
+
const featureRows = [];
|
|
41
|
+
const capabilityFeatureRows = [];
|
|
42
|
+
const featureRepoRows = [];
|
|
43
|
+
const featureServiceRows = [];
|
|
44
|
+
const seenFeatureRepo = new Set();
|
|
45
|
+
const seenFeatureService = new Set();
|
|
46
|
+
const seenFeatures = new Set(inputs.existingFeatureIds);
|
|
47
|
+
const files = [];
|
|
48
|
+
if (inputs.profile === "platform-profile") {
|
|
49
|
+
for (const absPath of await findPlatformGroundingFiles(inputs.sddPath)) {
|
|
50
|
+
const capId = capabilityIdFromPath(absPath, inputs.sddPath);
|
|
51
|
+
files.push({ absPath, capabilityId: capId });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else if (inputs.profile === "integration-product") {
|
|
55
|
+
const absPath = await findIntegrationGroundingFile(inputs.sddPath);
|
|
56
|
+
if (absPath !== null) {
|
|
57
|
+
// For integration-product, the integration itself is the
|
|
58
|
+
// capability surface; use the SDD's product id.
|
|
59
|
+
files.push({ absPath, capabilityId: inputs.productId });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
for (const { absPath, capabilityId } of files) {
|
|
63
|
+
const relPath = relative(inputs.sddPath, absPath);
|
|
64
|
+
if (capabilityId === "") {
|
|
65
|
+
inputs.findings.add("convention", `${relPath}: capability id could not be resolved from file path`);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (!inputs.knownCapabilityIds.has(capabilityId)) {
|
|
69
|
+
inputs.findings.add("convention", `${relPath}: capability "${capabilityId}" from file path does not resolve against capabilities.csv`);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const text = await readFile(absPath, "utf-8");
|
|
73
|
+
const rows = parseGroundingTable(text);
|
|
74
|
+
if (rows.length === 0) {
|
|
75
|
+
inputs.findings.add("coverage", `${relPath}: feature-grounding.md found but no recognisable Feature-to-Code Mapping table`);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const slugsInThisFile = new Set();
|
|
79
|
+
for (const row of rows) {
|
|
80
|
+
if (slugsInThisFile.has(row.slug)) {
|
|
81
|
+
inputs.findings.add("divergence", `${relPath}:${row.lineNumber}: duplicate feature slug "${row.slug}" in same file (first occurrence wins)`);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
slugsInThisFile.add(row.slug);
|
|
85
|
+
const featureId = `${capabilityId}-${row.slug}`;
|
|
86
|
+
if (seenFeatures.has(featureId)) {
|
|
87
|
+
inputs.findings.add("divergence", `${relPath}:${row.lineNumber}: feature id "${featureId}" already emitted by an earlier source (feature-tree / feature-spec wins)`);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
seenFeatures.add(featureId);
|
|
91
|
+
featureRows.push({
|
|
92
|
+
id: featureId,
|
|
93
|
+
name: row.slug,
|
|
94
|
+
product_id: "",
|
|
95
|
+
capability_id: capabilityId,
|
|
96
|
+
parent_group_id: "",
|
|
97
|
+
parent_feature_id: "",
|
|
98
|
+
description: deriveDescription(row),
|
|
99
|
+
maturity: "",
|
|
100
|
+
status: "active",
|
|
101
|
+
source: "feature-grounding",
|
|
102
|
+
runway: "",
|
|
103
|
+
source_sdd_id: "",
|
|
104
|
+
});
|
|
105
|
+
const cfId = `${capabilityId}__${featureId}`;
|
|
106
|
+
capabilityFeatureRows.push({
|
|
107
|
+
id: cfId,
|
|
108
|
+
capability_id: capabilityId,
|
|
109
|
+
feature_id: featureId,
|
|
110
|
+
});
|
|
111
|
+
// feature_service edges
|
|
112
|
+
const services = resolveServices(row, inputs);
|
|
113
|
+
for (const serviceId of services) {
|
|
114
|
+
const edgeId = `${featureId}__${serviceId}`;
|
|
115
|
+
if (seenFeatureService.has(edgeId))
|
|
116
|
+
continue;
|
|
117
|
+
seenFeatureService.add(edgeId);
|
|
118
|
+
featureServiceRows.push({
|
|
119
|
+
id: edgeId,
|
|
120
|
+
feature_id: featureId,
|
|
121
|
+
service_id: serviceId,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
// feature_repo edges
|
|
125
|
+
const repos = resolveRepos(row, inputs);
|
|
126
|
+
for (const repoKey of repos) {
|
|
127
|
+
const edgeId = `${featureId}__${repoKey}`;
|
|
128
|
+
if (seenFeatureRepo.has(edgeId))
|
|
129
|
+
continue;
|
|
130
|
+
seenFeatureRepo.add(edgeId);
|
|
131
|
+
featureRepoRows.push({
|
|
132
|
+
id: edgeId,
|
|
133
|
+
feature_id: featureId,
|
|
134
|
+
repo_id: repoKey,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
featureRows,
|
|
141
|
+
capabilityFeatureRows,
|
|
142
|
+
featureRepoRows,
|
|
143
|
+
featureServiceRows,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Build the description column by joining non-feature cells, capped at
|
|
148
|
+
* 500 chars to match the feature-tree bullet convention.
|
|
149
|
+
*/
|
|
150
|
+
function deriveDescription(row) {
|
|
151
|
+
const parts = [];
|
|
152
|
+
for (const [key, value] of row.cells) {
|
|
153
|
+
if (value === "")
|
|
154
|
+
continue;
|
|
155
|
+
parts.push(`${prettyHeader(key)}: ${value}`);
|
|
156
|
+
}
|
|
157
|
+
const joined = parts.join(" • ");
|
|
158
|
+
return joined.length > DESCRIPTION_MAX
|
|
159
|
+
? joined.slice(0, DESCRIPTION_MAX)
|
|
160
|
+
: joined;
|
|
161
|
+
}
|
|
162
|
+
function prettyHeader(key) {
|
|
163
|
+
return key
|
|
164
|
+
.split("_")
|
|
165
|
+
.map((p) => (p.length === 0 ? p : p[0].toUpperCase() + p.slice(1)))
|
|
166
|
+
.join(" ");
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Resolve service ids referenced in a row's cells. Strategy:
|
|
170
|
+
* - Tokenize backtick-quoted identifiers + CamelCase / kebab-case tokens.
|
|
171
|
+
* - Strip extensions (.ts/.java/.yaml/.kt/.py) and trailing parens.
|
|
172
|
+
* - Try exact match against services.id (lowercased).
|
|
173
|
+
* - Try alias map (case-sensitive — display names often carry case).
|
|
174
|
+
*/
|
|
175
|
+
function resolveServices(row, inputs) {
|
|
176
|
+
const out = new Set();
|
|
177
|
+
for (const col of SERVICE_RESOLUTION_COLUMNS) {
|
|
178
|
+
const cell = row.cells.get(col) ?? "";
|
|
179
|
+
if (cell === "")
|
|
180
|
+
continue;
|
|
181
|
+
for (const token of tokenize(cell)) {
|
|
182
|
+
const resolved = resolveServiceToken(token, inputs);
|
|
183
|
+
if (resolved !== null)
|
|
184
|
+
out.add(resolved);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return [...out].sort();
|
|
188
|
+
}
|
|
189
|
+
function resolveServiceToken(rawToken, inputs) {
|
|
190
|
+
// Try alias first (case-sensitive).
|
|
191
|
+
if (inputs.aliases !== null) {
|
|
192
|
+
const aliased = inputs.aliases.serviceAliases.get(rawToken);
|
|
193
|
+
if (aliased !== undefined && inputs.knownServiceIds.has(aliased)) {
|
|
194
|
+
return aliased;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Normalise + try exact match.
|
|
198
|
+
const normalised = normaliseToken(rawToken);
|
|
199
|
+
if (normalised === "")
|
|
200
|
+
return null;
|
|
201
|
+
if (inputs.knownServiceIds.has(normalised))
|
|
202
|
+
return normalised;
|
|
203
|
+
// Try alias on normalised form too.
|
|
204
|
+
if (inputs.aliases !== null) {
|
|
205
|
+
const aliased = inputs.aliases.serviceAliases.get(normalised);
|
|
206
|
+
if (aliased !== undefined && inputs.knownServiceIds.has(aliased)) {
|
|
207
|
+
return aliased;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Resolve repo ids from file-path references. Strategy:
|
|
214
|
+
* - Tokenize path-like spans (contain `/` or end in known extensions).
|
|
215
|
+
* - For each token: try longest-prefix match against
|
|
216
|
+
* `canonical_repo_key`s; e.g. `connect-app-shell-api-master@abc/src/...`
|
|
217
|
+
* → `connect-app-shell-api` (after stripping branch/sha suffix).
|
|
218
|
+
* - Also accept the alias map for display-name → canonical-key.
|
|
219
|
+
*/
|
|
220
|
+
function resolveRepos(row, inputs) {
|
|
221
|
+
const out = new Set();
|
|
222
|
+
for (const col of REPO_RESOLUTION_COLUMNS) {
|
|
223
|
+
const cell = row.cells.get(col) ?? "";
|
|
224
|
+
if (cell === "")
|
|
225
|
+
continue;
|
|
226
|
+
for (const token of tokenize(cell)) {
|
|
227
|
+
const resolved = resolveRepoToken(token, inputs);
|
|
228
|
+
if (resolved !== null)
|
|
229
|
+
out.add(resolved);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return [...out].sort();
|
|
233
|
+
}
|
|
234
|
+
function resolveRepoToken(rawToken, inputs) {
|
|
235
|
+
// Try alias first.
|
|
236
|
+
if (inputs.aliases !== null) {
|
|
237
|
+
const aliased = inputs.aliases.repoAliases.get(rawToken);
|
|
238
|
+
if (aliased !== undefined && inputs.knownRepoKeys.has(aliased)) {
|
|
239
|
+
return aliased;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// Direct match on the full token (rare).
|
|
243
|
+
if (inputs.knownRepoKeys.has(rawToken))
|
|
244
|
+
return rawToken;
|
|
245
|
+
// Walk every path segment and try to recover a repo key. Each
|
|
246
|
+
// segment may carry a `-master@<sha>` or `@<sha>` suffix; strip
|
|
247
|
+
// those before matching.
|
|
248
|
+
for (const segment of rawToken.split("/")) {
|
|
249
|
+
const stripped = segment
|
|
250
|
+
.replace(/-master@.*$/, "")
|
|
251
|
+
.replace(/@[^/]+$/, "");
|
|
252
|
+
if (stripped !== "" && inputs.knownRepoKeys.has(stripped)) {
|
|
253
|
+
return stripped;
|
|
254
|
+
}
|
|
255
|
+
// Also try the segment with the `-master` literal removed (no @sha).
|
|
256
|
+
const trailingMaster = stripped.replace(/-master$/, "");
|
|
257
|
+
if (trailingMaster !== stripped &&
|
|
258
|
+
inputs.knownRepoKeys.has(trailingMaster)) {
|
|
259
|
+
return trailingMaster;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Extract candidate identifier tokens from a markdown cell. Matches:
|
|
266
|
+
* - Backticked spans: `` `AuthHandler.handleLoginRequest()` ``
|
|
267
|
+
* - Bare identifiers: `MasternauthOauthService`
|
|
268
|
+
* - kebab-case identifiers: `connect-app-shell-api`
|
|
269
|
+
* - Path-like tokens with at least one `/`.
|
|
270
|
+
* Strips leading method names (e.g. `AuthHandler.foo()` → `AuthHandler`).
|
|
271
|
+
*/
|
|
272
|
+
function tokenize(cell) {
|
|
273
|
+
const out = new Set();
|
|
274
|
+
// Backticked spans.
|
|
275
|
+
for (const match of cell.matchAll(/`([^`]+)`/g)) {
|
|
276
|
+
const inner = match[1] ?? "";
|
|
277
|
+
addCandidatesFromToken(inner, out);
|
|
278
|
+
}
|
|
279
|
+
// Bare identifiers outside backticks — strip backtick spans first.
|
|
280
|
+
const stripped = cell.replace(/`[^`]+`/g, " ");
|
|
281
|
+
for (const match of stripped.matchAll(/[A-Za-z][A-Za-z0-9._@/-]*[A-Za-z0-9]/g)) {
|
|
282
|
+
addCandidatesFromToken(match[0], out);
|
|
283
|
+
}
|
|
284
|
+
return [...out];
|
|
285
|
+
}
|
|
286
|
+
function addCandidatesFromToken(token, out) {
|
|
287
|
+
if (token === "")
|
|
288
|
+
return;
|
|
289
|
+
// Path token: take first segment as a candidate AND keep the full path.
|
|
290
|
+
if (token.includes("/")) {
|
|
291
|
+
out.add(token);
|
|
292
|
+
const first = token.split("/")[0] ?? "";
|
|
293
|
+
if (first !== "" && first !== token)
|
|
294
|
+
out.add(first);
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
// Method/class form: split on `.`, contribute each segment except (), [].
|
|
298
|
+
const head = token.split(/[(.[]/)[0] ?? "";
|
|
299
|
+
if (head !== "")
|
|
300
|
+
out.add(head);
|
|
301
|
+
// Also keep the full token for alias-map matching on exact display
|
|
302
|
+
// strings like `AuthHandler.handleLoginRequest`.
|
|
303
|
+
out.add(token);
|
|
304
|
+
}
|
|
305
|
+
function normaliseToken(token) {
|
|
306
|
+
return token
|
|
307
|
+
.toLowerCase()
|
|
308
|
+
.replace(/\.(ts|tsx|js|jsx|java|kt|kts|py|go|rs|yaml|yml|json|md)$/i, "")
|
|
309
|
+
.replace(/\(\)$/, "")
|
|
310
|
+
.trim();
|
|
311
|
+
}
|
|
312
|
+
//# sourceMappingURL=feature-grounding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-grounding.js","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/feature-grounding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAIrC,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,0BAA0B,EAC1B,mBAAmB,GAEpB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B,iFAAiF;AACjF,MAAM,0BAA0B,GAAG;IACjC,eAAe;IACf,YAAY;IACZ,kBAAkB;IAClB,UAAU;CACX,CAAC;AAEF,qEAAqE;AACrE,MAAM,uBAAuB,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;AA2B9D,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAA8B;IAE9B,MAAM,WAAW,GAAmB,EAAE,CAAC;IACvC,MAAM,qBAAqB,GAAmB,EAAE,CAAC;IACjD,MAAM,eAAe,GAAmB,EAAE,CAAC;IAC3C,MAAM,kBAAkB,GAAmB,EAAE,CAAC;IAC9C,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAC1C,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC7C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAExD,MAAM,KAAK,GAAgD,EAAE,CAAC;IAE9D,IAAI,MAAM,CAAC,OAAO,KAAK,kBAAkB,EAAE,CAAC;QAC1C,KAAK,MAAM,OAAO,IAAI,MAAM,0BAA0B,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACvE,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;YAC5D,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;SAAM,IAAI,MAAM,CAAC,OAAO,KAAK,qBAAqB,EAAE,CAAC;QACpD,MAAM,OAAO,GAAG,MAAM,4BAA4B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACnE,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,yDAAyD;YACzD,gDAAgD;YAChD,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,KAAK,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,KAAK,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAClD,IAAI,YAAY,KAAK,EAAE,EAAE,CAAC;YACxB,MAAM,CAAC,QAAQ,CAAC,GAAG,CACjB,YAAY,EACZ,GAAG,OAAO,sDAAsD,CACjE,CAAC;YACF,SAAS;QACX,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YACjD,MAAM,CAAC,QAAQ,CAAC,GAAG,CACjB,YAAY,EACZ,GAAG,OAAO,iBAAiB,YAAY,4DAA4D,CACpG,CAAC;YACF,SAAS;QACX,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,CAAC,QAAQ,CAAC,GAAG,CACjB,UAAU,EACV,GAAG,OAAO,gFAAgF,CAC3F,CAAC;YACF,SAAS;QACX,CAAC;QAED,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;QAC1C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClC,MAAM,CAAC,QAAQ,CAAC,GAAG,CACjB,YAAY,EACZ,GAAG,OAAO,IAAI,GAAG,CAAC,UAAU,6BAA6B,GAAG,CAAC,IAAI,wCAAwC,CAC1G,CAAC;gBACF,SAAS;YACX,CAAC;YACD,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAE9B,MAAM,SAAS,GAAG,GAAG,YAAY,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YAChD,IAAI,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBAChC,MAAM,CAAC,QAAQ,CAAC,GAAG,CACjB,YAAY,EACZ,GAAG,OAAO,IAAI,GAAG,CAAC,UAAU,iBAAiB,SAAS,2EAA2E,CAClI,CAAC;gBACF,SAAS;YACX,CAAC;YACD,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAE5B,WAAW,CAAC,IAAI,CAAC;gBACf,EAAE,EAAE,SAAS;gBACb,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,UAAU,EAAE,EAAE;gBACd,aAAa,EAAE,YAAY;gBAC3B,eAAe,EAAE,EAAE;gBACnB,iBAAiB,EAAE,EAAE;gBACrB,WAAW,EAAE,iBAAiB,CAAC,GAAG,CAAC;gBACnC,QAAQ,EAAE,EAAE;gBACZ,MAAM,EAAE,QAAQ;gBAChB,MAAM,EAAE,mBAAmB;gBAC3B,MAAM,EAAE,EAAE;gBACV,aAAa,EAAE,EAAE;aAClB,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,GAAG,YAAY,KAAK,SAAS,EAAE,CAAC;YAC7C,qBAAqB,CAAC,IAAI,CAAC;gBACzB,EAAE,EAAE,IAAI;gBACR,aAAa,EAAE,YAAY;gBAC3B,UAAU,EAAE,SAAS;aACtB,CAAC,CAAC;YAEH,wBAAwB;YACxB,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC9C,KAAK,MAAM,SAAS,IAAI,QAAQ,EAAE,CAAC;gBACjC,MAAM,MAAM,GAAG,GAAG,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5C,IAAI,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC;oBAAE,SAAS;gBAC7C,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAC/B,kBAAkB,CAAC,IAAI,CAAC;oBACtB,EAAE,EAAE,MAAM;oBACV,UAAU,EAAE,SAAS;oBACrB,UAAU,EAAE,SAAS;iBACtB,CAAC,CAAC;YACL,CAAC;YAED,qBAAqB;YACrB,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACxC,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;gBAC5B,MAAM,MAAM,GAAG,GAAG,SAAS,KAAK,OAAO,EAAE,CAAC;gBAC1C,IAAI,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC;oBAAE,SAAS;gBAC1C,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAC5B,eAAe,CAAC,IAAI,CAAC;oBACnB,EAAE,EAAE,MAAM;oBACV,UAAU,EAAE,SAAS;oBACrB,OAAO,EAAE,OAAO;iBACjB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,WAAW;QACX,qBAAqB;QACrB,eAAe;QACf,kBAAkB;KACnB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,GAAiB;IAC1C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QACrC,IAAI,KAAK,KAAK,EAAE;YAAE,SAAS;QAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;IAC/C,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO,MAAM,CAAC,MAAM,GAAG,eAAe;QACpC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC;QAClC,CAAC,CAAC,MAAM,CAAC;AACb,CAAC;AAED,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO,GAAG;SACP,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;SACnE,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CACtB,GAAiB,EACjB,MAA8B;IAE9B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,0BAA0B,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACtC,IAAI,IAAI,KAAK,EAAE;YAAE,SAAS;QAC1B,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACpD,IAAI,QAAQ,KAAK,IAAI;gBAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,SAAS,mBAAmB,CAC1B,QAAgB,EAChB,MAA8B;IAE9B,oCAAoC;IACpC,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5D,IAAI,OAAO,KAAK,SAAS,IAAI,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACjE,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IACD,+BAA+B;IAC/B,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,UAAU,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IAC9D,oCAAoC;IACpC,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC9D,IAAI,OAAO,KAAK,SAAS,IAAI,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACjE,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,YAAY,CACnB,GAAiB,EACjB,MAA8B;IAE9B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,uBAAuB,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACtC,IAAI,IAAI,KAAK,EAAE;YAAE,SAAS;QAC1B,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACjD,IAAI,QAAQ,KAAK,IAAI;gBAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,SAAS,gBAAgB,CACvB,QAAgB,EAChB,MAA8B;IAE9B,mBAAmB;IACnB,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACzD,IAAI,OAAO,KAAK,SAAS,IAAI,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/D,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IACD,yCAAyC;IACzC,IAAI,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IACxD,8DAA8D;IAC9D,gEAAgE;IAChE,yBAAyB;IACzB,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAG,OAAO;aACrB,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;aAC1B,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAC1B,IAAI,QAAQ,KAAK,EAAE,IAAI,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1D,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,qEAAqE;QACrE,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACxD,IACE,cAAc,KAAK,QAAQ;YAC3B,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,cAAc,CAAC,EACxC,CAAC;YACD,OAAO,cAAc,CAAC;QACxB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,oBAAoB;IACpB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAChD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,sBAAsB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACrC,CAAC;IACD,mEAAmE;IACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IAC/C,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,QAAQ,CACnC,uCAAuC,CACxC,EAAE,CAAC;QACF,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAa,EAAE,GAAgB;IAC7D,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO;IACzB,wEAAwE;IACxE,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACf,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACxC,IAAI,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,KAAK;YAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IACD,0EAA0E;IAC1E,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,IAAI,IAAI,KAAK,EAAE;QAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,mEAAmE;IACnE,iDAAiD;IACjD,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACnC,OAAO,KAAK;SACT,WAAW,EAAE;SACb,OAAO,CAAC,2DAA2D,EAAE,EAAE,CAAC;SACxE,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;SACpB,IAAI,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -22,6 +22,10 @@ export { buildFeatures } from "./features.js";
|
|
|
22
22
|
export type { FeaturesBuildInputs, FeaturesBuildResult, } from "./features.js";
|
|
23
23
|
export { buildFeatureGroups } from "./feature-groups.js";
|
|
24
24
|
export type { FeatureGroupsBuildInputs } from "./feature-groups.js";
|
|
25
|
+
export { buildFeatureGrounding } from "./feature-grounding.js";
|
|
26
|
+
export type { FeatureGroundingInputs, FeatureGroundingResult, } from "./feature-grounding.js";
|
|
27
|
+
export { buildCapabilitySpec } from "./capability-spec.js";
|
|
28
|
+
export type { CapabilitySpecInputs, CapabilitySpecResult, } from "./capability-spec.js";
|
|
25
29
|
export { buildContracts } from "./contracts.js";
|
|
26
30
|
export type { ContractsBuildInputs, ContractsBuildResult, } from "./contracts.js";
|
|
27
31
|
export { buildRepoEdges } from "./repo-edges.js";
|
|
@@ -32,6 +36,8 @@ export { buildServiceEvent, buildCapabilityEvent } from "./event-edges.js";
|
|
|
32
36
|
export type { ServiceEventInputs, CapabilityEventInputs, } from "./event-edges.js";
|
|
33
37
|
export { buildServiceContract } from "./service-contract.js";
|
|
34
38
|
export type { ServiceContractInputs } from "./service-contract.js";
|
|
39
|
+
export { buildServiceContractConsumes } from "./service-contract-consumes.js";
|
|
40
|
+
export type { ServiceContractConsumesInputs } from "./service-contract-consumes.js";
|
|
35
41
|
export { buildGlossaryItems } from "./glossary.js";
|
|
36
42
|
export type { GlossaryItemsBuildInputs, GlossaryItemsResult, } from "./glossary.js";
|
|
37
43
|
export { buildGlossaryXref } from "./glossary-xref.js";
|