@moda-ai/cli 1.55.73 → 1.55.75

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.
@@ -109,10 +109,10 @@ import {
109
109
  } from "./cli-0v6na3yp.js";
110
110
 
111
111
  // src/harness-extract/enumerators/agents.ts
112
- var import_typescript12 = __toESM(require_typescript(), 1);
112
+ var import_typescript14 = __toESM(require_typescript(), 1);
113
113
 
114
114
  // src/harness-extract/index.ts
115
- var import_typescript10 = __toESM(require_typescript(), 1);
115
+ var import_typescript13 = __toESM(require_typescript(), 1);
116
116
  import { resolve as resolve13 } from "node:path";
117
117
 
118
118
  // src/harness-extract/ast.ts
@@ -1307,8 +1307,11 @@ function selectKey(tree, key, missing) {
1307
1307
  if (member.key === "...") {
1308
1308
  const fromSpread = selectKey(member, key, missing);
1309
1309
  if (fromSpread !== missing) {
1310
- if (fromSpread.resolution === "unresolved") {
1310
+ const mayLack = hasWhere(fromSpread, (node) => node === missing);
1311
+ if (mayLack || fromSpread.resolution === "unresolved") {
1311
1312
  const prior = selectKey({ ...tree, children: members.slice(0, index) }, key, missing);
1313
+ if (prior !== missing && mayLack)
1314
+ return substituteWhere(fromSpread, (node) => node === missing, prior);
1312
1315
  if (prior !== missing)
1313
1316
  return { ...fromSpread, kind: "oneOf", children: [prior, fromSpread], resolution: "partial", note: "unknown spread may override property" };
1314
1317
  }
@@ -1354,16 +1357,14 @@ function leaves(tree) {
1354
1357
  return flow.length > 0 && tree.kind !== "template" ? flow.flatMap(leaves) : [tree];
1355
1358
  }
1356
1359
  function hasWhere(tree, match) {
1357
- return match(tree) || valueChildren(tree).some((child) => hasWhere(child, match));
1360
+ return match(tree) || FLOW_KINDS.has(tree.kind) && valueChildren(tree).some((child) => hasWhere(child, match));
1358
1361
  }
1359
1362
  function substituteWhere(tree, match, replacement) {
1360
1363
  if (match(tree))
1361
1364
  return tree.key !== undefined ? { ...replacement, key: tree.key } : replacement;
1362
1365
  if (!hasWhere(tree, match))
1363
1366
  return tree;
1364
- if (FLOW_KINDS.has(tree.kind))
1365
- return mapFlow(tree, (child) => substituteWhere(child, match, replacement));
1366
- return { ...tree, children: (tree.children ?? []).map((child) => substituteWhere(child, match, replacement)) };
1367
+ return mapFlow(tree, (child) => substituteWhere(child, match, replacement));
1367
1368
  }
1368
1369
  function allValues(tree) {
1369
1370
  if (tree.kind === "object" || tree.kind === "array" || tree.kind === "assembled" && tree.text === "array") {
@@ -1610,7 +1611,7 @@ class CallIndex {
1610
1611
  this.byName ??= this.build();
1611
1612
  const out = this.direct(name, limit, (declaration) => declares(declaration, fn));
1612
1613
  if (isDefaultExport(fn) && name !== "default" && out.length < limit)
1613
- out.push(...this.direct("default", limit - out.length, (declaration) => declares(declaration, fn)));
1614
+ out.push(...this.direct("default", limit - out.length, (declaration) => declares(declaration, fn), new Set(out)));
1614
1615
  for (const alias of this.aliases.get(name) ?? []) {
1615
1616
  if (out.length >= limit)
1616
1617
  break;
@@ -1711,11 +1712,13 @@ class CallIndex {
1711
1712
  this.checkingDefaults.delete(declaration);
1712
1713
  }
1713
1714
  }
1714
- direct(name, limit, matches) {
1715
+ direct(name, limit, matches, found) {
1715
1716
  const candidates = this.byName.get(name) ?? [];
1716
1717
  const out = [];
1717
1718
  let checked = 0;
1718
1719
  for (const call of candidates) {
1720
+ if (found?.has(call))
1721
+ continue;
1719
1722
  if (out.length >= limit || checked >= limit * 20)
1720
1723
  break;
1721
1724
  checked += 1;
@@ -17641,6 +17644,103 @@ function hasDirective(text) {
17641
17644
  const plain = text.replace(/\{\{[^}]*\}\}/g, " ").trim();
17642
17645
  return DIRECTIVE_ANYWHERE.test(plain) || DIRECTIVE_VERB.test(plain);
17643
17646
  }
17647
+ var ERROR_TEXT = /^\s*(?:error\b|failed\b|could not\b|couldn't\b|cannot\b|can't\b|unable to\b|invalid\b|unknown\b|missing\b|not found\b)/i;
17648
+ function toolResultIsPrompt(owner, pieces) {
17649
+ if (!owner)
17650
+ return false;
17651
+ if (import_typescript8.default.isShorthandPropertyAssignment(owner) || import_typescript8.default.isPropertyAssignment(owner) && !isNamedTableEntry(owner))
17652
+ return false;
17653
+ const own = pieces.map((piece) => piece.trim()).filter(Boolean);
17654
+ if (own.length === 0)
17655
+ return false;
17656
+ const text = withoutLabels(own.join(`
17657
+ `));
17658
+ if (own.every((piece) => ERROR_TEXT.test(piece)) && !IMPERATIVE.test(text))
17659
+ return false;
17660
+ if (!hasDirective(text) && !IMPERATIVE.test(text))
17661
+ return false;
17662
+ const fn = import_typescript8.default.isFunctionLike(owner) ? owner : import_typescript8.default.isVariableDeclaration(owner) && owner.initializer && import_typescript8.default.isFunctionLike(unwrapNode(owner.initializer)) ? unwrapNode(owner.initializer) : undefined;
17663
+ return !fn || isTextBuilder(fn);
17664
+ }
17665
+ function isNamedTableEntry(property) {
17666
+ const object = property.parent;
17667
+ if (object.properties.some((entry) => entry.name && import_typescript8.default.isIdentifier(entry.name) && entry.name.text === "type"))
17668
+ return false;
17669
+ let node = object;
17670
+ while (import_typescript8.default.isObjectLiteralExpression(node) || import_typescript8.default.isPropertyAssignment(node) || import_typescript8.default.isParenthesizedExpression(node) || import_typescript8.default.isAsExpression(node) || import_typescript8.default.isSatisfiesExpression(node) || import_typescript8.default.isTypeAssertionExpression(node)) {
17671
+ node = node.parent;
17672
+ }
17673
+ return import_typescript8.default.isVariableDeclaration(node) || import_typescript8.default.isPropertyDeclaration(node) || import_typescript8.default.isExportAssignment(node);
17674
+ }
17675
+ function withoutLabels(text) {
17676
+ return text.replace(/\{\{[^}]*\}\}/g, " ").replace(/(^|[.!?\n]\s*)[A-Za-z][\w -]{0,24}:(?=\s)/g, "$1");
17677
+ }
17678
+ var IMPERATIVE_VERBS = "keep|write|reply|respond|return|answer|use|include|output|list|describe|summari[sz]e|explain|decide|pick|choose|rate|score|label|extract|generate|draft|revise|rewrite|translate|tell|ask|call|check|verify|follow|format|limit|stop|continue|focus|consider|act|identify|compare|judge|review|repair|fix|plan|propose|suggest|recommend|find|search|read|treat|cite|flag|mark|rank|group|merge|drop|skip|wait|confirm|send|offer|share|re-share|lean|vary|retry|resend|retell|replace|unschedule|reschedule|reconnect|connect|attach|pass|move|open|try|run|re-run|rerun|load|save|update|delete|remove|add|create|edit|post|publish|schedule|mention|note|let|give|show|present|announce|surface|ping|text|message|forward|route|hand|escalate|report|log";
17679
+ var IMPERATIVE = new RegExp(`(?:^|[.!?:;\\n]\\s*|\\bif\\b[^.!?\\n]{0,160},\\s*)(?:then\\s+)?(?:${IMPERATIVE_VERBS})\\b`, "i");
17680
+ function unwrapNode(node) {
17681
+ let current = node;
17682
+ while (import_typescript8.default.isParenthesizedExpression(current) || import_typescript8.default.isAsExpression(current) || import_typescript8.default.isSatisfiesExpression(current))
17683
+ current = current.expression;
17684
+ return current;
17685
+ }
17686
+ function isTextBuilder(fn) {
17687
+ const modifiers = import_typescript8.default.canHaveModifiers(fn) ? import_typescript8.default.getModifiers(fn) ?? [] : [];
17688
+ if (modifiers.some((modifier) => modifier.kind === import_typescript8.default.SyntaxKind.AsyncKeyword))
17689
+ return false;
17690
+ const declared = fn.type?.getText().replace(/\s+/g, "");
17691
+ if (declared && !/^(?:Promise<)?(?:(?:readonly)?string(?:\[\])?|null|undefined)(?:\|(?:(?:readonly)?string(?:\[\])?|null|undefined))*>?$/.test(declared))
17692
+ return false;
17693
+ let builder = true;
17694
+ let returns = 0;
17695
+ let failures = 0;
17696
+ const visit = (node) => {
17697
+ if (!builder)
17698
+ return;
17699
+ if (node !== fn && import_typescript8.default.isFunctionLike(node))
17700
+ return;
17701
+ if (import_typescript8.default.isAwaitExpression(node))
17702
+ builder = false;
17703
+ else if (import_typescript8.default.isReturnStatement(node) && node.expression) {
17704
+ if (returnsRecord(node.expression))
17705
+ builder = false;
17706
+ returns += 1;
17707
+ if (ERROR_TEXT.test(leadingText(node.expression)))
17708
+ failures += 1;
17709
+ import_typescript8.default.forEachChild(node, visit);
17710
+ } else
17711
+ import_typescript8.default.forEachChild(node, visit);
17712
+ };
17713
+ const body = fn.body;
17714
+ if (body && !import_typescript8.default.isBlock(body))
17715
+ return !returnsRecord(body);
17716
+ if (body)
17717
+ import_typescript8.default.forEachChild(body, visit);
17718
+ return builder && !(returns > 1 && failures > 0 && takesContext(fn));
17719
+ }
17720
+ function takesContext(fn) {
17721
+ return fn.parameters.some((parameter) => {
17722
+ const name = import_typescript8.default.isIdentifier(parameter.name) ? parameter.name.text : "";
17723
+ return /^(?:ctx|context|env|sql|db|tx)$/.test(name) || /(?:Context|Env)\b/.test(parameter.type?.getText() ?? "");
17724
+ });
17725
+ }
17726
+ function leadingText(expr) {
17727
+ const value = unwrapNode(expr);
17728
+ if (import_typescript8.default.isStringLiteral(value) || import_typescript8.default.isNoSubstitutionTemplateLiteral(value))
17729
+ return value.text;
17730
+ if (import_typescript8.default.isTemplateExpression(value))
17731
+ return value.head.text;
17732
+ if (import_typescript8.default.isBinaryExpression(value) && value.operatorToken.kind === import_typescript8.default.SyntaxKind.PlusToken)
17733
+ return leadingText(value.left);
17734
+ return "";
17735
+ }
17736
+ function returnsRecord(expr) {
17737
+ const value = unwrapNode(expr);
17738
+ if (import_typescript8.default.isObjectLiteralExpression(value))
17739
+ return true;
17740
+ if (import_typescript8.default.isConditionalExpression(value))
17741
+ return returnsRecord(value.whenTrue) || returnsRecord(value.whenFalse);
17742
+ return value.kind === import_typescript8.default.SyntaxKind.TrueKeyword || value.kind === import_typescript8.default.SyntaxKind.FalseKeyword || import_typescript8.default.isNumericLiteral(value);
17743
+ }
17644
17744
  function isInstructionDescription(text) {
17645
17745
  if (text.length >= 2000)
17646
17746
  return true;
@@ -17792,7 +17892,7 @@ class PromptResolver {
17792
17892
  const line = `${ref.path}:${ref.line}`;
17793
17893
  firstOnLine.set(line, Math.min(firstOnLine.get(line) ?? Infinity, ref.start));
17794
17894
  }
17795
- const refs = [...this.refs.values()].map(({ pieces, start, ...ref }) => {
17895
+ const refs = [...this.refs.values()].filter((ref) => this.keepAll || ref.role !== "tool-result" || toolResultIsPrompt(ref.ownerNode, [...ref.pieces.values()])).map(({ pieces, start, ownerNode: _owner, ...ref }) => {
17796
17896
  const later = start > firstOnLine.get(`${ref.path}:${ref.line}`);
17797
17897
  const column = later ? this.columnOf(ref.path, start) : undefined;
17798
17898
  return {
@@ -18369,7 +18469,8 @@ class PromptResolver {
18369
18469
  hops: walk.hops,
18370
18470
  via: [...walk.flags],
18371
18471
  pieces: new Map,
18372
- start: anchor.getStart(sf)
18472
+ start: anchor.getStart(sf),
18473
+ ...owner ? { ownerNode: owner.node } : {}
18373
18474
  };
18374
18475
  this.refs.set(key, ref);
18375
18476
  }
@@ -18390,6 +18491,15 @@ class PromptResolver {
18390
18491
  return;
18391
18492
  return this.relative(resolvePath(dirname7(statement.getSourceFile().fileName), spec.replace(/\?raw$/, "")));
18392
18493
  }
18494
+ preferModelRole(ref, walk) {
18495
+ const toolPath = walk.role === "tool-result" || walk.role === "tool-description";
18496
+ if (ref.role === "tool-result" && !toolPath) {
18497
+ ref.role = walk.role;
18498
+ ref.hops = walk.hops;
18499
+ ref.via = [...walk.flags];
18500
+ }
18501
+ return ref.role === "tool-result" || walk.role !== "tool-result";
18502
+ }
18393
18503
  fileRef(path, walk) {
18394
18504
  if (TEST_SOURCE.test(path))
18395
18505
  return;
@@ -18399,9 +18509,11 @@ class PromptResolver {
18399
18509
  ref = { id, path, line: 1, endLine: 1, start: 0, kind: "file", role: walk.role, text: "", callSiteIds: [], hops: walk.hops, via: [...walk.flags], pieces: new Map };
18400
18510
  this.refs.set(id, ref);
18401
18511
  }
18512
+ const counts = this.preferModelRole(ref, walk);
18402
18513
  if (!ref.callSiteIds.includes(walk.site.id))
18403
18514
  ref.callSiteIds.push(walk.site.id);
18404
- ref.via = ref.via.filter((f) => walk.flags.includes(f));
18515
+ if (counts)
18516
+ ref.via = ref.via.filter((f) => walk.flags.includes(f));
18405
18517
  }
18406
18518
  markUnresolved(node, reason, walk) {
18407
18519
  const sf = node.getSourceFile();
@@ -19037,7 +19149,7 @@ async function runHarnessCommand(context) {
19037
19149
  throw new CliInputError("Focused remote prompt analysis is not supported yet.", "Use local --analyst=claude|codex|cursor|local-scan, or drop --concern for a full remote report.");
19038
19150
  }
19039
19151
  if (context.flags["github-actions"] === "true") {
19040
- const { runGithubActionsAnalyze } = await import("./harness-github-actions-p4011crc.js");
19152
+ const { runGithubActionsAnalyze } = await import("./harness-github-actions-d0rb1wmk.js");
19041
19153
  const result = await runGithubActionsAnalyze(rootDir, {
19042
19154
  writeReport: (report2) => {
19043
19155
  const normalized = normalizeHarnessReport(report2);
@@ -19183,8 +19295,8 @@ async function runHarnessCommand(context) {
19183
19295
  }
19184
19296
  const { artifacts, unknowns } = deterministicGraphItems(rootDir, promote === "all" ? undefined : promote);
19185
19297
  tagComponentStatus({ runtimeAgents: [], artifacts }, rootDir);
19186
- const { extractHarnessWithContext: extractHarnessWithContext2 } = await import("./index-4z7h9mam.js");
19187
- const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-femt9s00.js");
19298
+ const { extractHarnessWithContext: extractHarnessWithContext2 } = await import("./index-2rhvz7fa.js");
19299
+ const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-dk98sc3s.js");
19188
19300
  let components = { runtimeAgents: [], artifacts: [], warnings: [] };
19189
19301
  if (promote === "all" || promote === "topology" || promote === "tools") {
19190
19302
  const { result, ctx } = extractHarnessWithContext2(rootDir);
@@ -19218,8 +19330,8 @@ async function runHarnessCommand(context) {
19218
19330
  }
19219
19331
  case "extract": {
19220
19332
  writeHumanProgress(context, "Harness extract: tracing model call sites (no LLM, no network)...");
19221
- const { extractHarnessWithContext: extractHarnessWithContext2, serializeExtractResult } = await import("./index-4z7h9mam.js");
19222
- const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-femt9s00.js");
19333
+ const { extractHarnessWithContext: extractHarnessWithContext2, serializeExtractResult } = await import("./index-2rhvz7fa.js");
19334
+ const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-dk98sc3s.js");
19223
19335
  const { result, ctx } = extractHarnessWithContext2(rootDir, { fresh: true });
19224
19336
  const artifacts = deterministicArtifacts(rootDir);
19225
19337
  tagComponentStatus({ runtimeAgents: [], artifacts }, rootDir);
@@ -26642,164 +26754,1129 @@ function collectModelLiterals(rootDir) {
26642
26754
  return { literals: [...found].sort(), truncated: capped || skipped };
26643
26755
  }
26644
26756
 
26645
- // src/harness-extract/types.ts
26646
- var EXTRACT_SCHEMA_VERSION = 1;
26647
- // src/harness-extract/tools.ts
26648
- var PASS_THROUGH2 = new Set(["ref", "call", "param", "oneOf", "lookup"]);
26649
- var DEFINITION_KEYS = new Set(["description", "input_schema", "inputSchema", "parameters", "schema", "execute", "type", "strict"]);
26650
- function member(tree, key) {
26651
- const members = tree.children ?? [];
26652
- for (let index = members.length - 1;index >= 0; index -= 1)
26653
- if (members[index].key === key)
26654
- return members[index];
26655
- return;
26656
- }
26657
- function singleLiteral2(tree) {
26658
- if (!tree)
26659
- return;
26660
- if (tree.kind === "literal")
26661
- return tree.text;
26662
- if (PASS_THROUGH2.has(tree.kind)) {
26663
- const flow = valueChildren(tree);
26664
- if (flow.length === 1)
26665
- return singleLiteral2(flow[0]);
26666
- }
26667
- return;
26668
- }
26669
- function objectsOf(tree) {
26670
- if (tree.kind === "object")
26671
- return [tree];
26672
- if (PASS_THROUGH2.has(tree.kind))
26673
- return valueChildren(tree).flatMap(objectsOf);
26674
- return [];
26675
- }
26676
- function definitionName(tree) {
26677
- const fn = member(tree, "function");
26678
- const fnObject = fn ? objectsOf(fn)[0] : undefined;
26679
- const fnName = fnObject ? singleLiteral2(member(fnObject, "name")) : undefined;
26680
- if (fnName && fnObject)
26681
- return { name: fnName, path: fnObject.path, line: fnObject.line, via: "function.name" };
26682
- const nameNode = member(tree, "name");
26683
- const name = singleLiteral2(nameNode);
26684
- const keys = (tree.children ?? []).map((child) => child.key ?? "");
26685
- if (name && nameNode && keys.some((key) => DEFINITION_KEYS.has(key)))
26686
- return { name, path: nameNode.path, line: nameNode.line, via: "name" };
26687
- return;
26688
- }
26689
- function toolNamesOf(tree) {
26690
- const out = { names: [], unresolved: [] };
26691
- const visit = (node, inArray, names) => {
26692
- if (node.kind === "array" || node.kind === "assembled" && node.text === "array") {
26693
- for (const child of node.children ?? [])
26694
- visit(child, true, names);
26695
- return;
26696
- }
26697
- if (node.kind === "object") {
26698
- const definition = definitionName(node);
26699
- if (definition) {
26700
- names.push(definition);
26701
- return;
26702
- }
26703
- if (inArray) {
26704
- out.unresolved.push({ ...node, note: "tool object without a literal name" });
26705
- return;
26757
+ // src/harness-extract/emit-tools.ts
26758
+ var import_typescript12 = __toESM(require_typescript(), 1);
26759
+ import { existsSync as existsSync9 } from "node:fs";
26760
+ import { join as join14, posix as posix3 } from "node:path";
26761
+
26762
+ // src/harness-extract/enumerators/common.ts
26763
+ var import_typescript10 = __toESM(require_typescript(), 1);
26764
+ import { readdirSync as readdirSync8, readFileSync as readFileSync15 } from "node:fs";
26765
+ import { dirname as dirname10, join as join13, posix as posix2, relative as relative10 } from "node:path";
26766
+ var cache = new WeakMap;
26767
+ var SKIP = new Set(["node_modules", "dist", "build", "out", "vendor", "coverage", "__pycache__"]);
26768
+ var TEST_PATH4 = /(?:^|\/)(?:test|tests|__tests__|test-fixtures|fixtures?|__fixtures__|__mocks__|e2e)\/|\.(?:test|spec)\.[cm]?[jt]sx?$/i;
26769
+ var EVAL_PATH2 = /(?:^|\/)evals?\/|\.evals?\.[cm]?[jt]sx?$/i;
26770
+ function enumerationRepository(ctx) {
26771
+ const existing = cache.get(ctx);
26772
+ if (existing)
26773
+ return existing;
26774
+ const files = [];
26775
+ const walk = (dir) => {
26776
+ for (const entry of readdirSync8(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
26777
+ const abs = join13(dir, entry.name);
26778
+ if (entry.isDirectory()) {
26779
+ if (!entry.name.startsWith(".") && !SKIP.has(entry.name))
26780
+ walk(abs);
26781
+ } else if (entry.isFile() && /\.(?:[cm]?[jt]sx?|py|jsonc?|toml)$/.test(entry.name) && !/\.d\.[cm]?ts$/.test(entry.name)) {
26782
+ const path = relative10(ctx.rootDir, abs).split("\\").join("/");
26783
+ try {
26784
+ const text = readFileSync15(abs, "utf8");
26785
+ if (text.length > 1024 * 1024)
26786
+ continue;
26787
+ const source = ctx.programFor(path)?.getSourceFile(abs) ?? import_typescript10.default.createSourceFile(abs, text, import_typescript10.default.ScriptTarget.Latest, true, path.endsWith("tsx") ? import_typescript10.default.ScriptKind.TSX : import_typescript10.default.ScriptKind.TS);
26788
+ files.push({ path, text, source });
26789
+ } catch {}
26706
26790
  }
26707
- const record = new Map;
26708
- const set = (hit) => {
26709
- record.delete(hit.name);
26710
- record.set(hit.name, hit);
26711
- };
26712
- for (const child of node.children ?? []) {
26713
- if (child.key === "...") {
26714
- const spread = [];
26715
- visit(child, false, spread);
26716
- spread.forEach(set);
26717
- } else if (child.key) {
26718
- set({ name: child.key, path: child.path, line: child.line, via: "key" });
26719
- }
26791
+ }
26792
+ };
26793
+ walk(ctx.rootDir);
26794
+ const workers = [];
26795
+ const paths = new Set(files.map((file) => file.path));
26796
+ const closure = (main) => {
26797
+ const found = new Set, pending = [main];
26798
+ for (let index = 0;index < pending.length; index++) {
26799
+ const path = pending[index];
26800
+ if (found.has(path))
26801
+ continue;
26802
+ found.add(path);
26803
+ const file = files.find((entry) => entry.path === path);
26804
+ if (!file)
26805
+ continue;
26806
+ for (const ref of import_typescript10.default.preProcessFile(file.text, true, true).importedFiles) {
26807
+ if (!ref.fileName.startsWith("."))
26808
+ continue;
26809
+ const base = posix2.normalize(posix2.join(posix2.dirname(path), ref.fileName)).replace(/\.[cm]?js$/, "");
26810
+ const target = [base, ...[".ts", ".tsx", ".js", ".mjs", "/index.ts", "/index.js"].map((suffix) => base + suffix)].find((candidate) => paths.has(candidate));
26811
+ if (target)
26812
+ pending.push(target);
26720
26813
  }
26721
- names.push(...record.values());
26722
- return;
26723
26814
  }
26724
- if (PASS_THROUGH2.has(node.kind) && valueChildren(node).length > 0) {
26725
- for (const child of valueChildren(node))
26726
- visit(child, inArray, names);
26727
- return;
26815
+ return found;
26816
+ };
26817
+ for (const file of files)
26818
+ if (/(?:^|\/)wrangler(?:\.[\w.-]+)?\.(?:jsonc?|toml)$/.test(file.path)) {
26819
+ try {
26820
+ const config2 = file.path.endsWith(".toml") ? parse(file.text) : JSON.parse(stripJsonc(file.text));
26821
+ const variants = [["default", config2], ...Object.entries(config2.env ?? {}).map(([name, section]) => [name, { ...config2, ...section, queues: section.queues, workflows: section.workflows }])];
26822
+ for (const [environment, section] of variants) {
26823
+ if (typeof section.main !== "string" || isTestWorkerConfig({ path: file.path, name: section.name, mains: [section.main] }))
26824
+ continue;
26825
+ const main = posix2.normalize(posix2.join(dirname10(file.path), section.main));
26826
+ workers.push({ id: `${file.path}#${environment}`, main, cron: Boolean(section.triggers?.crons?.length), queueBindings: new Set((section.queues?.producers ?? []).flatMap((producer) => typeof producer.binding === "string" ? [producer.binding] : [])), workflowClasses: (section.workflows ?? []).flatMap((binding) => typeof binding.class_name === "string" && !binding.script_name ? [binding.class_name] : []), files: closure(main) });
26827
+ }
26828
+ } catch {}
26728
26829
  }
26729
- out.unresolved.push(node);
26830
+ const queueBindingsFor = (path) => {
26831
+ const owners = workers.filter((worker) => worker.files.has(path));
26832
+ return new Set(owners[0] ? [...owners[0].queueBindings].filter((binding) => owners.every((worker) => worker.queueBindings.has(binding))) : []);
26730
26833
  };
26731
- visit(tree, false, out.names);
26732
- return out;
26834
+ const reach = buildImportGraphReachability(ctx.rootDir);
26835
+ const repo = { files, workers, queueBindingsFor, cronEntrypoints: new Set(workers.filter((worker) => worker.cron).map((worker) => worker.main)), deployedFiles: reach.inProd, status: (path) => reach.inProd.has(path) || reach.reachable.has(path) ? "reachable" : "defined_only" };
26836
+ cache.set(ctx, repo);
26837
+ return repo;
26733
26838
  }
26734
-
26735
- // src/harness-extract/index.ts
26736
- var PROMPT_ROLES = new Set(["system", "user", "messages", "prompt", "instructions", "questions"]);
26737
- var MAX_HELPER_CALLERS = 200;
26738
- var MAX_DERIVED = 5000;
26739
- var MAX_CALLER_CHAIN = 3;
26740
- var cache = new Map;
26741
- function clearExtractCache() {
26742
- cache.clear();
26839
+ function lineOf5(node) {
26840
+ return node.getSourceFile().getLineAndCharacterOfPosition(node.getStart()).line + 1;
26743
26841
  }
26744
- function extractHarness(rootDir, options = {}) {
26745
- return extractHarnessWithContext(rootDir, options).result;
26842
+ function nameOf(node) {
26843
+ if (!node)
26844
+ return;
26845
+ if (import_typescript10.default.isComputedPropertyName(node) && import_typescript10.default.isStringLiteralLike(node.expression))
26846
+ return node.expression.text;
26847
+ return import_typescript10.default.isIdentifier(node) || import_typescript10.default.isStringLiteralLike(node) || import_typescript10.default.isNumericLiteral(node) ? node.text : undefined;
26746
26848
  }
26747
- function extractHarnessWithContext(rootDir, options = {}) {
26748
- const root = resolve13(rootDir);
26749
- const { fresh, ...rest } = options;
26750
- const key = `${root}\x00${JSON.stringify(rest)}`;
26751
- const fingerprint = sourceFingerprint(root, rest);
26752
- const cached = fresh ? undefined : cache.get(key);
26753
- if (cached && cached.fingerprint === fingerprint)
26754
- return cached.output;
26755
- const output = runExtract(root, options);
26756
- cache.set(key, { output, fingerprint });
26757
- return output;
26849
+ function visit(node, fn) {
26850
+ fn(node);
26851
+ import_typescript10.default.forEachChild(node, (child) => visit(child, fn));
26758
26852
  }
26759
- function argRef(rootDir, node, key) {
26760
- const source = node.getSourceFile();
26761
- const ref = { path: relPath(rootDir, source.fileName), start: node.getStart(source), end: node.getEnd(), line: lineOf(node) };
26762
- if (key !== undefined)
26763
- ref.key = key;
26764
- Object.defineProperty(ref, "node", { value: node, enumerable: false });
26765
- return ref;
26853
+ function componentId(kind, path, name) {
26854
+ return `${kind}:${path}:${name}`;
26766
26855
  }
26767
- function namedEnclosingFunction(node) {
26768
- for (let fn = enclosingFunction(node);fn; fn = enclosingFunction(fn)) {
26769
- const name = functionName(fn);
26770
- if (name)
26771
- return { fn, name };
26772
- }
26773
- return;
26856
+ function artifact(type, name, file, node, reason, status) {
26857
+ return { id: componentId(type, file.path, name), type, name, scope: "shared", sourcePath: file.path, usedByAgentIds: [], confidence: 1, evidence: [{ path: file.path, line: lineOf5(node), reason }], status };
26774
26858
  }
26775
- function qualifiedName(fn, name) {
26776
- const cls = enclosingClass(fn);
26777
- const owner = cls && (fn.parent === cls || fn.parent && fn.parent.parent === cls) ? className(cls) : undefined;
26778
- return owner ? `${owner}.${name}` : name;
26859
+ function agent(name, file, node, reason, status) {
26860
+ return { id: componentId("agent", file.path, name), name, kind: "runtime_agent", root: ".", entrypointIds: [], channelAdapterIds: [], artifactIds: [], identityNamespaceIds: [], deploymentIds: [], frameworkIds: [], modelProviderIds: [], confidence: 1, evidence: [{ path: file.path, line: lineOf5(node), reason }], status };
26779
26861
  }
26780
- function functionScope(rootDir, fn, name) {
26781
- const parts = [qualifiedName(fn, name)];
26782
- const object = objectLiteralOf2(fn);
26783
- if (object) {
26784
- const holder = object.parent && import_typescript10.default.isVariableDeclaration(object.parent) && import_typescript10.default.isIdentifier(object.parent.name) ? object.parent.name.text : `L${lineOf(object)}`;
26785
- parts.unshift(holder);
26786
- }
26787
- for (let outer = namedEnclosingFunction(object ?? fn);outer; outer = namedEnclosingFunction(outer.fn))
26788
- parts.unshift(qualifiedName(outer.fn, outer.name));
26789
- return `${relPath(rootDir, fn.getSourceFile().fileName)}#${parts.join(".")}`;
26862
+ function emptyResult() {
26863
+ return { runtimeAgents: [], artifacts: [], warnings: [] };
26790
26864
  }
26791
- function objectLiteralOf2(fn) {
26792
- const member2 = import_typescript10.default.isMethodDeclaration(fn) || import_typescript10.default.isGetAccessorDeclaration(fn) || import_typescript10.default.isSetAccessorDeclaration(fn) ? fn : import_typescript10.default.isPropertyAssignment(fn.parent) ? fn.parent : undefined;
26793
- return member2 && import_typescript10.default.isObjectLiteralExpression(member2.parent) ? member2.parent : undefined;
26865
+ function stableResult(result) {
26866
+ const unique2 = (values) => [...new Map(values.map((x) => [x.id, x])).values()].sort((a, b) => a.id.localeCompare(b.id));
26867
+ return { runtimeAgents: unique2(result.runtimeAgents), artifacts: unique2(result.artifacts), warnings: [...new Set(result.warnings)].sort() };
26794
26868
  }
26795
- function scopeOf(rootDir, node) {
26796
- const named = namedEnclosingFunction(node);
26797
- if (named)
26798
- return functionScope(rootDir, named.fn, named.name);
26799
- const path = relPath(rootDir, node.getSourceFile().fileName);
26800
- let outermost;
26801
- for (let fn = enclosingFunction(node);fn; fn = enclosingFunction(fn))
26802
- outermost = fn;
26869
+
26870
+ // src/harness-extract/tool-owners.ts
26871
+ var import_typescript11 = __toESM(require_typescript(), 1);
26872
+ var AGENT_BASES3 = new Set(["Think", "Agent", "AIChatAgent"]);
26873
+ var ROLE_FIELD = /^(?:role|roleId|roleName|kind|type|id|slug|agentRole|subagentRole)$/i;
26874
+ var MAX_HOPS = 10;
26875
+ var MIN_ALLOWLIST = 3;
26876
+ var TOOL_LIST_PARAM = /^(?:allow(?:list|ed)?|allowedTools|toolNames|tools|requested)$/i;
26877
+ var ALLOWLIST_SHARE = 0.6;
26878
+ function sourceFilesOf(ctx) {
26879
+ const out = [];
26880
+ for (const program of ctx.programs) {
26881
+ for (const source of program.getSourceFiles()) {
26882
+ if (source.isDeclarationFile || /[\\/]node_modules[\\/]/.test(source.fileName))
26883
+ continue;
26884
+ const rel2 = relPath(ctx.rootDir, source.fileName);
26885
+ if (rel2.startsWith(".."))
26886
+ continue;
26887
+ if (ctx.programFor(source.fileName) !== program)
26888
+ continue;
26889
+ out.push({ program, source, rel: rel2 });
26890
+ }
26891
+ }
26892
+ return out;
26893
+ }
26894
+ function isOneOffScript(rel2, reach) {
26895
+ if (!/^scripts\//.test(rel2))
26896
+ return false;
26897
+ return !reach?.inProd.has(rel2);
26898
+ }
26899
+
26900
+ class ToolOwners {
26901
+ ctx;
26902
+ classes = [];
26903
+ byDeclaration = new Map;
26904
+ references = new Map;
26905
+ edges = new Map;
26906
+ allowlists;
26907
+ constructor(ctx) {
26908
+ this.ctx = ctx;
26909
+ const memo = createFrameworkMemo();
26910
+ for (const { program, source, rel: rel2 } of sourceFilesOf(ctx)) {
26911
+ if (isTestPath(rel2))
26912
+ continue;
26913
+ const checker = program.getTypeChecker();
26914
+ const visit2 = (node) => {
26915
+ if ((import_typescript11.default.isClassDeclaration(node) || import_typescript11.default.isClassExpression(node)) && node.name) {
26916
+ let info;
26917
+ try {
26918
+ info = frameworkBaseOf(node, checker, memo);
26919
+ } catch {
26920
+ info = undefined;
26921
+ }
26922
+ if (info?.base && AGENT_BASES3.has(info.base)) {
26923
+ const agent2 = {
26924
+ name: node.name.text,
26925
+ path: rel2,
26926
+ line: lineOf(node.name),
26927
+ abstract: Boolean(import_typescript11.default.getCombinedModifierFlags(node) & import_typescript11.default.ModifierFlags.Abstract),
26928
+ base: info.base,
26929
+ baseModule: info.module,
26930
+ parent: superclassOf(node, checker),
26931
+ declaration: node,
26932
+ fields: classFields(node),
26933
+ methods: new Set(node.members.filter((member) => import_typescript11.default.isMethodDeclaration(member) || import_typescript11.default.isGetAccessorDeclaration(member)).map((member) => propertyNameText(member.name) ?? ""))
26934
+ };
26935
+ this.classes.push(agent2);
26936
+ this.byDeclaration.set(node, agent2);
26937
+ }
26938
+ }
26939
+ import_typescript11.default.forEachChild(node, visit2);
26940
+ };
26941
+ visit2(source);
26942
+ }
26943
+ }
26944
+ concrete() {
26945
+ return this.classes.filter((agent2) => !agent2.abstract);
26946
+ }
26947
+ fieldOf(name, field) {
26948
+ let current = this.classes.find((agent2) => agent2.name === name);
26949
+ for (let hops = 0;current && hops < 10; hops += 1) {
26950
+ if (field in current.fields)
26951
+ return current.fields[field];
26952
+ current = current.parent ? this.byDeclaration.get(current.parent) : undefined;
26953
+ }
26954
+ return;
26955
+ }
26956
+ inheritors(owner, method) {
26957
+ const out = [];
26958
+ for (const agent2 of this.classes) {
26959
+ if (agent2.abstract)
26960
+ continue;
26961
+ let current = agent2;
26962
+ let ok = false;
26963
+ for (let hops = 0;current && hops < 10; hops += 1) {
26964
+ if (current === owner) {
26965
+ ok = true;
26966
+ break;
26967
+ }
26968
+ if (method && current.methods.has(method))
26969
+ break;
26970
+ current = current.parent ? this.byDeclaration.get(current.parent) : undefined;
26971
+ }
26972
+ if (ok)
26973
+ out.push(agent2.name);
26974
+ }
26975
+ return out;
26976
+ }
26977
+ ownersOf(node, program) {
26978
+ const sets = { direct: new Set, rpc: new Set, open: new Set };
26979
+ const start = this.positionOf(node, program);
26980
+ if (!start)
26981
+ return { direct: [], rpc: [], open: [] };
26982
+ const seen = new Set;
26983
+ let frontier = [{ position: start, via: "direct" }];
26984
+ for (let hops = 0;frontier.length > 0 && hops <= MAX_HOPS; hops += 1) {
26985
+ const next = [];
26986
+ for (const { position, via } of frontier) {
26987
+ for (const agent2 of position.agents)
26988
+ sets[via].add(agent2);
26989
+ const key = `${position.id}|${via}`;
26990
+ if (seen.has(key))
26991
+ continue;
26992
+ seen.add(key);
26993
+ for (const edge of this.edgesOf(position, program))
26994
+ next.push({ position: edge.position, via: combineVia(via, edge.via) });
26995
+ }
26996
+ frontier = next;
26997
+ }
26998
+ const direct = [...sets.direct].sort();
26999
+ return {
27000
+ direct,
27001
+ rpc: [...sets.rpc].filter((name) => !sets.direct.has(name)).sort(),
27002
+ open: [...sets.open].filter((name) => !sets.direct.has(name)).sort()
27003
+ };
27004
+ }
27005
+ positionOf(node, program) {
27006
+ let method;
27007
+ for (let current = node;current; current = current.parent) {
27008
+ if ((import_typescript11.default.isMethodDeclaration(current) || import_typescript11.default.isGetAccessorDeclaration(current) || import_typescript11.default.isPropertyDeclaration(current)) && import_typescript11.default.isClassLike(current.parent) && import_typescript11.default.isIdentifier(current.name)) {
27009
+ method = current.name;
27010
+ }
27011
+ if (import_typescript11.default.isClassLike(current)) {
27012
+ const agent2 = this.byDeclaration.get(current);
27013
+ if (!agent2)
27014
+ return current.name ? this.holderPosition(current.name, program) : undefined;
27015
+ const guards = fieldGuards(node, current);
27016
+ const agents = this.inheritors(agent2, method?.text).filter((name) => guards.every((guard) => guard.holds(this.fieldOf(name, guard.field))));
27017
+ const anchor = method ?? current;
27018
+ return { id: nodeId(anchor), anchor, agents, agent: agent2, method };
27019
+ }
27020
+ }
27021
+ const holder = holderName(node);
27022
+ return holder ? this.holderPosition(holder, program) : undefined;
27023
+ }
27024
+ holderPosition(name, program) {
27025
+ const target = valueDeclaration(resolvedSymbol(name, program.getTypeChecker())) ?? name.parent;
27026
+ return { id: nodeId(target), anchor: target, agents: [], holder: name };
27027
+ }
27028
+ edgesOf(position, program) {
27029
+ const cached = this.edges.get(position.id);
27030
+ if (cached)
27031
+ return cached;
27032
+ const out = [];
27033
+ this.edges.set(position.id, out);
27034
+ const checker = program.getTypeChecker();
27035
+ if (position.holder) {
27036
+ for (const reference of this.referencesOf(program, position.holder.text)) {
27037
+ if (reference === position.holder || isDeclarationName(reference))
27038
+ continue;
27039
+ if (valueDeclaration(resolvedSymbol(reference, checker)) !== position.anchor)
27040
+ continue;
27041
+ const next = this.positionOf(reference, program);
27042
+ if (next)
27043
+ out.push({ position: next, via: "direct" });
27044
+ }
27045
+ } else if (position.agent && position.method) {
27046
+ const owner = position.agent;
27047
+ const name = position.method.text;
27048
+ const unique2 = this.classes.filter((agent2) => agent2.methods.has(name)).length === 1 && owner.methods.has(name);
27049
+ const declaration = position.method.parent;
27050
+ const takesToolList = import_typescript11.default.isMethodDeclaration(declaration) && declaration.parameters.some((param) => import_typescript11.default.isIdentifier(param.name) && TOOL_LIST_PARAM.test(param.name.text));
27051
+ for (const reference of this.referencesOf(program, name)) {
27052
+ const access = reference.parent;
27053
+ if (!access || !import_typescript11.default.isPropertyAccessExpression(access) || access.name !== reference)
27054
+ continue;
27055
+ if (access.expression.kind === import_typescript11.default.SyntaxKind.ThisKeyword) {
27056
+ if (!isWithin3(reference, owner.declaration))
27057
+ continue;
27058
+ const next2 = this.positionOf(reference, program);
27059
+ if (next2)
27060
+ out.push({ position: { ...next2, agents: [] }, via: "direct" });
27061
+ continue;
27062
+ }
27063
+ if (!unique2 || !import_typescript11.default.isCallExpression(access.parent) || access.parent.expression !== access)
27064
+ continue;
27065
+ const resolved = valueDeclaration(resolvedSymbol(reference, checker));
27066
+ if (resolved && resolved.parent !== owner.declaration)
27067
+ continue;
27068
+ const next = this.positionOf(reference, program);
27069
+ if (next)
27070
+ out.push({ position: next, via: takesToolList ? "open" : "rpc" });
27071
+ }
27072
+ }
27073
+ return out;
27074
+ }
27075
+ referencesOf(program, name) {
27076
+ let index = this.references.get(program);
27077
+ if (!index) {
27078
+ index = new Map;
27079
+ for (const source of program.getSourceFiles()) {
27080
+ if (source.isDeclarationFile || /[\\/]node_modules[\\/]/.test(source.fileName))
27081
+ continue;
27082
+ if (isTestPath(relPath(this.ctx.rootDir, source.fileName)))
27083
+ continue;
27084
+ const visit2 = (node) => {
27085
+ if (import_typescript11.default.isIdentifier(node)) {
27086
+ const list = index.get(node.text);
27087
+ if (list)
27088
+ list.push(node);
27089
+ else
27090
+ index.set(node.text, [node]);
27091
+ }
27092
+ import_typescript11.default.forEachChild(node, visit2);
27093
+ };
27094
+ visit2(source);
27095
+ }
27096
+ this.references.set(program, index);
27097
+ }
27098
+ return index.get(name) ?? [];
27099
+ }
27100
+ indexAllowlists(knownTools) {
27101
+ this.allowlists = [];
27102
+ for (const { program, source, rel: rel2 } of sourceFilesOf(this.ctx)) {
27103
+ if (isTestPath(rel2))
27104
+ continue;
27105
+ const checker = program.getTypeChecker();
27106
+ const visit2 = (node) => {
27107
+ if (import_typescript11.default.isArrayLiteralExpression(node) && (!node.parent || !import_typescript11.default.isSpreadElement(node.parent))) {
27108
+ const entries = stringEntries(node, checker);
27109
+ const named = entries.filter((entry) => knownTools.has(entry) || entry.endsWith("*") && entry.length > 2);
27110
+ if (entries.length >= MIN_ALLOWLIST && named.length / entries.length >= ALLOWLIST_SHARE) {
27111
+ const agents = this.allowlistOwners(node, program);
27112
+ if (agents.length > 0)
27113
+ this.allowlists.push({ entries, agents, path: rel2 });
27114
+ }
27115
+ }
27116
+ import_typescript11.default.forEachChild(node, visit2);
27117
+ };
27118
+ visit2(source);
27119
+ }
27120
+ }
27121
+ allowlisted() {
27122
+ return new Set((this.allowlists ?? []).flatMap((list) => list.agents));
27123
+ }
27124
+ agentsFor(tool, owners, allowlistApplies = () => true) {
27125
+ const restricted = this.allowlisted();
27126
+ const out = new Set([...owners.direct, ...owners.open, ...owners.rpc.filter((agent2) => !restricted.has(agent2)), ...this.allowlistAgents(tool, allowlistApplies)]);
27127
+ return [...out].sort();
27128
+ }
27129
+ allowlistAgents(tool, applies = () => true) {
27130
+ const out = new Set;
27131
+ for (const list of this.allowlists ?? []) {
27132
+ if (!applies(list.path))
27133
+ continue;
27134
+ if (list.entries.some((entry) => entry === tool || entry.endsWith("*") && tool.startsWith(entry.slice(0, -1)))) {
27135
+ for (const agent2 of list.agents)
27136
+ out.add(agent2);
27137
+ }
27138
+ }
27139
+ return [...out].sort();
27140
+ }
27141
+ allowlistOwners(list, program) {
27142
+ const keys = new Set;
27143
+ const direct = new Set;
27144
+ const checker = program.getTypeChecker();
27145
+ const visited = new Set;
27146
+ const walk = (node, hops) => {
27147
+ if (hops > 4 || visited.has(node))
27148
+ return;
27149
+ visited.add(node);
27150
+ for (let current = node.parent;current; current = current.parent) {
27151
+ if (import_typescript11.default.isClassLike(current)) {
27152
+ const agent2 = this.byDeclaration.get(current);
27153
+ if (agent2)
27154
+ for (const name of this.inheritors(agent2, undefined))
27155
+ direct.add(name);
27156
+ return;
27157
+ }
27158
+ if (import_typescript11.default.isFunctionLike(current))
27159
+ return;
27160
+ if (import_typescript11.default.isPropertyAssignment(current) || import_typescript11.default.isShorthandPropertyAssignment(current)) {
27161
+ const key = propertyNameText(current.name);
27162
+ if (key)
27163
+ keys.add(key);
27164
+ }
27165
+ if (import_typescript11.default.isObjectLiteralExpression(current)) {
27166
+ for (const property of current.properties) {
27167
+ if (!import_typescript11.default.isPropertyAssignment(property) || !ROLE_FIELD.test(propertyNameText(property.name) ?? ""))
27168
+ continue;
27169
+ const value = unwrap(property.initializer);
27170
+ if (import_typescript11.default.isStringLiteral(value))
27171
+ keys.add(value.text);
27172
+ }
27173
+ }
27174
+ if (import_typescript11.default.isVariableDeclaration(current) && import_typescript11.default.isIdentifier(current.name)) {
27175
+ const target = current;
27176
+ for (const reference of this.referencesOf(program, current.name.text)) {
27177
+ if (reference === current.name || isDeclarationName(reference))
27178
+ continue;
27179
+ if (valueDeclaration(resolvedSymbol(reference, checker)) !== target)
27180
+ continue;
27181
+ walk(reference, hops + 1);
27182
+ }
27183
+ return;
27184
+ }
27185
+ }
27186
+ };
27187
+ walk(list, 0);
27188
+ for (const agent2 of this.concrete()) {
27189
+ if (Object.entries(agent2.fields).some(([field, value]) => ROLE_FIELD.test(field) && keys.has(value)))
27190
+ direct.add(agent2.name);
27191
+ }
27192
+ return [...direct].sort();
27193
+ }
27194
+ }
27195
+ function combineVia(current, edge) {
27196
+ if (current === "open" || edge === "open")
27197
+ return "open";
27198
+ if (current === "rpc" || edge === "rpc")
27199
+ return "rpc";
27200
+ return "direct";
27201
+ }
27202
+ function nodeId(node) {
27203
+ return `${node.getSourceFile().fileName}:${node.getStart()}`;
27204
+ }
27205
+ function fieldGuards(node, cls) {
27206
+ const out = [];
27207
+ let child = node;
27208
+ for (let current = node.parent;current && current !== cls; child = current, current = current.parent) {
27209
+ let condition;
27210
+ let whenTrue;
27211
+ if (import_typescript11.default.isConditionalExpression(current) && child !== current.condition) {
27212
+ condition = current.condition;
27213
+ whenTrue = child === current.whenTrue;
27214
+ } else if (import_typescript11.default.isIfStatement(current) && child !== current.expression) {
27215
+ condition = current.expression;
27216
+ whenTrue = child === current.thenStatement;
27217
+ }
27218
+ if (!condition || whenTrue === undefined)
27219
+ continue;
27220
+ const test = unwrap(condition);
27221
+ if (!import_typescript11.default.isBinaryExpression(test))
27222
+ continue;
27223
+ const op = test.operatorToken.kind;
27224
+ const equal = op === import_typescript11.default.SyntaxKind.EqualsEqualsEqualsToken || op === import_typescript11.default.SyntaxKind.EqualsEqualsToken;
27225
+ const notEqual = op === import_typescript11.default.SyntaxKind.ExclamationEqualsEqualsToken || op === import_typescript11.default.SyntaxKind.ExclamationEqualsToken;
27226
+ if (!equal && !notEqual)
27227
+ continue;
27228
+ const sides = [unwrap(test.left), unwrap(test.right)];
27229
+ const access = sides.find((side) => import_typescript11.default.isPropertyAccessExpression(side) && side.expression.kind === import_typescript11.default.SyntaxKind.ThisKeyword);
27230
+ const literal = sides.find((side) => import_typescript11.default.isStringLiteral(side));
27231
+ if (!access || !literal)
27232
+ continue;
27233
+ const wantEqual = equal === whenTrue;
27234
+ const value = literal.text;
27235
+ out.push({ field: access.name.text, holds: (actual) => actual === undefined || actual === value === wantEqual });
27236
+ }
27237
+ return out;
27238
+ }
27239
+ function isWithin3(node, container) {
27240
+ for (let current = node;current; current = current.parent)
27241
+ if (current === container)
27242
+ return true;
27243
+ return false;
27244
+ }
27245
+ function superclassOf(node, checker) {
27246
+ const heritage = node.heritageClauses?.find((clause) => clause.token === import_typescript11.default.SyntaxKind.ExtendsKeyword)?.types[0];
27247
+ if (!heritage)
27248
+ return;
27249
+ const expression = unwrap(heritage.expression);
27250
+ const declaration = valueDeclaration(resolvedSymbol(import_typescript11.default.isPropertyAccessExpression(expression) ? expression.name : expression, checker));
27251
+ return declaration && (import_typescript11.default.isClassDeclaration(declaration) || import_typescript11.default.isClassExpression(declaration)) ? declaration : undefined;
27252
+ }
27253
+ function classFields(node) {
27254
+ const fields = {};
27255
+ for (const member of node.members) {
27256
+ if (!import_typescript11.default.isPropertyDeclaration(member) || !member.initializer)
27257
+ continue;
27258
+ const name = propertyNameText(member.name);
27259
+ if (!name)
27260
+ continue;
27261
+ const value = unwrap(member.initializer);
27262
+ if (import_typescript11.default.isStringLiteral(value) || import_typescript11.default.isNoSubstitutionTemplateLiteral(value))
27263
+ fields[name] = value.text;
27264
+ else if (value.kind === import_typescript11.default.SyntaxKind.TrueKeyword)
27265
+ fields[name] = "true";
27266
+ else if (value.kind === import_typescript11.default.SyntaxKind.FalseKeyword)
27267
+ fields[name] = "false";
27268
+ }
27269
+ return fields;
27270
+ }
27271
+ function holderName(node) {
27272
+ let found;
27273
+ for (let current = node.parent;current; current = current.parent) {
27274
+ if (import_typescript11.default.isFunctionDeclaration(current) && current.name)
27275
+ return current.name;
27276
+ if (import_typescript11.default.isVariableDeclaration(current) && import_typescript11.default.isIdentifier(current.name)) {
27277
+ found = current.name;
27278
+ const statement = current.parent?.parent;
27279
+ if (statement && import_typescript11.default.isVariableStatement(statement) && import_typescript11.default.isSourceFile(statement.parent))
27280
+ return found;
27281
+ const init = current.initializer ? unwrap(current.initializer) : undefined;
27282
+ if (init && (import_typescript11.default.isArrowFunction(init) || import_typescript11.default.isFunctionExpression(init)))
27283
+ return found;
27284
+ }
27285
+ }
27286
+ return found;
27287
+ }
27288
+ function isDeclarationName(identifier) {
27289
+ const parent = identifier.parent;
27290
+ if (!parent)
27291
+ return false;
27292
+ if (import_typescript11.default.isImportSpecifier(parent) || import_typescript11.default.isImportClause(parent) || import_typescript11.default.isNamespaceImport(parent) || import_typescript11.default.isExportSpecifier(parent))
27293
+ return true;
27294
+ return (import_typescript11.default.isVariableDeclaration(parent) || import_typescript11.default.isFunctionDeclaration(parent) || import_typescript11.default.isClassDeclaration(parent) || import_typescript11.default.isParameter(parent) || import_typescript11.default.isPropertyDeclaration(parent) || import_typescript11.default.isMethodDeclaration(parent)) && parent.name === identifier;
27295
+ }
27296
+ function stringEntries(expression, checker, depth = 0) {
27297
+ if (depth > 4)
27298
+ return [];
27299
+ const value = unwrap(expression);
27300
+ if (import_typescript11.default.isIdentifier(value)) {
27301
+ const declaration = valueDeclaration(resolvedSymbol(value, checker));
27302
+ return declaration && import_typescript11.default.isVariableDeclaration(declaration) && declaration.initializer ? stringEntries(declaration.initializer, checker, depth + 1) : [];
27303
+ }
27304
+ if (!import_typescript11.default.isArrayLiteralExpression(value))
27305
+ return [];
27306
+ const out = [];
27307
+ for (const element of value.elements) {
27308
+ if (import_typescript11.default.isSpreadElement(element)) {
27309
+ out.push(...stringEntries(element.expression, checker, depth + 1));
27310
+ continue;
27311
+ }
27312
+ const text = constantString(element, checker, depth);
27313
+ if (text !== undefined)
27314
+ out.push(text);
27315
+ }
27316
+ return out;
27317
+ }
27318
+ function constantString(expression, checker, depth) {
27319
+ const value = unwrap(expression);
27320
+ if (import_typescript11.default.isStringLiteral(value) || import_typescript11.default.isNoSubstitutionTemplateLiteral(value))
27321
+ return value.text;
27322
+ if (depth > 4)
27323
+ return;
27324
+ if (import_typescript11.default.isIdentifier(value)) {
27325
+ const declaration = valueDeclaration(resolvedSymbol(value, checker));
27326
+ return declaration && import_typescript11.default.isVariableDeclaration(declaration) && declaration.initializer ? constantString(declaration.initializer, checker, depth + 1) : undefined;
27327
+ }
27328
+ if (import_typescript11.default.isTemplateExpression(value)) {
27329
+ let text = value.head.text;
27330
+ for (const span of value.templateSpans) {
27331
+ const part = constantString(span.expression, checker, depth + 1);
27332
+ if (part === undefined)
27333
+ return;
27334
+ text += part + span.literal.text;
27335
+ }
27336
+ return text;
27337
+ }
27338
+ return;
27339
+ }
27340
+
27341
+ // src/harness-extract/tools.ts
27342
+ var PASS_THROUGH2 = new Set(["ref", "call", "param", "oneOf", "lookup"]);
27343
+ var DEFINITION_KEYS = new Set(["description", "input_schema", "inputSchema", "parameters", "schema", "execute", "type", "strict"]);
27344
+ function member(tree, key) {
27345
+ const members = tree.children ?? [];
27346
+ for (let index = members.length - 1;index >= 0; index -= 1)
27347
+ if (members[index].key === key)
27348
+ return members[index];
27349
+ return;
27350
+ }
27351
+ function singleLiteral2(tree) {
27352
+ if (!tree)
27353
+ return;
27354
+ if (tree.kind === "literal")
27355
+ return tree.text;
27356
+ if (PASS_THROUGH2.has(tree.kind)) {
27357
+ const flow = valueChildren(tree);
27358
+ if (flow.length === 1)
27359
+ return singleLiteral2(flow[0]);
27360
+ }
27361
+ return;
27362
+ }
27363
+ function objectsOf(tree) {
27364
+ if (tree.kind === "object")
27365
+ return [tree];
27366
+ if (PASS_THROUGH2.has(tree.kind))
27367
+ return valueChildren(tree).flatMap(objectsOf);
27368
+ return [];
27369
+ }
27370
+ function definitionName(tree) {
27371
+ const fn = member(tree, "function");
27372
+ const fnObject = fn ? objectsOf(fn)[0] : undefined;
27373
+ const fnName = fnObject ? singleLiteral2(member(fnObject, "name")) : undefined;
27374
+ if (fnName && fnObject)
27375
+ return { name: fnName, path: fnObject.path, line: fnObject.line, via: "function.name" };
27376
+ const nameNode = member(tree, "name");
27377
+ const name = singleLiteral2(nameNode);
27378
+ const keys = (tree.children ?? []).map((child) => child.key ?? "");
27379
+ if (name && nameNode && keys.some((key) => DEFINITION_KEYS.has(key)))
27380
+ return { name, path: nameNode.path, line: nameNode.line, via: "name" };
27381
+ return;
27382
+ }
27383
+ function toolNamesOf(tree) {
27384
+ const out = { names: [], unresolved: [] };
27385
+ const visit2 = (node, inArray, names) => {
27386
+ if (node.kind === "array" || node.kind === "assembled" && node.text === "array") {
27387
+ for (const child of node.children ?? [])
27388
+ visit2(child, true, names);
27389
+ return;
27390
+ }
27391
+ if (node.kind === "object") {
27392
+ const definition = definitionName(node);
27393
+ if (definition) {
27394
+ names.push(definition);
27395
+ return;
27396
+ }
27397
+ if (inArray) {
27398
+ out.unresolved.push({ ...node, note: "tool object without a literal name" });
27399
+ return;
27400
+ }
27401
+ const record = new Map;
27402
+ const set = (hit) => {
27403
+ record.delete(hit.name);
27404
+ record.set(hit.name, hit);
27405
+ };
27406
+ for (const child of node.children ?? []) {
27407
+ if (child.key === "...") {
27408
+ const spread = [];
27409
+ visit2(child, false, spread);
27410
+ spread.forEach(set);
27411
+ } else if (child.key) {
27412
+ set({ name: child.key, path: child.path, line: child.line, via: "key" });
27413
+ }
27414
+ }
27415
+ names.push(...record.values());
27416
+ return;
27417
+ }
27418
+ if (PASS_THROUGH2.has(node.kind) && valueChildren(node).length > 0) {
27419
+ for (const child of valueChildren(node))
27420
+ visit2(child, inArray, names);
27421
+ return;
27422
+ }
27423
+ out.unresolved.push(node);
27424
+ };
27425
+ visit2(tree, false, out.names);
27426
+ return out;
27427
+ }
27428
+
27429
+ // src/harness-extract/emit-tools.ts
27430
+ var SCHEMA_KEYS = ["input_schema", "inputSchema", "parameters", "output_schema"];
27431
+ var TOOL_BODY_KEYS = ["execute", "handler"];
27432
+ var TOOL_FACTORY = /^(?:tool|dynamicTool|agentTool|createTool|defineTool)$/;
27433
+ var TOOL_MODULE = /^(?:ai|agents(?:\/.*)?|@cloudflare\/[\w-]+(?:\/.*)?|@mastra\/[\w-]+|@ai-sdk\/[\w-]+|@openai\/agents(?:-core)?|@langchain\/[\w-]+)$/;
27434
+ var MODEL_FACING_NAME = /^[A-Za-z_][\w.:-]{0,127}$/;
27435
+ var MAX_NAMES_PER_SITE = 64;
27436
+ var MAX_TOOLS = 1e4;
27437
+ var MAX_EVIDENCE_PER_TOOL = 64;
27438
+ var MAX_DEFINITIONS_PER_TOOL = 64;
27439
+ var MAX_DEFINITION_BYTES = 8 * 1024 * 1024;
27440
+ var MAX_BODY_BYTES = 64000;
27441
+ function emitTools(result, ctx, options = {}) {
27442
+ const owners = options.owners ?? new ToolOwners(ctx);
27443
+ const agentForScope = createAgentScopeResolver(result, ctx);
27444
+ let reach;
27445
+ try {
27446
+ reach = buildImportGraphReachability(ctx.rootDir);
27447
+ } catch {
27448
+ reach = undefined;
27449
+ }
27450
+ const skipPath = (rel2) => isTestPath(rel2) || isOneOffScript(rel2, reach);
27451
+ const tracers = new Map;
27452
+ const tracerFor = (program) => {
27453
+ let tracer = tracers.get(program);
27454
+ if (!tracer) {
27455
+ const checker = program.getTypeChecker();
27456
+ tracer = new ValueTracer(ctx.rootDir, checker, new CallIndex(program, checker), { maxDepth: 8, maxNodes: 400, maxCallers: 8 });
27457
+ tracers.set(program, tracer);
27458
+ }
27459
+ return tracer;
27460
+ };
27461
+ const packageOf = workspacePackages(ctx.rootDir);
27462
+ const found = new Map;
27463
+ const ownersByTool = new Map;
27464
+ let definitionBytes = 0;
27465
+ const limit = () => {
27466
+ const warning = "tools: bounded tool catalog budget reached; some evidence or bodies omitted";
27467
+ if (!result.warnings.includes(warning))
27468
+ result.warnings.push(warning);
27469
+ };
27470
+ const add = (name, via, evidence, toolOwners, definition, displayName, enclosing) => {
27471
+ if (!MODEL_FACING_NAME.test(name))
27472
+ return;
27473
+ const pkg = packageOf(evidence.path);
27474
+ const key = name;
27475
+ let tool = found.get(key);
27476
+ if (!tool) {
27477
+ if (found.size >= MAX_TOOLS) {
27478
+ limit();
27479
+ return;
27480
+ }
27481
+ tool = { name, status: enumerationRepository(ctx).status(evidence.path) === "defined_only" ? "defined_only" : "reachable", ...pkg ? { package: pkg } : {}, via, evidence: [], agents: [], calledFrom: [], definitions: [] };
27482
+ found.set(key, tool);
27483
+ ownersByTool.set(key, { direct: [], rpc: [], open: [] });
27484
+ }
27485
+ if (enumerationRepository(ctx).status(evidence.path) !== "defined_only")
27486
+ tool.status = "reachable";
27487
+ if (tool.evidence.length < MAX_EVIDENCE_PER_TOOL && !tool.evidence.some((other) => other.path === evidence.path && other.line === evidence.line)) {
27488
+ tool.evidence.push(evidence);
27489
+ tool.calledFrom.push({ path: evidence.path, line: evidence.line, ...enclosing ? { enclosing } : {} });
27490
+ }
27491
+ if (definition) {
27492
+ const source = definition.getSourceFile();
27493
+ const path = relPath(ctx.rootDir, source.fileName), start = definition.getStart(source);
27494
+ if (tool.definitions.length < MAX_DEFINITIONS_PER_TOOL && !tool.definitions.some((other) => other.path === path && other.start === start)) {
27495
+ const text = Buffer.from(definition.getText(source));
27496
+ if (text.length > MAX_BODY_BYTES) {
27497
+ const warning = `tools: ${name} definition at ${path}:${lineOf(definition)} exceeds ${MAX_BODY_BYTES} bytes; its body is truncated`;
27498
+ if (!result.warnings.includes(warning))
27499
+ result.warnings.push(warning);
27500
+ }
27501
+ const body = text.subarray(0, Math.max(0, Math.min(MAX_BODY_BYTES, MAX_DEFINITION_BYTES - definitionBytes))).toString("utf8");
27502
+ definitionBytes += Buffer.byteLength(body);
27503
+ if (definitionBytes >= MAX_DEFINITION_BYTES)
27504
+ limit();
27505
+ tool.definitions.push({ path, start, end: definition.getEnd(), line: lineOf(definition), scope: scopeOf(ctx.rootDir, definition), body });
27506
+ }
27507
+ }
27508
+ const merged = ownersByTool.get(key);
27509
+ for (const agent2 of toolOwners.direct)
27510
+ if (!merged.direct.includes(agent2))
27511
+ merged.direct.push(agent2);
27512
+ for (const agent2 of toolOwners.rpc)
27513
+ if (!merged.rpc.includes(agent2))
27514
+ merged.rpc.push(agent2);
27515
+ for (const agent2 of toolOwners.open)
27516
+ if (!merged.open.includes(agent2))
27517
+ merged.open.push(agent2);
27518
+ tool.displayName ??= displayName;
27519
+ };
27520
+ for (const { program, source, rel: rel2 } of sourceFilesOf(ctx)) {
27521
+ if (skipPath(rel2))
27522
+ continue;
27523
+ const checker = program.getTypeChecker();
27524
+ const tracer = tracerFor(program);
27525
+ const names = (expression) => literalStrings(expression, tracer).slice(0, MAX_NAMES_PER_SITE);
27526
+ const at = (node, reason) => ({ path: rel2, line: lineOf(node), reason });
27527
+ const visitObject = (object) => {
27528
+ const keys = object.properties.map((property) => propertyNameText(property.name) ?? "");
27529
+ const nameExpr = propertyValue(object, "name");
27530
+ if (nameExpr && SCHEMA_KEYS.some((key) => keys.includes(key)) && !isSchemaProperty(object)) {
27531
+ const list = names(nameExpr);
27532
+ if (list.length > 0) {
27533
+ const span = registryEntryOf(object);
27534
+ const agents = owners.ownersOf(span, program);
27535
+ for (const name of list)
27536
+ add(name, "definition", at(nameExpr, "tool definition (name beside its input schema)"), agents, span, displayNameOf(object, tracer), enclosingName(object));
27537
+ }
27538
+ }
27539
+ const toolNameExpr = propertyValue(object, "toolName");
27540
+ if (toolNameExpr && keys.includes("description")) {
27541
+ const list = names(toolNameExpr);
27542
+ if (list.length > 0) {
27543
+ const agents = owners.ownersOf(object, program);
27544
+ for (const name of list)
27545
+ add(name, "role-table", at(toolNameExpr, "role table row naming the tool the model sees"), agents, object, displayNameOf(object, tracer), enclosingName(object));
27546
+ }
27547
+ }
27548
+ for (const property of object.properties) {
27549
+ if (!import_typescript12.default.isPropertyAssignment(property) || !isToolValue(property.initializer, checker))
27550
+ continue;
27551
+ const list = import_typescript12.default.isComputedPropertyName(property.name) ? names(property.name.expression) : [propertyNameText(property.name)].filter((key) => Boolean(key));
27552
+ if (list.length === 0)
27553
+ continue;
27554
+ const agents = owners.ownersOf(property, program);
27555
+ const options2 = toolOptions(property.initializer);
27556
+ const definition = definitionNode(property.initializer, checker);
27557
+ for (const name of list)
27558
+ add(name, "record", at(property, "tools record key"), agents, definition, options2 ? displayNameOf(options2, tracer) : undefined, enclosingName(property));
27559
+ }
27560
+ };
27561
+ const visit2 = (node) => {
27562
+ try {
27563
+ if (import_typescript12.default.isObjectLiteralExpression(node)) {
27564
+ visitObject(node);
27565
+ } else if (import_typescript12.default.isBinaryExpression(node) && node.operatorToken.kind === import_typescript12.default.SyntaxKind.EqualsToken && import_typescript12.default.isElementAccessExpression(node.left) && isToolValue(node.right, checker)) {
27566
+ const list = names(node.left.argumentExpression);
27567
+ if (list.length > 0) {
27568
+ const agents = owners.ownersOf(node, program);
27569
+ const options2 = toolOptions(node.right);
27570
+ const definition = definitionNode(node.right, checker);
27571
+ for (const name of list)
27572
+ add(name, "record", at(node, "tool stored under this key"), agents, definition, options2 ? displayNameOf(options2, tracer) : undefined, enclosingName(node));
27573
+ }
27574
+ }
27575
+ } catch {}
27576
+ import_typescript12.default.forEachChild(node, visit2);
27577
+ };
27578
+ visit2(source);
27579
+ }
27580
+ for (const role of result.roles) {
27581
+ if (role.role !== "tools" || role.sink.isTest || skipPath(role.sink.path))
27582
+ continue;
27583
+ const program = ctx.programFor(role.sink.path);
27584
+ const siteOwners = program ? ownersAtSite(owners, program, role.sink.path, role.sink.line) : { direct: [], rpc: [], open: [] };
27585
+ for (const hit of toolNamesOf(role.tree).names) {
27586
+ if (skipPath(hit.path))
27587
+ continue;
27588
+ add(hit.name, "tools-arg", { path: hit.path, line: hit.line, reason: `named in the tools argument of ${role.sink.callee} at ${role.sink.path}:${role.sink.line}` }, siteOwners, undefined, undefined, role.sink.enclosing);
27589
+ }
27590
+ }
27591
+ owners.indexAllowlists(new Set([...found.values()].map((tool) => tool.name)));
27592
+ const callOwners = new Map;
27593
+ for (const role of result.roles) {
27594
+ if (role.role !== "tools" || role.sink.isTest || skipPath(role.sink.path))
27595
+ continue;
27596
+ const ids = agentForScope(role.sink.scope);
27597
+ for (const hit of toolNamesOf(role.tree).names) {
27598
+ let owners2 = callOwners.get(hit.name);
27599
+ if (!owners2)
27600
+ callOwners.set(hit.name, owners2 = new Set);
27601
+ for (const id of ids)
27602
+ owners2.add(id);
27603
+ }
27604
+ }
27605
+ for (const [key, tool] of found) {
27606
+ const ids = new Set;
27607
+ for (const name of owners.agentsFor(tool.name, ownersByTool.get(key))) {
27608
+ const classes = owners.classes.filter((entry) => entry.name === name);
27609
+ if (classes.length === 1)
27610
+ for (const id of agentForScope(`${classes[0].path}#${name}`))
27611
+ ids.add(id);
27612
+ }
27613
+ for (const id of callOwners.get(tool.name) ?? [])
27614
+ ids.add(id);
27615
+ tool.agents = [...ids].sort();
27616
+ }
27617
+ return [...found.values()].sort((a, b) => a.name.localeCompare(b.name) || (a.package ?? "").localeCompare(b.package ?? ""));
27618
+ }
27619
+ function registryEntryOf(object) {
27620
+ const parent = object.parent;
27621
+ if (parent && import_typescript12.default.isPropertyAssignment(parent) && propertyNameText(parent.name) === "definition" && import_typescript12.default.isObjectLiteralExpression(parent.parent)) {
27622
+ return parent.parent;
27623
+ }
27624
+ return object;
27625
+ }
27626
+ function definitionNode(expression, checker, depth = 0) {
27627
+ const value = unwrap(expression);
27628
+ if (import_typescript12.default.isCallExpression(value) || import_typescript12.default.isObjectLiteralExpression(value))
27629
+ return value;
27630
+ if (import_typescript12.default.isIdentifier(value) && depth < 2) {
27631
+ const declaration = valueDeclaration(resolvedSymbol(value, checker));
27632
+ if (declaration && import_typescript12.default.isVariableDeclaration(declaration) && declaration.initializer)
27633
+ return definitionNode(declaration.initializer, checker, depth + 1);
27634
+ }
27635
+ return;
27636
+ }
27637
+ function ownersAtSite(owners, program, path, line) {
27638
+ const source = program.getSourceFiles().find((file) => file.fileName.endsWith(`/${path}`) || file.fileName === path);
27639
+ if (!source)
27640
+ return { direct: [], rpc: [], open: [] };
27641
+ const position = source.getPositionOfLineAndCharacter(Math.max(0, line - 1), 0);
27642
+ let node = source;
27643
+ const descend = (current) => {
27644
+ for (const child of current.getChildren(source)) {
27645
+ if (child.getStart(source) <= position && position < child.getEnd()) {
27646
+ node = child;
27647
+ descend(child);
27648
+ return;
27649
+ }
27650
+ }
27651
+ };
27652
+ descend(source);
27653
+ return owners.ownersOf(node, program);
27654
+ }
27655
+ function literalStrings(expression, tracer) {
27656
+ const value = unwrap(expression);
27657
+ if (import_typescript12.default.isStringLiteral(value) || import_typescript12.default.isNoSubstitutionTemplateLiteral(value))
27658
+ return [value.text];
27659
+ let tree;
27660
+ try {
27661
+ tree = tracer.trace(value);
27662
+ } catch {
27663
+ return [];
27664
+ }
27665
+ return [...new Set(renderings(tree, MAX_NAMES_PER_SITE).filter((text) => text.length > 0 && !text.includes("${...}")))];
27666
+ }
27667
+ function displayNameOf(object, tracer) {
27668
+ for (const key of ["displayName", "title"]) {
27669
+ const value = propertyValue(object, key);
27670
+ if (!value)
27671
+ continue;
27672
+ const [text] = literalStrings(value, tracer);
27673
+ if (text)
27674
+ return text;
27675
+ }
27676
+ return;
27677
+ }
27678
+ function toolOptions(expression) {
27679
+ const value = unwrap(expression);
27680
+ if (import_typescript12.default.isObjectLiteralExpression(value))
27681
+ return value;
27682
+ if (import_typescript12.default.isCallExpression(value)) {
27683
+ for (const argument of value.arguments) {
27684
+ const inner = unwrap(argument);
27685
+ if (import_typescript12.default.isObjectLiteralExpression(inner))
27686
+ return inner;
27687
+ }
27688
+ }
27689
+ return;
27690
+ }
27691
+ function enclosingName(node) {
27692
+ const parts = [];
27693
+ for (let current = node.parent;current; current = current.parent) {
27694
+ if ((import_typescript12.default.isFunctionDeclaration(current) || import_typescript12.default.isMethodDeclaration(current)) && current.name && parts.length === 0) {
27695
+ parts.unshift(propertyNameText(current.name) ?? "");
27696
+ } else if (import_typescript12.default.isVariableDeclaration(current) && import_typescript12.default.isIdentifier(current.name) && parts.length === 0) {
27697
+ parts.unshift(current.name.text);
27698
+ } else if (import_typescript12.default.isClassLike(current) && current.name) {
27699
+ parts.unshift(current.name.text);
27700
+ break;
27701
+ }
27702
+ }
27703
+ const joined = parts.filter(Boolean).join(".");
27704
+ return joined || undefined;
27705
+ }
27706
+ function isSchemaProperty(object) {
27707
+ const parent = object.parent;
27708
+ if (!parent || !import_typescript12.default.isPropertyAssignment(parent))
27709
+ return false;
27710
+ const holder = parent.parent;
27711
+ return import_typescript12.default.isObjectLiteralExpression(holder) && import_typescript12.default.isPropertyAssignment(holder.parent) && propertyNameText(holder.parent.name) === "properties";
27712
+ }
27713
+ function isToolValue(expression, checker, depth = 0) {
27714
+ const value = unwrap(expression);
27715
+ if (import_typescript12.default.isCallExpression(value)) {
27716
+ const callee = unwrap(value.expression);
27717
+ const name = import_typescript12.default.isIdentifier(callee) ? callee : import_typescript12.default.isPropertyAccessExpression(callee) ? callee.name : undefined;
27718
+ if (!name)
27719
+ return false;
27720
+ if (TOOL_FACTORY.test(name.text))
27721
+ return true;
27722
+ if (import_typescript12.default.isIdentifier(callee)) {
27723
+ const origin = importOrigin(callee, checker);
27724
+ if (origin && TOOL_MODULE.test(origin.module) && /tool/i.test(origin.imported))
27725
+ return true;
27726
+ }
27727
+ return false;
27728
+ }
27729
+ if (import_typescript12.default.isObjectLiteralExpression(value)) {
27730
+ const keys = value.properties.map((property) => propertyNameText(property.name) ?? "");
27731
+ return SCHEMA_KEYS.some((key) => keys.includes(key)) && TOOL_BODY_KEYS.some((key) => keys.includes(key)) && keys.includes("description") && !keys.includes("name");
27732
+ }
27733
+ if (import_typescript12.default.isIdentifier(value) && depth < 2) {
27734
+ const declaration = valueDeclaration(resolvedSymbol(value, checker));
27735
+ if (declaration && import_typescript12.default.isVariableDeclaration(declaration) && declaration.initializer && declaration.parent.flags & import_typescript12.default.NodeFlags.Const) {
27736
+ return isToolValue(declaration.initializer, checker, depth + 1);
27737
+ }
27738
+ }
27739
+ return false;
27740
+ }
27741
+ var emitted = new WeakMap;
27742
+ function emitToolsCached(result, ctx) {
27743
+ let tools = emitted.get(result);
27744
+ if (!tools) {
27745
+ tools = emitTools(result, ctx);
27746
+ emitted.set(result, tools);
27747
+ }
27748
+ return tools;
27749
+ }
27750
+ function toolArtifactId(name, pkg) {
27751
+ const slug2 = (text) => text.replace(/[^A-Za-z0-9_.:-]+/g, "_");
27752
+ return `tool.extract.${slug2(name)}`;
27753
+ }
27754
+ function workspacePackages(rootDir) {
27755
+ const cache2 = new Map;
27756
+ const lookup = (dir) => {
27757
+ if (dir === "" || dir === ".")
27758
+ return "";
27759
+ const cached = cache2.get(dir);
27760
+ if (cached !== undefined)
27761
+ return cached;
27762
+ const found = existsSync9(join14(rootDir, dir, "package.json")) ? dir : lookup(posix3.dirname(dir) === "." ? "" : posix3.dirname(dir));
27763
+ cache2.set(dir, found);
27764
+ return found;
27765
+ };
27766
+ return (rel2) => lookup(posix3.dirname(rel2) === "." ? "" : posix3.dirname(rel2));
27767
+ }
27768
+ function toolDefinitionRefs(tools) {
27769
+ const out = [];
27770
+ for (const tool of tools) {
27771
+ const definition = tool.definitions[0];
27772
+ if (!definition)
27773
+ continue;
27774
+ out.push({
27775
+ toolId: toolArtifactId(tool.name, tool.package),
27776
+ name: tool.name,
27777
+ definition: { path: definition.path, start: definition.start, end: definition.end, line: definition.line },
27778
+ ...tool.agents.length > 0 ? { agentIds: [...tool.agents] } : {},
27779
+ scope: definition.scope
27780
+ });
27781
+ }
27782
+ return out;
27783
+ }
27784
+ function toolArtifacts(tools, runtimeAgents = []) {
27785
+ const knownIds = new Set(runtimeAgents.map((agent2) => agent2.id));
27786
+ return tools.map((tool) => {
27787
+ const usedByAgentIds = [...new Set(tool.agents.filter((id) => knownIds.has(id)))];
27788
+ const artifact2 = {
27789
+ id: toolArtifactId(tool.name, tool.package),
27790
+ type: "tool",
27791
+ name: tool.name,
27792
+ status: tool.status,
27793
+ scope: usedByAgentIds.length === 1 ? "agent" : "shared",
27794
+ ...tool.definitions[0] ? { sourcePath: tool.definitions[0].path } : {},
27795
+ ...tool.definitions[0] ? { body: tool.definitions[0].body } : {},
27796
+ ...tool.definitions.length > 1 ? { definitionVariants: tool.definitions.map((definition) => ({ sourcePath: definition.path, body: definition.body, evidence: [{ path: definition.path, line: definition.line }] })) } : {},
27797
+ usedByAgentIds,
27798
+ confidence: 0.9,
27799
+ confidenceReason: `Deterministic: model-facing tool name read from ${tool.via === "tools-arg" ? "a traced tools argument" : "its definition"} (call-site extractor).`,
27800
+ evidence: tool.evidence.map((entry) => ({ path: entry.path, line: entry.line, reason: entry.reason })),
27801
+ calledFrom: tool.calledFrom,
27802
+ agentClasses: [...tool.agents],
27803
+ ...tool.displayName ? { displayName: tool.displayName } : {}
27804
+ };
27805
+ return artifact2;
27806
+ });
27807
+ }
27808
+
27809
+ // src/harness-extract/types.ts
27810
+ var EXTRACT_SCHEMA_VERSION = 1;
27811
+
27812
+ // src/harness-extract/index.ts
27813
+ var PROMPT_ROLES = new Set(["system", "user", "messages", "prompt", "instructions", "questions"]);
27814
+ var MAX_HELPER_CALLERS = 200;
27815
+ var MAX_DERIVED = 5000;
27816
+ var MAX_CALLER_CHAIN = 3;
27817
+ var cache2 = new Map;
27818
+ function clearExtractCache() {
27819
+ cache2.clear();
27820
+ }
27821
+ function extractHarness(rootDir, options = {}) {
27822
+ return extractHarnessWithContext(rootDir, options).result;
27823
+ }
27824
+ function extractHarnessWithContext(rootDir, options = {}) {
27825
+ const root = resolve13(rootDir);
27826
+ const { fresh, ...rest } = options;
27827
+ const key = `${root}\x00${JSON.stringify(rest)}`;
27828
+ const fingerprint = sourceFingerprint(root, rest);
27829
+ const cached = fresh ? undefined : cache2.get(key);
27830
+ if (cached && cached.fingerprint === fingerprint)
27831
+ return cached.output;
27832
+ const output = runExtract(root, options);
27833
+ cache2.set(key, { output, fingerprint });
27834
+ return output;
27835
+ }
27836
+ function argRef(rootDir, node, key) {
27837
+ const source = node.getSourceFile();
27838
+ const ref = { path: relPath(rootDir, source.fileName), start: node.getStart(source), end: node.getEnd(), line: lineOf(node) };
27839
+ if (key !== undefined)
27840
+ ref.key = key;
27841
+ Object.defineProperty(ref, "node", { value: node, enumerable: false });
27842
+ return ref;
27843
+ }
27844
+ function namedEnclosingFunction(node) {
27845
+ for (let fn = enclosingFunction(node);fn; fn = enclosingFunction(fn)) {
27846
+ const name = functionName(fn);
27847
+ if (name)
27848
+ return { fn, name };
27849
+ }
27850
+ return;
27851
+ }
27852
+ function qualifiedName(fn, name) {
27853
+ const cls = enclosingClass(fn);
27854
+ const owner = cls && (fn.parent === cls || fn.parent && fn.parent.parent === cls) ? className(cls) : undefined;
27855
+ return owner ? `${owner}.${name}` : name;
27856
+ }
27857
+ function functionScope(rootDir, fn, name) {
27858
+ const parts = [qualifiedName(fn, name)];
27859
+ const object = objectLiteralOf2(fn);
27860
+ if (object) {
27861
+ const holder = object.parent && import_typescript13.default.isVariableDeclaration(object.parent) && import_typescript13.default.isIdentifier(object.parent.name) ? object.parent.name.text : `L${lineOf(object)}`;
27862
+ parts.unshift(holder);
27863
+ }
27864
+ for (let outer = namedEnclosingFunction(object ?? fn);outer; outer = namedEnclosingFunction(outer.fn))
27865
+ parts.unshift(qualifiedName(outer.fn, outer.name));
27866
+ return `${relPath(rootDir, fn.getSourceFile().fileName)}#${parts.join(".")}`;
27867
+ }
27868
+ function objectLiteralOf2(fn) {
27869
+ const member2 = import_typescript13.default.isMethodDeclaration(fn) || import_typescript13.default.isGetAccessorDeclaration(fn) || import_typescript13.default.isSetAccessorDeclaration(fn) ? fn : import_typescript13.default.isPropertyAssignment(fn.parent) ? fn.parent : undefined;
27870
+ return member2 && import_typescript13.default.isObjectLiteralExpression(member2.parent) ? member2.parent : undefined;
27871
+ }
27872
+ function scopeOf(rootDir, node) {
27873
+ const named = namedEnclosingFunction(node);
27874
+ if (named)
27875
+ return functionScope(rootDir, named.fn, named.name);
27876
+ const path = relPath(rootDir, node.getSourceFile().fileName);
27877
+ let outermost;
27878
+ for (let fn = enclosingFunction(node);fn; fn = enclosingFunction(fn))
27879
+ outermost = fn;
26803
27880
  return outermost ? `${path}#L${lineOf(outermost)}` : path;
26804
27881
  }
26805
27882
  function callerChain(rootDir, anchor, calls, memo) {
@@ -26828,15 +27905,15 @@ function findAgentClasses(program, checker, memo) {
26828
27905
  for (const source of program.getSourceFiles()) {
26829
27906
  if (source.isDeclarationFile || /[\\/]node_modules[\\/]/.test(source.fileName))
26830
27907
  continue;
26831
- const visit = (node) => {
26832
- if ((import_typescript10.default.isClassDeclaration(node) || import_typescript10.default.isClassExpression(node)) && node.heritageClauses) {
27908
+ const visit2 = (node) => {
27909
+ if ((import_typescript13.default.isClassDeclaration(node) || import_typescript13.default.isClassExpression(node)) && node.heritageClauses) {
26833
27910
  const base = frameworkBaseOf(node, checker, memo).base;
26834
27911
  if (base && AGENT_CLASS_BASES.has(base))
26835
27912
  out.push(node);
26836
27913
  }
26837
- import_typescript10.default.forEachChild(node, visit);
27914
+ import_typescript13.default.forEachChild(node, visit2);
26838
27915
  };
26839
- visit(source);
27916
+ visit2(source);
26840
27917
  }
26841
27918
  return out;
26842
27919
  }
@@ -26878,35 +27955,35 @@ function siteFields(sources, rootDir) {
26878
27955
  return out;
26879
27956
  }
26880
27957
  function paramFlow(node, fn, checker, hops = 0) {
26881
- if (!import_typescript10.default.isExpression(node) || hops > 2)
27958
+ if (!import_typescript13.default.isExpression(node) || hops > 2)
26882
27959
  return;
26883
27960
  const expr = unwrap(node);
26884
- if (import_typescript10.default.isBinaryExpression(expr) && (expr.operatorToken.kind === import_typescript10.default.SyntaxKind.QuestionQuestionToken || expr.operatorToken.kind === import_typescript10.default.SyntaxKind.BarBarToken)) {
27961
+ if (import_typescript13.default.isBinaryExpression(expr) && (expr.operatorToken.kind === import_typescript13.default.SyntaxKind.QuestionQuestionToken || expr.operatorToken.kind === import_typescript13.default.SyntaxKind.BarBarToken)) {
26885
27962
  return paramFlow(expr.left, fn, checker, hops);
26886
27963
  }
26887
- if (import_typescript10.default.isPropertyAccessExpression(expr) && import_typescript10.default.isIdentifier(unwrap(expr.expression))) {
27964
+ if (import_typescript13.default.isPropertyAccessExpression(expr) && import_typescript13.default.isIdentifier(unwrap(expr.expression))) {
26888
27965
  const inner = paramFlow(expr.expression, fn, checker, hops);
26889
27966
  return inner && inner.key === undefined ? { param: inner.param, key: expr.name.text } : undefined;
26890
27967
  }
26891
- if (!import_typescript10.default.isIdentifier(expr))
27968
+ if (!import_typescript13.default.isIdentifier(expr))
26892
27969
  return;
26893
27970
  const declaration = valueDeclaration(resolvedSymbol(expr, checker));
26894
27971
  if (!declaration)
26895
27972
  return;
26896
- if (import_typescript10.default.isParameter(declaration) && declaration.parent === fn && !declaration.dotDotDotToken)
27973
+ if (import_typescript13.default.isParameter(declaration) && declaration.parent === fn && !declaration.dotDotDotToken)
26897
27974
  return { param: declaration };
26898
- if (import_typescript10.default.isBindingElement(declaration) && import_typescript10.default.isObjectBindingPattern(declaration.parent) && import_typescript10.default.isParameter(declaration.parent.parent) && declaration.parent.parent.parent === fn && !declaration.dotDotDotToken) {
27975
+ if (import_typescript13.default.isBindingElement(declaration) && import_typescript13.default.isObjectBindingPattern(declaration.parent) && import_typescript13.default.isParameter(declaration.parent.parent) && declaration.parent.parent.parent === fn && !declaration.dotDotDotToken) {
26899
27976
  const key = propertyNameText(declaration.propertyName ?? declaration.name);
26900
27977
  return key ? { param: declaration.parent.parent, key } : undefined;
26901
27978
  }
26902
- if (import_typescript10.default.isVariableDeclaration(declaration) && declaration.initializer && enclosingFunction(declaration) === fn && declaration.parent.flags & import_typescript10.default.NodeFlags.Const) {
27979
+ if (import_typescript13.default.isVariableDeclaration(declaration) && declaration.initializer && enclosingFunction(declaration) === fn && declaration.parent.flags & import_typescript13.default.NodeFlags.Const) {
26903
27980
  return paramFlow(declaration.initializer, fn, checker, hops + 1);
26904
27981
  }
26905
27982
  return;
26906
27983
  }
26907
27984
  function roleParamFlow(arg, fn, checker) {
26908
27985
  const object = unwrap(arg.node);
26909
- if (arg.key !== undefined && !arg.key.includes(".") && import_typescript10.default.isObjectLiteralExpression(object)) {
27986
+ if (arg.key !== undefined && !arg.key.includes(".") && import_typescript13.default.isObjectLiteralExpression(object)) {
26910
27987
  const value = propertyValue(object, arg.key);
26911
27988
  const flow = value ? paramFlow(value, fn, checker) : undefined;
26912
27989
  return flow ? { ...flow, viaProperty: true } : undefined;
@@ -26918,9 +27995,9 @@ function descendArg(argument, path) {
26918
27995
  let index = 0;
26919
27996
  for (;index < path.length; index += 1) {
26920
27997
  let value = unwrap(node);
26921
- if (import_typescript10.default.isCallExpression(value) && value.expression.getText() === "JSON.stringify" && value.arguments[0])
27998
+ if (import_typescript13.default.isCallExpression(value) && value.expression.getText() === "JSON.stringify" && value.arguments[0])
26922
27999
  value = unwrap(value.arguments[0]);
26923
- const next = import_typescript10.default.isObjectLiteralExpression(value) ? propertyValue(value, path[index]) : undefined;
28000
+ const next = import_typescript13.default.isObjectLiteralExpression(value) ? propertyValue(value, path[index]) : undefined;
26924
28001
  if (!next)
26925
28002
  break;
26926
28003
  node = next;
@@ -26997,8 +28074,8 @@ function runExtract(rootDir, options) {
26997
28074
  };
26998
28075
  sites.push({ site, entry, anchor, sources, level: 0 });
26999
28076
  };
27000
- const visit = (node) => {
27001
- if (import_typescript10.default.isCallExpression(node) || import_typescript10.default.isNewExpression(node)) {
28077
+ const visit2 = (node) => {
28078
+ if (import_typescript13.default.isCallExpression(node) || import_typescript13.default.isNewExpression(node)) {
27002
28079
  for (const recognizer of CALL_SINKS) {
27003
28080
  let match;
27004
28081
  const begin = performance.now();
@@ -27013,7 +28090,7 @@ function runExtract(rootDir, options) {
27013
28090
  break;
27014
28091
  }
27015
28092
  }
27016
- } else if (import_typescript10.default.isClassDeclaration(node) || import_typescript10.default.isClassExpression(node)) {
28093
+ } else if (import_typescript13.default.isClassDeclaration(node) || import_typescript13.default.isClassExpression(node)) {
27017
28094
  for (const recognizer of classRecognizers) {
27018
28095
  try {
27019
28096
  for (const match of recognizer.match(node, ctx2))
@@ -27023,9 +28100,9 @@ function runExtract(rootDir, options) {
27023
28100
  }
27024
28101
  }
27025
28102
  }
27026
- import_typescript10.default.forEachChild(node, visit);
28103
+ import_typescript13.default.forEachChild(node, visit2);
27027
28104
  };
27028
- visit(source);
28105
+ visit2(source);
27029
28106
  }
27030
28107
  } catch (error) {
27031
28108
  warnings.push(`sinks ${entry.configPath ?? "(fallback)"}: ${error.message}`);
@@ -27075,7 +28152,7 @@ function runExtract(rootDir, options) {
27075
28152
  const sources = [];
27076
28153
  for (const { source: role, flow } of flowing) {
27077
28154
  const argument = call.arguments[named.fn.parameters.indexOf(flow.param)];
27078
- if (!argument || import_typescript10.default.isSpreadElement(argument))
28155
+ if (!argument || import_typescript13.default.isSpreadElement(argument))
27079
28156
  continue;
27080
28157
  const arg = descendArg(argument, [flow.key, flow.viaProperty ? undefined : role.arg.key].filter((part) => Boolean(part)));
27081
28158
  sources.push({ ...role, bindings: extendBindings(role.bindings, callerBindings), arg });
@@ -27204,11 +28281,21 @@ function runExtract(rootDir, options) {
27204
28281
  timings.models = Date.now() - begin;
27205
28282
  result.durationMs = Date.now() - started;
27206
28283
  }
28284
+ if (options.tools ?? true) {
28285
+ const begin = Date.now();
28286
+ try {
28287
+ result.toolDefinitions = toolDefinitionRefs(emitToolsCached(result, ctx));
28288
+ } catch (error) {
28289
+ warnings.push(`tools: ${error.message}`);
28290
+ }
28291
+ timings.tools = Date.now() - begin;
28292
+ result.durationMs = Date.now() - started;
28293
+ }
27207
28294
  return { result, ctx };
27208
28295
  }
27209
28296
  function nodeSpanning(source, start, end) {
27210
28297
  let best;
27211
- const visit = (node) => {
28298
+ const visit2 = (node) => {
27212
28299
  const nodeStart = node.getStart(source);
27213
28300
  if (nodeStart > start || node.getEnd() < end)
27214
28301
  return;
@@ -27217,9 +28304,9 @@ function nodeSpanning(source, start, end) {
27217
28304
  return;
27218
28305
  }
27219
28306
  best = node;
27220
- import_typescript10.default.forEachChild(node, visit);
28307
+ import_typescript13.default.forEachChild(node, visit2);
27221
28308
  };
27222
- visit(source);
28309
+ visit2(source);
27223
28310
  return best;
27224
28311
  }
27225
28312
  function serializeExtractResult(result) {
@@ -27263,114 +28350,6 @@ function assignAgentIds(result, agentForScope) {
27263
28350
  }
27264
28351
  }
27265
28352
 
27266
- // src/harness-extract/enumerators/common.ts
27267
- var import_typescript11 = __toESM(require_typescript(), 1);
27268
- import { readdirSync as readdirSync8, readFileSync as readFileSync15 } from "node:fs";
27269
- import { dirname as dirname10, join as join13, posix as posix2, relative as relative10 } from "node:path";
27270
- var cache2 = new WeakMap;
27271
- var SKIP = new Set(["node_modules", "dist", "build", "out", "vendor", "coverage", "__pycache__"]);
27272
- var TEST_PATH4 = /(?:^|\/)(?:test|tests|__tests__|test-fixtures|fixtures?|__fixtures__|__mocks__|e2e)\/|\.(?:test|spec)\.[cm]?[jt]sx?$/i;
27273
- var EVAL_PATH2 = /(?:^|\/)evals?\/|\.evals?\.[cm]?[jt]sx?$/i;
27274
- function enumerationRepository(ctx) {
27275
- const existing = cache2.get(ctx);
27276
- if (existing)
27277
- return existing;
27278
- const files = [];
27279
- const walk = (dir) => {
27280
- for (const entry of readdirSync8(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
27281
- const abs = join13(dir, entry.name);
27282
- if (entry.isDirectory()) {
27283
- if (!entry.name.startsWith(".") && !SKIP.has(entry.name))
27284
- walk(abs);
27285
- } else if (entry.isFile() && /\.(?:[cm]?[jt]sx?|py|jsonc?|toml)$/.test(entry.name) && !/\.d\.[cm]?ts$/.test(entry.name)) {
27286
- const path = relative10(ctx.rootDir, abs).split("\\").join("/");
27287
- try {
27288
- const text = readFileSync15(abs, "utf8");
27289
- if (text.length > 1024 * 1024)
27290
- continue;
27291
- const source = ctx.programFor(path)?.getSourceFile(abs) ?? import_typescript11.default.createSourceFile(abs, text, import_typescript11.default.ScriptTarget.Latest, true, path.endsWith("tsx") ? import_typescript11.default.ScriptKind.TSX : import_typescript11.default.ScriptKind.TS);
27292
- files.push({ path, text, source });
27293
- } catch {}
27294
- }
27295
- }
27296
- };
27297
- walk(ctx.rootDir);
27298
- const workers = [];
27299
- const paths = new Set(files.map((file) => file.path));
27300
- const closure = (main) => {
27301
- const found = new Set, pending = [main];
27302
- for (let index = 0;index < pending.length; index++) {
27303
- const path = pending[index];
27304
- if (found.has(path))
27305
- continue;
27306
- found.add(path);
27307
- const file = files.find((entry) => entry.path === path);
27308
- if (!file)
27309
- continue;
27310
- for (const ref of import_typescript11.default.preProcessFile(file.text, true, true).importedFiles) {
27311
- if (!ref.fileName.startsWith("."))
27312
- continue;
27313
- const base = posix2.normalize(posix2.join(posix2.dirname(path), ref.fileName)).replace(/\.[cm]?js$/, "");
27314
- const target = [base, ...[".ts", ".tsx", ".js", ".mjs", "/index.ts", "/index.js"].map((suffix) => base + suffix)].find((candidate) => paths.has(candidate));
27315
- if (target)
27316
- pending.push(target);
27317
- }
27318
- }
27319
- return found;
27320
- };
27321
- for (const file of files)
27322
- if (/(?:^|\/)wrangler(?:\.[\w.-]+)?\.(?:jsonc?|toml)$/.test(file.path)) {
27323
- try {
27324
- const config2 = file.path.endsWith(".toml") ? parse(file.text) : JSON.parse(stripJsonc(file.text));
27325
- const variants = [["default", config2], ...Object.entries(config2.env ?? {}).map(([name, section]) => [name, { ...config2, ...section, queues: section.queues, workflows: section.workflows }])];
27326
- for (const [environment, section] of variants) {
27327
- if (typeof section.main !== "string" || isTestWorkerConfig({ path: file.path, name: section.name, mains: [section.main] }))
27328
- continue;
27329
- const main = posix2.normalize(posix2.join(dirname10(file.path), section.main));
27330
- workers.push({ id: `${file.path}#${environment}`, main, cron: Boolean(section.triggers?.crons?.length), queueBindings: new Set((section.queues?.producers ?? []).flatMap((producer) => typeof producer.binding === "string" ? [producer.binding] : [])), workflowClasses: (section.workflows ?? []).flatMap((binding) => typeof binding.class_name === "string" && !binding.script_name ? [binding.class_name] : []), files: closure(main) });
27331
- }
27332
- } catch {}
27333
- }
27334
- const queueBindingsFor = (path) => {
27335
- const owners = workers.filter((worker) => worker.files.has(path));
27336
- return new Set(owners[0] ? [...owners[0].queueBindings].filter((binding) => owners.every((worker) => worker.queueBindings.has(binding))) : []);
27337
- };
27338
- const reach = buildImportGraphReachability(ctx.rootDir);
27339
- const repo = { files, workers, queueBindingsFor, cronEntrypoints: new Set(workers.filter((worker) => worker.cron).map((worker) => worker.main)), deployedFiles: reach.inProd, status: (path) => reach.inProd.has(path) || reach.reachable.has(path) ? "reachable" : "defined_only" };
27340
- cache2.set(ctx, repo);
27341
- return repo;
27342
- }
27343
- function lineOf5(node) {
27344
- return node.getSourceFile().getLineAndCharacterOfPosition(node.getStart()).line + 1;
27345
- }
27346
- function nameOf(node) {
27347
- if (!node)
27348
- return;
27349
- if (import_typescript11.default.isComputedPropertyName(node) && import_typescript11.default.isStringLiteralLike(node.expression))
27350
- return node.expression.text;
27351
- return import_typescript11.default.isIdentifier(node) || import_typescript11.default.isStringLiteralLike(node) || import_typescript11.default.isNumericLiteral(node) ? node.text : undefined;
27352
- }
27353
- function visit(node, fn) {
27354
- fn(node);
27355
- import_typescript11.default.forEachChild(node, (child) => visit(child, fn));
27356
- }
27357
- function componentId(kind, path, name) {
27358
- return `${kind}:${path}:${name}`;
27359
- }
27360
- function artifact(type, name, file, node, reason, status) {
27361
- return { id: componentId(type, file.path, name), type, name, scope: "shared", sourcePath: file.path, usedByAgentIds: [], confidence: 1, evidence: [{ path: file.path, line: lineOf5(node), reason }], status };
27362
- }
27363
- function agent(name, file, node, reason, status) {
27364
- return { id: componentId("agent", file.path, name), name, kind: "runtime_agent", root: ".", entrypointIds: [], channelAdapterIds: [], artifactIds: [], identityNamespaceIds: [], deploymentIds: [], frameworkIds: [], modelProviderIds: [], confidence: 1, evidence: [{ path: file.path, line: lineOf5(node), reason }], status };
27365
- }
27366
- function emptyResult() {
27367
- return { runtimeAgents: [], artifacts: [], warnings: [] };
27368
- }
27369
- function stableResult(result) {
27370
- const unique2 = (values) => [...new Map(values.map((x) => [x.id, x])).values()].sort((a, b) => a.id.localeCompare(b.id));
27371
- return { runtimeAgents: unique2(result.runtimeAgents), artifacts: unique2(result.artifacts), warnings: [...new Set(result.warnings)].sort() };
27372
- }
27373
-
27374
28353
  // src/harness-extract/enumerators/agents.ts
27375
28354
  function agentForScope(scope, enumeration) {
27376
28355
  return enumeration.agentForScope(scope);
@@ -27379,15 +28358,15 @@ function createAgentScopeResolver(result, ctx) {
27379
28358
  return enumerateAgents(result, ctx).agentForScope;
27380
28359
  }
27381
28360
  var enumerations = new WeakMap;
27382
- var AGENT_BASES3 = new Set(["Think", "Agent", "AIChatAgent", "McpAgent"]);
28361
+ var AGENT_BASES4 = new Set(["Think", "Agent", "AIChatAgent", "McpAgent"]);
27383
28362
  var HTTP_METHODS2 = new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"]);
27384
28363
  function routeOf(fn, file) {
27385
28364
  const name = functionName(fn);
27386
28365
  if (name && HTTP_METHODS2.has(name) && /(?:^|\/)(?:route|\+server)\.[cm]?[jt]sx?$/.test(file.path))
27387
28366
  return `${name} ${file.path}`;
27388
28367
  const parent = fn.parent;
27389
- if (parent && import_typescript12.default.isCallExpression(parent) && import_typescript12.default.isPropertyAccessExpression(parent.expression) && /^(get|post|put|patch|delete|all|on)$/.test(parent.expression.name.text)) {
27390
- const path = parent.arguments.find(import_typescript12.default.isStringLiteralLike);
28368
+ if (parent && import_typescript14.default.isCallExpression(parent) && import_typescript14.default.isPropertyAccessExpression(parent.expression) && /^(get|post|put|patch|delete|all|on)$/.test(parent.expression.name.text)) {
28369
+ const path = parent.arguments.find(import_typescript14.default.isStringLiteralLike);
27391
28370
  if (path)
27392
28371
  return `${parent.expression.name.text.toUpperCase()} ${path.text} (${file.path})`;
27393
28372
  }
@@ -27409,19 +28388,19 @@ function enumerateAgents(result, ctx) {
27409
28388
  continue;
27410
28389
  const checker = ctx.checkerFor(file.path);
27411
28390
  visit(file.source, (node) => {
27412
- if ((import_typescript12.default.isClassDeclaration(node) || import_typescript12.default.isClassExpression(node)) && node.name) {
28391
+ if ((import_typescript14.default.isClassDeclaration(node) || import_typescript14.default.isClassExpression(node)) && node.name) {
27413
28392
  const name2 = node.name.text;
27414
28393
  const info = checker ? frameworkBaseOf(node, checker, memo) : undefined;
27415
28394
  const directBase = node.heritageClauses?.flatMap((h) => h.types).map((x) => x.expression.getText()) ?? [];
27416
28395
  const protocolEvents = new Set;
27417
28396
  visit(node, (member2) => {
27418
- if (import_typescript12.default.isStringLiteralLike(member2))
28397
+ if (import_typescript14.default.isStringLiteralLike(member2))
27419
28398
  protocolEvents.add(member2.text);
27420
28399
  });
27421
28400
  const realtime = protocolEvents.has("session.update") && protocolEvents.has("response.create") && [...protocolEvents].some((event) => event.includes("function_call"));
27422
- const exported = import_typescript12.default.getCombinedModifierFlags(node) & import_typescript12.default.ModifierFlags.Export;
27423
- const abstract = import_typescript12.default.getCombinedModifierFlags(node) & import_typescript12.default.ModifierFlags.Abstract;
27424
- if (!abstract && (exported || bound.has(name2)) && (info?.base && AGENT_BASES3.has(info.base) || directBase.some((x) => AGENT_BASES3.has(x)) || exported && realtime)) {
28401
+ const exported = import_typescript14.default.getCombinedModifierFlags(node) & import_typescript14.default.ModifierFlags.Export;
28402
+ const abstract = import_typescript14.default.getCombinedModifierFlags(node) & import_typescript14.default.ModifierFlags.Abstract;
28403
+ if (!abstract && (exported || bound.has(name2)) && (info?.base && AGENT_BASES4.has(info.base) || directBase.some((x) => AGENT_BASES4.has(x)) || exported && realtime)) {
27425
28404
  classes.push({ file, node, name: name2, chain: info?.chain ?? [name2, ...directBase] });
27426
28405
  }
27427
28406
  }
@@ -27458,10 +28437,10 @@ function enumerateAgents(result, ctx) {
27458
28437
  };
27459
28438
  if (name) {
27460
28439
  const parts = [qualified(node, name)];
27461
- const member2 = import_typescript12.default.isMethodDeclaration(node) || import_typescript12.default.isGetAccessorDeclaration(node) || import_typescript12.default.isSetAccessorDeclaration(node) ? node : import_typescript12.default.isPropertyAssignment(node.parent) ? node.parent : undefined;
27462
- const object = member2 && import_typescript12.default.isObjectLiteralExpression(member2.parent) ? member2.parent : undefined;
28440
+ const member2 = import_typescript14.default.isMethodDeclaration(node) || import_typescript14.default.isGetAccessorDeclaration(node) || import_typescript14.default.isSetAccessorDeclaration(node) ? node : import_typescript14.default.isPropertyAssignment(node.parent) ? node.parent : undefined;
28441
+ const object = member2 && import_typescript14.default.isObjectLiteralExpression(member2.parent) ? member2.parent : undefined;
27463
28442
  if (object)
27464
- parts.unshift(import_typescript12.default.isVariableDeclaration(object.parent) && import_typescript12.default.isIdentifier(object.parent.name) ? object.parent.name.text : `L${lineOf5(object)}`);
28443
+ parts.unshift(import_typescript14.default.isVariableDeclaration(object.parent) && import_typescript14.default.isIdentifier(object.parent.name) ? object.parent.name.text : `L${lineOf5(object)}`);
27465
28444
  for (let outer = (object ?? node).parent;outer; outer = outer.parent) {
27466
28445
  if (isFunctionLike(outer)) {
27467
28446
  const outerName = functionName(outer);
@@ -27483,7 +28462,7 @@ function enumerateAgents(result, ctx) {
27483
28462
  const checker = ctx.checkerFor(node.getSourceFile().fileName.slice(ctx.rootDir.length + 1));
27484
28463
  const bases = node.heritageClauses?.flatMap((clause) => clause.types).flatMap((base) => {
27485
28464
  const declaration = checker && valueDeclaration(resolvedSymbol(base.expression, checker));
27486
- return declaration && import_typescript12.default.isClassLike(declaration) ? classChain(declaration, seen) : [];
28465
+ return declaration && import_typescript14.default.isClassLike(declaration) ? classChain(declaration, seen) : [];
27487
28466
  }) ?? [];
27488
28467
  return [node, ...bases];
27489
28468
  };
@@ -27499,32 +28478,32 @@ function enumerateAgents(result, ctx) {
27499
28478
  return;
27500
28479
  };
27501
28480
  const bindingTruth = (condition, worker) => {
27502
- if (condition.kind === import_typescript12.default.SyntaxKind.TrueKeyword)
28481
+ if (condition.kind === import_typescript14.default.SyntaxKind.TrueKeyword)
27503
28482
  return true;
27504
- if (condition.kind === import_typescript12.default.SyntaxKind.FalseKeyword)
28483
+ if (condition.kind === import_typescript14.default.SyntaxKind.FalseKeyword)
27505
28484
  return false;
27506
- if (import_typescript12.default.isPrefixUnaryExpression(condition) && condition.operator === import_typescript12.default.SyntaxKind.ExclamationToken) {
28485
+ if (import_typescript14.default.isPrefixUnaryExpression(condition) && condition.operator === import_typescript14.default.SyntaxKind.ExclamationToken) {
27507
28486
  const value = bindingTruth(condition.operand, worker);
27508
28487
  return value === undefined ? undefined : !value;
27509
28488
  }
27510
- if (import_typescript12.default.isPropertyAccessExpression(condition) && /^(?:this\.)?env$/.test(condition.expression.getText()) && (worker ? repo.workers.find((entry) => entry.id === worker)?.queueBindings : repo.queueBindingsFor(condition.getSourceFile().fileName.slice(ctx.rootDir.length + 1)))?.has(condition.name.text))
28489
+ if (import_typescript14.default.isPropertyAccessExpression(condition) && /^(?:this\.)?env$/.test(condition.expression.getText()) && (worker ? repo.workers.find((entry) => entry.id === worker)?.queueBindings : repo.queueBindingsFor(condition.getSourceFile().fileName.slice(ctx.rootDir.length + 1)))?.has(condition.name.text))
27511
28490
  return true;
27512
28491
  return;
27513
28492
  };
27514
- const returns = (node) => Boolean(node && (import_typescript12.default.isReturnStatement(node) || import_typescript12.default.isBlock(node) && node.statements.length && import_typescript12.default.isReturnStatement(node.statements[node.statements.length - 1])));
28493
+ const returns = (node) => Boolean(node && (import_typescript14.default.isReturnStatement(node) || import_typescript14.default.isBlock(node) && node.statements.length && import_typescript14.default.isReturnStatement(node.statements[node.statements.length - 1])));
27515
28494
  const deployed = (node, worker) => {
27516
28495
  for (let current = node;current.parent; current = current.parent) {
27517
28496
  const parent = current.parent;
27518
- if (import_typescript12.default.isIfStatement(parent)) {
28497
+ if (import_typescript14.default.isIfStatement(parent)) {
27519
28498
  const truth = bindingTruth(parent.expression, worker);
27520
28499
  if (truth !== undefined && (current === parent.thenStatement ? !truth : current === parent.elseStatement ? truth : false))
27521
28500
  return false;
27522
28501
  }
27523
- if (import_typescript12.default.isBlock(parent))
28502
+ if (import_typescript14.default.isBlock(parent))
27524
28503
  for (const prior of parent.statements) {
27525
28504
  if (prior.getStart() >= current.getStart())
27526
28505
  break;
27527
- if (import_typescript12.default.isIfStatement(prior)) {
28506
+ if (import_typescript14.default.isIfStatement(prior)) {
27528
28507
  const truth = bindingTruth(prior.expression, worker);
27529
28508
  if (truth !== undefined && returns(truth ? prior.thenStatement : prior.elseStatement))
27530
28509
  return false;
@@ -27550,7 +28529,7 @@ function enumerateAgents(result, ctx) {
27550
28529
  const descend = (node) => {
27551
28530
  if (node.getStart() <= offset && node.getEnd() >= offset) {
27552
28531
  anchor = node;
27553
- import_typescript12.default.forEachChild(node, descend);
28532
+ import_typescript14.default.forEachChild(node, descend);
27554
28533
  }
27555
28534
  };
27556
28535
  descend(file.source);
@@ -27559,21 +28538,21 @@ function enumerateAgents(result, ctx) {
27559
28538
  continue;
27560
28539
  markModel(scope, anchor);
27561
28540
  const tools = site.toolsArg ? ctx.nodeAt(site.toolsArg) : undefined;
27562
- scope.hasTools ||= Boolean(tools && !(import_typescript12.default.isObjectLiteralExpression(tools) && tools.properties.length === 0) && !(import_typescript12.default.isArrayLiteralExpression(tools) && tools.elements.length === 0));
28541
+ scope.hasTools ||= Boolean(tools && !(import_typescript14.default.isObjectLiteralExpression(tools) && tools.properties.length === 0) && !(import_typescript14.default.isArrayLiteralExpression(tools) && tools.elements.length === 0));
27563
28542
  scope.aliases.push(site.scope);
27564
28543
  }
27565
28544
  const targetsOf = (node, file) => {
27566
28545
  const checker = ctx.checkerFor(file.path);
27567
28546
  if (!checker)
27568
28547
  return [];
27569
- const at = import_typescript12.default.isPropertyAccessExpression(node) ? node.name : node;
28548
+ const at = import_typescript14.default.isPropertyAccessExpression(node) ? node.name : node;
27570
28549
  const declaration = valueDeclaration(resolvedSymbol(at, checker));
27571
28550
  if (!declaration)
27572
28551
  return [];
27573
28552
  const direct = byNode.get(declaration) ?? scopes.get(keyOf(declaration));
27574
28553
  if (direct)
27575
28554
  return [direct];
27576
- if (import_typescript12.default.isVariableDeclaration(declaration) && declaration.initializer) {
28555
+ if (import_typescript14.default.isVariableDeclaration(declaration) && declaration.initializer) {
27577
28556
  const fn = byNode.get(declaration.initializer) ?? scopes.get(keyOf(declaration.initializer));
27578
28557
  if (fn)
27579
28558
  return [fn];
@@ -27585,19 +28564,19 @@ function enumerateAgents(result, ctx) {
27585
28564
  if (node !== scope.node && isFunctionLike(node)) {
27586
28565
  return;
27587
28566
  }
27588
- if (import_typescript12.default.isWhileStatement(node) || import_typescript12.default.isDoStatement(node) || import_typescript12.default.isForStatement(node) || import_typescript12.default.isForOfStatement(node))
28567
+ if (import_typescript14.default.isWhileStatement(node) || import_typescript14.default.isDoStatement(node) || import_typescript14.default.isForStatement(node) || import_typescript14.default.isForOfStatement(node))
27589
28568
  scope.hasLoop = true;
27590
- if ((import_typescript12.default.isIdentifier(node) || import_typescript12.default.isStringLiteralLike(node)) && /^(?:tool_calls|toolCalls|tool_use|tool_result|tool_results|toolResults)$/.test(node.text)) {
28569
+ if ((import_typescript14.default.isIdentifier(node) || import_typescript14.default.isStringLiteralLike(node)) && /^(?:tool_calls|toolCalls|tool_use|tool_result|tool_results|toolResults)$/.test(node.text)) {
27591
28570
  scope.hasTools = true;
27592
28571
  scope.toolFeedback = true;
27593
28572
  }
27594
- if (import_typescript12.default.isObjectLiteralExpression(node)) {
27595
- const fields = new Map(node.properties.filter(import_typescript12.default.isPropertyAssignment).map((p2) => [nameOf(p2.name), p2.initializer]));
28573
+ if (import_typescript14.default.isObjectLiteralExpression(node)) {
28574
+ const fields = new Map(node.properties.filter(import_typescript14.default.isPropertyAssignment).map((p2) => [nameOf(p2.name), p2.initializer]));
27596
28575
  const type = fields.get("type");
27597
- if (type && import_typescript12.default.isStringLiteralLike(type) && type.text === "tool" && fields.has("name"))
28576
+ if (type && import_typescript14.default.isStringLiteralLike(type) && type.text === "tool" && fields.has("name"))
27598
28577
  scope.forcedOutput = true;
27599
28578
  }
27600
- if (import_typescript12.default.isCallExpression(node) || import_typescript12.default.isNewExpression(node)) {
28579
+ if (import_typescript14.default.isCallExpression(node) || import_typescript14.default.isNewExpression(node)) {
27601
28580
  const callee = node.expression.getText();
27602
28581
  if (/(?:chat\.)?completions\.create$|messages\.(?:create|stream)$|responses\.(?:create|stream)$/.test(callee))
27603
28582
  markModel(scope, node);
@@ -27605,7 +28584,7 @@ function enumerateAgents(result, ctx) {
27605
28584
  markModel(scope, node);
27606
28585
  const connect = (at) => {
27607
28586
  for (const target of byNode.has(at) ? [byNode.get(at)] : targetsOf(at, scope.file)) {
27608
- if (import_typescript12.default.isPropertyAccessExpression(at) && at.expression.kind === import_typescript12.default.SyntaxKind.ThisKeyword) {
28587
+ if (import_typescript14.default.isPropertyAccessExpression(at) && at.expression.kind === import_typescript14.default.SyntaxKind.ThisKeyword) {
27609
28588
  virtualEdges.set(`${scope.key}|${target.key}`, at.name.text);
27610
28589
  scope.virtualCalls.set(target.key, at.name.text);
27611
28590
  }
@@ -27624,30 +28603,30 @@ function enumerateAgents(result, ctx) {
27624
28603
  connect(at);
27625
28604
  return;
27626
28605
  }
27627
- if (import_typescript12.default.isIdentifier(at) || import_typescript12.default.isPropertyAccessExpression(at))
28606
+ if (import_typescript14.default.isIdentifier(at) || import_typescript14.default.isPropertyAccessExpression(at))
27628
28607
  connect(at);
27629
- import_typescript12.default.forEachChild(at, connectArgument);
28608
+ import_typescript14.default.forEachChild(at, connectArgument);
27630
28609
  };
27631
28610
  for (const argument of node.arguments ?? [])
27632
28611
  connectArgument(argument);
27633
28612
  for (const argument of node.arguments ?? [])
27634
- if (import_typescript12.default.isObjectLiteralExpression(argument)) {
28613
+ if (import_typescript14.default.isObjectLiteralExpression(argument)) {
27635
28614
  const fields = new Set(argument.properties.map((p2) => nameOf(p2.name)));
27636
28615
  if (fields.has("model") && fields.has("messages") && fields.has("tools")) {
27637
28616
  markModel(scope, node);
27638
28617
  scope.hasTools = true;
27639
28618
  }
27640
28619
  }
27641
- if (/(?:^|\.)(?:stepCountIs|isStepCount)$/.test(node.expression.getText()) && node.arguments?.[0] && import_typescript12.default.isNumericLiteral(node.arguments?.[0]) && Number(node.arguments?.[0].text) > 1) {
28620
+ if (/(?:^|\.)(?:stepCountIs|isStepCount)$/.test(node.expression.getText()) && node.arguments?.[0] && import_typescript14.default.isNumericLiteral(node.arguments?.[0]) && Number(node.arguments?.[0].text) > 1) {
27642
28621
  scope.hasLoop = true;
27643
28622
  scope.configuredSteps = true;
27644
28623
  }
27645
28624
  }
27646
- if (import_typescript12.default.isPropertyAssignment(node) && nameOf(node.name) === "maxSteps" && import_typescript12.default.isNumericLiteral(node.initializer) && Number(node.initializer.text) > 1) {
28625
+ if (import_typescript14.default.isPropertyAssignment(node) && nameOf(node.name) === "maxSteps" && import_typescript14.default.isNumericLiteral(node.initializer) && Number(node.initializer.text) > 1) {
27647
28626
  scope.hasLoop = true;
27648
28627
  scope.configuredSteps = true;
27649
28628
  }
27650
- import_typescript12.default.forEachChild(node, inspect);
28629
+ import_typescript14.default.forEachChild(node, inspect);
27651
28630
  };
27652
28631
  inspect(scope.node);
27653
28632
  }
@@ -27672,19 +28651,19 @@ function enumerateAgents(result, ctx) {
27672
28651
  values.add(id);
27673
28652
  };
27674
28653
  for (const cls of classes) {
27675
- const emitted = agent(cls.name, cls.file, cls.node, "Concrete agent/framework class or realtime model/tool bridge", repo.status(cls.file.path));
27676
- agents.set(emitted.id, emitted);
28654
+ const emitted2 = agent(cls.name, cls.file, cls.node, "Concrete agent/framework class or realtime model/tool bridge", repo.status(cls.file.path));
28655
+ agents.set(emitted2.id, emitted2);
27677
28656
  }
27678
28657
  for (const scope of scopes.values()) {
27679
28658
  let nestedInFunction = false;
27680
- for (let parent = scope.node.parent;parent && !import_typescript12.default.isClassLike(parent); parent = parent.parent)
28659
+ for (let parent = scope.node.parent;parent && !import_typescript14.default.isClassLike(parent); parent = parent.parent)
27681
28660
  if (isFunctionLike(parent)) {
27682
28661
  nestedInFunction = true;
27683
28662
  break;
27684
28663
  }
27685
28664
  if (scope.className && !nestedInFunction) {
27686
28665
  let member2 = scope.node;
27687
- while (member2.parent && !import_typescript12.default.isClassLike(member2.parent))
28666
+ while (member2.parent && !import_typescript14.default.isClassLike(member2.parent))
27688
28667
  member2 = member2.parent;
27689
28668
  const memberName = "name" in member2 ? nameOf(member2.name) : undefined;
27690
28669
  for (const cls of classes) {
@@ -27709,9 +28688,9 @@ function enumerateAgents(result, ctx) {
27709
28688
  const name = boundary.route ?? functionName(boundary.node);
27710
28689
  if (!name)
27711
28690
  continue;
27712
- const emitted = agent(name, boundary.file, scope.node, "Function or route owns a multi-step model/tool feedback loop", repo.status(boundary.file.path));
27713
- agents.set(emitted.id, emitted);
27714
- assign(boundary.key, emitted.id);
28691
+ const emitted2 = agent(name, boundary.file, scope.node, "Function or route owns a multi-step model/tool feedback loop", repo.status(boundary.file.path));
28692
+ agents.set(emitted2.id, emitted2);
28693
+ assign(boundary.key, emitted2.id);
27715
28694
  }
27716
28695
  }
27717
28696
  let changed = true;
@@ -27778,7 +28757,7 @@ function enumerateAgents(result, ctx) {
27778
28757
  }
27779
28758
 
27780
28759
  // src/harness-extract/enumerators/workflows.ts
27781
- var import_typescript13 = __toESM(require_typescript(), 1);
28760
+ var import_typescript15 = __toESM(require_typescript(), 1);
27782
28761
  function enumerateWorkflows(result, ctx) {
27783
28762
  const output = emptyResult();
27784
28763
  const repo = enumerationRepository(ctx);
@@ -27791,10 +28770,10 @@ function enumerateWorkflows(result, ctx) {
27791
28770
  continue;
27792
28771
  for (const name of worker.workflowClasses) {
27793
28772
  let exported = checker.getExportsOfModule(module).find((symbol) => symbol.name === name);
27794
- if (exported && exported.flags & import_typescript13.default.SymbolFlags.Alias)
28773
+ if (exported && exported.flags & import_typescript15.default.SymbolFlags.Alias)
27795
28774
  exported = checker.getAliasedSymbol(exported);
27796
28775
  const declaration = exported && valueDeclaration(exported);
27797
- if (declaration && import_typescript13.default.isClassDeclaration(declaration))
28776
+ if (declaration && import_typescript15.default.isClassDeclaration(declaration))
27798
28777
  bindings.add(nodeKey(declaration));
27799
28778
  }
27800
28779
  }
@@ -27803,7 +28782,7 @@ function enumerateWorkflows(result, ctx) {
27803
28782
  if (!/\.[cm]?[jt]sx?$/.test(file.path) || TEST_PATH4.test(file.path) || EVAL_PATH2.test(file.path))
27804
28783
  continue;
27805
28784
  visit(file.source, (node) => {
27806
- if (!import_typescript13.default.isClassDeclaration(node) || !node.name || import_typescript13.default.getCombinedModifierFlags(node) & import_typescript13.default.ModifierFlags.Abstract)
28785
+ if (!import_typescript15.default.isClassDeclaration(node) || !node.name || import_typescript15.default.getCombinedModifierFlags(node) & import_typescript15.default.ModifierFlags.Abstract)
27807
28786
  return;
27808
28787
  const checker = ctx.checkerFor(file.path);
27809
28788
  const base = checker ? frameworkBaseOf(node, checker, memo)?.base : undefined;
@@ -27828,7 +28807,7 @@ function enumerateWorkflows(result, ctx) {
27828
28807
  if (!cls || !workerClasses.has(nodeKey(cls)))
27829
28808
  return calls;
27830
28809
  const member2 = scope.node.parent === cls ? scope.node : scope.node.parent;
27831
- if (import_typescript13.default.getCombinedModifierFlags(member2) & import_typescript13.default.ModifierFlags.Static)
28810
+ if (import_typescript15.default.getCombinedModifierFlags(member2) & import_typescript15.default.ModifierFlags.Static)
27832
28811
  return calls;
27833
28812
  return new Set([...calls].map((key) => {
27834
28813
  const method = scope.virtualCalls.get(key);
@@ -27842,24 +28821,24 @@ function enumerateWorkflows(result, ctx) {
27842
28821
  if (!node || visited.has(node))
27843
28822
  return;
27844
28823
  visited.add(node);
27845
- if (import_typescript13.default.isParenthesizedExpression(node) || import_typescript13.default.isAsExpression(node) || import_typescript13.default.isSatisfiesExpression(node) || import_typescript13.default.isNonNullExpression(node)) {
28824
+ if (import_typescript15.default.isParenthesizedExpression(node) || import_typescript15.default.isAsExpression(node) || import_typescript15.default.isSatisfiesExpression(node) || import_typescript15.default.isNonNullExpression(node)) {
27846
28825
  resolveWorker(node.expression);
27847
28826
  return;
27848
28827
  }
27849
- if (import_typescript13.default.isCallExpression(node) && /(?:^|\.)withSentry$/.test(node.expression.getText())) {
28828
+ if (import_typescript15.default.isCallExpression(node) && /(?:^|\.)withSentry$/.test(node.expression.getText())) {
27850
28829
  for (const argument of node.arguments)
27851
28830
  resolveWorker(argument);
27852
28831
  return;
27853
28832
  }
27854
- if (import_typescript13.default.isExportAssignment(node)) {
28833
+ if (import_typescript15.default.isExportAssignment(node)) {
27855
28834
  resolveWorker(node.expression);
27856
28835
  return;
27857
28836
  }
27858
- if (import_typescript13.default.isVariableDeclaration(node)) {
28837
+ if (import_typescript15.default.isVariableDeclaration(node)) {
27859
28838
  resolveWorker(node.initializer);
27860
28839
  return;
27861
28840
  }
27862
- if (import_typescript13.default.isIdentifier(node) && checker) {
28841
+ if (import_typescript15.default.isIdentifier(node) && checker) {
27863
28842
  resolveWorker(valueDeclaration(resolvedSymbol(node, checker)));
27864
28843
  return;
27865
28844
  }
@@ -27867,17 +28846,17 @@ function enumerateWorkflows(result, ctx) {
27867
28846
  };
27868
28847
  const module = mainFile && checker?.getSymbolAtLocation(mainFile.source);
27869
28848
  const exported = module && checker?.getExportsOfModule(module).find((symbol2) => symbol2.name === "default");
27870
- const symbol = exported && checker && (exported.flags & import_typescript13.default.SymbolFlags.Alias ? checker.getAliasedSymbol(exported) : exported);
28849
+ const symbol = exported && checker && (exported.flags & import_typescript15.default.SymbolFlags.Alias ? checker.getAliasedSymbol(exported) : exported);
27871
28850
  resolveWorker(symbol && valueDeclaration(symbol));
27872
28851
  const collectImplementations = (node) => {
27873
- if (!import_typescript13.default.isClassLike(node) || workerClasses.has(nodeKey(node)))
28852
+ if (!import_typescript15.default.isClassLike(node) || workerClasses.has(nodeKey(node)))
27874
28853
  return;
27875
28854
  workerClasses.add(nodeKey(node));
27876
28855
  for (const member2 of node.members) {
27877
- if (import_typescript13.default.getCombinedModifierFlags(member2) & import_typescript13.default.ModifierFlags.Static)
28856
+ if (import_typescript15.default.getCombinedModifierFlags(member2) & import_typescript15.default.ModifierFlags.Static)
27878
28857
  continue;
27879
28858
  const name = nameOf(member2.name);
27880
- const implementation = byKey.get(nodeKey(member2)) ?? (import_typescript13.default.isPropertyDeclaration(member2) && member2.initializer ? byKey.get(nodeKey(member2.initializer)) : undefined);
28859
+ const implementation = byKey.get(nodeKey(member2)) ?? (import_typescript15.default.isPropertyDeclaration(member2) && member2.initializer ? byKey.get(nodeKey(member2.initializer)) : undefined);
27881
28860
  if (name && !implementations.has(name))
27882
28861
  implementations.set(name, implementation?.key ?? "(non-callable override)");
27883
28862
  }
@@ -27904,19 +28883,19 @@ function enumerateWorkflows(result, ctx) {
27904
28883
  if (!node || seen2.has(node))
27905
28884
  return;
27906
28885
  seen2.add(node);
27907
- if (import_typescript13.default.isIdentifier(node) && checker) {
28886
+ if (import_typescript15.default.isIdentifier(node) && checker) {
27908
28887
  resolveScheduled(valueDeclaration(resolvedSymbol(node, checker)), seen2);
27909
28888
  return;
27910
28889
  }
27911
- if (import_typescript13.default.isVariableDeclaration(node) || import_typescript13.default.isPropertyAssignment(node) || import_typescript13.default.isPropertyDeclaration(node)) {
28890
+ if (import_typescript15.default.isVariableDeclaration(node) || import_typescript15.default.isPropertyAssignment(node) || import_typescript15.default.isPropertyDeclaration(node)) {
27912
28891
  resolveScheduled(node.initializer, seen2);
27913
28892
  return;
27914
28893
  }
27915
- if (import_typescript13.default.isShorthandPropertyAssignment(node)) {
28894
+ if (import_typescript15.default.isShorthandPropertyAssignment(node)) {
27916
28895
  resolveScheduled(checker && valueDeclaration(checker.getShorthandAssignmentValueSymbol(node)), seen2);
27917
28896
  return;
27918
28897
  }
27919
- if (import_typescript13.default.isParenthesizedExpression(node) || import_typescript13.default.isAsExpression(node) || import_typescript13.default.isSatisfiesExpression(node) || import_typescript13.default.isNonNullExpression(node)) {
28898
+ if (import_typescript15.default.isParenthesizedExpression(node) || import_typescript15.default.isAsExpression(node) || import_typescript15.default.isSatisfiesExpression(node) || import_typescript15.default.isNonNullExpression(node)) {
27920
28899
  resolveScheduled(node.expression, seen2);
27921
28900
  return;
27922
28901
  }
@@ -27926,11 +28905,11 @@ function enumerateWorkflows(result, ctx) {
27926
28905
  if (seen2.has(node))
27927
28906
  return;
27928
28907
  seen2.add(node);
27929
- const members = import_typescript13.default.isObjectLiteralExpression(node) ? node.properties : import_typescript13.default.isClassLike(node) ? node.members : [];
27930
- const handlers = members.filter((member2) => nameOf(member2.name) === "scheduled" && !(import_typescript13.default.getCombinedModifierFlags(member2) & import_typescript13.default.ModifierFlags.Static));
28908
+ const members = import_typescript15.default.isObjectLiteralExpression(node) ? node.properties : import_typescript15.default.isClassLike(node) ? node.members : [];
28909
+ const handlers = members.filter((member2) => nameOf(member2.name) === "scheduled" && !(import_typescript15.default.getCombinedModifierFlags(member2) & import_typescript15.default.ModifierFlags.Static));
27931
28910
  for (const member2 of handlers)
27932
28911
  resolveScheduled(member2);
27933
- if (!handlers.length && import_typescript13.default.isClassLike(node) && checker)
28912
+ if (!handlers.length && import_typescript15.default.isClassLike(node) && checker)
27934
28913
  for (const base of node.heritageClauses?.flatMap((clause) => clause.types) ?? []) {
27935
28914
  const declaration = valueDeclaration(resolvedSymbol(base.expression, checker));
27936
28915
  if (declaration)
@@ -27976,7 +28955,7 @@ function enumerateWorkflows(result, ctx) {
27976
28955
  }
27977
28956
 
27978
28957
  // src/harness-extract/enumerators/catalog.ts
27979
- var import_typescript14 = __toESM(require_typescript(), 1);
28958
+ var import_typescript16 = __toESM(require_typescript(), 1);
27980
28959
  var THINK_WORKSPACE_TOOLS = ["read", "write", "edit", "list", "find", "grep", "delete"];
27981
28960
  function strings(expression, checker, seen = new Set) {
27982
28961
  if (!expression)
@@ -27985,35 +28964,35 @@ function strings(expression, checker, seen = new Set) {
27985
28964
  if (seen.has(node))
27986
28965
  return [];
27987
28966
  seen.add(node);
27988
- if (import_typescript14.default.isIdentifier(node)) {
28967
+ if (import_typescript16.default.isIdentifier(node)) {
27989
28968
  const declaration = checker && valueDeclaration(resolvedSymbol(node, checker));
27990
- if (!declaration || !import_typescript14.default.isVariableDeclaration(declaration))
28969
+ if (!declaration || !import_typescript16.default.isVariableDeclaration(declaration))
27991
28970
  return [];
27992
28971
  return strings(declaration.initializer, checker, seen);
27993
28972
  }
27994
- if (import_typescript14.default.isArrayLiteralExpression(node))
27995
- return node.elements.flatMap((entry) => import_typescript14.default.isSpreadElement(entry) ? strings(entry.expression, checker, seen) : strings(entry, checker, seen));
27996
- if (import_typescript14.default.isStringLiteralLike(node))
28973
+ if (import_typescript16.default.isArrayLiteralExpression(node))
28974
+ return node.elements.flatMap((entry) => import_typescript16.default.isSpreadElement(entry) ? strings(entry.expression, checker, seen) : strings(entry, checker, seen));
28975
+ if (import_typescript16.default.isStringLiteralLike(node))
27997
28976
  return [{ name: node.text, node }];
27998
- if (import_typescript14.default.isNewExpression(node) && node.expression.getText() === "Set")
28977
+ if (import_typescript16.default.isNewExpression(node) && node.expression.getText() === "Set")
27999
28978
  return strings(node.arguments?.[0], checker, seen);
28000
28979
  return [];
28001
28980
  }
28002
28981
  function property(object, name) {
28003
28982
  const entry = object.properties.find((item) => item.name && nameOf(item.name) === name);
28004
- return entry && import_typescript14.default.isPropertyAssignment(entry) ? entry.initializer : entry && import_typescript14.default.isShorthandPropertyAssignment(entry) ? entry.name : undefined;
28983
+ return entry && import_typescript16.default.isPropertyAssignment(entry) ? entry.initializer : entry && import_typescript16.default.isShorthandPropertyAssignment(entry) ? entry.name : undefined;
28005
28984
  }
28006
28985
  function inheritedTrue(node, propertyName2, checker, seen = new Set) {
28007
28986
  if (seen.has(node))
28008
28987
  return false;
28009
28988
  seen.add(node);
28010
28989
  const own = node.members.find((member2) => nameOf(member2.name) === propertyName2);
28011
- if (own && import_typescript14.default.isPropertyDeclaration(own) && own.initializer)
28012
- return unwrap(own.initializer).kind === import_typescript14.default.SyntaxKind.TrueKeyword;
28990
+ if (own && import_typescript16.default.isPropertyDeclaration(own) && own.initializer)
28991
+ return unwrap(own.initializer).kind === import_typescript16.default.SyntaxKind.TrueKeyword;
28013
28992
  if (checker)
28014
28993
  for (const base of node.heritageClauses?.flatMap((h) => h.types) ?? []) {
28015
28994
  const declaration = valueDeclaration(resolvedSymbol(base.expression, checker));
28016
- if (declaration && (import_typescript14.default.isClassDeclaration(declaration) || import_typescript14.default.isClassExpression(declaration)))
28995
+ if (declaration && (import_typescript16.default.isClassDeclaration(declaration) || import_typescript16.default.isClassExpression(declaration)))
28017
28996
  return inheritedTrue(declaration, propertyName2, checker, seen);
28018
28997
  }
28019
28998
  return false;
@@ -28028,10 +29007,10 @@ function enumerateToolCatalog(result, ctx) {
28028
29007
  if (!owners.length || !checker)
28029
29008
  continue;
28030
29009
  visit(scope.node, (node) => {
28031
- if (!import_typescript14.default.isIdentifier(node) || !/ALLOW|MCP_NAME/.test(node.text))
29010
+ if (!import_typescript16.default.isIdentifier(node) || !/ALLOW|MCP_NAME/.test(node.text))
28032
29011
  return;
28033
29012
  const declaration = valueDeclaration(resolvedSymbol(node, checker));
28034
- if (!declaration || !import_typescript14.default.isVariableDeclaration(declaration) || !import_typescript14.default.isIdentifier(declaration.name))
29013
+ if (!declaration || !import_typescript16.default.isVariableDeclaration(declaration) || !import_typescript16.default.isIdentifier(declaration.name))
28035
29014
  return;
28036
29015
  const key = `${declaration.getSourceFile().fileName}:${declaration.name.text}`;
28037
29016
  let existing = symbolOwners.get(key);
@@ -28052,7 +29031,7 @@ function enumerateToolCatalog(result, ctx) {
28052
29031
  if (!file || !checker)
28053
29032
  continue;
28054
29033
  visit(file.source, (node) => {
28055
- if ((import_typescript14.default.isClassDeclaration(node) || import_typescript14.default.isClassExpression(node)) && node.name?.text === runtime.name && frameworkBaseOf(node, checker, memo)?.base === "Think")
29034
+ if ((import_typescript16.default.isClassDeclaration(node) || import_typescript16.default.isClassExpression(node)) && node.name?.text === runtime.name && frameworkBaseOf(node, checker, memo)?.base === "Think")
28056
29035
  thinkIds.add(runtime.id);
28057
29036
  });
28058
29037
  }
@@ -28069,11 +29048,11 @@ function enumerateToolCatalog(result, ctx) {
28069
29048
  continue;
28070
29049
  const checker = ctx.checkerFor(file.path), declarations = new Map;
28071
29050
  visit(file.source, (node) => {
28072
- if (import_typescript14.default.isVariableDeclaration(node) && import_typescript14.default.isIdentifier(node.name) && node.initializer)
29051
+ if (import_typescript16.default.isVariableDeclaration(node) && import_typescript16.default.isIdentifier(node.name) && node.initializer)
28073
29052
  declarations.set(node.name.text, node.initializer);
28074
29053
  });
28075
29054
  visit(file.source, (node) => {
28076
- if ((import_typescript14.default.isClassDeclaration(node) || import_typescript14.default.isClassExpression(node)) && node.name && agentByName.has(node.name.text)) {
29055
+ if ((import_typescript16.default.isClassDeclaration(node) || import_typescript16.default.isClassExpression(node)) && node.name && agentByName.has(node.name.text)) {
28077
29056
  const info = checker ? frameworkBaseOf(node, checker, memo) : undefined;
28078
29057
  const directThink = node.heritageClauses?.some((h) => h.types.some((t) => t.expression.getText() === "Think"));
28079
29058
  if (info?.base === "Think" || directThink) {
@@ -28085,37 +29064,37 @@ function enumerateToolCatalog(result, ctx) {
28085
29064
  add(name, file, node, "think", "Think workspace tool inherited by this concrete agent", owners2);
28086
29065
  }
28087
29066
  }
28088
- if (import_typescript14.default.isPropertyAccessExpression(node) && node.name.text === "activate_skill" || import_typescript14.default.isPropertyAssignment(node) && nameOf(node.name) === "activate_skill") {
29067
+ if (import_typescript16.default.isPropertyAccessExpression(node) && node.name.text === "activate_skill" || import_typescript16.default.isPropertyAssignment(node) && nameOf(node.name) === "activate_skill") {
28089
29068
  const owner = ownersAt(node, file.path);
28090
29069
  add("activate_skill", file, node, "think", "Source explicitly exposes Think skill activation", owner);
28091
29070
  }
28092
- if (import_typescript14.default.isCallExpression(node) && import_typescript14.default.isPropertyAccessExpression(node.expression) && /^(?:registerTool|tool)$/.test(node.expression.name.text) && checker) {
29071
+ if (import_typescript16.default.isCallExpression(node) && import_typescript16.default.isPropertyAccessExpression(node.expression) && /^(?:registerTool|tool)$/.test(node.expression.name.text) && checker) {
28093
29072
  const receiver = valueDeclaration(resolvedSymbol(node.expression.expression, checker));
28094
- const init = receiver && import_typescript14.default.isVariableDeclaration(receiver) && receiver.initializer ? unwrap(receiver.initializer) : undefined;
28095
- const origin = init && import_typescript14.default.isNewExpression(init) && import_typescript14.default.isIdentifier(init.expression) ? importOrigin(init.expression, checker) : undefined;
29073
+ const init = receiver && import_typescript16.default.isVariableDeclaration(receiver) && receiver.initializer ? unwrap(receiver.initializer) : undefined;
29074
+ const origin = init && import_typescript16.default.isNewExpression(init) && import_typescript16.default.isIdentifier(init.expression) ? importOrigin(init.expression, checker) : undefined;
28096
29075
  const name = node.arguments[0];
28097
- if (origin?.module.startsWith("@modelcontextprotocol/sdk/") && origin.imported === "McpServer" && name && import_typescript14.default.isStringLiteralLike(name)) {
29076
+ if (origin?.module.startsWith("@modelcontextprotocol/sdk/") && origin.imported === "McpServer" && name && import_typescript16.default.isStringLiteralLike(name)) {
28098
29077
  add(name.text, file, name, "mcp_server", "MCP SDK server explicitly registers this model-facing tool name", ownersAt(node, file.path));
28099
29078
  }
28100
29079
  }
28101
- if (import_typescript14.default.isCallExpression(node) && import_typescript14.default.isPropertyAccessExpression(node.expression) && node.expression.expression.getText() === "Output" && node.expression.name.text === "object") {
29080
+ if (import_typescript16.default.isCallExpression(node) && import_typescript16.default.isPropertyAccessExpression(node.expression) && node.expression.expression.getText() === "Output" && node.expression.name.text === "object") {
28102
29081
  const owners2 = ownersAt(node, file.path).filter((id) => thinkIds.has(id));
28103
- if (owners2.length && checker && import_typescript14.default.isIdentifier(node.expression.expression) && ["ai", "@cloudflare/think"].includes(importOrigin(node.expression.expression, checker)?.module ?? ""))
29082
+ if (owners2.length && checker && import_typescript16.default.isIdentifier(node.expression.expression) && ["ai", "@cloudflare/think"].includes(importOrigin(node.expression.expression, checker)?.module ?? ""))
28104
29083
  add("think_final_answer", file, node, "think", "Think structured output is offered as the framework final-answer tool", owners2);
28105
29084
  }
28106
- if (import_typescript14.default.isCallExpression(node) && import_typescript14.default.isIdentifier(node.expression) && node.expression.text === "createExecuteRuntime") {
29085
+ if (import_typescript16.default.isCallExpression(node) && import_typescript16.default.isIdentifier(node.expression) && node.expression.text === "createExecuteRuntime") {
28107
29086
  const owners2 = ownersAt(node, file.path).filter((id) => thinkIds.has(id));
28108
29087
  if (owners2.length && checker && importOrigin(node.expression, checker)?.module.startsWith("@cloudflare/think"))
28109
29088
  add("execute", file, node, "think", "Think Code Mode runtime explicitly enabled for this agent", owners2);
28110
29089
  }
28111
- if (!import_typescript14.default.isObjectLiteralExpression(node))
29090
+ if (!import_typescript16.default.isObjectLiteralExpression(node))
28112
29091
  return;
28113
29092
  const serverNames = strings(property(node, "name"), checker), allow = property(node, "allow");
28114
29093
  if (serverNames.length !== 1 || !allow || !property(node, "url"))
28115
29094
  return;
28116
29095
  const server = serverNames[0].name;
28117
29096
  const owners = ownersAt(node, file.path);
28118
- if (import_typescript14.default.isStringLiteralLike(unwrap(allow)) && unwrap(allow).text === "all") {
29097
+ if (import_typescript16.default.isStringLiteralLike(unwrap(allow)) && unwrap(allow).text === "all") {
28119
29098
  const entry = add(`${server} dynamic MCP tools`, file, allow, "mcp_dynamic_group", "Server schemas are admitted dynamically as one bounded catalog group", owners);
28120
29099
  entry.serverName = server;
28121
29100
  entry.dynamicGroup = true;
@@ -28166,23 +29145,30 @@ function enumerateToolCatalog(result, ctx) {
28166
29145
  var ENUMERATORS = [
28167
29146
  { id: "agents", enumerate: ({ result }, ctx) => ({ runtimeAgents: enumerateAgents(result, ctx).runtimeAgents }) },
28168
29147
  { id: "workflows", enumerate: ({ result }, ctx) => enumerateWorkflows(result, ctx) },
28169
- { id: "framework-mcp-catalog", enumerate: ({ result }, ctx) => enumerateToolCatalog(result, ctx) }
29148
+ { id: "framework-mcp-catalog", enumerate: ({ result }, ctx) => enumerateToolCatalog(result, ctx) },
29149
+ { id: "tool-registry", enumerate: ({ result }, ctx) => ({ artifacts: toolArtifacts(emitToolsCached(result, ctx), enumerateAgents(result, ctx).runtimeAgents) }) }
28170
29150
  ];
28171
29151
  function enumerateHarnessComponents(result, ctx) {
28172
29152
  const agents = enumerateAgents(result, ctx), workflows = enumerateWorkflows(result, ctx), catalog = enumerateToolCatalog(result, ctx);
28173
- return stableResult({ runtimeAgents: agents.runtimeAgents, artifacts: [...workflows.artifacts, ...catalog.artifacts], warnings: [...workflows.warnings, ...catalog.warnings] });
29153
+ return stableResult({ runtimeAgents: agents.runtimeAgents, artifacts: [...workflows.artifacts, ...toolArtifacts(emitToolsCached(result, ctx), agents.runtimeAgents), ...catalog.artifacts], warnings: [...workflows.warnings, ...catalog.warnings] });
28174
29154
  }
28175
29155
  function mergeEnumeratedComponents(artifacts, components) {
28176
29156
  const merged = new Map;
28177
29157
  const definitions = new Map;
28178
- for (const item of [...artifacts, ...components.artifacts]) {
29158
+ const registry = components.artifacts.filter((item) => item.type === "tool" && item.id.startsWith("tool.extract."));
29159
+ for (const item of [...registry, ...artifacts, ...components.artifacts.filter((item2) => !registry.includes(item2))]) {
28179
29160
  const key = item.type === "tool" ? `tool:${item.name}` : item.id;
28180
- if (item.type === "tool" && item.body) {
29161
+ if (item.type === "tool") {
29162
+ const own = item.definitionVariants ?? (item.body ? [{ sourcePath: item.sourcePath, body: item.body, evidence: item.evidence }] : []);
28181
29163
  let variants = definitions.get(key);
28182
- if (!variants)
28183
- definitions.set(key, variants = []);
28184
- if (!variants.some((entry) => entry.id === item.id && entry.body === item.body))
28185
- variants.push({ id: item.id, sourcePath: item.sourcePath, body: item.body, evidence: [...item.evidence], usedByAgentIds: [...item.usedByAgentIds] });
29164
+ for (const variant of own) {
29165
+ if (!variant.body)
29166
+ continue;
29167
+ if (!variants)
29168
+ definitions.set(key, variants = []);
29169
+ if (!variants.some((entry) => entry.id === item.id && entry.sourcePath === variant.sourcePath && entry.body === variant.body))
29170
+ variants.push({ id: item.id, sourcePath: variant.sourcePath, body: variant.body, evidence: [...variant.evidence ?? item.evidence], usedByAgentIds: [...item.usedByAgentIds] });
29171
+ }
28186
29172
  }
28187
29173
  const previous = merged.get(key);
28188
29174
  if (!previous) {
@@ -28213,4 +29199,4 @@ function mergeEnumeratedComponents(artifacts, components) {
28213
29199
  return { runtimeAgents, artifacts: output };
28214
29200
  }
28215
29201
 
28216
- export { startRemoteAnalyze, pollRemoteAnalyzeUntilDone, isRecoverableRemoteRun, checkPromptMapping, safePromptEvidencePath, discoverHarnessPromptSources, valueChildren, selectKey, allValues, renderings, CALL_SINKS, registerCallSink, registerClassSink, isModelId, collectModels, modelArtifacts, modelUnknowns, collectModelLiterals, EXTRACT_SCHEMA_VERSION, agentForScope, createAgentScopeResolver, enumerateAgents, enumerateWorkflows, enumerateToolCatalog, ENUMERATORS, enumerateHarnessComponents, mergeEnumeratedComponents, toolNamesOf, clearExtractCache, extractHarness, extractHarnessWithContext, serializeExtractResult, runEnumerators, assignAgentIds, runHarnessCommand, writeHarnessAnalyzeResult, emitWrittenArtifacts, analyzeHarnessPrompts, isToolGroupPlaceholder, repairExternalAnalystReport, deriveRelationshipsFromGraph, deterministicArtifacts, deterministicGraphItems, mergeDeterministicArtifacts, analystRefutations, describeCodingAgentEvent, analystEventProgress, isRetryableExternalAnalystFailure, sleep, summarizeInvalidAnalystReport, isDeterministicLocalAnalyst, resolveHarnessAnalyzeConcern, resolveExternalHarnessAnalystInvocation, detectAvailableCodingAgents, codingAgentDisplayName, runCodingAgent, readOnlyClaudeExtraArgs, resolveAnalystModel, renderExternalHarnessAnalystPrompt, CONCERN_CANDIDATE_KINDS, SEED_CANDIDATE_KIND_LABELS, renderAnalystCandidateLines, renderAnalystSeedLines, truncateText, scanHarness, summarizeHarness, buildSourceSnapshot, writeHumanProgress, describeSyncIdentity, describeSyncTenantLabel, findFresherHarnessReports, writeHarnessArtifacts, assertHarnessGraphSyncQuality, graphForSync, inventoryFiles, numericEnv, numericEnvAllowZero, computeDeterministicFloor, stableId, titleFromId, promptNameFromPath };
29202
+ export { startRemoteAnalyze, pollRemoteAnalyzeUntilDone, isRecoverableRemoteRun, checkPromptMapping, safePromptEvidencePath, discoverHarnessPromptSources, valueChildren, selectKey, allValues, renderings, CALL_SINKS, registerCallSink, registerClassSink, isModelId, collectModels, modelArtifacts, modelUnknowns, collectModelLiterals, agentForScope, createAgentScopeResolver, enumerateAgents, toolNamesOf, EXTRACT_SCHEMA_VERSION, enumerateWorkflows, enumerateToolCatalog, ENUMERATORS, enumerateHarnessComponents, mergeEnumeratedComponents, clearExtractCache, extractHarness, extractHarnessWithContext, scopeOf, serializeExtractResult, runEnumerators, assignAgentIds, runHarnessCommand, writeHarnessAnalyzeResult, emitWrittenArtifacts, analyzeHarnessPrompts, isToolGroupPlaceholder, repairExternalAnalystReport, deriveRelationshipsFromGraph, deterministicArtifacts, deterministicGraphItems, mergeDeterministicArtifacts, analystRefutations, describeCodingAgentEvent, analystEventProgress, isRetryableExternalAnalystFailure, sleep, summarizeInvalidAnalystReport, isDeterministicLocalAnalyst, resolveHarnessAnalyzeConcern, resolveExternalHarnessAnalystInvocation, detectAvailableCodingAgents, codingAgentDisplayName, runCodingAgent, readOnlyClaudeExtraArgs, resolveAnalystModel, renderExternalHarnessAnalystPrompt, CONCERN_CANDIDATE_KINDS, SEED_CANDIDATE_KIND_LABELS, renderAnalystCandidateLines, renderAnalystSeedLines, truncateText, scanHarness, summarizeHarness, buildSourceSnapshot, writeHumanProgress, describeSyncIdentity, describeSyncTenantLabel, findFresherHarnessReports, writeHarnessArtifacts, assertHarnessGraphSyncQuality, graphForSync, inventoryFiles, numericEnv, numericEnvAllowZero, computeDeterministicFloor, stableId, titleFromId, promptNameFromPath };