@agent-surface/cli 0.11.1 → 0.12.1

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.
@@ -4,24 +4,40 @@ import {
4
4
  } from "./chunk-QIVOZAWX.js";
5
5
 
6
6
  // src/baseline.ts
7
- import { mkdirSync, readFileSync, writeFileSync } from "fs";
8
- import { dirname, join, resolve } from "path";
7
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
8
+ import { dirname, join, resolve, sep } from "path";
9
9
  import { serializeSurfaceSnapshot } from "@agent-surface/testing";
10
10
  var DEFAULT_BASELINE_DIR = ".agent-surface";
11
+ var SCENARIO_MANIFEST_FILE = "scenarios.json";
11
12
  function baselineDirFor(configPath, configured) {
12
13
  return resolve(dirname(configPath), configured ?? DEFAULT_BASELINE_DIR);
13
14
  }
14
15
  function baselinePath(dir, scenario) {
15
- return join(dir, `${scenario}.json`);
16
+ const reserved = /* @__PURE__ */ new Set(["scenarios", "coverage-allow", "unresolved-allow"]);
17
+ if (scenario.length === 0 || scenario === "." || scenario === ".." || scenario.includes("/") || scenario.includes("\\") || scenario.includes("\0") || reserved.has(scenario)) {
18
+ throw new Error(`invalid scenario name ${JSON.stringify(scenario)} \u2014 use a filename-safe name`);
19
+ }
20
+ const root = resolve(dir);
21
+ const path = resolve(root, `${scenario}.json`);
22
+ if (!path.startsWith(`${root}${sep}`)) {
23
+ throw new Error(`scenario ${JSON.stringify(scenario)} escapes the baseline directory`);
24
+ }
25
+ return path;
26
+ }
27
+ function scenarioManifestPath(dir) {
28
+ return join(dir, SCENARIO_MANIFEST_FILE);
16
29
  }
17
30
  function normalize(snapshot) {
18
31
  return serializeSurfaceSnapshot(snapshot);
19
32
  }
20
33
  function readBaseline(path) {
34
+ if (!existsSync(path)) return void 0;
21
35
  try {
22
36
  return JSON.parse(readFileSync(path, "utf8"));
23
- } catch {
24
- return void 0;
37
+ } catch (error) {
38
+ throw new Error(
39
+ `could not read baseline ${path}: ${error instanceof Error ? error.message : String(error)}`
40
+ );
25
41
  }
26
42
  }
