@aisdlc/core 2.2.4 → 2.4.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/index.js CHANGED
@@ -266,19 +266,26 @@ function extractPythonFunctions(content, filePath) {
266
266
  }
267
267
  return buildMetricsFromBlocks(blocks, content, filePath);
268
268
  }
269
- function processBraceLine(line, state, blocks, lineIndex, ext) {
270
- if (!state.currentFn) {
271
- const candidate = matchFunctionHeader(line, ext);
272
- if (!candidate) return;
269
+ function tryStartBraceFunction(line, state, ext) {
270
+ if (state.currentFn || state.inBlockComment || state.rawTerm) return;
271
+ const candidate = matchFunctionHeader(line, ext);
272
+ if (candidate) {
273
273
  state.currentFn = candidate;
274
274
  state.braceCount = 0;
275
275
  state.fnLines = [];
276
276
  }
277
- state.fnLines.push(line);
278
- const res = scanBracesInLine(line, state.inBlockComment, ext);
277
+ }
278
+ function updateBraceScanState(line, state, ext) {
279
+ const res = scanBracesInLine(line, state.inBlockComment, state.rawTerm, ext);
279
280
  state.inBlockComment = res.nowInBlock;
281
+ state.rawTerm = res.nowRawTerm;
280
282
  state.braceCount += res.delta;
281
- if (state.braceCount === 0 && state.fnLines.length > 1) {
283
+ }
284
+ function processBraceLine(line, state, blocks, lineIndex, ext) {
285
+ tryStartBraceFunction(line, state, ext);
286
+ if (state.currentFn) state.fnLines.push(line);
287
+ updateBraceScanState(line, state, ext);
288
+ if (state.currentFn && state.braceCount === 0 && state.fnLines.length > 1) {
282
289
  blocks.push({ name: state.currentFn, body: state.fnLines.join("\n"), startLine: lineIndex });
283
290
  state.currentFn = null;
284
291
  state.fnLines = [];
@@ -288,98 +295,153 @@ function extractBraceFunctions(content, filePath) {
288
295
  const ext = path4.extname(filePath).toLowerCase();
289
296
  const lines = content.split("\n");
290
297
  const blocks = [];
291
- const state = { currentFn: null, braceCount: 0, fnLines: [], inBlockComment: false };
298
+ const state = {
299
+ currentFn: null,
300
+ braceCount: 0,
301
+ fnLines: [],
302
+ inBlockComment: false,
303
+ rawTerm: null
304
+ };
292
305
  for (let i = 0; i < lines.length; i++) {
293
306
  processBraceLine(lines[i], state, blocks, i, ext);
294
307
  }
295
308
  return buildMetricsFromBlocks(blocks, content, filePath);
296
309
  }
310
+ var HEADER_EXCLUSIONS = /* @__PURE__ */ new Set([
311
+ "if",
312
+ "for",
313
+ "foreach",
314
+ "while",
315
+ "switch",
316
+ "catch",
317
+ "select",
318
+ "match",
319
+ "class",
320
+ "struct",
321
+ "interface",
322
+ "record",
323
+ "enum",
324
+ "namespace",
325
+ "using",
326
+ "lock",
327
+ "fixed",
328
+ "synchronized",
329
+ "try",
330
+ "else"
331
+ ]);
297
332
  function matchCStyleHeader(line) {
298
333
  const match = line.match(
299
- /(?:(?:public|private|protected|static|async|virtual|override|fn)\s+)*(?:function\s+([a-zA-Z0-9_$]+)|(?:[a-zA-Z0-9_<>[\]?]+\s+)+([a-zA-Z0-9_$]+)\s*\([^;{]*\)\s*(?:throws\s+[^{]+)?\{|([a-zA-Z0-9_$]+)\s*\([^;{]*\)\s*(?::\s*[^{]+\s*)?\{)/
334
+ /(?:(?:public|private|protected|internal|static|async|virtual|override|sealed|abstract|final|synchronized|default|fn)\s+)*(?:function\s+([a-zA-Z0-9_$]+)|(?:[a-zA-Z0-9_<>[\]?,.\s]+\s+)+([a-zA-Z0-9_$]+)\s*(?:<[^>]+>)?\s*\([^;{}]*\)\s*(?:where\s+[^{]+|throws\s+[^{]+)?\{|([a-zA-Z0-9_$]+)\s*\([^;{}]*\)\s*(?::\s*[^{]+\s*)?\{)/
300
335
  );
301
336
  if (!match) return null;
302
337
  const candidate = match[1] || match[2] || match[3];
303
- const exclusions = ["if", "for", "while", "switch", "catch", "select", "match", "class", "struct"];
304
- return candidate && !exclusions.includes(candidate) ? candidate : null;
338
+ return candidate && !HEADER_EXCLUSIONS.has(candidate) ? candidate : null;
305
339
  }
306
340
  function matchFunctionHeader(line, ext) {
307
341
  const trimmed = line.trim();
308
- if (trimmed.startsWith("//") || trimmed.startsWith("/*") || trimmed.startsWith("*")) return null;
342
+ if (trimmed.startsWith("//") || trimmed.startsWith("/*") || trimmed.startsWith("*") || trimmed.startsWith("#")) {
343
+ return null;
344
+ }
309
345
  if (ext === ".go") {
310
- const match = line.match(/func\s+(?:\([^)]*\)\s*)?([a-zA-Z0-9_$]+)\s*\(/);
346
+ const match = line.match(/func\s+(?:\([^)]*\)\s*)?([a-zA-Z0-9_$]+)\s*(?:\[[^\]]*\])?\s*\(/);
311
347
  return match ? match[1] : null;
312
348
  }
313
349
  if (ext === ".rs") {
314
- const match = line.match(/(?:pub\s+)?(?:async\s+)?(?:unsafe\s+)?fn\s+([a-zA-Z0-9_$]+)\s*\(/);
350
+ const match = line.match(/(?:pub(?:\([^)]*\))?\s+)?(?:async\s+)?(?:unsafe\s+)?(?:const\s+)?fn\s+([a-zA-Z0-9_$]+)\s*(?:<[^>]*>)?\s*\(/);
315
351
  return match ? match[1] : null;
316
352
  }
317
353
  return matchCStyleHeader(line);
318
354
  }
319
- function handleStringChar(char, inString) {
320
- if (char === inString) return { inString: null, skip: false };
321
- return { inString, skip: char === "\\" };
322
- }
323
- function handleBlockState(char, next, inBlock) {
324
- if (inBlock && char === "*" && next === "/") return { inBlock: false, skip: true };
325
- return { inBlock, skip: false };
326
- }
327
- function checkCommentOrQuote(char, next, ext) {
328
- if (char === "/" && next === "/") return { startBlock: false, quote: null, isLineComment: true };
329
- if (char === "/" && next === "*") return { startBlock: true, quote: null, isLineComment: false };
330
- const isQuote = char === '"' || char === "'" || char === "`" && ext === ".go";
331
- return { startBlock: false, quote: isQuote ? char : null, isLineComment: false };
332
- }
333
- function stepSkippedState(char, next, inBlock, inString) {
334
- if (inBlock) {
335
- const res = handleBlockState(char, next, inBlock);
336
- return { inBlock: res.inBlock, inString, skip: res.skip, handled: true };
337
- }
338
- if (inString) {
339
- const res = handleStringChar(char, inString);
340
- return { inBlock, inString: res.inString, skip: res.skip, handled: true };
341
- }
342
- return { inBlock, inString, skip: false, handled: false };
343
- }
344
- function checkCodeChar(char, next, ext) {
345
- const trigger = checkCommentOrQuote(char, next, ext);
346
- if (trigger.isLineComment) return { delta: 0, startBlock: false, quote: null, stop: true };
347
- if (trigger.startBlock) return { delta: 0, startBlock: true, quote: null, stop: false };
348
- if (trigger.quote) return { delta: 0, startBlock: false, quote: trigger.quote, stop: false };
349
- const delta = char === "{" ? 1 : char === "}" ? -1 : 0;
350
- return { delta, startBlock: false, quote: null, stop: false };
351
- }
352
- function applyCodeChar(res, state) {
353
- if (res.stop) return { advance: 0, stop: true };
354
- if (res.startBlock) {
355
+ function detectRustOrGoRawString(sub, ext) {
356
+ if (ext === ".rs") {
357
+ const m = sub.match(/^r(#*)"/);
358
+ return m ? { term: `"${m[1]}`, advance: m[0].length - 1 } : null;
359
+ }
360
+ if (ext === ".go" && sub.startsWith("`")) {
361
+ return { term: "`", advance: 0 };
362
+ }
363
+ return null;
364
+ }
365
+ function detectCsJavaOrCppRawString(sub, ext) {
366
+ if (ext === ".cs" || ext === ".java") {
367
+ const m = sub.match(/^\$*("{3,})/);
368
+ if (m) return { term: m[1], advance: m[0].length - 1 };
369
+ const v = ext === ".cs" ? sub.match(/^(@\$|\$@|@)"/) : null;
370
+ return v ? { term: '"', advance: v[0].length - 1 } : null;
371
+ }
372
+ const cpp = sub.match(/^R"([a-zA-Z0-9_]*)\(/);
373
+ return cpp ? { term: `)${cpp[1]}"`, advance: cpp[0].length - 1 } : null;
374
+ }
375
+ function detectRawStringOpen(line, index, ext) {
376
+ const sub = line.slice(index);
377
+ return detectRustOrGoRawString(sub, ext) || detectCsJavaOrCppRawString(sub, ext);
378
+ }
379
+ function consumeRawOrBlock(line, index, state) {
380
+ if (state.inBlock) {
381
+ if (line[index] === "*" && line[index + 1] === "/") {
382
+ state.inBlock = false;
383
+ return { advance: 1, handled: true };
384
+ }
385
+ return { advance: 0, handled: true };
386
+ }
387
+ if (state.rawTerm) {
388
+ if (line.startsWith(state.rawTerm, index)) {
389
+ const len = state.rawTerm.length - 1;
390
+ state.rawTerm = null;
391
+ return { advance: len, handled: true };
392
+ }
393
+ return { advance: 0, handled: true };
394
+ }
395
+ return { advance: 0, handled: false };
396
+ }
397
+ function consumeNormalQuote(line, index, state) {
398
+ if (!state.inString) return { advance: 0, handled: false };
399
+ const ch = line[index];
400
+ if (ch === "\\") return { advance: 1, handled: true };
401
+ if (ch === state.inString) state.inString = null;
402
+ return { advance: 0, handled: true };
403
+ }
404
+ function applyQuoteOrBrace(ch, state) {
405
+ if (ch === '"' || ch === "'") {
406
+ state.inString = ch;
407
+ return;
408
+ }
409
+ if (ch === "{") state.delta++;
410
+ if (ch === "}") state.delta--;
411
+ }
412
+ function stepActiveCodeToken(line, j, ext, state) {
413
+ const pair = line.slice(j, j + 2);
414
+ if (pair === "//") return { advance: 0, stop: true };
415
+ if (pair === "/*") {
355
416
  state.inBlock = true;
356
417
  return { advance: 1, stop: false };
357
418
  }
358
- if (res.quote) {
359
- state.inString = res.quote;
360
- return { advance: 0, stop: false };
419
+ const rawOpen = detectRawStringOpen(line, j, ext);
420
+ if (rawOpen) {
421
+ state.rawTerm = rawOpen.term;
422
+ return { advance: rawOpen.advance, stop: false };
361
423
  }
362
- state.delta += res.delta;
424
+ applyQuoteOrBrace(line[j], state);
363
425
  return { advance: 0, stop: false };
364
426
  }
365
- function scanBracesInLine(line, wasInBlock, ext) {
366
- const state = { delta: 0, inBlock: wasInBlock, inString: null };
427
+ function scanBracesInLine(line, wasInBlock, wasRawTerm, ext) {
428
+ const state = { delta: 0, inBlock: wasInBlock, rawTerm: wasRawTerm, inString: null };
367
429
  for (let j = 0; j < line.length; j++) {
368
- const char = line[j];
369
- const next = j + 1 < line.length ? line[j + 1] : "";
370
- const skipped = stepSkippedState(char, next, state.inBlock, state.inString);
371
- if (skipped.handled) {
372
- state.inBlock = skipped.inBlock;
373
- state.inString = skipped.inString;
374
- if (skipped.skip) j++;
430
+ const rawOrBlock = consumeRawOrBlock(line, j, state);
431
+ if (rawOrBlock.handled) {
432
+ j += rawOrBlock.advance;
433
+ continue;
434
+ }
435
+ const quoteStep = consumeNormalQuote(line, j, state);
436
+ if (quoteStep.handled) {
437
+ j += quoteStep.advance;
375
438
  continue;
376
439
  }
377
- const res = checkCodeChar(char, next, ext);
378
- const step = applyCodeChar(res, state);
379
- if (step.stop) break;
380
- j += step.advance;
440
+ const codeStep = stepActiveCodeToken(line, j, ext, state);
441
+ if (codeStep.stop) break;
442
+ j += codeStep.advance;
381
443
  }
382
- return { delta: state.delta, nowInBlock: state.inBlock };
444
+ return { delta: state.delta, nowInBlock: state.inBlock, nowRawTerm: state.rawTerm };
383
445
  }
384
446
  function buildMetricsFromBlocks(blocks, content, filePath) {
385
447
  if (blocks.length === 0) {
@@ -403,11 +465,20 @@ function buildMetricsFromBlocks(blocks, content, filePath) {
403
465
  }
404
466
  function detectPolyglotSmells(body) {
405
467
  const smells = [];
406
- if (/#\s*noqa|#\s*type:\s*ignore|@SuppressWarnings/.test(body)) {
468
+ if (/#\s*noqa|#\s*type:\s*ignore|@SuppressWarnings|#pragma\s+warning\s+disable/.test(body)) {
407
469
  smells.push("Supresi\xF3n no autorizada de linter");
408
470
  }
409
471
  return smells;
410
472
  }
473
+ function stripStringsAndComments(body, ext) {
474
+ let cleaned = body;
475
+ if (ext === ".py") {
476
+ cleaned = cleaned.replace(/"""[\s\S]*?"""|'''[\s\S]*?'''/g, '""').replace(/#.*/g, "");
477
+ } else {
478
+ cleaned = cleaned.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, "").replace(/r(#+)"[\s\S]*?"\1/g, '""').replace(/R"([a-zA-Z0-9_]*)\([\s\S]*?\)\1"/g, '""').replace(/\$*"{3,}[\s\S]*?"{3,}/g, '""').replace(/`[\s\S]*?`/g, '""');
479
+ }
480
+ return cleaned.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g, '""');
481
+ }
411
482
  function computeHalsteadMI(body, cyclomatic, loc, commentCount) {
412
483
  const cleanText = body.replace(/\/\*[\s\S]*?\*\/|\/\/.*|#.*/g, "");
413
484
  const tokens = cleanText.split(/[\s,;().{}[\]=+\-*/<>!&|:]+/).filter((t) => t.length > 0);
@@ -432,9 +503,11 @@ function countCommentsAndLoc(rawLines, isPy) {
432
503
  function calculatePolyglotMetrics(body, name, filePath, startLine) {
433
504
  const ext = path4.extname(filePath).toLowerCase();
434
505
  const rawLines = body.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0);
435
- const { loc, commentCount, cleanLines } = countCommentsAndLoc(rawLines, ext === ".py");
436
- const cyclomatic = computePolyglotCyclomatic(body, ext);
437
- const cognitive = computePolyglotCognitive(cleanLines, ext === ".py");
506
+ const { loc, commentCount } = countCommentsAndLoc(rawLines, ext === ".py");
507
+ const strippedBody = stripStringsAndComments(body, ext);
508
+ const strippedLines = strippedBody.split(/\r?\n/).filter((l) => l.trim().length > 0);
509
+ const cyclomatic = computePolyglotCyclomatic(strippedBody, ext);
510
+ const cognitive = computePolyglotCognitive(strippedLines, ext === ".py");
438
511
  const maintainability = computeHalsteadMI(body, cyclomatic, loc, commentCount);
439
512
  return {
440
513
  functionName: name,
@@ -447,40 +520,60 @@ function calculatePolyglotMetrics(body, name, filePath, startLine) {
447
520
  line: startLine ? startLine + 1 : 1
448
521
  };
449
522
  }
450
- function computePolyglotCyclomatic(body, ext) {
451
- let regex;
523
+ function getCyclomaticPattern(ext) {
452
524
  if (ext === ".py") {
453
- regex = /\b(if|elif|for|while|except)\b|\b(and|or)\b/g;
454
- } else if (ext === ".go") {
455
- regex = /\b(if|for|case|select)\b|&&|\|\|/g;
456
- } else if (ext === ".rs") {
457
- regex = /\b(if|for|while|match)\b|&&|\|\||\?/g;
458
- } else {
459
- regex = /\b(if|else\s+if|for|while|catch|case)\b|\?|&&|\|\|/g;
525
+ return /\b(if|elif|for|while|except|case)\b|\b(and|or)\b/g;
526
+ }
527
+ if (ext === ".go") {
528
+ return /\b(if|for|case|select)\b|&&|\|\|/g;
529
+ }
530
+ if (ext === ".rs") {
531
+ return /\b(if|for|while|match)\b|&&|\|\||\?/g;
532
+ }
533
+ if (ext === ".cs") {
534
+ return /\b(if|else\s+if|for|foreach|while|catch|case|when)\b|\?\?|\?\.(?=[a-zA-Z_])|&&|\|\|/g;
535
+ }
536
+ if (ext === ".java") {
537
+ return /\b(if|else\s+if|for|while|catch|case|when)\b|&&|\|\|/g;
460
538
  }
461
- const cleanBody = body.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g, "");
462
- const matches = cleanBody.match(regex);
539
+ return /\b(if|else\s+if|for|while|catch|case)\b|\?|&&|\|\|/g;
540
+ }
541
+ function computePolyglotCyclomatic(strippedBody, ext) {
542
+ const regex = getCyclomaticPattern(ext);
543
+ const matches = strippedBody.match(regex);
463
544
  return 1 + (matches ? matches.length : 0);
464
545
  }
465
- function computePolyglotCognitive(lines, isPy) {
546
+ var PY_COGNITIVE_RE = /\b(if|elif|for|while|except|match)\b/;
547
+ var BRACE_COGNITIVE_RE = /\b(if|for|foreach|while|catch|match|select|switch)\b/;
548
+ function computePythonCognitive(lines) {
549
+ let cognitive = 0;
550
+ const baseIndent = lines.length > 0 ? lines[0].length - lines[0].trimStart().length : 0;
551
+ for (let i = 1; i < lines.length; i++) {
552
+ const line = lines[i];
553
+ if (PY_COGNITIVE_RE.test(line)) {
554
+ const relIndent = Math.max(0, line.length - line.trimStart().length - baseIndent - 4);
555
+ cognitive += 1 + Math.floor(relIndent / 4);
556
+ }
557
+ }
558
+ return cognitive;
559
+ }
560
+ function computeBraceCognitive(lines) {
466
561
  let cognitive = 0;
467
562
  let nesting = 0;
468
- for (const line of lines) {
469
- if (isPy) {
470
- const indent = line.length - line.trimStart().length;
471
- if (/\b(if|elif|for|while|except)\b/.test(line)) {
472
- cognitive += 1 + Math.floor(indent / 4);
473
- }
474
- } else {
475
- if (line.includes("{")) nesting++;
476
- if (line.includes("}")) nesting = Math.max(0, nesting - 1);
477
- if (/\b(if|for|while|catch|match|select)\b/.test(line)) {
478
- cognitive += 1 + nesting;
479
- }
563
+ for (let i = 1; i < lines.length; i++) {
564
+ const line = lines[i];
565
+ if (BRACE_COGNITIVE_RE.test(line)) {
566
+ cognitive += 1 + nesting;
480
567
  }
568
+ const opens = (line.match(/\{/g) || []).length;
569
+ const closes = (line.match(/\}/g) || []).length;
570
+ nesting = Math.max(0, nesting + opens - closes);
481
571
  }
482
572
  return cognitive;
483
573
  }
574
+ function computePolyglotCognitive(lines, isPy) {
575
+ return isPy ? computePythonCognitive(lines) : computeBraceCognitive(lines);
576
+ }
484
577
  function walkMdFiles(dir, fileList = [], excludeDirs = [
485
578
  "node_modules",
486
579
  ".git",
@@ -1064,9 +1157,54 @@ function collectTestCorpus(rootDir, allMdFiles) {
1064
1157
  }
1065
1158
  return { gherkinSources, combinedTests: testContents.join("\n") };
1066
1159
  }
1067
- function assembleCoverageResult(reqAudit, taskAudit, useCaseFlows, reqErrors, taskErrors, ucErrors) {
1160
+ function isCucumberScenarioPassed(element) {
1161
+ const steps = Array.isArray(element.steps) ? element.steps : [];
1162
+ if (steps.length === 0) return false;
1163
+ return steps.every((s) => {
1164
+ const res = s.result;
1165
+ return res && res.status === "passed";
1166
+ });
1167
+ }
1168
+ function countCucumberScenarios(raw) {
1169
+ let passed = 0;
1170
+ let failed = 0;
1171
+ for (const feat of raw) {
1172
+ const elements = Array.isArray(feat.elements) ? feat.elements : [];
1173
+ for (const el of elements) {
1174
+ if (isCucumberScenarioPassed(el)) passed++;
1175
+ else failed++;
1176
+ }
1177
+ }
1178
+ return { passed, failed };
1179
+ }
1180
+ function parseCucumberReportFile(reportPath) {
1181
+ if (!fs7.existsSync(reportPath)) return void 0;
1182
+ try {
1183
+ const raw = JSON.parse(fs7.readFileSync(reportPath, "utf-8"));
1184
+ if (!Array.isArray(raw)) return void 0;
1185
+ const { passed, failed } = countCucumberScenarios(raw);
1186
+ return {
1187
+ evaluatedFeatures: raw.length,
1188
+ passedScenarios: passed,
1189
+ failedScenarios: failed,
1190
+ passed: passed + failed > 0 && failed === 0
1191
+ };
1192
+ } catch {
1193
+ return void 0;
1194
+ }
1195
+ }
1196
+ function resolveCucumberReport(rootDir, options) {
1197
+ const candidate = options.cucumberReportPath ? path4.isAbsolute(options.cucumberReportPath) ? options.cucumberReportPath : path4.join(rootDir, options.cucumberReportPath) : path4.join(rootDir, "reports", "cucumber-report.json");
1198
+ const parsed = parseCucumberReportFile(candidate);
1199
+ if (parsed) return parsed;
1200
+ if (options.enforceCucumberExecution) {
1201
+ return { evaluatedFeatures: 0, passedScenarios: 0, failedScenarios: 1, passed: false };
1202
+ }
1203
+ return void 0;
1204
+ }
1205
+ function assembleCoverageResult(reqAudit, taskAudit, useCaseFlows, reqErrors, taskErrors, ucErrors, rootDir, options) {
1068
1206
  return {
1069
- success: reqErrors === 0 && taskErrors === 0 && ucErrors === 0,
1207
+ success: reqErrors === 0 && taskErrors === 0 && ucErrors === 0 && (!resolveCucumberReport(rootDir, options) || resolveCucumberReport(rootDir, options).passed),
1070
1208
  totalRequirements: reqAudit.length,
1071
1209
  passedRequirements: reqAudit.length - reqErrors,
1072
1210
  failedRequirements: reqErrors,
@@ -1077,6 +1215,7 @@ function assembleCoverageResult(reqAudit, taskAudit, useCaseFlows, reqErrors, ta
1077
1215
  tasks: taskAudit,
1078
1216
  useCaseFlows,
1079
1217
  failedUseCaseFlows: ucErrors,
1218
+ ...resolveCucumberReport(rootDir, options) ? { cucumberExecution: resolveCucumberReport(rootDir, options) } : {},
1080
1219
  reportMarkdown: generateTestingCoverageReportMarkdown(reqAudit, taskAudit, reqErrors, taskErrors)
1081
1220
  };
1082
1221
  }
@@ -1128,7 +1267,9 @@ function verifyTestingCoverage(options = {}) {
1128
1267
  state.useCaseFlows,
1129
1268
  state.reqErrors,
1130
1269
  state.taskErrors,
1131
- state.ucErrors
1270
+ state.ucErrors,
1271
+ rootDir,
1272
+ options
1132
1273
  );
1133
1274
  }
1134
1275
 
@@ -5504,6 +5645,277 @@ function verifyTasksGovernance(options = {}) {
5504
5645
  );
5505
5646
  return assembleGovernanceResult(data, reportMarkdown);
5506
5647
  }
5648
+ var BddStepRegistry = class {
5649
+ definitions = [];
5650
+ register(pattern, handler) {
5651
+ this.definitions.push({ pattern, handler });
5652
+ return this;
5653
+ }
5654
+ given(pattern, handler) {
5655
+ return this.register(pattern, handler);
5656
+ }
5657
+ when(pattern, handler) {
5658
+ return this.register(pattern, handler);
5659
+ }
5660
+ then(pattern, handler) {
5661
+ return this.register(pattern, handler);
5662
+ }
5663
+ getDefinitions() {
5664
+ return this.definitions;
5665
+ }
5666
+ };
5667
+ var STEP_PREFIX_RE = /^(Given|When|Then|And|But|Dado|Cuando|Entonces|Y|Pero)\s+(.+)$/i;
5668
+ var SCENARIO_HEADER_RE = /^(Scenario|Escenario|Scenario Outline|Esquema del escenario):\s*(.+)$/i;
5669
+ function parseTableRowCells(line) {
5670
+ return line.trim().replace(/^\|/, "").replace(/\|$/, "").split("|").map((c) => c.trim());
5671
+ }
5672
+ function attachStepTableRow(lastStep, cells) {
5673
+ if (!lastStep || cells.length < 2) return;
5674
+ if (!lastStep.table) lastStep.table = {};
5675
+ lastStep.table[cells[0]] = cells[1];
5676
+ }
5677
+ function attachExampleRow(scenario, headers, cells) {
5678
+ if (!scenario) return headers;
5679
+ if (headers.length === 0) return cells;
5680
+ const row = {};
5681
+ for (let i = 0; i < headers.length; i++) {
5682
+ row[headers[i]] = cells[i] ?? "";
5683
+ }
5684
+ scenario.examples.push(row);
5685
+ return headers;
5686
+ }
5687
+ function createInitialParseState() {
5688
+ return {
5689
+ featureName: "Unnamed Feature",
5690
+ featureTags: [],
5691
+ pendingTags: [],
5692
+ backgroundSteps: [],
5693
+ scenarios: [],
5694
+ currentScenario: null,
5695
+ inBackground: false,
5696
+ inExamples: false,
5697
+ exampleHeaders: []
5698
+ };
5699
+ }
5700
+ function handleStructuralHeaderLine(line, state) {
5701
+ if (/^(Feature|Caracter[ií]stica):/i.test(line)) {
5702
+ state.featureName = line.replace(/^(Feature|Caracter[ií]stica):\s*/i, "").trim();
5703
+ state.featureTags.push(...state.pendingTags);
5704
+ state.pendingTags = [];
5705
+ return true;
5706
+ }
5707
+ if (/^(Background|Antecedentes):/i.test(line)) {
5708
+ state.inBackground = true;
5709
+ state.inExamples = false;
5710
+ state.currentScenario = null;
5711
+ return true;
5712
+ }
5713
+ if (/^(Examples|Ejemplos):/i.test(line)) {
5714
+ state.inExamples = true;
5715
+ state.exampleHeaders = [];
5716
+ return true;
5717
+ }
5718
+ return false;
5719
+ }
5720
+ function startScenarioBlock(scenMatch, state) {
5721
+ state.inBackground = false;
5722
+ state.inExamples = false;
5723
+ const block = {
5724
+ name: scenMatch[2].trim(),
5725
+ tags: [...state.featureTags, ...state.pendingTags],
5726
+ isOutline: /outline|esquema/i.test(scenMatch[1]),
5727
+ steps: [],
5728
+ examples: []
5729
+ };
5730
+ state.pendingTags = [];
5731
+ state.scenarios.push(block);
5732
+ state.currentScenario = block;
5733
+ }
5734
+ function appendParsedStep(stepMatch, state) {
5735
+ const step = { keyword: stepMatch[1], text: stepMatch[2].trim() };
5736
+ if (state.inBackground) {
5737
+ state.backgroundSteps.push(step);
5738
+ } else if (state.currentScenario) {
5739
+ state.currentScenario.steps.push(step);
5740
+ }
5741
+ }
5742
+ function handleScenarioOrStepLine(line, state) {
5743
+ const scenMatch = line.match(SCENARIO_HEADER_RE);
5744
+ if (scenMatch) {
5745
+ startScenarioBlock(scenMatch, state);
5746
+ return;
5747
+ }
5748
+ const stepMatch = line.match(STEP_PREFIX_RE);
5749
+ if (stepMatch) {
5750
+ appendParsedStep(stepMatch, state);
5751
+ }
5752
+ }
5753
+ function processFeatureLine(rawLine, state) {
5754
+ const line = rawLine.trim();
5755
+ if (!line || line.startsWith("#")) return;
5756
+ if (line.startsWith("@")) {
5757
+ const tags = line.split(/\s+/).filter((t) => t.startsWith("@"));
5758
+ state.pendingTags.push(...tags);
5759
+ return;
5760
+ }
5761
+ if (line.startsWith("|")) {
5762
+ const cells = parseTableRowCells(line);
5763
+ if (state.inExamples) {
5764
+ state.exampleHeaders = attachExampleRow(state.currentScenario, state.exampleHeaders, cells);
5765
+ } else {
5766
+ const targetList = state.inBackground ? state.backgroundSteps : state.currentScenario?.steps || [];
5767
+ attachStepTableRow(targetList[targetList.length - 1], cells);
5768
+ }
5769
+ return;
5770
+ }
5771
+ if (!handleStructuralHeaderLine(line, state)) {
5772
+ handleScenarioOrStepLine(line, state);
5773
+ }
5774
+ }
5775
+ function parseFeatureDocument(content) {
5776
+ const state = createInitialParseState();
5777
+ for (const rawLine of content.split(/\r?\n/)) {
5778
+ processFeatureLine(rawLine, state);
5779
+ }
5780
+ return {
5781
+ featureName: state.featureName,
5782
+ tags: state.featureTags,
5783
+ backgroundSteps: state.backgroundSteps,
5784
+ scenarios: state.scenarios
5785
+ };
5786
+ }
5787
+ function interpolatePlaceholders(text, row) {
5788
+ let out = text;
5789
+ for (const [k, v] of Object.entries(row)) {
5790
+ out = out.replace(new RegExp(`<${k}>`, "g"), v);
5791
+ }
5792
+ return out;
5793
+ }
5794
+ function expandScenarioOutlines(scenarios) {
5795
+ const expanded = [];
5796
+ for (const sc of scenarios) {
5797
+ if (!sc.isOutline || sc.examples.length === 0) {
5798
+ expanded.push(sc);
5799
+ continue;
5800
+ }
5801
+ sc.examples.forEach((row, idx) => {
5802
+ expanded.push({
5803
+ name: `${sc.name} (Example #${idx + 1})`,
5804
+ tags: sc.tags,
5805
+ isOutline: false,
5806
+ steps: sc.steps.map((st) => ({
5807
+ keyword: st.keyword,
5808
+ text: interpolatePlaceholders(st.text, row),
5809
+ table: st.table
5810
+ })),
5811
+ examples: []
5812
+ });
5813
+ });
5814
+ }
5815
+ return expanded;
5816
+ }
5817
+ function matchStepDefinition(text, definitions) {
5818
+ for (const entry of definitions) {
5819
+ if (typeof entry.pattern === "string") {
5820
+ if (entry.pattern === text) return { entry, args: [] };
5821
+ } else {
5822
+ const m = text.match(entry.pattern);
5823
+ if (m) return { entry, args: m.slice(1) };
5824
+ }
5825
+ }
5826
+ return null;
5827
+ }
5828
+ async function executeSingleStep(step, definitions) {
5829
+ const matched = matchStepDefinition(step.text, definitions);
5830
+ if (!matched) {
5831
+ return { keyword: step.keyword, text: step.text, status: "undefined", durationMs: 0 };
5832
+ }
5833
+ const start = Date.now();
5834
+ try {
5835
+ await matched.entry.handler(matched.args, step.table);
5836
+ return { keyword: step.keyword, text: step.text, status: "passed", durationMs: Date.now() - start };
5837
+ } catch (err) {
5838
+ const msg = err instanceof Error ? err.message : String(err);
5839
+ return {
5840
+ keyword: step.keyword,
5841
+ text: step.text,
5842
+ status: "failed",
5843
+ durationMs: Date.now() - start,
5844
+ errorMessage: msg
5845
+ };
5846
+ }
5847
+ }
5848
+ async function executeScenarioSteps(allSteps, definitions) {
5849
+ const stepResults = [];
5850
+ let status = "passed";
5851
+ for (const step of allSteps) {
5852
+ if (status !== "passed") {
5853
+ stepResults.push({ keyword: step.keyword, text: step.text, status: "skipped", durationMs: 0 });
5854
+ continue;
5855
+ }
5856
+ const res = await executeSingleStep(step, definitions);
5857
+ stepResults.push(res);
5858
+ if (res.status === "failed" || res.status === "undefined") {
5859
+ status = res.status;
5860
+ }
5861
+ }
5862
+ return { stepResults, status };
5863
+ }
5864
+ async function runAllExpandedScenarios(parsed, definitions) {
5865
+ const expanded = expandScenarioOutlines(parsed.scenarios);
5866
+ const out = [];
5867
+ for (const sc of expanded) {
5868
+ const combinedSteps = [...parsed.backgroundSteps, ...sc.steps];
5869
+ const { stepResults, status } = await executeScenarioSteps(combinedSteps, definitions);
5870
+ out.push({ name: sc.name, tags: sc.tags, status, steps: stepResults });
5871
+ }
5872
+ return out;
5873
+ }
5874
+ async function executeBddFeature(featurePath, registry, options = {}) {
5875
+ const rootDir = options.rootDir || process.cwd();
5876
+ const fullPath = path4.isAbsolute(featurePath) ? featurePath : path4.join(rootDir, featurePath);
5877
+ const parsed = parseFeatureDocument(fs7.readFileSync(fullPath, "utf-8"));
5878
+ const scenarios = await runAllExpandedScenarios(parsed, registry.getDefinitions());
5879
+ const report = {
5880
+ uri: path4.relative(rootDir, fullPath).replace(/\\/g, "/"),
5881
+ featureName: parsed.featureName,
5882
+ tags: parsed.tags,
5883
+ scenarios,
5884
+ passed: scenarios.length > 0 && scenarios.every((s) => s.status === "passed")
5885
+ };
5886
+ if (options.writeReportPath) writeCucumberJsonReport([report], options.writeReportPath);
5887
+ return report;
5888
+ }
5889
+ function mapStepToCucumberJson(st) {
5890
+ return {
5891
+ keyword: `${st.keyword} `,
5892
+ name: st.text,
5893
+ result: {
5894
+ status: st.status,
5895
+ duration: st.durationMs * 1e6,
5896
+ ...st.errorMessage ? { error_message: st.errorMessage } : {}
5897
+ }
5898
+ };
5899
+ }
5900
+ function mapFeatureToCucumberJson(r) {
5901
+ return {
5902
+ uri: r.uri,
5903
+ name: r.featureName,
5904
+ tags: r.tags.map((t) => ({ name: t })),
5905
+ elements: r.scenarios.map((sc) => ({
5906
+ type: "scenario",
5907
+ name: sc.name,
5908
+ tags: sc.tags.map((t) => ({ name: t })),
5909
+ steps: sc.steps.map(mapStepToCucumberJson)
5910
+ }))
5911
+ };
5912
+ }
5913
+ function writeCucumberJsonReport(reports, outputPath) {
5914
+ const dir = path4.dirname(outputPath);
5915
+ if (!fs7.existsSync(dir)) fs7.mkdirSync(dir, { recursive: true });
5916
+ const payload = JSON.stringify(reports.map(mapFeatureToCucumberJson), null, 2);
5917
+ fs7.writeFileSync(outputPath, payload, "utf-8");
5918
+ }
5507
5919
  function isToolAvailable(toolName) {
5508
5920
  try {
5509
5921
  const cmd = process.platform === "win32" ? "where" : "which";
@@ -5657,6 +6069,214 @@ function scanPnpmStore(pnpmDir, directNames, seen) {
5657
6069
  }
5658
6070
  }
5659
6071
  }
6072
+ function readTextIfExists(filePath) {
6073
+ if (!fs7.existsSync(filePath)) return null;
6074
+ try {
6075
+ return fs7.readFileSync(filePath, "utf-8");
6076
+ } catch {
6077
+ return null;
6078
+ }
6079
+ }
6080
+ function extractTomlField(block, key) {
6081
+ const m = block.match(new RegExp(`^\\s*${key}\\s*=\\s*["']([^"']+)["']`, "m"));
6082
+ return m ? m[1].trim() : void 0;
6083
+ }
6084
+ function extractPyprojectDirectDeps(content) {
6085
+ const direct = /* @__PURE__ */ new Set();
6086
+ const matches = content.matchAll(/^([a-zA-Z0-9_.-]+)\s*=\s*(?:["'{]|true)/gm);
6087
+ for (const m of matches) {
6088
+ const key = m[1].toLowerCase();
6089
+ if (!["name", "version", "description", "license", "python", "readme"].includes(key)) {
6090
+ direct.add(key);
6091
+ }
6092
+ }
6093
+ return direct;
6094
+ }
6095
+ function parseSingleTomlBlock(block, lockPath, directNames) {
6096
+ const name = extractTomlField(block, "name");
6097
+ const version = extractTomlField(block, "version");
6098
+ if (!name || !version) return null;
6099
+ const spdx = normalizeSpdxLicense(extractTomlField(block, "license") || "UNKNOWN");
6100
+ return {
6101
+ name,
6102
+ version,
6103
+ spdxLicense: spdx,
6104
+ purl: `pkg:pypi/${name.toLowerCase()}@${version}`,
6105
+ path: lockPath,
6106
+ isDirect: directNames.size === 0 || directNames.has(name.toLowerCase())
6107
+ };
6108
+ }
6109
+ function parseTomlPackageBlocks(content, lockPath, directNames, seen) {
6110
+ for (const block of content.split(/\[\[package\]\]/g).slice(1)) {
6111
+ const dep = parseSingleTomlBlock(block, lockPath, directNames);
6112
+ if (dep && !seen.has(`pypi:${dep.name}@${dep.version}`)) {
6113
+ seen.set(`pypi:${dep.name}@${dep.version}`, dep);
6114
+ }
6115
+ }
6116
+ }
6117
+ function parsePipfileSection(pkgs, isDirect, lockPath, seen) {
6118
+ for (const [name, meta] of Object.entries(pkgs)) {
6119
+ const rawVer = String(meta.version || "").replace(/^==/, "") || "unknown";
6120
+ const spdx = normalizeSpdxLicense(meta.license || "UNKNOWN");
6121
+ const key = `pypi:${name}@${rawVer}`;
6122
+ if (!seen.has(key)) {
6123
+ seen.set(key, {
6124
+ name,
6125
+ version: rawVer,
6126
+ spdxLicense: spdx,
6127
+ purl: `pkg:pypi/${name.toLowerCase()}@${rawVer}`,
6128
+ path: lockPath,
6129
+ isDirect
6130
+ });
6131
+ }
6132
+ }
6133
+ }
6134
+ function scanPythonDependencies(rootDir, seen) {
6135
+ const pyproject = readTextIfExists(path4.join(rootDir, "pyproject.toml")) || "";
6136
+ const directNames = extractPyprojectDirectDeps(pyproject);
6137
+ for (const lockName of ["poetry.lock", "uv.lock"]) {
6138
+ const lockPath = path4.join(rootDir, lockName);
6139
+ const content = readTextIfExists(lockPath);
6140
+ if (content) parseTomlPackageBlocks(content, lockPath, directNames, seen);
6141
+ }
6142
+ const pipfileLockPath = path4.join(rootDir, "Pipfile.lock");
6143
+ const pipfileRaw = readTextIfExists(pipfileLockPath);
6144
+ if (!pipfileRaw) return;
6145
+ try {
6146
+ const data = JSON.parse(pipfileRaw);
6147
+ parsePipfileSection(data.default || {}, true, pipfileLockPath, seen);
6148
+ parsePipfileSection(data.develop || {}, false, pipfileLockPath, seen);
6149
+ } catch {
6150
+ }
6151
+ }
6152
+ function parseGoRequireLine(line, goModPath) {
6153
+ const cleaned = line.replace(/^require\s+/, "").trim();
6154
+ const commentIdx = cleaned.indexOf("//");
6155
+ const codePart = (commentIdx >= 0 ? cleaned.slice(0, commentIdx) : cleaned).trim();
6156
+ const commentPart = commentIdx >= 0 ? cleaned.slice(commentIdx + 2).trim() : "";
6157
+ const parts = codePart.split(/\s+/);
6158
+ if (parts.length < 2) return null;
6159
+ const modName = parts[0];
6160
+ const rawVer = parts[1].replace(/^v/, "");
6161
+ const isIndirect = /\bindirect\b/i.test(commentPart);
6162
+ const licenseMatch = commentPart.match(/(?:spdx|license)\s*:\s*([A-Za-z0-9.+-]+)/i);
6163
+ const spdx = licenseMatch ? normalizeSpdxLicense(licenseMatch[1]) : "UNKNOWN";
6164
+ return {
6165
+ name: modName,
6166
+ version: rawVer,
6167
+ spdxLicense: spdx,
6168
+ purl: `pkg:golang/${modName}@v${rawVer}`,
6169
+ path: goModPath,
6170
+ isDirect: !isIndirect
6171
+ };
6172
+ }
6173
+ function extractGoCandidateLines(content) {
6174
+ const out = [];
6175
+ let inBlock = false;
6176
+ for (const rawLine of content.split(/\r?\n/)) {
6177
+ const trimmed = rawLine.trim();
6178
+ if (/^require\s*\($/.test(trimmed)) inBlock = true;
6179
+ else if (inBlock && trimmed === ")") inBlock = false;
6180
+ else if (inBlock || trimmed.startsWith("require ")) out.push(trimmed);
6181
+ }
6182
+ return out;
6183
+ }
6184
+ function scanGoDependencies(rootDir, seen) {
6185
+ const goModPath = path4.join(rootDir, "go.mod");
6186
+ const content = readTextIfExists(goModPath);
6187
+ if (!content) return;
6188
+ for (const line of extractGoCandidateLines(content)) {
6189
+ const dep = parseGoRequireLine(line, goModPath);
6190
+ if (dep && !seen.has(`golang:${dep.name}@${dep.version}`)) {
6191
+ seen.set(`golang:${dep.name}@${dep.version}`, dep);
6192
+ }
6193
+ }
6194
+ }
6195
+ function extractCargoDirectDeps(cargoToml) {
6196
+ const map = /* @__PURE__ */ new Map();
6197
+ let inDeps = false;
6198
+ for (const line of cargoToml.split(/\r?\n/)) {
6199
+ const trimmed = line.trim();
6200
+ if (trimmed.startsWith("[")) {
6201
+ inDeps = /^\[(?:dev-|build-)?dependencies\]$/.test(trimmed);
6202
+ continue;
6203
+ }
6204
+ if (!inDeps || !trimmed || trimmed.startsWith("#")) continue;
6205
+ const m = trimmed.match(/^([a-zA-Z0-9_-]+)\s*=\s*(.+)$/);
6206
+ if (m) {
6207
+ const licMatch = m[2].match(/license\s*=\s*["']([^"']+)["']/);
6208
+ map.set(m[1], licMatch ? licMatch[1] : "UNKNOWN");
6209
+ }
6210
+ }
6211
+ return map;
6212
+ }
6213
+ function parseCargoLockBlock(block, rootName, directMeta, cargoLockPath) {
6214
+ const name = extractTomlField(block, "name");
6215
+ const version = extractTomlField(block, "version");
6216
+ if (!name || !version || name === rootName) return null;
6217
+ const blockLic = extractTomlField(block, "license") || directMeta.get(name) || "UNKNOWN";
6218
+ return {
6219
+ name,
6220
+ version,
6221
+ spdxLicense: normalizeSpdxLicense(blockLic),
6222
+ purl: `pkg:cargo/${name}@${version}`,
6223
+ path: cargoLockPath,
6224
+ isDirect: directMeta.size === 0 || directMeta.has(name)
6225
+ };
6226
+ }
6227
+ function scanRustDependencies(rootDir, seen) {
6228
+ const cargoLockPath = path4.join(rootDir, "Cargo.lock");
6229
+ const lockContent = readTextIfExists(cargoLockPath);
6230
+ if (!lockContent) return;
6231
+ const cargoToml = readTextIfExists(path4.join(rootDir, "Cargo.toml")) || "";
6232
+ const directMeta = extractCargoDirectDeps(cargoToml);
6233
+ const rootName = extractTomlField(cargoToml, "name");
6234
+ for (const block of lockContent.split(/\[\[package\]\]/g).slice(1)) {
6235
+ const dep = parseCargoLockBlock(block, rootName, directMeta, cargoLockPath);
6236
+ if (dep && !seen.has(`cargo:${dep.name}@${dep.version}`)) {
6237
+ seen.set(`cargo:${dep.name}@${dep.version}`, dep);
6238
+ }
6239
+ }
6240
+ }
6241
+ function extractXmlTag(xml, tag) {
6242
+ const m = xml.match(new RegExp(`<${tag}>([^<]+)</${tag}>`));
6243
+ return m ? m[1].trim() : void 0;
6244
+ }
6245
+ function resolveMavenBlockLicense(block, defaultLic) {
6246
+ const tagLic = extractXmlTag(block, "license");
6247
+ if (tagLic) return tagLic;
6248
+ const commentLic = block.match(/<!--\s*(?:spdx|license)\s*:\s*([A-Za-z0-9.+-]+)\s*-->/i)?.[1];
6249
+ return commentLic || defaultLic;
6250
+ }
6251
+ function parseMavenDepBlock(block, defaultLic, pomPath) {
6252
+ const groupId = extractXmlTag(block, "groupId");
6253
+ const artifactId = extractXmlTag(block, "artifactId");
6254
+ if (!groupId || !artifactId) return null;
6255
+ const version = extractXmlTag(block, "version") || "unknown";
6256
+ const inlineLic = resolveMavenBlockLicense(block, defaultLic);
6257
+ return {
6258
+ name: `${groupId}:${artifactId}`,
6259
+ version,
6260
+ spdxLicense: normalizeSpdxLicense(inlineLic),
6261
+ purl: `pkg:maven/${groupId}/${artifactId}@${version}`,
6262
+ path: pomPath,
6263
+ isDirect: true
6264
+ };
6265
+ }
6266
+ function scanMavenDependencies(rootDir, seen) {
6267
+ const pomPath = path4.join(rootDir, "pom.xml");
6268
+ const content = readTextIfExists(pomPath);
6269
+ if (!content) return;
6270
+ const projectLicBlock = content.match(/<licenses>([\s\S]*?)<\/licenses>/)?.[1] || "";
6271
+ const defaultLic = extractXmlTag(projectLicBlock, "name") || "UNKNOWN";
6272
+ const depBlocks = content.match(/<dependency>[\s\S]*?<\/dependency>/g) || [];
6273
+ for (const block of depBlocks) {
6274
+ const dep = parseMavenDepBlock(block, defaultLic, pomPath);
6275
+ if (dep && !seen.has(`maven:${dep.name}@${dep.version}`)) {
6276
+ seen.set(`maven:${dep.name}@${dep.version}`, dep);
6277
+ }
6278
+ }
6279
+ }
5660
6280
  function scanWithNativeFs(rootDir, options = {}) {
5661
6281
  const directNames = extractDirectDepNames(rootDir, options.productionOnly);
5662
6282
  const seen = /* @__PURE__ */ new Map();
@@ -5667,6 +6287,10 @@ function scanWithNativeFs(rootDir, options = {}) {
5667
6287
  scanPnpmStore(path4.join(nmDir, ".pnpm"), directNames, seen);
5668
6288
  }
5669
6289
  }
6290
+ scanPythonDependencies(rootDir, seen);
6291
+ scanGoDependencies(rootDir, seen);
6292
+ scanRustDependencies(rootDir, seen);
6293
+ scanMavenDependencies(rootDir, seen);
5670
6294
  const allDeps = Array.from(seen.values());
5671
6295
  if (options.depth === "direct") {
5672
6296
  return allDeps.filter((d) => d.isDirect);
@@ -5736,10 +6360,17 @@ var SEVERITY_RANK = {
5736
6360
  LOW: 1,
5737
6361
  UNKNOWN: 0
5738
6362
  };
6363
+ function isExemptByVex(v, vexStatements) {
6364
+ if (!vexStatements || vexStatements.length === 0) return false;
6365
+ return vexStatements.some(
6366
+ (stmt) => stmt.id === v.id && (stmt.state === "not_affected" || stmt.state === "fixed") && (!stmt.package || stmt.package === v.packageName)
6367
+ );
6368
+ }
5739
6369
  function evaluateVulnerabilityThresholds(vulnerabilities, options) {
5740
6370
  const minRank = options?.failOnSeverity ? SEVERITY_RANK[options.failOnSeverity] ?? 3 : void 0;
5741
6371
  const maxScore = options?.maxCvssScore;
5742
6372
  const failing = vulnerabilities.filter((v) => {
6373
+ if (isExemptByVex(v, options?.vexStatements)) return false;
5743
6374
  const rankMatch = minRank !== void 0 && SEVERITY_RANK[v.severity] >= minRank;
5744
6375
  const scoreMatch = maxScore !== void 0 && v.cvssV3Score !== void 0 && v.cvssV3Score >= maxScore;
5745
6376
  return rankMatch || scoreMatch;
@@ -5869,42 +6500,77 @@ function buildCycloneDxComponent(dep) {
5869
6500
  }
5870
6501
  return comp;
5871
6502
  }
5872
- function generateCycloneDxSbom(dependencies, options = {}) {
6503
+ function buildVexAnalysis(vex) {
6504
+ if (!vex) return void 0;
6505
+ return {
6506
+ state: vex.state,
6507
+ justification: vex.justification,
6508
+ detail: vex.detail,
6509
+ response: vex.response
6510
+ };
6511
+ }
6512
+ function mapScaVulnToCycloneDx(v, vexStatements) {
6513
+ const matchingVex = vexStatements.find(
6514
+ (stmt) => stmt.id === v.id && (!stmt.package || stmt.package === v.packageName)
6515
+ );
6516
+ return {
6517
+ id: v.id,
6518
+ source: v.primaryUrl ? { name: "NVD/GHSA", url: v.primaryUrl } : void 0,
6519
+ ratings: [{ score: v.cvssV3Score, severity: v.severity.toLowerCase(), method: "CVSSv3", vector: v.cvssV3Vector }],
6520
+ analysis: buildVexAnalysis(matchingVex),
6521
+ affects: [{ ref: `pkg:npm/${v.packageName}@${v.installedVersion}` }]
6522
+ };
6523
+ }
6524
+ function mapStandaloneVex(stmt) {
6525
+ return {
6526
+ id: stmt.id,
6527
+ analysis: buildVexAnalysis(stmt),
6528
+ affects: stmt.package ? [{ ref: stmt.package }] : void 0
6529
+ };
6530
+ }
6531
+ function buildCycloneDxVulnerabilities(vulnerabilities = [], vexStatements = []) {
6532
+ const out = vulnerabilities.map((v) => mapScaVulnToCycloneDx(v, vexStatements));
6533
+ const seenIds = new Set(out.map((item) => item.id));
6534
+ for (const stmt of vexStatements) {
6535
+ if (!seenIds.has(stmt.id)) {
6536
+ out.push(mapStandaloneVex(stmt));
6537
+ seenIds.add(stmt.id);
6538
+ }
6539
+ }
6540
+ return out;
6541
+ }
6542
+ function resolveProjectIdentity(options) {
5873
6543
  let name = options.projectName || "ai-sdlc-project";
5874
6544
  let version = options.projectVersion || "1.0.0";
5875
- if (options.rootDir) {
5876
- const pkgPath = path4.join(options.rootDir, "package.json");
5877
- if (fs7.existsSync(pkgPath)) {
5878
- try {
5879
- const pkg = JSON.parse(fs7.readFileSync(pkgPath, "utf-8"));
5880
- if (pkg.name) name = pkg.name;
5881
- if (pkg.version) version = pkg.version;
5882
- } catch {
5883
- }
5884
- }
6545
+ if (!options.rootDir) return { name, version };
6546
+ const pkgPath = path4.join(options.rootDir, "package.json");
6547
+ if (!fs7.existsSync(pkgPath)) return { name, version };
6548
+ try {
6549
+ const pkg = JSON.parse(fs7.readFileSync(pkgPath, "utf-8"));
6550
+ if (pkg.name) name = pkg.name;
6551
+ if (pkg.version) version = pkg.version;
6552
+ } catch {
5885
6553
  }
5886
- const components = dependencies.map(buildCycloneDxComponent);
6554
+ return { name, version };
6555
+ }
6556
+ function buildBomMetadata(name, version) {
6557
+ return {
6558
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
6559
+ tools: [{ vendor: "AI-SDLC", name: "@aisdlc/core", version: "2.4.0" }],
6560
+ component: { type: "application", name, version }
6561
+ };
6562
+ }
6563
+ function generateCycloneDxSbom(dependencies, options = {}) {
6564
+ const { name, version } = resolveProjectIdentity(options);
6565
+ const cdxVulns = buildCycloneDxVulnerabilities(options.vulnerabilities, options.vexStatements);
5887
6566
  return {
5888
6567
  bomFormat: "CycloneDX",
5889
6568
  specVersion: "1.5",
5890
6569
  version: 1,
5891
6570
  serialNumber: `urn:uuid:${crypto.randomUUID()}`,
5892
- metadata: {
5893
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
5894
- tools: [
5895
- {
5896
- vendor: "AI-SDLC",
5897
- name: "@aisdlc/core",
5898
- version: "1.0.0"
5899
- }
5900
- ],
5901
- component: {
5902
- type: "application",
5903
- name,
5904
- version
5905
- }
5906
- },
5907
- components
6571
+ metadata: buildBomMetadata(name, version),
6572
+ components: dependencies.map(buildCycloneDxComponent),
6573
+ ...cdxVulns.length > 0 ? { vulnerabilities: cdxVulns } : {}
5908
6574
  };
5909
6575
  }
5910
6576
  function tryAtomicWrite(filePath, content) {
@@ -6072,17 +6738,24 @@ function parseExceptions(exceptions) {
6072
6738
  }
6073
6739
  return map;
6074
6740
  }
6741
+ function parseVexStatements(doc) {
6742
+ const rawList = doc?.vex_statements || doc?.exceptions?.vex_statements || [];
6743
+ if (!Array.isArray(rawList)) return [];
6744
+ return rawList.filter((item) => Boolean(item && typeof item.id === "string" && typeof item.state === "string"));
6745
+ }
6075
6746
  function parseLicensePolicy(content) {
6076
6747
  try {
6077
6748
  const doc = yaml3.load(content);
6078
6749
  const { permitted, restricted, blocked } = classifyCategories(doc?.categories);
6079
6750
  const exception_packages = parseExceptions(doc?.exceptions);
6751
+ const vex_statements = parseVexStatements(doc);
6080
6752
  return {
6081
6753
  version: doc?.version || "1.0",
6082
6754
  permitted: permitted.length > 0 ? permitted : DEFAULT_PERMITTED,
6083
6755
  restricted: restricted.length > 0 ? restricted : DEFAULT_RESTRICTED,
6084
6756
  blocked: blocked.length > 0 ? blocked : DEFAULT_BLOCKED,
6085
6757
  exception_packages,
6758
+ vex_statements,
6086
6759
  rawPolicy: doc
6087
6760
  };
6088
6761
  } catch {
@@ -6091,7 +6764,8 @@ function parseLicensePolicy(content) {
6091
6764
  permitted: DEFAULT_PERMITTED,
6092
6765
  restricted: DEFAULT_RESTRICTED,
6093
6766
  blocked: DEFAULT_BLOCKED,
6094
- exception_packages: {}
6767
+ exception_packages: {},
6768
+ vex_statements: []
6095
6769
  };
6096
6770
  }
6097
6771
  }
@@ -6266,10 +6940,10 @@ function shouldGenerateSbom(options, rawPolicy) {
6266
6940
  if (options.generateSbom === false) return false;
6267
6941
  return Boolean(options.generateSbom || options.sbomPath || rawPolicy?.ci_gates?.generate_sbom);
6268
6942
  }
6269
- function maybeGenerateSbom(options, rootDir, rawPolicy, dependencies) {
6943
+ function maybeGenerateSbom(options, rootDir, rawPolicy, dependencies, vulnerabilities, vexStatements) {
6270
6944
  if (!shouldGenerateSbom(options, rawPolicy)) return void 0;
6271
6945
  const sbomPath = options.sbomPath || path4.join(rootDir, "reports", "sbom.cdx.json");
6272
- const sbom = generateCycloneDxSbom(dependencies, { rootDir });
6946
+ const sbom = generateCycloneDxSbom(dependencies, { rootDir, vulnerabilities, vexStatements });
6273
6947
  writeCycloneDxSbom(sbom, sbomPath);
6274
6948
  return sbomPath;
6275
6949
  }
@@ -6282,9 +6956,9 @@ function maybeGenerateNotices(options, rootDir, rawPolicy, dependencies) {
6282
6956
  writeThirdPartyNotices(noticesContent, noticesPath);
6283
6957
  return noticesPath;
6284
6958
  }
6285
- function handleDynamicScaArtifacts(options, rootDir, rawPolicy, dependencies) {
6959
+ function handleDynamicScaArtifacts(options, rootDir, rawPolicy, dependencies, vulnerabilities, vexStatements) {
6286
6960
  return {
6287
- sbomPath: maybeGenerateSbom(options, rootDir, rawPolicy, dependencies),
6961
+ sbomPath: maybeGenerateSbom(options, rootDir, rawPolicy, dependencies, vulnerabilities, vexStatements),
6288
6962
  noticesPath: maybeGenerateNotices(options, rootDir, rawPolicy, dependencies)
6289
6963
  };
6290
6964
  }
@@ -6313,7 +6987,7 @@ function buildSkippedVulnResult() {
6313
6987
  skipReason: "Trivy scanner is not installed on host environment. Vulnerability check gracefully skipped."
6314
6988
  };
6315
6989
  }
6316
- function checkVulnerabilities(rootDir, options) {
6990
+ function checkVulnerabilities(rootDir, options, vexStatements) {
6317
6991
  if (options.scanVulnerabilities === false) {
6318
6992
  return { vulnerabilities: [], blocked: false };
6319
6993
  }
@@ -6321,7 +6995,10 @@ function checkVulnerabilities(rootDir, options) {
6321
6995
  if (!res.executed) {
6322
6996
  return buildSkippedVulnResult();
6323
6997
  }
6324
- const evalResult = evaluateVulnerabilityThresholds(res.vulnerabilities, options.vulnerabilityThresholds);
6998
+ const evalResult = evaluateVulnerabilityThresholds(res.vulnerabilities, {
6999
+ ...options.vulnerabilityThresholds,
7000
+ vexStatements
7001
+ });
6325
7002
  return { vulnerabilities: res.vulnerabilities, blocked: evalResult.blocked };
6326
7003
  }
6327
7004
  function assembleDynamicLicenseResult(dependencies, permittedCount, violations, reportMarkdown, artifacts, vulnData) {
@@ -6345,7 +7022,8 @@ function toCleanPolicy(policyWithRaw) {
6345
7022
  permitted: policyWithRaw.permitted,
6346
7023
  restricted: policyWithRaw.restricted,
6347
7024
  blocked: policyWithRaw.blocked,
6348
- exception_packages: policyWithRaw.exception_packages
7025
+ exception_packages: policyWithRaw.exception_packages,
7026
+ vex_statements: policyWithRaw.vex_statements
6349
7027
  };
6350
7028
  }
6351
7029
  function scanDependenciesForVerification(options, rootDir, rawPolicy) {
@@ -6365,8 +7043,15 @@ function verifyLicenses(options = {}) {
6365
7043
  }
6366
7044
  const dependencies = scanDependenciesForVerification(options, rootDir, policyWithRaw.rawPolicy);
6367
7045
  const { violations, permittedCount } = evaluateDependencyList(dependencies, policy);
6368
- const artifacts = handleDynamicScaArtifacts(options, rootDir, policyWithRaw.rawPolicy, dependencies);
6369
- const vulnData = checkVulnerabilities(rootDir, options);
7046
+ const vulnData = checkVulnerabilities(rootDir, options, policy.vex_statements);
7047
+ const artifacts = handleDynamicScaArtifacts(
7048
+ options,
7049
+ rootDir,
7050
+ policyWithRaw.rawPolicy,
7051
+ dependencies,
7052
+ vulnData.vulnerabilities,
7053
+ policy.vex_statements
7054
+ );
6370
7055
  const reportMarkdown = generateLicenseReportMarkdown(dependencies, violations, policy, artifacts.sbomPath);
6371
7056
  return assembleDynamicLicenseResult(dependencies, permittedCount, violations, reportMarkdown, artifacts, vulnData);
6372
7057
  }
@@ -15906,7 +16591,145 @@ function initProject(options = {}) {
15906
16591
  tryInstallGitHook(destDir, options.dryRun)
15907
16592
  );
15908
16593
  }
16594
+ var DEFAULT_DLP_RULES = [
16595
+ {
16596
+ id: "DLP-001-PRIVATE-KEY",
16597
+ description: "PEM / RSA / EC / OPENSSH Private Key Block",
16598
+ pattern: "-----BEGIN (?:[A-Z0-9_-]+ )?PRIVATE KEY-----[\\s\\S]*?-----END (?:[A-Z0-9_-]+ )?PRIVATE KEY-----",
16599
+ replacement: "[REDACTED:PRIVATE_KEY]",
16600
+ enabled: true
16601
+ },
16602
+ {
16603
+ id: "DLP-002-API-TOKEN",
16604
+ description: "Cloud, GitHub, Slack, OpenAI, Stripe, and AWS Access Tokens",
16605
+ pattern: "\\b(?:gh[pousr]_[A-Za-z0-9_]{36,255}|github_pat_[0-9a-zA-Z_]{82}|sk-(?:proj-|live-)?[a-zA-Z0-9_-]{32,}|AKIA[0-9A-Z]{16}|xox[baprs]-[0-9]{10,13}-[0-9]{10,13}[a-zA-Z0-9-]*|(?:sk|rk)_(?:live|test)_[0-9a-zA-Z]{24,99})\\b",
16606
+ replacement: "[REDACTED:API_TOKEN]",
16607
+ enabled: true
16608
+ },
16609
+ {
16610
+ id: "DLP-003-JWT",
16611
+ description: "Plaintext JSON Web Token (JWT)",
16612
+ pattern: "\\beyJ[A-Za-z0-9_-]{10,}\\.eyJ[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}\\b",
16613
+ replacement: "[REDACTED:JWT_TOKEN]",
16614
+ enabled: true
16615
+ },
16616
+ {
16617
+ id: "DLP-004-CREDIT-CARD",
16618
+ description: "Payment Card Number (13-19 digits formatted)",
16619
+ pattern: "\\b(?:\\d{4}[- ]\\d{4}[- ]\\d{4}[- ]\\d{4}|\\d{16})\\b",
16620
+ replacement: "[REDACTED:CREDIT_CARD]",
16621
+ enabled: true
16622
+ },
16623
+ {
16624
+ id: "DLP-005-EMAIL",
16625
+ description: "Personal or Corporate Email Address",
16626
+ pattern: "\\b[A-Za-z0-9._%+-]+@(?!example\\.com|localhost|test\\.local)[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\b",
16627
+ replacement: "[REDACTED:EMAIL]",
16628
+ enabled: true
16629
+ },
16630
+ {
16631
+ id: "DLP-006-INTERNAL-URL",
16632
+ description: "Internal Intranet / Corp Service URL",
16633
+ pattern: "https?://(?:[A-Za-z0-9._-]+:[A-Za-z0-9._-]+@|[A-Za-z0-9.-]+\\.(?:internal|corp|intranet|local)\\b)[^\\s\"'`<>]*",
16634
+ replacement: "[REDACTED:INTERNAL_URL]",
16635
+ enabled: true
16636
+ }
16637
+ ];
16638
+ function createDefaultDlpPolicy() {
16639
+ return {
16640
+ version: "1.0",
16641
+ enabled: true,
16642
+ zero_data_retention_required: true,
16643
+ rules: [...DEFAULT_DLP_RULES]
16644
+ };
16645
+ }
16646
+ function normalizeParsedRule(raw, idx) {
16647
+ if (typeof raw.pattern !== "string" || !raw.pattern) return null;
16648
+ return {
16649
+ id: typeof raw.id === "string" ? raw.id : `DLP-CUSTOM-${idx + 1}`,
16650
+ description: typeof raw.description === "string" ? raw.description : "Custom DLP rule",
16651
+ pattern: raw.pattern,
16652
+ replacement: typeof raw.replacement === "string" ? raw.replacement : "[REDACTED]",
16653
+ enabled: raw.enabled !== false
16654
+ };
16655
+ }
16656
+ function parseDlpPolicy(yamlContent) {
16657
+ const fallback = createDefaultDlpPolicy();
16658
+ if (!yamlContent || !yamlContent.trim()) return fallback;
16659
+ try {
16660
+ const doc = yaml3.load(yamlContent);
16661
+ if (!doc || typeof doc !== "object") return fallback;
16662
+ const rawRules = Array.isArray(doc.rules) ? doc.rules : [];
16663
+ const parsedRules = rawRules.map((r, i) => normalizeParsedRule(r, i)).filter((r) => r !== null);
16664
+ return {
16665
+ version: typeof doc.version === "string" ? doc.version : "1.0",
16666
+ enabled: doc.enabled !== false,
16667
+ zero_data_retention_required: Boolean(doc.zero_data_retention_required ?? true),
16668
+ rules: parsedRules.length > 0 ? parsedRules : fallback.rules
16669
+ };
16670
+ } catch {
16671
+ return fallback;
16672
+ }
16673
+ }
16674
+ function loadDlpPolicy(rootDir, customPolicyPath) {
16675
+ const base = rootDir || process.cwd();
16676
+ const filePath = customPolicyPath ? path4.isAbsolute(customPolicyPath) ? customPolicyPath : path4.join(base, customPolicyPath) : path4.join(base, "dlp-policy.yaml");
16677
+ if (!fs7.existsSync(filePath)) return createDefaultDlpPolicy();
16678
+ try {
16679
+ return parseDlpPolicy(fs7.readFileSync(filePath, "utf-8"));
16680
+ } catch {
16681
+ return createDefaultDlpPolicy();
16682
+ }
16683
+ }
16684
+ function applySingleDlpRule(text, rule) {
16685
+ if (rule.enabled === false) return { output: text, matches: 0 };
16686
+ try {
16687
+ const regex = new RegExp(rule.pattern, "g");
16688
+ let matches = 0;
16689
+ const output = text.replace(regex, () => {
16690
+ matches++;
16691
+ return rule.replacement;
16692
+ });
16693
+ return { output, matches };
16694
+ } catch {
16695
+ return { output: text, matches: 0 };
16696
+ }
16697
+ }
16698
+ function sanitizeDlpText(text, policy = createDefaultDlpPolicy()) {
16699
+ if (!policy.enabled || !text) {
16700
+ return { sanitizedText: text, redactionCount: 0, triggeredRuleIds: [] };
16701
+ }
16702
+ let current = text;
16703
+ let totalRedactions = 0;
16704
+ const triggered = [];
16705
+ for (const rule of policy.rules) {
16706
+ const res = applySingleDlpRule(current, rule);
16707
+ if (res.matches > 0) {
16708
+ current = res.output;
16709
+ totalRedactions += res.matches;
16710
+ triggered.push(rule.id);
16711
+ }
16712
+ }
16713
+ return {
16714
+ sanitizedText: current,
16715
+ redactionCount: totalRedactions,
16716
+ triggeredRuleIds: triggered
16717
+ };
16718
+ }
16719
+ function sanitizeDlpPayload(payload, policy = createDefaultDlpPolicy()) {
16720
+ if (!policy.enabled || payload === null || payload === void 0) return payload;
16721
+ if (typeof payload === "string") {
16722
+ return sanitizeDlpText(payload, policy).sanitizedText;
16723
+ }
16724
+ const serialized = JSON.stringify(payload);
16725
+ const { sanitizedText } = sanitizeDlpText(serialized, policy);
16726
+ try {
16727
+ return JSON.parse(sanitizedText);
16728
+ } catch {
16729
+ return payload;
16730
+ }
16731
+ }
15909
16732
 
15910
- export { ALL_ARCHITECTURE_TEMPLATES, BRANCH_PATTERNS, DEFAULT_EXCLUDED_PATTERNS, DEFAULT_EXCLUDES, DEFAULT_EXTENSIONS, DEFAULT_PRIVACY_POLICY, DEFAULT_SAST_EXCLUDES, GENERAL_SOURCE_EXTENSIONS, KPI_SUMMARY_END_TAG, KPI_SUMMARY_START_TAG, LIFECYCLE_SKILL_TEMPLATES, OpenSpecAdapter, PII_SAST_RULES, PREPARE_COMMIT_MSG_SCRIPT, PROMPT_INJECTION_SIGNATURES, PROTECTED_BYPASS_PATTERNS, SARIF_SCHEMA_2_1_0, SARIF_VERSION, SAST_RULES, SCHEMA_SCHEMAS_ARCHITECTURE_ADR_SCHEMA_JSON, SCHEMA_SCHEMAS_ARCHITECTURE_COMPONENT_SCHEMA_JSON, SCHEMA_SCHEMAS_ARCHITECTURE_INTRODUCTION_AND_GOALS_SCHEMA_JSON, SCHEMA_SCHEMAS_COMPLIANCE_LICENSE_MANIFEST_SCHEMA_JSON, SCHEMA_SCHEMAS_COMPLIANCE_LICENSE_POLICY_SCHEMA_JSON, SCHEMA_SCHEMAS_COMPLIANCE_QUALITY_POLICY_SCHEMA_JSON, SCHEMA_SCHEMAS_IDE_MCP_CONFIG_SCHEMA_JSON, SCHEMA_SCHEMAS_MANUALS_PRODUCTION_MANUAL_SCHEMA_JSON, SCHEMA_SCHEMAS_MANUALS_USER_MANUAL_SCHEMA_JSON, SCHEMA_SCHEMAS_PRIVACY_DATA_ASSET_SCHEMA_JSON, SCHEMA_SCHEMAS_PRIVACY_PRIVACY_POLICY_SCHEMA_JSON, SCHEMA_SCHEMAS_PRIVACY_PRIVACY_REQ_SCHEMA_JSON, SCHEMA_SCHEMAS_PRIVACY_PRIVACY_ROPA_SCHEMA_JSON, SCHEMA_SCHEMAS_PRODUCT_ACTOR_SCHEMA_JSON, SCHEMA_SCHEMAS_PRODUCT_BOUNDED_CONTEXT_SCHEMA_JSON, SCHEMA_SCHEMAS_PRODUCT_BUSINESS_RULE_SCHEMA_JSON, SCHEMA_SCHEMAS_PRODUCT_JOURNEY_SCHEMA_JSON, SCHEMA_SCHEMAS_PRODUCT_REQUIREMENT_SCHEMA_JSON, SCHEMA_SCHEMAS_PRODUCT_TERM_SCHEMA_JSON, SCHEMA_SCHEMAS_PRODUCT_USE_CASE_SCHEMA_JSON, SCHEMA_SCHEMAS_SAFETY_HAZARD_SCHEMA_JSON, SCHEMA_SCHEMAS_SAFETY_SAFETY_REQ_SCHEMA_JSON, SCHEMA_SCHEMAS_SDD_DESIGN_SCHEMA_JSON, SCHEMA_SCHEMAS_SDD_HANDOFF_SCHEMA_JSON, SCHEMA_SCHEMAS_SDD_PROPOSAL_SCHEMA_JSON, SCHEMA_SCHEMAS_SDD_RELEASE_KPIS_SCHEMA_JSON, SCHEMA_SCHEMAS_SDD_SESSION_TELEMETRY_SCHEMA_JSON, SCHEMA_SCHEMAS_SDD_SPEC_SCHEMA_JSON, SCHEMA_SCHEMAS_SDD_TASKS_SCHEMA_JSON, SCHEMA_SCHEMAS_SECURITY_ABUSE_CASE_SCHEMA_JSON, SCHEMA_SCHEMAS_SECURITY_ENCLAVE_SCHEMA_JSON, SCHEMA_SCHEMAS_SECURITY_SECURITY_REQ_SCHEMA_JSON, SCHEMA_SCHEMAS_SECURITY_THREAT_ACTOR_SCHEMA_JSON, SCHEMA_SCHEMAS_WORKFLOW_AGENT_HANDOFF_SCHEMA_JSON, SECRET_RULES, SPECIALIZED_AGENT_TEMPLATES, STARTER_ANTIGRAVITY_MCP, STARTER_ANTIGRAVITY_RULES, STARTER_ARCH_ADR, STARTER_ARCH_ARCHITECTURE_CONSTRAINTS, STARTER_ARCH_COMPONENT, STARTER_ARCH_CONTEXT_AND_SCOPE, STARTER_ARCH_CROSS_CUTTING_CONCEPTS, STARTER_ARCH_DEPLOYMENT_VIEW, STARTER_ARCH_GLOSSARY, STARTER_ARCH_INTRODUCTION_AND_GOALS, STARTER_ARCH_LEVEL_1_WHITEBOX, STARTER_ARCH_QUALITY_REQUIREMENTS, STARTER_ARCH_RISKS_AND_TECHNICAL_DEBT, STARTER_ARCH_RUNTIME_VIEW, STARTER_ARCH_SOLUTION_STRATEGY, STARTER_AZURE_PIPELINES, STARTER_BASE_TEMPLATES, STARTER_BITBUCKET_PIPELINES, STARTER_CLAUDE_RULES, STARTER_COMPLIANCE_LICENSE_MANIFEST_YAML, STARTER_COPILOT_RULES, STARTER_CURSOR_CORE_RULES, STARTER_CURSOR_MCP, STARTER_CURSOR_PRODUCT_RULES, STARTER_CURSOR_QUALITY_RULES, STARTER_GITHUB_CI, STARTER_GITHUB_DEPLOY_DASHBOARD, STARTER_GITHUB_PR_KPI, STARTER_GITHUB_PULL_REQUEST_TEMPLATE, STARTER_GITHUB_SDD_INTEGRATE, STARTER_GITLAB_CI, STARTER_LICENSE_POLICY, STARTER_PRIVACY_POLICY, STARTER_PROCESS_README, STARTER_PULL_REQUEST_TEMPLATE, STARTER_QUALITY_POLICY, STARTER_REQUIREMENT_TEMPLATE, STARTER_SCHEMAS, STARTER_SCHEMAS_MAP, STARTER_TASK_TEMPLATE, STARTER_TEMPLATES_CI_AZURE_PIPELINES_YML, STARTER_TEMPLATES_CI_BITBUCKET_PIPELINES_YML, STARTER_TEMPLATES_CI_GITHUB_WORKFLOWS_CI_YML, STARTER_TEMPLATES_CI_GITHUB_WORKFLOWS_DEPLOY_DASHBOARD_YML, STARTER_TEMPLATES_CI_GITHUB_WORKFLOWS_PR_KPI_SUMMARY_YML, STARTER_TEMPLATES_CI_GITHUB_WORKFLOWS_SDD_INTEGRATE_ON_MERGE_YML, STARTER_TEMPLATES_CI__GITLAB_CI_YML, STARTER_TEMPLATES_COMPLIANCE_COMMERCIAL_ACQUISITION_REQUEST_TEMPLATE_MD, STARTER_TEMPLATES_MANUALS_PRODUCTION_MANUAL_TEMPLATE_MD, STARTER_TEMPLATES_MANUALS_USER_MANUAL_TEMPLATE_MD, STARTER_TEMPLATES_PRIVACY_DATA_ASSET_TEMPLATE_MD, STARTER_TEMPLATES_PRIVACY_DPIA_REQUEST_TEMPLATE_MD, STARTER_TEMPLATES_PRIVACY_PRIVACY_REQ_TEMPLATE_MD, STARTER_TEMPLATES_PRIVACY_PRIVACY_ROPA_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_ACTOR_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_BOUNDED_CONTEXT_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_BUSINESS_RULE_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_JOURNEY_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_REQUIREMENT_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_TERM_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_USER_DESIGN_FEEDBACK_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_USE_CASE_TEMPLATE_MD, STARTER_TEMPLATES_SAFETY_HAZARD_TEMPLATE_MD, STARTER_TEMPLATES_SAFETY_SAFETY_REQ_TEMPLATE_MD, STARTER_TEMPLATES_SDD_DESIGN_TEMPLATE_MD, STARTER_TEMPLATES_SDD_HANDOFF_TEMPLATE_YAML, STARTER_TEMPLATES_SDD_PROPOSAL_TEMPLATE_MD, STARTER_TEMPLATES_SDD_PULL_REQUEST_TEMPLATE_MD, STARTER_TEMPLATES_SDD_SPEC_TEMPLATE_MD, STARTER_TEMPLATES_SDD_TASKS_TEMPLATE_MD, STARTER_TEMPLATES_SECURITY_ABUSE_CASE_TEMPLATE_MD, STARTER_TEMPLATES_SECURITY_ENCLAVE_TEMPLATE_MD, STARTER_TEMPLATES_SECURITY_SECURITY_REQ_TEMPLATE_MD, STARTER_TEMPLATES_SECURITY_THREAT_ACTOR_TEMPLATE_MD, STARTER_TEMPLATES_WORKFLOW_AGENT_HANDOFF_TEMPLATE_MD, STARTER_VSCODE_MCP, STARTER_WORKFLOW_HANDOFF_TEMPLATE, STARTER__GITHUB_PULL_REQUEST_TEMPLATE_MD, SpecKitAdapter, TYPE_TO_SCHEMA_MAP, VALID_AGENT_TARGETS, VALID_ARCHITECTURE_GRANULARITIES, VALID_AUTONOMY_MODES, VALID_CHANGE_PROFILES, VALID_CI_PROVIDERS, aggregateCommitKpiRecords, aggregatePrKpis, aggregateReleaseKpis, analyzeBddVariantsForRequirement, appendRevisionHistoryRow, applyRatchetMode, buildCycloneDxComponent, buildFeatureFileContent, buildGraphElements, calculateJaccardSimilarity, calculateMetrics, calculateRating, calculateShannonEntropy, checkGherkinInSync, checkoutTaskBranch, classifyBranch, classifyMetricFromMessage, collectAgentFiles, collectDashboardMetrics, collectHistoricalKpis, computeCanonicalSha256, computeSha256, computeViolationSignature, createDefaultQualityPolicy, depositProductHandoffSidecar, detectActiveChangeForIntegration, detectAuthorIdentity, detectLanguage, detectProfileFromChange, detectPromptInjection, emitCiOutput, evaluateCompoundLicense, evaluateSingleDependency, evaluateVulnerabilityThresholds, extractBaselineEntriesFromResults, extractCitations, extractCommitKpisFromRange, extractDirectDepNames, extractFeatureTags, extractFrontmatter, extractFunctions, extractFunctionsBraceLanguages, extractFunctionsPolyglot, extractFunctionsPython, extractFunctionsTypeScriptAst, extractGherkinBlock, extractGherkinFeatures, extractNormativeText, findChangeWorkspaceDir, findLicenseFile, formatCommitTrailers, formatPrKpiMarkdown, formatReleaseKpiMarkdown, generateBranchHierarchyPlan, generateCycloneDxSbom, generateDashboardReport, generateDuplicatesReportMarkdown, generateGovernanceReportMarkdown, generateLicenseReportMarkdown, generatePdacReportMarkdown, generatePrivacyReportMarkdown, generateQualityReport, generateRopaInventoryMarkdown, generateSastReportMarkdown, generateSecretsReportMarkdown, generateSecuritySarifReport, generateSuppressionsAuditReport, generateTestingCoverageReportMarkdown, generateThirdPartyNotices, generateTraceabilityReportMarkdown, getArchitectureTemplates, getCytoscapeScript, getGitDiffLines, getNextCorrelativeNumber, getSddAdapter, inferArtifactTypeFromId, inferMissingTrailers, initProject, injectKpisIntoPrBody, installGitHooks, integrateSddChange, isGitleaksInstalled, isMetricWorsened, isPathProtectedFromPatch, isPlaceholderOrIgnored, isRequirementArtifact2 as isRequirementArtifact, isSemgrepInstalled, isToolAvailable, loadPrivacyPolicy, loadProductHandoffSidecar, loadQualityBaseline, locateTaskInActiveChanges, mapSastSeverityToSarifLevel, maskSecret, normalizeSpdxLicense, normalizeUri, parseCommitTrailers, parseFrontmatter, parseFrontmatterId, parseGenericDoc, parseLicensePolicy, parseMarkdownFrontmatter, parseQualityPolicy, parseRequirementFile, parseSecuritySuppression, parseSpecCatalogScope, parseTasksDoc, parseTasksFromContent, parseTrivyVulnerabilities, processPackageDir, readCodeCoverageSummary, readPackageJson, renderAntigravityAgentFile, renderAntigravitySkillFile, renderAutonomyModeSection, renderClaudeAgentFile, renderClaudeSkillFile, renderCopilotAgentFile, renderCopilotSkillFile, renderCursorAgentFile, renderCursorSkillFile, renderDashboardHtml, renderManualsTab, resolveAgentTargets, resolveBranchHierarchy, resolveCiEnvironment, resolveCytoscapePath, resolveDefaultBranchBase, resolveFeatureFilePath, resolveGitRef, resolveLicenseFromFile, resolveReleaseBaseBranch, resolveSastCwe, resolveSastOwasp, resolveSchemaForArtifact, resolveTargetFiles, runGitleaksCli, runSemgrepCli, scaffoldSddChange, scanAllProductHandoffs, scanAllTestArtifacts, scanContentForSecrets, scanFileForPrivacyViolations, scanFileForSast, scanInstalledLicenses, scanManualsInWorkspace, scanPnpmStore, scanSubdirectories, scanWithNativeFs, scanWithSyft, scanWithTrivy, serializeSarifDocument, slugify, syncPdacDigests, tokenizeTitle, updateCitationsInContent, validateAgainstSchema, validateArtifactSchema, verifyArtifactDuplicates, verifyArtifactsSchemas, verifyLicenses, verifyManuals, verifyPdacGraph, verifyPrivacy, verifyProgressiveFriction, verifyQualityGate, verifySast, verifySddIntegration, verifySecrets, verifyTasksGovernance, verifyTestingCoverage, verifyTraceability, walkDir, walkMdFiles, walkProjectFiles, walkSourceFiles, walkTaskFiles, writeCycloneDxSbom, writeQualityBaseline, writeReleaseKpiReport, writeSecuritySarifReport, writeThirdPartyNotices };
16733
+ export { ALL_ARCHITECTURE_TEMPLATES, BRANCH_PATTERNS, BddStepRegistry, DEFAULT_DLP_RULES, DEFAULT_EXCLUDED_PATTERNS, DEFAULT_EXCLUDES, DEFAULT_EXTENSIONS, DEFAULT_PRIVACY_POLICY, DEFAULT_SAST_EXCLUDES, GENERAL_SOURCE_EXTENSIONS, KPI_SUMMARY_END_TAG, KPI_SUMMARY_START_TAG, LIFECYCLE_SKILL_TEMPLATES, OpenSpecAdapter, PII_SAST_RULES, PREPARE_COMMIT_MSG_SCRIPT, PROMPT_INJECTION_SIGNATURES, PROTECTED_BYPASS_PATTERNS, SARIF_SCHEMA_2_1_0, SARIF_VERSION, SAST_RULES, SCHEMA_SCHEMAS_ARCHITECTURE_ADR_SCHEMA_JSON, SCHEMA_SCHEMAS_ARCHITECTURE_COMPONENT_SCHEMA_JSON, SCHEMA_SCHEMAS_ARCHITECTURE_INTRODUCTION_AND_GOALS_SCHEMA_JSON, SCHEMA_SCHEMAS_COMPLIANCE_LICENSE_MANIFEST_SCHEMA_JSON, SCHEMA_SCHEMAS_COMPLIANCE_LICENSE_POLICY_SCHEMA_JSON, SCHEMA_SCHEMAS_COMPLIANCE_QUALITY_POLICY_SCHEMA_JSON, SCHEMA_SCHEMAS_IDE_MCP_CONFIG_SCHEMA_JSON, SCHEMA_SCHEMAS_MANUALS_PRODUCTION_MANUAL_SCHEMA_JSON, SCHEMA_SCHEMAS_MANUALS_USER_MANUAL_SCHEMA_JSON, SCHEMA_SCHEMAS_PRIVACY_DATA_ASSET_SCHEMA_JSON, SCHEMA_SCHEMAS_PRIVACY_PRIVACY_POLICY_SCHEMA_JSON, SCHEMA_SCHEMAS_PRIVACY_PRIVACY_REQ_SCHEMA_JSON, SCHEMA_SCHEMAS_PRIVACY_PRIVACY_ROPA_SCHEMA_JSON, SCHEMA_SCHEMAS_PRODUCT_ACTOR_SCHEMA_JSON, SCHEMA_SCHEMAS_PRODUCT_BOUNDED_CONTEXT_SCHEMA_JSON, SCHEMA_SCHEMAS_PRODUCT_BUSINESS_RULE_SCHEMA_JSON, SCHEMA_SCHEMAS_PRODUCT_JOURNEY_SCHEMA_JSON, SCHEMA_SCHEMAS_PRODUCT_REQUIREMENT_SCHEMA_JSON, SCHEMA_SCHEMAS_PRODUCT_TERM_SCHEMA_JSON, SCHEMA_SCHEMAS_PRODUCT_USE_CASE_SCHEMA_JSON, SCHEMA_SCHEMAS_SAFETY_HAZARD_SCHEMA_JSON, SCHEMA_SCHEMAS_SAFETY_SAFETY_REQ_SCHEMA_JSON, SCHEMA_SCHEMAS_SDD_DESIGN_SCHEMA_JSON, SCHEMA_SCHEMAS_SDD_HANDOFF_SCHEMA_JSON, SCHEMA_SCHEMAS_SDD_PROPOSAL_SCHEMA_JSON, SCHEMA_SCHEMAS_SDD_RELEASE_KPIS_SCHEMA_JSON, SCHEMA_SCHEMAS_SDD_SESSION_TELEMETRY_SCHEMA_JSON, SCHEMA_SCHEMAS_SDD_SPEC_SCHEMA_JSON, SCHEMA_SCHEMAS_SDD_TASKS_SCHEMA_JSON, SCHEMA_SCHEMAS_SECURITY_ABUSE_CASE_SCHEMA_JSON, SCHEMA_SCHEMAS_SECURITY_ENCLAVE_SCHEMA_JSON, SCHEMA_SCHEMAS_SECURITY_SECURITY_REQ_SCHEMA_JSON, SCHEMA_SCHEMAS_SECURITY_THREAT_ACTOR_SCHEMA_JSON, SCHEMA_SCHEMAS_WORKFLOW_AGENT_HANDOFF_SCHEMA_JSON, SECRET_RULES, SPECIALIZED_AGENT_TEMPLATES, STARTER_ANTIGRAVITY_MCP, STARTER_ANTIGRAVITY_RULES, STARTER_ARCH_ADR, STARTER_ARCH_ARCHITECTURE_CONSTRAINTS, STARTER_ARCH_COMPONENT, STARTER_ARCH_CONTEXT_AND_SCOPE, STARTER_ARCH_CROSS_CUTTING_CONCEPTS, STARTER_ARCH_DEPLOYMENT_VIEW, STARTER_ARCH_GLOSSARY, STARTER_ARCH_INTRODUCTION_AND_GOALS, STARTER_ARCH_LEVEL_1_WHITEBOX, STARTER_ARCH_QUALITY_REQUIREMENTS, STARTER_ARCH_RISKS_AND_TECHNICAL_DEBT, STARTER_ARCH_RUNTIME_VIEW, STARTER_ARCH_SOLUTION_STRATEGY, STARTER_AZURE_PIPELINES, STARTER_BASE_TEMPLATES, STARTER_BITBUCKET_PIPELINES, STARTER_CLAUDE_RULES, STARTER_COMPLIANCE_LICENSE_MANIFEST_YAML, STARTER_COPILOT_RULES, STARTER_CURSOR_CORE_RULES, STARTER_CURSOR_MCP, STARTER_CURSOR_PRODUCT_RULES, STARTER_CURSOR_QUALITY_RULES, STARTER_GITHUB_CI, STARTER_GITHUB_DEPLOY_DASHBOARD, STARTER_GITHUB_PR_KPI, STARTER_GITHUB_PULL_REQUEST_TEMPLATE, STARTER_GITHUB_SDD_INTEGRATE, STARTER_GITLAB_CI, STARTER_LICENSE_POLICY, STARTER_PRIVACY_POLICY, STARTER_PROCESS_README, STARTER_PULL_REQUEST_TEMPLATE, STARTER_QUALITY_POLICY, STARTER_REQUIREMENT_TEMPLATE, STARTER_SCHEMAS, STARTER_SCHEMAS_MAP, STARTER_TASK_TEMPLATE, STARTER_TEMPLATES_CI_AZURE_PIPELINES_YML, STARTER_TEMPLATES_CI_BITBUCKET_PIPELINES_YML, STARTER_TEMPLATES_CI_GITHUB_WORKFLOWS_CI_YML, STARTER_TEMPLATES_CI_GITHUB_WORKFLOWS_DEPLOY_DASHBOARD_YML, STARTER_TEMPLATES_CI_GITHUB_WORKFLOWS_PR_KPI_SUMMARY_YML, STARTER_TEMPLATES_CI_GITHUB_WORKFLOWS_SDD_INTEGRATE_ON_MERGE_YML, STARTER_TEMPLATES_CI__GITLAB_CI_YML, STARTER_TEMPLATES_COMPLIANCE_COMMERCIAL_ACQUISITION_REQUEST_TEMPLATE_MD, STARTER_TEMPLATES_MANUALS_PRODUCTION_MANUAL_TEMPLATE_MD, STARTER_TEMPLATES_MANUALS_USER_MANUAL_TEMPLATE_MD, STARTER_TEMPLATES_PRIVACY_DATA_ASSET_TEMPLATE_MD, STARTER_TEMPLATES_PRIVACY_DPIA_REQUEST_TEMPLATE_MD, STARTER_TEMPLATES_PRIVACY_PRIVACY_REQ_TEMPLATE_MD, STARTER_TEMPLATES_PRIVACY_PRIVACY_ROPA_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_ACTOR_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_BOUNDED_CONTEXT_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_BUSINESS_RULE_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_JOURNEY_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_REQUIREMENT_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_TERM_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_USER_DESIGN_FEEDBACK_TEMPLATE_MD, STARTER_TEMPLATES_PRODUCT_USE_CASE_TEMPLATE_MD, STARTER_TEMPLATES_SAFETY_HAZARD_TEMPLATE_MD, STARTER_TEMPLATES_SAFETY_SAFETY_REQ_TEMPLATE_MD, STARTER_TEMPLATES_SDD_DESIGN_TEMPLATE_MD, STARTER_TEMPLATES_SDD_HANDOFF_TEMPLATE_YAML, STARTER_TEMPLATES_SDD_PROPOSAL_TEMPLATE_MD, STARTER_TEMPLATES_SDD_PULL_REQUEST_TEMPLATE_MD, STARTER_TEMPLATES_SDD_SPEC_TEMPLATE_MD, STARTER_TEMPLATES_SDD_TASKS_TEMPLATE_MD, STARTER_TEMPLATES_SECURITY_ABUSE_CASE_TEMPLATE_MD, STARTER_TEMPLATES_SECURITY_ENCLAVE_TEMPLATE_MD, STARTER_TEMPLATES_SECURITY_SECURITY_REQ_TEMPLATE_MD, STARTER_TEMPLATES_SECURITY_THREAT_ACTOR_TEMPLATE_MD, STARTER_TEMPLATES_WORKFLOW_AGENT_HANDOFF_TEMPLATE_MD, STARTER_VSCODE_MCP, STARTER_WORKFLOW_HANDOFF_TEMPLATE, STARTER__GITHUB_PULL_REQUEST_TEMPLATE_MD, SpecKitAdapter, TYPE_TO_SCHEMA_MAP, VALID_AGENT_TARGETS, VALID_ARCHITECTURE_GRANULARITIES, VALID_AUTONOMY_MODES, VALID_CHANGE_PROFILES, VALID_CI_PROVIDERS, aggregateCommitKpiRecords, aggregatePrKpis, aggregateReleaseKpis, analyzeBddVariantsForRequirement, appendRevisionHistoryRow, applyRatchetMode, buildCycloneDxComponent, buildCycloneDxVulnerabilities, buildFeatureFileContent, buildGraphElements, calculateJaccardSimilarity, calculateMetrics, calculateRating, calculateShannonEntropy, checkGherkinInSync, checkoutTaskBranch, classifyBranch, classifyMetricFromMessage, collectAgentFiles, collectDashboardMetrics, collectHistoricalKpis, computeCanonicalSha256, computeSha256, computeViolationSignature, createDefaultDlpPolicy, createDefaultQualityPolicy, depositProductHandoffSidecar, detectActiveChangeForIntegration, detectAuthorIdentity, detectLanguage, detectProfileFromChange, detectPromptInjection, emitCiOutput, evaluateCompoundLicense, evaluateSingleDependency, evaluateVulnerabilityThresholds, executeBddFeature, extractBaselineEntriesFromResults, extractCitations, extractCommitKpisFromRange, extractDirectDepNames, extractFeatureTags, extractFrontmatter, extractFunctions, extractFunctionsBraceLanguages, extractFunctionsPolyglot, extractFunctionsPython, extractFunctionsTypeScriptAst, extractGherkinBlock, extractGherkinFeatures, extractNormativeText, findChangeWorkspaceDir, findLicenseFile, formatCommitTrailers, formatPrKpiMarkdown, formatReleaseKpiMarkdown, generateBranchHierarchyPlan, generateCycloneDxSbom, generateDashboardReport, generateDuplicatesReportMarkdown, generateGovernanceReportMarkdown, generateLicenseReportMarkdown, generatePdacReportMarkdown, generatePrivacyReportMarkdown, generateQualityReport, generateRopaInventoryMarkdown, generateSastReportMarkdown, generateSecretsReportMarkdown, generateSecuritySarifReport, generateSuppressionsAuditReport, generateTestingCoverageReportMarkdown, generateThirdPartyNotices, generateTraceabilityReportMarkdown, getArchitectureTemplates, getCytoscapeScript, getGitDiffLines, getNextCorrelativeNumber, getSddAdapter, inferArtifactTypeFromId, inferMissingTrailers, initProject, injectKpisIntoPrBody, installGitHooks, integrateSddChange, isGitleaksInstalled, isMetricWorsened, isPathProtectedFromPatch, isPlaceholderOrIgnored, isRequirementArtifact2 as isRequirementArtifact, isSemgrepInstalled, isToolAvailable, loadDlpPolicy, loadPrivacyPolicy, loadProductHandoffSidecar, loadQualityBaseline, locateTaskInActiveChanges, mapSastSeverityToSarifLevel, maskSecret, normalizeSpdxLicense, normalizeUri, parseCommitTrailers, parseDlpPolicy, parseFeatureDocument, parseFrontmatter, parseFrontmatterId, parseGenericDoc, parseLicensePolicy, parseMarkdownFrontmatter, parseQualityPolicy, parseRequirementFile, parseSecuritySuppression, parseSpecCatalogScope, parseTasksDoc, parseTasksFromContent, parseTrivyVulnerabilities, processPackageDir, readCodeCoverageSummary, readPackageJson, renderAntigravityAgentFile, renderAntigravitySkillFile, renderAutonomyModeSection, renderClaudeAgentFile, renderClaudeSkillFile, renderCopilotAgentFile, renderCopilotSkillFile, renderCursorAgentFile, renderCursorSkillFile, renderDashboardHtml, renderManualsTab, resolveAgentTargets, resolveBranchHierarchy, resolveCiEnvironment, resolveCytoscapePath, resolveDefaultBranchBase, resolveFeatureFilePath, resolveGitRef, resolveLicenseFromFile, resolveReleaseBaseBranch, resolveSastCwe, resolveSastOwasp, resolveSchemaForArtifact, resolveTargetFiles, runGitleaksCli, runSemgrepCli, sanitizeDlpPayload, sanitizeDlpText, scaffoldSddChange, scanAllProductHandoffs, scanAllTestArtifacts, scanContentForSecrets, scanFileForPrivacyViolations, scanFileForSast, scanGoDependencies, scanInstalledLicenses, scanManualsInWorkspace, scanMavenDependencies, scanPnpmStore, scanPythonDependencies, scanRustDependencies, scanSubdirectories, scanWithNativeFs, scanWithSyft, scanWithTrivy, serializeSarifDocument, slugify, syncPdacDigests, tokenizeTitle, updateCitationsInContent, validateAgainstSchema, validateArtifactSchema, verifyArtifactDuplicates, verifyArtifactsSchemas, verifyLicenses, verifyManuals, verifyPdacGraph, verifyPrivacy, verifyProgressiveFriction, verifyQualityGate, verifySast, verifySddIntegration, verifySecrets, verifyTasksGovernance, verifyTestingCoverage, verifyTraceability, walkDir, walkMdFiles, walkProjectFiles, walkSourceFiles, walkTaskFiles, writeCucumberJsonReport, writeCycloneDxSbom, writeQualityBaseline, writeReleaseKpiReport, writeSecuritySarifReport, writeThirdPartyNotices };
15911
16734
  //# sourceMappingURL=index.js.map
15912
16735
  //# sourceMappingURL=index.js.map