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