27
43
  function writeBaseline(path, value) {
@@ -29,6 +45,18 @@ function writeBaseline(path, value) {
29
45
  writeFileSync(path, `${JSON.stringify(value, null, 2)}
30
46
  `, "utf8");
31
47
  }
48
+ function readScenarioManifest(dir) {
49
+ const path = scenarioManifestPath(dir);
50
+ const value = readBaseline(path);
51
+ if (value === void 0) return void 0;
52
+ if (typeof value !== "object" || value === null || !Array.isArray(value.scenarios) || !value.scenarios.every((name) => typeof name === "string")) {
53
+ throw new Error(`${path} must contain { "scenarios": string[] }`);
54
+ }
55
+ return [...value.scenarios].sort();
56
+ }
57
+ function writeScenarioManifest(dir, scenarios) {
58
+ writeBaseline(scenarioManifestPath(dir), { scenarios: [...scenarios].sort() });
59
+ }
32
60
  var PATH_SEGMENT = /([^.[\]]+)|\[(\d+)\]/g;
33
61
  function subjectFor(document, path) {
34
62
  let node = document;
@@ -97,7 +125,7 @@ function formatValue(value) {
97
125
  }
98
126
 
99
127
  // src/coverage.ts
100
- import { existsSync, readFileSync as readFileSync2 } from "fs";
128
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
101
129
  import { join as join2 } from "path";
102
130
  var ALLOWLIST_FILE = "coverage-allow.json";
103
131
  var UNREAD_ALLOWLIST_FILE = "unresolved-allow.json";
@@ -108,7 +136,7 @@ function unreadAllowlistPathFor(baselineDir) {
108
136
  return join2(baselineDir, UNREAD_ALLOWLIST_FILE);
109
137
  }
110
138
  function readAllowlist(path, keyName = "capabilityId") {
111
- if (!existsSync(path)) return {};
139
+ if (!existsSync2(path)) return {};
112
140
  let parsed;
113
141
  try {
114
142
  parsed = JSON.parse(readFileSync2(path, "utf8"));
@@ -130,7 +158,7 @@ function readAllowlist(path, keyName = "capabilityId") {
130
158
  return allowlist;
131
159
  }
132
160
  function unreadKey(entry) {
133
- return `${entry.origin.file}#${entry.reason ?? "unknown"}`;
161
+ return `${entry.origin.file}#${entry.reason ?? "unknown"}#${entry.origin.site}`;
134
162
  }
135
163
  function buildCoverageReport(input) {
136
164
  const unreached = [];
@@ -155,7 +183,8 @@ function buildCoverageReport(input) {
155
183
  const stillUnread = new Set(input.unresolved.map(unreadKey));
156
184
  const staleUnreadAllowlist = Object.keys(unreadAllowlist).filter((key) => !stillUnread.has(key)).sort();
157
185
  const unaccounted = [...input.reachedIds].filter((id) => !input.authored.has(id)).sort();
158
- const domainReached = unaccounted.filter((id) => id.startsWith("domain:"));
186
+ const domainReached = [...input.reachedIds].filter((id) => id.startsWith("domain:")).sort();
187
+ const unmanifestedDomain = input.domainAuthoritative ? unaccounted.filter((id) => id.startsWith("domain:")) : [];
159
188
  const undeclared = unaccounted.filter((id) => !id.startsWith("domain:"));
160
189
  return {
161
190
  authored: input.authored.size,
@@ -166,6 +195,8 @@ function buildCoverageReport(input) {
166
195
  unreached,
167
196
  undeclared,
168
197
  domainReached,
198
+ unmanifestedDomain,
199
+ domainAuthoritative: input.domainAuthoritative === true,
169
200
  unresolved: unread,
170
201
  allowed,
171
202
  staleAllowlist,
@@ -177,6 +208,7 @@ function buildCoverageReport(input) {
177
208
  }
178
209
  function coverageExitCode(report, options = {}) {
179
210
  if (report.unreached.length > 0) return 1;
211
+ if (report.unmanifestedDomain.length > 0) return 1;
180
212
  if (report.unresolved.length > 0 && !options.allowUnresolved) return 1;
181
213
  if (report.staleAllowlist.length > 0) return 1;
182
214
  if (report.staleUnreadAllowlist.length > 0) return 1;
@@ -184,13 +216,34 @@ function coverageExitCode(report, options = {}) {
184
216
  }
185
217
 
186
218
  // src/extract.ts
187
- import { existsSync as existsSync2 } from "fs";
219
+ import { createHash } from "crypto";
220
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
188
221
  import { dirname as dirname2, isAbsolute, join as join3, relative, resolve as resolve2 } from "path";
189
222
  import ts from "typescript";
190
223
  var UNRESOLVED_ID = "<unresolved>";
191
224
  function findTsconfig(from) {
192
225
  return ts.findConfigFile(resolve2(from), ts.sys.fileExists, "tsconfig.json");
193
226
  }
227
+ function readLiteralConfigScope(configPath) {
228
+ const source = ts.createSourceFile(
229
+ configPath,
230
+ readFileSync3(configPath, "utf8"),
231
+ ts.ScriptTarget.Latest,
232
+ true,
233
+ configPath.endsWith("x") ? ts.ScriptKind.TSX : ts.ScriptKind.TS
234
+ );
235
+ let scope;
236
+ const visit = (node) => {
237
+ if (scope) return;
238
+ if (ts.isPropertyAssignment(node) && propertyName(node.name) === "scope" && ts.isArrayLiteralExpression(node.initializer)) {
239
+ const values = node.initializer.elements.map((entry) => literalText(entry));
240
+ if (values.every((value) => value !== void 0)) scope = values;
241
+ }
242
+ ts.forEachChild(node, visit);
243
+ };
244
+ visit(source);
245
+ return scope;
246
+ }
194
247
  function readProgramFiles(tsconfigPath) {
195
248
  const read = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
196
249
  if (read.error) {
@@ -210,9 +263,65 @@ function readProgramFiles(tsconfigPath) {
210
263
  }
211
264
  return { fileNames: parsed.fileNames, options: parsed.options };
212
265
  }
213
- function calleeName(call) {
214
- if (ts.isIdentifier(call.expression)) return call.expression.text;
215
- if (ts.isPropertyAccessExpression(call.expression)) return call.expression.name.text;
266
+ var REGISTRATION_HOOKS = /* @__PURE__ */ new Set(["useAgentComponent", "useAgentAction", "useAgentObservation"]);
267
+ function isRegistrationModule(specifier) {
268
+ return specifier.startsWith("@agent-surface/");
269
+ }
270
+ var NO_IMPORTS = { locals: /* @__PURE__ */ new Map(), namespaces: /* @__PURE__ */ new Set() };
271
+ function importedRegistrations(source) {
272
+ const locals = /* @__PURE__ */ new Map();
273
+ const namespaces = /* @__PURE__ */ new Set();
274
+ for (const statement of source.statements) {
275
+ if (!ts.isImportDeclaration(statement)) continue;
276
+ if (!ts.isStringLiteral(statement.moduleSpecifier)) continue;
277
+ if (!isRegistrationModule(statement.moduleSpecifier.text)) continue;
278
+ const clause = statement.importClause;
279
+ if (!clause || clause.isTypeOnly || !clause.namedBindings) continue;
280
+ if (ts.isNamespaceImport(clause.namedBindings)) {
281
+ namespaces.add(clause.namedBindings.name.text);
282
+ continue;
283
+ }
284
+ for (const element of clause.namedBindings.elements) {
285
+ if (element.isTypeOnly) continue;
286
+ const imported = (element.propertyName ?? element.name).text;
287
+ if (REGISTRATION_HOOKS.has(imported)) locals.set(element.name.text, imported);
288
+ }
289
+ }
290
+ return { locals, namespaces };
291
+ }
292
+ function renamedRegistrationExports(source, imports) {
293
+ const renamed = [];
294
+ for (const statement of source.statements) {
295
+ if (!ts.isExportDeclaration(statement) || statement.isTypeOnly) continue;
296
+ const clause = statement.exportClause;
297
+ if (!clause || !ts.isNamedExports(clause)) continue;
298
+ const from = statement.moduleSpecifier;
299
+ const fromOurs = from !== void 0 && ts.isStringLiteral(from) && isRegistrationModule(from.text);
300
+ if (from && !fromOurs) continue;
301
+ for (const element of clause.elements) {
302
+ if (element.isTypeOnly) continue;
303
+ const local = (element.propertyName ?? element.name).text;
304
+ const hook = fromOurs ? REGISTRATION_HOOKS.has(local) ? local : void 0 : imports.locals.get(local);
305
+ if (hook === void 0 || element.name.text === hook) continue;
306
+ renamed.push({ node: element, hook, exported: element.name.text });
307
+ }
308
+ }
309
+ return renamed;
310
+ }
311
+ function namespaceMember(object, member, imports) {
312
+ return ts.isIdentifier(object) && imports.namespaces.has(object.text) && REGISTRATION_HOOKS.has(member);
313
+ }
314
+ function calleeName(call, imports = NO_IMPORTS) {
315
+ const callee = call.expression;
316
+ if (ts.isIdentifier(callee)) return imports.locals.get(callee.text) ?? callee.text;
317
+ if (ts.isPropertyAccessExpression(callee)) {
318
+ if (namespaceMember(callee.expression, callee.name.text, imports)) return callee.name.text;
319
+ return callee.name.text;
320
+ }
321
+ if (ts.isElementAccessExpression(callee)) {
322
+ const member = literalText(callee.argumentExpression);
323
+ if (member !== void 0 && namespaceMember(callee.expression, member, imports)) return member;
324
+ }
216
325
  return void 0;
217
326
  }
218
327
  function propertyName(name) {
@@ -375,9 +484,22 @@ function capabilitiesFromGroup(group, kind, componentType, componentPartial, emi
375
484
  emit.push(capability);
376
485
  }
377
486
  }
378
- function visitCall(call, emit, source, deferred, enclosing) {
379
- const callee = calleeName(call);
380
- if (callee === void 0) return;
487
+ function visitCall(call, emit, source, imports, deferred, enclosing) {
488
+ const callee = calleeName(call, imports);
489
+ if (callee === void 0) {
490
+ const object = ts.isElementAccessExpression(call.expression) ? call.expression.expression : void 0;
491
+ if (object && ts.isIdentifier(object) && imports.namespaces.has(object.text)) {
492
+ emit.push({
493
+ capabilityId: UNRESOLVED_ID,
494
+ kind: "action",
495
+ origin: emit.origin(call),
496
+ resolution: "unresolved",
497
+ reason: "dynamic-callee",
498
+ note: `a call reads a computed member of \`${object.text}\`, a namespace of this library \u2014 which export it calls, and so whether it registers anything, cannot be read here`
499
+ });
500
+ }
501
+ return;
502
+ }
381
503
  if (GRANULAR_HOOKS.has(callee)) {
382
504
  emit.push({
383
505
  capabilityId: UNRESOLVED_ID,
@@ -502,10 +624,84 @@ function callsWrapper(site, wrapper, compilerOptions) {
502
624
  }
503
625
  return false;
504
626
  }
627
+ function normalizedText(node, source) {
628
+ return node.getText(source).replace(/\s+/g, " ").trim();
629
+ }
630
+ function siteIdentity(source, node) {
631
+ const labels = [];
632
+ let enclosingCall = "";
633
+ let scope;
634
+ for (let parent = node.parent; parent && parent !== source; parent = parent.parent) {
635
+ if (!enclosingCall && ts.isCallExpression(parent)) {
636
+ enclosingCall = normalizedText(parent, source);
637
+ }
638
+ const named = (ts.isFunctionDeclaration(parent) || ts.isMethodDeclaration(parent)) && parent.name && (ts.isIdentifier(parent.name) || ts.isStringLiteral(parent.name)) ? parent.name.text : ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name) ? parent.name.text : void 0;
639
+ if (named !== void 0) {
640
+ labels.push(named);
641
+ scope ??= parent;
642
+ }
643
+ }
644
+ return { labels: labels.reverse(), enclosingCall, scope: scope ?? source };
645
+ }
646
+ function occurrence(scope, node, source) {
647
+ const text = normalizedText(node, source);
648
+ const start = node.getStart(source);
649
+ let rank = 0;
650
+ const visit = (candidate) => {
651
+ if (candidate.kind === node.kind && candidate.getStart(source) < start && normalizedText(candidate, source) === text) {
652
+ rank += 1;
653
+ }
654
+ ts.forEachChild(candidate, visit);
655
+ };
656
+ ts.forEachChild(scope, visit);
657
+ return rank;
658
+ }
659
+ function stableSite(source, node) {
660
+ const { labels, enclosingCall, scope } = siteIdentity(source, node);
661
+ return createHash("sha256").update(
662
+ `${labels.join("/")}\0${enclosingCall}\0${normalizedText(node, source)}\0${occurrence(
663
+ scope,
664
+ node,
665
+ source
666
+ )}`
667
+ ).digest("hex").slice(0, 12);
668
+ }
669
+ var packageNameCache = /* @__PURE__ */ new Map();
670
+ function packageNameFor(file) {
671
+ let dir = dirname2(file);
672
+ for (; ; ) {
673
+ if (packageNameCache.has(dir)) return packageNameCache.get(dir);
674
+ const packagePath = join3(dir, "package.json");
675
+ if (existsSync3(packagePath)) {
676
+ let name;
677
+ try {
678
+ const parsed = JSON.parse(readFileSync3(packagePath, "utf8"));
679
+ if (typeof parsed.name === "string") name = parsed.name;
680
+ } catch {
681
+ }
682
+ packageNameCache.set(dir, name);
683
+ return name;
684
+ }
685
+ const parent = dirname2(dir);
686
+ if (parent === dir) return void 0;
687
+ dir = parent;
688
+ }
689
+ }
690
+ var IMPLEMENTATION_PACKAGES = /* @__PURE__ */ new Set([
691
+ "@agent-surface/core",
692
+ "@agent-surface/react",
693
+ "@agent-surface/orpc",
694
+ "@agent-surface/testing",
695
+ "@agent-surface/webmcp",
696
+ "@agent-surface/cli"
697
+ ]);
698
+ function isAgentSurfaceImplementation(file) {
699
+ return IMPLEMENTATION_PACKAGES.has(packageNameFor(file) ?? "");
700
+ }
505
701
  function extractCapabilities(options) {
506
702
  const root = resolve2(options.root);
507
703
  const tsconfigPath = options.tsconfig ? isAbsolute(options.tsconfig) ? options.tsconfig : join3(root, options.tsconfig) : findTsconfig(root);
508
- if (!tsconfigPath || !existsSync2(tsconfigPath)) {
704
+ if (!tsconfigPath || !existsSync3(tsconfigPath)) {
509
705
  throw new Error(
510
706
  `no tsconfig.json found from ${root} \u2014 \`capabilities\` reads the TypeScript program, so it needs one (pass --tsconfig to point at it)`
511
707
  );
@@ -520,7 +716,7 @@ function extractCapabilities(options) {
520
716
  for (const source of program.getSourceFiles()) {
521
717
  if (source.isDeclarationFile) continue;
522
718
  if (source.fileName.includes("/node_modules/")) continue;
523
- if (!isInside(root, source.fileName)) {
719
+ if (!isInside(root, source.fileName) && isAgentSurfaceImplementation(source.fileName)) {
524
720
  filesOutsideRoot += 1;
525
721
  continue;
526
722
  }
@@ -529,9 +725,21 @@ function extractCapabilities(options) {
529
725
  push: (capability) => capabilities.push(capability),
530
726
  origin: (node) => ({
531
727
  file: relative(root, source.fileName),
532
- line: source.getLineAndCharacterOfPosition(node.getStart(source)).line + 1
728
+ line: source.getLineAndCharacterOfPosition(node.getStart(source)).line + 1,
729
+ site: stableSite(source, node)
533
730
  })
534
731
  };
732
+ const imports = importedRegistrations(source);
733
+ for (const renamed of renamedRegistrationExports(source, imports)) {
734
+ emit.push({
735
+ capabilityId: UNRESOLVED_ID,
736
+ kind: "action",
737
+ origin: emit.origin(renamed.node),
738
+ resolution: "unresolved",
739
+ reason: "dynamic-callee",
740
+ note: `${renamed.hook}() leaves this module as \`${renamed.exported}\`, so nothing at its call sites elsewhere proves they register anything \u2014 whatever they author is not in this catalog`
741
+ });
742
+ }
535
743
  let pendingName;
536
744
  const visit = (node, enclosing) => {
537
745
  const fn = functionLike(node);
@@ -543,7 +751,7 @@ function extractCapabilities(options) {
543
751
  pendingName = node.name.text;
544
752
  }
545
753
  if (ts.isCallExpression(node)) {
546
- visitCall(node, emit, source, deferred, enclosing);
754
+ visitCall(node, emit, source, imports, deferred, enclosing);
547
755
  if (ts.isIdentifier(node.expression)) {
548
756
  const name = node.expression.text;
549
757
  const sites = callsByName.get(name) ?? [];
@@ -634,6 +842,9 @@ function readInventory(options) {
634
842
  ...options.tsconfig ? { tsconfig: options.tsconfig } : {}
635
843
  });
636
844
  }
845
+ function staticConfigScope(options) {
846
+ return options.scope ?? readLiteralConfigScope(options.configPath);
847
+ }
637
848
  async function mountScenarios(options, onEach) {
638
849
  if (options.depth === "static") return void 0;
639
850
  const runner = await createSurfaceRunner(options.configPath);
@@ -644,6 +855,7 @@ async function mountScenarios(options, onEach) {
644
855
  );
645
856
  }
646
857
  const scenarios = options.scenario ? [options.scenario] : runner.scenarioNames;
858
+ const effectiveScope = options.scope ?? runner.config.scope;
647
859
  const results = [];
648
860
  const failures = [];
649
861
  for (const scenario of scenarios) {
@@ -665,12 +877,16 @@ async function mountScenarios(options, onEach) {
665
877
  }
666
878
  return {
667
879
  scenarios,
880
+ declaredScenarios: runner.scenarioNames,
668
881
  results,
669
882
  failures,
670
883
  baselineDir: baselineDirFor(
671
884
  options.configPath,
672
885
  options.baselineDir ?? runner.config.baselineDir
673
- )
886
+ ),
887
+ ...effectiveScope ? { scope: effectiveScope } : {},
888
+ domainCapabilities: Object.keys(runner.config.manifest?.tools ?? {}).map((path) => `domain:${path}`).sort(),
889
+ domainManifestConfigured: runner.config.manifest !== void 0
674
890
  };
675
891
  } finally {
676
892
  await runner.close();
@@ -681,10 +897,23 @@ function componentTypeOf(capabilityId) {
681
897
  const dot = withoutPlane.lastIndexOf(".");
682
898
  return dot === -1 ? withoutPlane : withoutPlane.slice(0, dot);
683
899
  }
900
+ function scopeInventory(inventory, scope) {
901
+ if (!inventory || !scope) return inventory;
902
+ return {
903
+ ...inventory,
904
+ capabilities: inventory.capabilities.filter(
905
+ (capability) => capability.resolution === "unresolved" || matchesScope(componentTypeOf(capability.capabilityId), scope)
906
+ )
907
+ };
908
+ }
909
+ function scopeCapabilityIds(ids, scope) {
910
+ return scope ? ids.filter((id) => matchesScope(componentTypeOf(id), scope)) : ids;
911
+ }
684
912
  function joinCoverage(inventory, runtime, options) {
685
913
  if (!inventory || !runtime) return void 0;
686
914
  if (runtime.failures.length > 0) return void 0;
687
- const inScope = (capabilityId) => matchesScope(componentTypeOf(capabilityId), options.scope);
915
+ const effectiveScope = options.scope ?? runtime.scope;
916
+ const inScope = (capabilityId) => matchesScope(componentTypeOf(capabilityId), effectiveScope);
688
917
  const origins = /* @__PURE__ */ new Map();
689
918
  for (const capability of inventory.capabilities) {
690
919
  if (!origins.has(capability.capabilityId)) {
@@ -692,6 +921,12 @@ function joinCoverage(inventory, runtime, options) {
692
921
  }
693
922
  }
694
923
  const authored = new Set([...authoredIds(inventory)].filter(inScope));
924
+ for (const capabilityId of runtime.domainCapabilities) {
925
+ if (inScope(capabilityId)) authored.add(capabilityId);
926
+ if (!origins.has(capabilityId)) {
927
+ origins.set(capabilityId, { file: "oRPC manifest", line: 0 });
928
+ }
929
+ }
695
930
  const reachedIds = /* @__PURE__ */ new Set();
696
931
  for (const result of runtime.results) {
697
932
  for (const capability of result.explanation.capabilities) {
@@ -705,13 +940,14 @@ function joinCoverage(inventory, runtime, options) {
705
940
  );
706
941
  const unreadAllowlistPath = unreadAllowlistPathFor(runtime.baselineDir);
707
942
  return buildCoverageReport({
708
- unreadAllowlist: readAllowlist(unreadAllowlistPath, "file#reason"),
943
+ unreadAllowlist: readAllowlist(unreadAllowlistPath, "file#reason#site"),
709
944
  unreadAllowlistPath,
945
+ domainAuthoritative: runtime.domainManifestConfigured,
710
946
  authored,
711
947
  origins,
712
948
  reachedIds,
713
949
  scenarios: runtime.scenarios,
714
- ...options.scope ? { scope: options.scope } : {},
950
+ ...effectiveScope ? { scope: effectiveScope } : {},
715
951
  unresolved: unresolved(inventory),
716
952
  allowlist,
717
953
  allowlistOutOfScope: Object.keys(wholeAllowlist).length - Object.keys(allowlist).length,
@@ -720,13 +956,18 @@ function joinCoverage(inventory, runtime, options) {
720
956
  }
721
957
 
722
958
  export {
959
+ SCENARIO_MANIFEST_FILE,
723
960
  baselinePath,
724
961
  normalize,
725
962
  readBaseline,
726
963
  writeBaseline,
964
+ readScenarioManifest,
965
+ writeScenarioManifest,
727
966
  annotate,
728
967
  diff,
729
968
  formatValue,
969
+ ALLOWLIST_FILE,
970
+ UNREAD_ALLOWLIST_FILE,
730
971
  unreadKey,
731
972
  coverageExitCode,
732
973
  findTsconfig,
@@ -734,7 +975,10 @@ export {
734
975
  authoredIds,
735
976
  unresolved,
736
977
  readInventory,
978
+ staticConfigScope,
737
979
  mountScenarios,
980
+ scopeInventory,
981
+ scopeCapabilityIds,
738
982
  joinCoverage
739
983
  };
740
- //# sourceMappingURL=chunk-2FG527AM.js.map
984
+ //# sourceMappingURL=chunk-Q5WOLWEW.js.map