@moda-ai/cli 1.55.63 → 1.55.64
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-y53qz08m.js → agent-hn9z5mtw.js} +3 -3
- package/dist/{cli-jfb2fnfh.js → cli-7mdzvenp.js} +3 -3
- package/dist/{cli-8b5yqyg3.js → cli-7rq27nht.js} +2 -2
- package/dist/{cli-xmv0fark.js → cli-rec661n7.js} +1126 -23
- package/dist/{index-gtqxj0fp.js → cli-vqhaj5tv.js} +2 -18
- package/dist/cli.js +7 -7
- package/dist/{doctor-34yw1shj.js → doctor-6bccjmx8.js} +2 -2
- package/dist/{harness-5e3qnand.js → harness-462pdr5e.js} +2 -1
- package/dist/{harness-github-actions-0mxwmp6g.js → harness-github-actions-vt8tt6n9.js} +2 -1
- package/dist/{index-tap398h2.js → index-1cjavfpa.js} +4 -3
- package/dist/index-xkgawks9.js +39 -0
- package/dist/{prompt-attribution-s7ec7bd3.js → prompt-attribution-nha0sccy.js} +2 -1
- package/dist/prompt-source-mcp.js +2 -1
- package/dist/{prompts-h59g3egz.js → prompts-nhsbq9me.js} +1 -1
- package/dist/{sync-jgk7dfjd.js → sync-tvf4cggm.js} +3 -2
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
|
@@ -94,6 +94,9 @@ import {
|
|
|
94
94
|
redactDeep,
|
|
95
95
|
shouldInventoryFile
|
|
96
96
|
} from "./cli-9a4b1wxz.js";
|
|
97
|
+
import {
|
|
98
|
+
extractHarnessWithContext
|
|
99
|
+
} from "./cli-vqhaj5tv.js";
|
|
97
100
|
import {
|
|
98
101
|
mergeBoundRuntimeClasses,
|
|
99
102
|
tagComponentStatus
|
|
@@ -121,7 +124,7 @@ import {
|
|
|
121
124
|
writeFileSync as writeFileSync5,
|
|
122
125
|
rmSync as rmSync4
|
|
123
126
|
} from "node:fs";
|
|
124
|
-
import { basename as basename7, delimiter, dirname as dirname7, join as join9, relative as
|
|
127
|
+
import { basename as basename7, delimiter, dirname as dirname7, join as join9, relative as relative7, resolve as resolve10, sep as sep5 } from "node:path";
|
|
125
128
|
import { confirm, select } from "@inquirer/prompts";
|
|
126
129
|
|
|
127
130
|
// src/analyst-tui.ts
|
|
@@ -15470,6 +15473,1092 @@ function promoteAll(report, rootDir) {
|
|
|
15470
15473
|
return [...byId.values()];
|
|
15471
15474
|
}
|
|
15472
15475
|
|
|
15476
|
+
// src/harness-extract/prompts/resolver.ts
|
|
15477
|
+
var import_typescript3 = __toESM(require_typescript(), 1);
|
|
15478
|
+
import { relative as relative6 } from "node:path";
|
|
15479
|
+
var DEFAULT_MAX_DEPTH = 24;
|
|
15480
|
+
var DEFAULT_MAX_PARAM_LEVELS = 3;
|
|
15481
|
+
var PROMPT_FIELDS = new Set([
|
|
15482
|
+
"content",
|
|
15483
|
+
"text",
|
|
15484
|
+
"system",
|
|
15485
|
+
"prompt",
|
|
15486
|
+
"instructions",
|
|
15487
|
+
"instruction",
|
|
15488
|
+
"systemPrompt",
|
|
15489
|
+
"system_prompt",
|
|
15490
|
+
"systemMessage",
|
|
15491
|
+
"system_message",
|
|
15492
|
+
"systemInstruction",
|
|
15493
|
+
"system_instruction",
|
|
15494
|
+
"messages",
|
|
15495
|
+
"user",
|
|
15496
|
+
"question",
|
|
15497
|
+
"questions",
|
|
15498
|
+
"task",
|
|
15499
|
+
"brief",
|
|
15500
|
+
"criteria",
|
|
15501
|
+
"rubric",
|
|
15502
|
+
"template",
|
|
15503
|
+
"backstory",
|
|
15504
|
+
"goal",
|
|
15505
|
+
"provider",
|
|
15506
|
+
"get",
|
|
15507
|
+
"render"
|
|
15508
|
+
]);
|
|
15509
|
+
var PROMPT_FIELD_NAME = /(?:prompt|instructions?|system|brief|intent|task|questions?|directive|guidance|rules?|context|section|block|persona|role|criteria|rubric|template|content|text|preamble|framing|nudge|reminder|policy)$/i;
|
|
15510
|
+
var TEXT_PRESERVING_METHODS = new Set([
|
|
15511
|
+
"trim",
|
|
15512
|
+
"trimStart",
|
|
15513
|
+
"trimEnd",
|
|
15514
|
+
"replace",
|
|
15515
|
+
"replaceAll",
|
|
15516
|
+
"concat",
|
|
15517
|
+
"slice",
|
|
15518
|
+
"toString",
|
|
15519
|
+
"normalize",
|
|
15520
|
+
"padEnd",
|
|
15521
|
+
"padStart"
|
|
15522
|
+
]);
|
|
15523
|
+
var ARRAY_ASSEMBLY_METHODS = new Set(["join", "concat", "flat", "filter", "slice", "reverse", "sort", "toSorted"]);
|
|
15524
|
+
var CALLBACK_METHODS = new Set(["map", "flatMap", "then", "catch"]);
|
|
15525
|
+
var TEST_SOURCE = /(?:^|\/)(?:__tests__|__mocks__|fixtures?|test-fixtures)\/|(?:^|\/)[^/]*\.(?:test|spec)\.[^/]+$/i;
|
|
15526
|
+
var LOCAL_ONLY_SITE = /^(?:scripts|evals?)\//;
|
|
15527
|
+
function readsAsInstructions2(text) {
|
|
15528
|
+
const plain = text.replace(/\{\{[^}]*\}\}/g, " x ");
|
|
15529
|
+
if (/^\s*(?:SELECT|WITH|INSERT|UPDATE|DELETE|CREATE|ALTER)\b/i.test(plain))
|
|
15530
|
+
return false;
|
|
15531
|
+
if (/^\s*(?:https?:\/\/|\/[\w-]+\/)\S*\s*$/.test(plain))
|
|
15532
|
+
return false;
|
|
15533
|
+
if (/^[\s\w,.()'"=]+$/.test(plain) && (plain.match(/,/g) ?? []).length >= 3 && !/[.!?:]\s/.test(plain))
|
|
15534
|
+
return false;
|
|
15535
|
+
if ((plain.match(/[{};=]/g) ?? []).length > plain.length / 25)
|
|
15536
|
+
return false;
|
|
15537
|
+
const words = plain.match(/[A-Za-z]{2,}/g) ?? [];
|
|
15538
|
+
return words.length >= 6 && /\s/.test(plain.trim());
|
|
15539
|
+
}
|
|
15540
|
+
function isDataWrapper(text) {
|
|
15541
|
+
const lines = text.split(`
|
|
15542
|
+
`).map((line) => line.trim()).filter(Boolean);
|
|
15543
|
+
if (lines.length === 0)
|
|
15544
|
+
return true;
|
|
15545
|
+
return lines.every((line) => (line.replace(/\{\{[^}]*\}\}/g, " ").replace(/<\/?[\w-]+>/g, " ").match(/[A-Za-z]{2,}/g) ?? []).length < 4);
|
|
15546
|
+
}
|
|
15547
|
+
var SHORT_TEXT = 300;
|
|
15548
|
+
var DIRECTIVE_ANYWHERE = /\b(?:you(?! were)|must|should|do not|don't|never|always|only|avoid|make sure|ensure|instead)\b/i;
|
|
15549
|
+
var DIRECTIVE_VERB = /(?:^|[.!?:;\n]\s*|\]\s*)(?:keep|write|reply|respond|return|answer|use|include|output|list|describe|summari[sz]e|explain|decide|pick|choose|rate|score|classify|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)\b/i;
|
|
15550
|
+
function hasDirective(text) {
|
|
15551
|
+
const plain = text.replace(/\{\{[^}]*\}\}/g, " ").trim();
|
|
15552
|
+
return DIRECTIVE_ANYWHERE.test(plain) || DIRECTIVE_VERB.test(plain);
|
|
15553
|
+
}
|
|
15554
|
+
function isInstructionDescription(text) {
|
|
15555
|
+
if (text.length >= 2000)
|
|
15556
|
+
return true;
|
|
15557
|
+
if (text.length < 600)
|
|
15558
|
+
return false;
|
|
15559
|
+
return /\b(?:you must|always|never|do not|don't|only (?:use|call)|use this (?:tool|when)|call this (?:tool|when|before|after)|before (?:calling|using)|when to use)\b/i.test(text);
|
|
15560
|
+
}
|
|
15561
|
+
function toolDefinitionSite(tool) {
|
|
15562
|
+
return {
|
|
15563
|
+
id: `tool:${tool.toolId}`,
|
|
15564
|
+
path: tool.definition.path,
|
|
15565
|
+
line: tool.definition.line,
|
|
15566
|
+
col: 1,
|
|
15567
|
+
callee: tool.name,
|
|
15568
|
+
sdk: "tool-definition",
|
|
15569
|
+
language: "ts",
|
|
15570
|
+
scope: tool.scope,
|
|
15571
|
+
promptArgs: [],
|
|
15572
|
+
isTest: false,
|
|
15573
|
+
isEval: false
|
|
15574
|
+
};
|
|
15575
|
+
}
|
|
15576
|
+
function resolvePromptArguments(callSites, context, options = {}) {
|
|
15577
|
+
const resolver = new PromptResolver(context, options);
|
|
15578
|
+
for (const tool of options.toolDefinitions ?? []) {
|
|
15579
|
+
const node = nodeOf(tool.definition, context);
|
|
15580
|
+
if (node)
|
|
15581
|
+
resolver.resolveTools(toolDefinitionSite(tool), node);
|
|
15582
|
+
}
|
|
15583
|
+
for (const site of callSites) {
|
|
15584
|
+
if (!/\.[cm]?[jt]sx?$/.test(site.path))
|
|
15585
|
+
continue;
|
|
15586
|
+
for (const { role, arg } of site.promptArgs) {
|
|
15587
|
+
const node = nodeOf(arg, context);
|
|
15588
|
+
if (!node)
|
|
15589
|
+
continue;
|
|
15590
|
+
resolver.resolveArgument(site, role, node, arg.key ? arg.key.split(".") : []);
|
|
15591
|
+
}
|
|
15592
|
+
const tools = site.toolsArg ? nodeOf(site.toolsArg, context) : undefined;
|
|
15593
|
+
if (tools)
|
|
15594
|
+
resolver.resolveTools(site, tools);
|
|
15595
|
+
}
|
|
15596
|
+
return resolver.result();
|
|
15597
|
+
}
|
|
15598
|
+
|
|
15599
|
+
class PromptResolver {
|
|
15600
|
+
context;
|
|
15601
|
+
refs = new Map;
|
|
15602
|
+
unresolved = new Map;
|
|
15603
|
+
maxDepth;
|
|
15604
|
+
maxParamLevels;
|
|
15605
|
+
keepAll;
|
|
15606
|
+
callersByName = new Map;
|
|
15607
|
+
aliasesByName = new Map;
|
|
15608
|
+
callersIndexed = false;
|
|
15609
|
+
methodIndex;
|
|
15610
|
+
constructor(context, options) {
|
|
15611
|
+
this.context = context;
|
|
15612
|
+
this.maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
15613
|
+
this.maxParamLevels = options.maxParamLevels ?? DEFAULT_MAX_PARAM_LEVELS;
|
|
15614
|
+
this.keepAll = options.keepAll === true;
|
|
15615
|
+
}
|
|
15616
|
+
resolveArgument(site, role, node, project = []) {
|
|
15617
|
+
const walk = { site, role, depth: 0, paramLevels: 0, bindings: new Map, hops: [], seen: new Set, project, flags: [] };
|
|
15618
|
+
this.value(node, undefined, walk);
|
|
15619
|
+
}
|
|
15620
|
+
resolveTools(site, node) {
|
|
15621
|
+
const walk = { site, role: "tool-description", depth: 0, paramLevels: 0, bindings: new Map, hops: [], seen: new Set, project: [], flags: [] };
|
|
15622
|
+
this.toolDefinitions(node, walk, 0, new Set);
|
|
15623
|
+
}
|
|
15624
|
+
toolDefinitions(node, walk, depth, seen) {
|
|
15625
|
+
if (depth > 8 || seen.has(node))
|
|
15626
|
+
return;
|
|
15627
|
+
seen.add(node);
|
|
15628
|
+
const expr = unwrap(node);
|
|
15629
|
+
if (import_typescript3.default.isArrayLiteralExpression(expr)) {
|
|
15630
|
+
for (const element of expr.elements)
|
|
15631
|
+
this.toolDefinitions(import_typescript3.default.isSpreadElement(element) ? element.expression : element, walk, depth + 1, seen);
|
|
15632
|
+
return;
|
|
15633
|
+
}
|
|
15634
|
+
if (import_typescript3.default.isObjectLiteralExpression(expr)) {
|
|
15635
|
+
const description = expr.properties.find((p2) => propertyName(p2) === "description");
|
|
15636
|
+
const handler = expr.properties.find((p2) => /^(?:execute|handler|run|invoke|call|func)$/.test(propertyName(p2) ?? ""));
|
|
15637
|
+
if (description || handler) {
|
|
15638
|
+
if (description && import_typescript3.default.isPropertyAssignment(description)) {
|
|
15639
|
+
this.value(description.initializer, { node: description, name: toolName(expr) ? `${toolName(expr)} description` : "description", kind: "literal" }, walk);
|
|
15640
|
+
}
|
|
15641
|
+
if (handler) {
|
|
15642
|
+
const fn = import_typescript3.default.isPropertyAssignment(handler) ? unwrap(handler.initializer) : handler;
|
|
15643
|
+
const resultWalk = { ...walk, role: "tool-result", namedOnly: true };
|
|
15644
|
+
if (import_typescript3.default.isArrowFunction(fn) || import_typescript3.default.isFunctionExpression(fn) || import_typescript3.default.isMethodDeclaration(fn))
|
|
15645
|
+
this.builderBody(fn, { node: fn, kind: "builder" }, resultWalk);
|
|
15646
|
+
else
|
|
15647
|
+
this.value(fn, undefined, resultWalk);
|
|
15648
|
+
}
|
|
15649
|
+
return;
|
|
15650
|
+
}
|
|
15651
|
+
for (const property of expr.properties) {
|
|
15652
|
+
if (import_typescript3.default.isPropertyAssignment(property))
|
|
15653
|
+
this.toolDefinitions(property.initializer, walk, depth + 1, seen);
|
|
15654
|
+
else if (import_typescript3.default.isShorthandPropertyAssignment(property))
|
|
15655
|
+
this.toolDefinitions(property.name, walk, depth + 1, seen);
|
|
15656
|
+
else if (import_typescript3.default.isSpreadAssignment(property))
|
|
15657
|
+
this.toolDefinitions(property.expression, walk, depth + 1, seen);
|
|
15658
|
+
}
|
|
15659
|
+
return;
|
|
15660
|
+
}
|
|
15661
|
+
if (import_typescript3.default.isIdentifier(expr) || import_typescript3.default.isPropertyAccessExpression(expr)) {
|
|
15662
|
+
for (const declaration of this.declarationsOf(import_typescript3.default.isPropertyAccessExpression(expr) ? expr.name : expr)) {
|
|
15663
|
+
const init = import_typescript3.default.isVariableDeclaration(declaration) || import_typescript3.default.isPropertyAssignment(declaration) || import_typescript3.default.isPropertyDeclaration(declaration) ? declaration.initializer : undefined;
|
|
15664
|
+
if (init)
|
|
15665
|
+
this.toolDefinitions(init, walk, depth + 1, seen);
|
|
15666
|
+
const fn = functionOf(declaration);
|
|
15667
|
+
if (fn?.body)
|
|
15668
|
+
this.returnsOf(fn, (value) => this.toolDefinitions(value, walk, depth + 1, seen));
|
|
15669
|
+
}
|
|
15670
|
+
return;
|
|
15671
|
+
}
|
|
15672
|
+
if (import_typescript3.default.isCallExpression(expr)) {
|
|
15673
|
+
const callee = import_typescript3.default.isPropertyAccessExpression(expr.expression) ? expr.expression.name : expr.expression;
|
|
15674
|
+
const fns = this.declarationsOf(callee).map(functionOf).filter((fn) => fn?.body);
|
|
15675
|
+
if (fns.length > 0)
|
|
15676
|
+
for (const fn of fns)
|
|
15677
|
+
this.returnsOf(fn, (value) => this.toolDefinitions(value, walk, depth + 1, seen));
|
|
15678
|
+
for (const argument of expr.arguments)
|
|
15679
|
+
this.toolDefinitions(argument, walk, depth + 1, seen);
|
|
15680
|
+
}
|
|
15681
|
+
}
|
|
15682
|
+
returnsOf(fn, each) {
|
|
15683
|
+
const body = fn.body;
|
|
15684
|
+
if (!body)
|
|
15685
|
+
return;
|
|
15686
|
+
if (!import_typescript3.default.isBlock(body)) {
|
|
15687
|
+
each(body);
|
|
15688
|
+
return;
|
|
15689
|
+
}
|
|
15690
|
+
const visit = (node) => {
|
|
15691
|
+
if (node !== fn && import_typescript3.default.isFunctionLike(node))
|
|
15692
|
+
return;
|
|
15693
|
+
if (import_typescript3.default.isReturnStatement(node) && node.expression)
|
|
15694
|
+
each(node.expression);
|
|
15695
|
+
import_typescript3.default.forEachChild(node, visit);
|
|
15696
|
+
};
|
|
15697
|
+
visit(body);
|
|
15698
|
+
}
|
|
15699
|
+
result() {
|
|
15700
|
+
const firstOnLine = new Map;
|
|
15701
|
+
for (const ref of this.refs.values()) {
|
|
15702
|
+
const line = `${ref.path}:${ref.line}`;
|
|
15703
|
+
firstOnLine.set(line, Math.min(firstOnLine.get(line) ?? Infinity, ref.start));
|
|
15704
|
+
}
|
|
15705
|
+
const refs = [...this.refs.values()].map(({ pieces, start, ...ref }) => {
|
|
15706
|
+
const later = start > firstOnLine.get(`${ref.path}:${ref.line}`);
|
|
15707
|
+
const column = later ? this.columnOf(ref.path, start) : undefined;
|
|
15708
|
+
return {
|
|
15709
|
+
...ref,
|
|
15710
|
+
...column ? { id: `${ref.id}:${column}`, column } : {},
|
|
15711
|
+
text: [...pieces.entries()].sort((a, b) => a[0] - b[0]).map(([, text]) => text).join(`
|
|
15712
|
+
`)
|
|
15713
|
+
};
|
|
15714
|
+
});
|
|
15715
|
+
return {
|
|
15716
|
+
refs: refs.filter((ref) => this.keepAll || readsAsInstructions2(ref.text) && !isDataWrapper(ref.text) && (ref.text.length >= SHORT_TEXT || ref.role === "questions" || ref.role === "tool-description" || hasDirective(ref.text)) && (ref.role !== "tool-description" || isInstructionDescription(ref.text))),
|
|
15717
|
+
unresolved: [...this.unresolved.values()]
|
|
15718
|
+
};
|
|
15719
|
+
}
|
|
15720
|
+
value(node, owner, walk) {
|
|
15721
|
+
if (walk.depth > this.maxDepth) {
|
|
15722
|
+
this.markUnresolved(node, "depth-limit", walk);
|
|
15723
|
+
return;
|
|
15724
|
+
}
|
|
15725
|
+
const expr = unwrap(node);
|
|
15726
|
+
if (walk.project.length > 0 && (import_typescript3.default.isStringLiteral(expr) || import_typescript3.default.isNoSubstitutionTemplateLiteral(expr) || import_typescript3.default.isTemplateExpression(expr) || import_typescript3.default.isBinaryExpression(expr) && expr.operatorToken.kind === import_typescript3.default.SyntaxKind.PlusToken)) {
|
|
15727
|
+
return;
|
|
15728
|
+
}
|
|
15729
|
+
if (import_typescript3.default.isStringLiteral(expr) || import_typescript3.default.isNoSubstitutionTemplateLiteral(expr)) {
|
|
15730
|
+
this.text(expr, expr.text, owner, walk);
|
|
15731
|
+
return;
|
|
15732
|
+
}
|
|
15733
|
+
if (import_typescript3.default.isTemplateExpression(expr)) {
|
|
15734
|
+
const sf = expr.getSourceFile();
|
|
15735
|
+
let text = expr.head.text;
|
|
15736
|
+
for (const span of expr.templateSpans) {
|
|
15737
|
+
text += `{{${span.expression.getText(sf).replace(/\s+/g, " ").slice(0, 60)}}}${span.literal.text}`;
|
|
15738
|
+
}
|
|
15739
|
+
this.text(expr, text, owner ?? { node: expr, kind: "template" }, walk);
|
|
15740
|
+
for (const span of expr.templateSpans)
|
|
15741
|
+
this.value(span.expression, undefined, flag(walk, "interpolated"));
|
|
15742
|
+
return;
|
|
15743
|
+
}
|
|
15744
|
+
if (import_typescript3.default.isBinaryExpression(expr)) {
|
|
15745
|
+
if (expr.operatorToken.kind === import_typescript3.default.SyntaxKind.PlusToken) {
|
|
15746
|
+
this.value(expr.left, owner, walk);
|
|
15747
|
+
this.value(expr.right, owner, walk);
|
|
15748
|
+
} else if (expr.operatorToken.kind === import_typescript3.default.SyntaxKind.BarBarToken || expr.operatorToken.kind === import_typescript3.default.SyntaxKind.QuestionQuestionToken) {
|
|
15749
|
+
this.value(expr.left, owner, walk);
|
|
15750
|
+
this.value(expr.right, owner, walk);
|
|
15751
|
+
}
|
|
15752
|
+
return;
|
|
15753
|
+
}
|
|
15754
|
+
if (import_typescript3.default.isConditionalExpression(expr)) {
|
|
15755
|
+
this.value(expr.whenTrue, owner, walk);
|
|
15756
|
+
this.value(expr.whenFalse, owner, walk);
|
|
15757
|
+
return;
|
|
15758
|
+
}
|
|
15759
|
+
if (import_typescript3.default.isArrayLiteralExpression(expr)) {
|
|
15760
|
+
for (const element of expr.elements) {
|
|
15761
|
+
this.value(import_typescript3.default.isSpreadElement(element) ? element.expression : element, owner, walk);
|
|
15762
|
+
}
|
|
15763
|
+
return;
|
|
15764
|
+
}
|
|
15765
|
+
if (import_typescript3.default.isObjectLiteralExpression(expr)) {
|
|
15766
|
+
this.objectValue(expr, walk);
|
|
15767
|
+
return;
|
|
15768
|
+
}
|
|
15769
|
+
if (import_typescript3.default.isIdentifier(expr)) {
|
|
15770
|
+
this.identifier(expr, owner, walk);
|
|
15771
|
+
return;
|
|
15772
|
+
}
|
|
15773
|
+
if (import_typescript3.default.isPropertyAccessExpression(expr)) {
|
|
15774
|
+
this.propertyAccess(expr, owner, walk);
|
|
15775
|
+
return;
|
|
15776
|
+
}
|
|
15777
|
+
if (import_typescript3.default.isElementAccessExpression(expr)) {
|
|
15778
|
+
this.elementAccess(expr, owner, walk);
|
|
15779
|
+
return;
|
|
15780
|
+
}
|
|
15781
|
+
if (import_typescript3.default.isCallExpression(expr)) {
|
|
15782
|
+
this.call(expr, owner, walk);
|
|
15783
|
+
return;
|
|
15784
|
+
}
|
|
15785
|
+
if (import_typescript3.default.isTaggedTemplateExpression(expr)) {
|
|
15786
|
+
this.value(expr.template, owner, walk);
|
|
15787
|
+
return;
|
|
15788
|
+
}
|
|
15789
|
+
if (import_typescript3.default.isArrowFunction(expr) || import_typescript3.default.isFunctionExpression(expr)) {
|
|
15790
|
+
this.builderBody(expr, { node: expr, name: owner?.name, kind: "builder" }, walk);
|
|
15791
|
+
}
|
|
15792
|
+
}
|
|
15793
|
+
objectValue(object, walk) {
|
|
15794
|
+
if (walk.project.length > 0) {
|
|
15795
|
+
const [field, ...rest] = walk.project;
|
|
15796
|
+
const inner = { ...walk, project: rest };
|
|
15797
|
+
for (const property of object.properties) {
|
|
15798
|
+
if (import_typescript3.default.isSpreadAssignment(property)) {
|
|
15799
|
+
this.value(property.expression, undefined, walk);
|
|
15800
|
+
continue;
|
|
15801
|
+
}
|
|
15802
|
+
if (propertyName(property) !== field)
|
|
15803
|
+
continue;
|
|
15804
|
+
if (import_typescript3.default.isPropertyAssignment(property))
|
|
15805
|
+
this.value(property.initializer, { node: property, name: field, kind: "literal" }, inner);
|
|
15806
|
+
else if (import_typescript3.default.isShorthandPropertyAssignment(property))
|
|
15807
|
+
this.identifier(property.name, undefined, inner);
|
|
15808
|
+
else if (import_typescript3.default.isMethodDeclaration(property) || import_typescript3.default.isGetAccessorDeclaration(property))
|
|
15809
|
+
this.builderBody(property, { node: property, name: field, kind: "builder" }, inner);
|
|
15810
|
+
}
|
|
15811
|
+
return;
|
|
15812
|
+
}
|
|
15813
|
+
const role = stringField(object, "role");
|
|
15814
|
+
if (role && /^(?:assistant|tool|function|model)$/.test(role))
|
|
15815
|
+
return;
|
|
15816
|
+
for (const property of object.properties) {
|
|
15817
|
+
if (import_typescript3.default.isSpreadAssignment(property)) {
|
|
15818
|
+
this.value(property.expression, undefined, walk);
|
|
15819
|
+
continue;
|
|
15820
|
+
}
|
|
15821
|
+
const key = propertyName(property);
|
|
15822
|
+
if (!key)
|
|
15823
|
+
continue;
|
|
15824
|
+
const promptField = PROMPT_FIELDS.has(key) || walk.promptObject === true;
|
|
15825
|
+
if (!promptField) {
|
|
15826
|
+
if (import_typescript3.default.isPropertyAssignment(property) && import_typescript3.default.isObjectLiteralExpression(unwrap(property.initializer))) {
|
|
15827
|
+
this.objectValue(unwrap(property.initializer), walk);
|
|
15828
|
+
}
|
|
15829
|
+
continue;
|
|
15830
|
+
}
|
|
15831
|
+
const inner = PROMPT_FIELDS.has(key) && !/^(?:content|text|messages|user|system|prompt)$/.test(key) ? { ...walk, promptObject: true } : walk;
|
|
15832
|
+
if (import_typescript3.default.isPropertyAssignment(property)) {
|
|
15833
|
+
const kind = role ? "message" : "literal";
|
|
15834
|
+
this.value(property.initializer, { node: property, name: role ? undefined : key, kind }, this.messageRole(inner, role));
|
|
15835
|
+
} else if (import_typescript3.default.isShorthandPropertyAssignment(property)) {
|
|
15836
|
+
this.identifier(property.name, undefined, inner);
|
|
15837
|
+
}
|
|
15838
|
+
}
|
|
15839
|
+
}
|
|
15840
|
+
messageRole(walk, role) {
|
|
15841
|
+
if (!role || walk.role !== "messages")
|
|
15842
|
+
return walk;
|
|
15843
|
+
return { ...walk, role: role === "system" || role === "developer" ? "system" : "user" };
|
|
15844
|
+
}
|
|
15845
|
+
identifier(identifier, owner, walk) {
|
|
15846
|
+
if (identifier.text === "undefined")
|
|
15847
|
+
return;
|
|
15848
|
+
const declarations = this.declarationsOf(identifier);
|
|
15849
|
+
if (declarations.length === 0) {
|
|
15850
|
+
this.markUnresolved(identifier, "external", walk);
|
|
15851
|
+
return;
|
|
15852
|
+
}
|
|
15853
|
+
for (const declaration of declarations)
|
|
15854
|
+
this.declaration(declaration, identifier, owner, walk);
|
|
15855
|
+
}
|
|
15856
|
+
propertyAccess(access, owner, walk) {
|
|
15857
|
+
const sf = access.getSourceFile();
|
|
15858
|
+
const text = access.getText(sf);
|
|
15859
|
+
if (/^(?:process\.env|import\.meta\.env|Deno\.env)\b/.test(text)) {
|
|
15860
|
+
this.markUnresolved(access, "env", walk);
|
|
15861
|
+
return;
|
|
15862
|
+
}
|
|
15863
|
+
const declarations = this.declarationsOf(access.name).filter(hasValue);
|
|
15864
|
+
if (walk.flags.includes("interpolated") && !PROMPT_FIELD_NAME.test(access.name.text) && declarations.length >= 3 && declarations.every((d) => import_typescript3.default.isPropertyAssignment(d) || import_typescript3.default.isShorthandPropertyAssignment(d))) {
|
|
15865
|
+
return;
|
|
15866
|
+
}
|
|
15867
|
+
if (declarations.length > 0) {
|
|
15868
|
+
for (const declaration of declarations)
|
|
15869
|
+
this.declaration(declaration, access, owner, walk);
|
|
15870
|
+
return;
|
|
15871
|
+
}
|
|
15872
|
+
if (walk.project.length === 0 && !PROMPT_FIELD_NAME.test(access.name.text))
|
|
15873
|
+
return;
|
|
15874
|
+
this.value(access.expression, owner, { ...flag(walk, "projected"), project: [access.name.text, ...walk.project] });
|
|
15875
|
+
}
|
|
15876
|
+
elementAccess(access, owner, walk) {
|
|
15877
|
+
const key = unwrap(access.argumentExpression);
|
|
15878
|
+
const literalKey = import_typescript3.default.isStringLiteral(key) || import_typescript3.default.isNumericLiteral(key) || import_typescript3.default.isNoSubstitutionTemplateLiteral(key) ? key.text : undefined;
|
|
15879
|
+
if (literalKey !== undefined) {
|
|
15880
|
+
const declarations = this.declarationsOf(access.argumentExpression);
|
|
15881
|
+
if (declarations.length > 0) {
|
|
15882
|
+
for (const declaration of declarations)
|
|
15883
|
+
this.declaration(declaration, access, owner, walk);
|
|
15884
|
+
return;
|
|
15885
|
+
}
|
|
15886
|
+
}
|
|
15887
|
+
const table = this.objectLiteralOf(access.expression);
|
|
15888
|
+
if (!table) {
|
|
15889
|
+
this.value(access.expression, owner, walk);
|
|
15890
|
+
return;
|
|
15891
|
+
}
|
|
15892
|
+
const next = this.step(literalKey ? walk : flag(walk, "dynamic-key"), access, literalKey ? `table field ${literalKey}` : "every field of a table read with a dynamic key");
|
|
15893
|
+
if (!next)
|
|
15894
|
+
return;
|
|
15895
|
+
if (import_typescript3.default.isArrayLiteralExpression(table)) {
|
|
15896
|
+
const elements = literalKey !== undefined && import_typescript3.default.isNumericLiteral(key) ? [table.elements[Number(literalKey)]].filter(Boolean) : table.elements;
|
|
15897
|
+
for (const element of elements)
|
|
15898
|
+
this.value(import_typescript3.default.isSpreadElement(element) ? element.expression : element, undefined, next);
|
|
15899
|
+
return;
|
|
15900
|
+
}
|
|
15901
|
+
for (const property of table.properties) {
|
|
15902
|
+
const name = propertyName(property);
|
|
15903
|
+
if (literalKey !== undefined && name !== literalKey)
|
|
15904
|
+
continue;
|
|
15905
|
+
if (import_typescript3.default.isPropertyAssignment(property))
|
|
15906
|
+
this.value(property.initializer, { node: property, name, kind: "literal" }, next);
|
|
15907
|
+
else if (import_typescript3.default.isMethodDeclaration(property))
|
|
15908
|
+
this.builderBody(property, { node: property, name, kind: "builder" }, next);
|
|
15909
|
+
else if (import_typescript3.default.isShorthandPropertyAssignment(property))
|
|
15910
|
+
this.identifier(property.name, undefined, next);
|
|
15911
|
+
}
|
|
15912
|
+
}
|
|
15913
|
+
call(call, owner, walk) {
|
|
15914
|
+
const callee = call.expression;
|
|
15915
|
+
if (import_typescript3.default.isPropertyAccessExpression(callee)) {
|
|
15916
|
+
const method = callee.name.text;
|
|
15917
|
+
if (method === "finally") {
|
|
15918
|
+
this.value(callee.expression, owner, walk);
|
|
15919
|
+
return;
|
|
15920
|
+
}
|
|
15921
|
+
if (CALLBACK_METHODS.has(method)) {
|
|
15922
|
+
const callbacks = call.arguments.map(unwrap).filter((a) => import_typescript3.default.isArrowFunction(a) || import_typescript3.default.isFunctionExpression(a));
|
|
15923
|
+
for (const callback of callbacks)
|
|
15924
|
+
this.builderBody(callback, owner ?? { node: callback, kind: "builder" }, walk);
|
|
15925
|
+
if (callbacks.length === 0)
|
|
15926
|
+
for (const argument of call.arguments)
|
|
15927
|
+
this.value(argument, owner, walk);
|
|
15928
|
+
if (method === "catch")
|
|
15929
|
+
this.value(callee.expression, owner, walk);
|
|
15930
|
+
return;
|
|
15931
|
+
}
|
|
15932
|
+
if (TEXT_PRESERVING_METHODS.has(method) || ARRAY_ASSEMBLY_METHODS.has(method)) {
|
|
15933
|
+
this.value(callee.expression, owner, walk);
|
|
15934
|
+
if (method === "concat")
|
|
15935
|
+
for (const argument of call.arguments)
|
|
15936
|
+
this.value(argument, owner, walk);
|
|
15937
|
+
return;
|
|
15938
|
+
}
|
|
15939
|
+
}
|
|
15940
|
+
if (walk.project.length > 0 && import_typescript3.default.isPropertyAccessExpression(callee) && callee.getText() === "JSON.stringify" && call.arguments[0]) {
|
|
15941
|
+
this.value(call.arguments[0], owner, walk);
|
|
15942
|
+
return;
|
|
15943
|
+
}
|
|
15944
|
+
if (import_typescript3.default.isIdentifier(callee) && /^(?:String|dedent|outdent|stripIndent|stripIndents|trim)$/.test(callee.text)) {
|
|
15945
|
+
for (const argument of call.arguments)
|
|
15946
|
+
this.value(argument, owner, walk);
|
|
15947
|
+
return;
|
|
15948
|
+
}
|
|
15949
|
+
const declarations = this.declarationsOf(import_typescript3.default.isPropertyAccessExpression(callee) ? callee.name : callee);
|
|
15950
|
+
let functions = declarations.map(functionOf).filter((fn) => Boolean(fn));
|
|
15951
|
+
if (functions.length === 0 && import_typescript3.default.isPropertyAccessExpression(callee)) {
|
|
15952
|
+
const methods = this.methodsNamed(callee.name.text);
|
|
15953
|
+
if (methods.length === 1)
|
|
15954
|
+
functions = methods;
|
|
15955
|
+
}
|
|
15956
|
+
functions = functions.filter((fn) => fn.body);
|
|
15957
|
+
if (functions.length === 0) {
|
|
15958
|
+
this.markUnresolved(call, /\b(?:fetch|read|load|get|query|select|find)\w*\s*$/i.test(callee.getText(call.getSourceFile())) ? "io" : "external", walk);
|
|
15959
|
+
return;
|
|
15960
|
+
}
|
|
15961
|
+
for (const fn of functions) {
|
|
15962
|
+
if (walk.seen.has(fn))
|
|
15963
|
+
continue;
|
|
15964
|
+
const name = functionName(fn);
|
|
15965
|
+
const next = this.step(walk, fn, `builder ${name ?? "function"} called at ${this.where(call)}`);
|
|
15966
|
+
if (!next)
|
|
15967
|
+
continue;
|
|
15968
|
+
next.bindings = new Map(next.bindings);
|
|
15969
|
+
bindParameters(fn, call.arguments, walk.bindings, next.bindings);
|
|
15970
|
+
this.builderBody(fn, { node: fn, name, kind: "builder" }, next);
|
|
15971
|
+
}
|
|
15972
|
+
}
|
|
15973
|
+
builderBody(fn, owner, walk) {
|
|
15974
|
+
const body = fn.body;
|
|
15975
|
+
if (!body)
|
|
15976
|
+
return;
|
|
15977
|
+
const inner = { ...walk, seen: new Set(walk.seen).add(fn) };
|
|
15978
|
+
if (!import_typescript3.default.isBlock(body)) {
|
|
15979
|
+
this.value(body, owner, inner);
|
|
15980
|
+
return;
|
|
15981
|
+
}
|
|
15982
|
+
const visit = (node) => {
|
|
15983
|
+
if (node !== fn && import_typescript3.default.isFunctionLike(node))
|
|
15984
|
+
return;
|
|
15985
|
+
if (import_typescript3.default.isReturnStatement(node) && node.expression)
|
|
15986
|
+
this.value(node.expression, owner, inner);
|
|
15987
|
+
import_typescript3.default.forEachChild(node, visit);
|
|
15988
|
+
};
|
|
15989
|
+
visit(body);
|
|
15990
|
+
}
|
|
15991
|
+
declaration(declaration, at, owner, walk) {
|
|
15992
|
+
if (walk.seen.has(declaration))
|
|
15993
|
+
return;
|
|
15994
|
+
if (import_typescript3.default.isParameter(declaration) || import_typescript3.default.isBindingElement(declaration) && isParameterBinding(declaration)) {
|
|
15995
|
+
this.parameter(declaration, at, owner, walk);
|
|
15996
|
+
return;
|
|
15997
|
+
}
|
|
15998
|
+
const sf = declaration.getSourceFile();
|
|
15999
|
+
if (this.isExternal(sf)) {
|
|
16000
|
+
this.markUnresolved(at, "external", walk);
|
|
16001
|
+
return;
|
|
16002
|
+
}
|
|
16003
|
+
const name = declarationName(declaration);
|
|
16004
|
+
const next = this.step(walk, declaration, `${name ?? "value"} defined here`);
|
|
16005
|
+
if (!next)
|
|
16006
|
+
return;
|
|
16007
|
+
next.seen = new Set(next.seen).add(declaration);
|
|
16008
|
+
if (import_typescript3.default.isVariableDeclaration(declaration)) {
|
|
16009
|
+
if (declaration.initializer) {
|
|
16010
|
+
const fn2 = unwrap(declaration.initializer);
|
|
16011
|
+
if (import_typescript3.default.isArrowFunction(fn2) || import_typescript3.default.isFunctionExpression(fn2)) {
|
|
16012
|
+
this.builderBody(fn2, { node: declaration, name, kind: "builder" }, next);
|
|
16013
|
+
} else {
|
|
16014
|
+
this.value(declaration.initializer, ownerFor(declaration, name, owner), next);
|
|
16015
|
+
}
|
|
16016
|
+
}
|
|
16017
|
+
this.assembly(declaration, ownerFor(declaration, name, owner), next);
|
|
16018
|
+
return;
|
|
16019
|
+
}
|
|
16020
|
+
if (import_typescript3.default.isPropertyAssignment(declaration)) {
|
|
16021
|
+
this.value(declaration.initializer, ownerFor(declaration, name, owner), next);
|
|
16022
|
+
return;
|
|
16023
|
+
}
|
|
16024
|
+
if (import_typescript3.default.isShorthandPropertyAssignment(declaration)) {
|
|
16025
|
+
this.identifier(declaration.name, owner, next);
|
|
16026
|
+
return;
|
|
16027
|
+
}
|
|
16028
|
+
if (import_typescript3.default.isPropertyDeclaration(declaration)) {
|
|
16029
|
+
if (declaration.initializer)
|
|
16030
|
+
this.value(declaration.initializer, ownerFor(declaration, name, owner), next);
|
|
16031
|
+
if (name && import_typescript3.default.isClassLike(declaration.parent)) {
|
|
16032
|
+
const visit = (node) => {
|
|
16033
|
+
if (import_typescript3.default.isBinaryExpression(node) && node.operatorToken.kind === import_typescript3.default.SyntaxKind.EqualsToken && import_typescript3.default.isPropertyAccessExpression(node.left) && node.left.expression.kind === import_typescript3.default.SyntaxKind.ThisKeyword && node.left.name.text === name) {
|
|
16034
|
+
this.value(node.right, undefined, next);
|
|
16035
|
+
}
|
|
16036
|
+
import_typescript3.default.forEachChild(node, visit);
|
|
16037
|
+
};
|
|
16038
|
+
visit(declaration.parent);
|
|
16039
|
+
}
|
|
16040
|
+
return;
|
|
16041
|
+
}
|
|
16042
|
+
if (import_typescript3.default.isEnumMember(declaration) && declaration.initializer) {
|
|
16043
|
+
this.value(declaration.initializer, ownerFor(declaration, name, owner), next);
|
|
16044
|
+
return;
|
|
16045
|
+
}
|
|
16046
|
+
const fn = functionOf(declaration);
|
|
16047
|
+
if (fn)
|
|
16048
|
+
this.builderBody(fn, { node: declaration, name, kind: "builder" }, next);
|
|
16049
|
+
}
|
|
16050
|
+
assembly(declaration, owner, walk) {
|
|
16051
|
+
if (!import_typescript3.default.isIdentifier(declaration.name))
|
|
16052
|
+
return;
|
|
16053
|
+
const name = declaration.name.text;
|
|
16054
|
+
const scope = enclosingScope(declaration);
|
|
16055
|
+
if (!scope)
|
|
16056
|
+
return;
|
|
16057
|
+
const isThis = (identifier) => identifier.text === name && this.declarationsOf(identifier).includes(declaration);
|
|
16058
|
+
const visit = (node) => {
|
|
16059
|
+
if (import_typescript3.default.isCallExpression(node) && import_typescript3.default.isPropertyAccessExpression(node.expression) && import_typescript3.default.isIdentifier(node.expression.expression) && isThis(node.expression.expression) && /^(?:push|unshift|splice)$/.test(node.expression.name.text)) {
|
|
16060
|
+
const args = node.expression.name.text === "splice" ? node.arguments.slice(2) : node.arguments;
|
|
16061
|
+
for (const argument of args)
|
|
16062
|
+
this.value(argument, owner, walk);
|
|
16063
|
+
}
|
|
16064
|
+
if (import_typescript3.default.isBinaryExpression(node) && import_typescript3.default.isIdentifier(node.left) && isThis(node.left)) {
|
|
16065
|
+
if (node.operatorToken.kind === import_typescript3.default.SyntaxKind.PlusEqualsToken)
|
|
16066
|
+
this.value(node.right, owner, walk);
|
|
16067
|
+
if (node.operatorToken.kind === import_typescript3.default.SyntaxKind.EqualsToken && node.right !== declaration.initializer)
|
|
16068
|
+
this.value(node.right, owner, walk);
|
|
16069
|
+
}
|
|
16070
|
+
import_typescript3.default.forEachChild(node, visit);
|
|
16071
|
+
};
|
|
16072
|
+
visit(scope);
|
|
16073
|
+
}
|
|
16074
|
+
parameter(declaration, at, owner, walk) {
|
|
16075
|
+
const bound = walk.bindings.get(declaration);
|
|
16076
|
+
if (bound) {
|
|
16077
|
+
this.value(bound.expr, undefined, { ...walk, bindings: bound.bindings, project: [...bound.project ?? [], ...walk.project] });
|
|
16078
|
+
return;
|
|
16079
|
+
}
|
|
16080
|
+
const parameter = import_typescript3.default.isParameter(declaration) ? declaration : parameterOf(declaration);
|
|
16081
|
+
const fn = parameter?.parent;
|
|
16082
|
+
if (!parameter || !fn || !import_typescript3.default.isFunctionLike(fn)) {
|
|
16083
|
+
this.markUnresolved(at, "param-unbound", walk);
|
|
16084
|
+
return;
|
|
16085
|
+
}
|
|
16086
|
+
if (walk.paramLevels >= this.maxParamLevels) {
|
|
16087
|
+
this.markUnresolved(at, "depth-limit", walk);
|
|
16088
|
+
return;
|
|
16089
|
+
}
|
|
16090
|
+
if (parameter.initializer)
|
|
16091
|
+
this.value(parameter.initializer, owner, walk);
|
|
16092
|
+
const callers = this.callersOf(fn);
|
|
16093
|
+
if (callers.length === 0) {
|
|
16094
|
+
if (!parameter.initializer)
|
|
16095
|
+
this.markUnresolved(at, "param-unbound", walk);
|
|
16096
|
+
return;
|
|
16097
|
+
}
|
|
16098
|
+
const index = fn.parameters.indexOf(parameter);
|
|
16099
|
+
for (const caller of callers) {
|
|
16100
|
+
const argument = caller.arguments[index];
|
|
16101
|
+
if (!argument)
|
|
16102
|
+
continue;
|
|
16103
|
+
const next = this.step(flag(walk, "caller-argument"), caller, `argument ${index + 1} at a caller of ${functionName(fn) ?? "the function"}`);
|
|
16104
|
+
if (!next)
|
|
16105
|
+
continue;
|
|
16106
|
+
next.paramLevels += 1;
|
|
16107
|
+
next.bindings = new Map;
|
|
16108
|
+
if (import_typescript3.default.isBindingElement(declaration)) {
|
|
16109
|
+
const field = bindingField(declaration);
|
|
16110
|
+
const object = import_typescript3.default.isObjectLiteralExpression(unwrap(argument)) ? unwrap(argument) : undefined;
|
|
16111
|
+
const property = object?.properties.find((p2) => propertyName(p2) === field);
|
|
16112
|
+
if (property && import_typescript3.default.isPropertyAssignment(property))
|
|
16113
|
+
this.value(property.initializer, undefined, next);
|
|
16114
|
+
else if (property && import_typescript3.default.isShorthandPropertyAssignment(property))
|
|
16115
|
+
this.identifier(property.name, undefined, next);
|
|
16116
|
+
else if (!object && field)
|
|
16117
|
+
this.value(argument, undefined, { ...next, project: [field, ...next.project] });
|
|
16118
|
+
continue;
|
|
16119
|
+
}
|
|
16120
|
+
this.value(argument, undefined, next);
|
|
16121
|
+
}
|
|
16122
|
+
}
|
|
16123
|
+
callersOf(fn) {
|
|
16124
|
+
const name = functionName(fn);
|
|
16125
|
+
if (!name)
|
|
16126
|
+
return [];
|
|
16127
|
+
this.indexCallers();
|
|
16128
|
+
const names = [name, ...this.aliasesByName.get(name) ?? []];
|
|
16129
|
+
const candidates = names.flatMap((alias) => this.callersByName.get(alias) ?? []);
|
|
16130
|
+
return candidates.filter((call) => {
|
|
16131
|
+
const callee = import_typescript3.default.isPropertyAccessExpression(call.expression) ? call.expression.name : call.expression;
|
|
16132
|
+
return this.declarationsOf(callee).some((declaration) => functionOf(declaration) === fn || declaration === fn);
|
|
16133
|
+
});
|
|
16134
|
+
}
|
|
16135
|
+
sourceFiles() {
|
|
16136
|
+
const byName = new Map;
|
|
16137
|
+
for (const program of this.context.programs) {
|
|
16138
|
+
for (const file of program.getSourceFiles()) {
|
|
16139
|
+
if (!this.isExternal(file) && !byName.has(file.fileName))
|
|
16140
|
+
byName.set(file.fileName, file);
|
|
16141
|
+
}
|
|
16142
|
+
}
|
|
16143
|
+
return [...byName.values()];
|
|
16144
|
+
}
|
|
16145
|
+
methodsNamed(name) {
|
|
16146
|
+
if (!this.methodIndex) {
|
|
16147
|
+
this.methodIndex = new Map;
|
|
16148
|
+
for (const file of this.sourceFiles()) {
|
|
16149
|
+
{
|
|
16150
|
+
const visit = (node) => {
|
|
16151
|
+
if (import_typescript3.default.isClassLike(node)) {
|
|
16152
|
+
for (const member of node.members) {
|
|
16153
|
+
if ((import_typescript3.default.isMethodDeclaration(member) || import_typescript3.default.isGetAccessorDeclaration(member)) && member.body && member.name && import_typescript3.default.isIdentifier(member.name)) {
|
|
16154
|
+
const list = this.methodIndex.get(member.name.text) ?? [];
|
|
16155
|
+
list.push(member);
|
|
16156
|
+
this.methodIndex.set(member.name.text, list);
|
|
16157
|
+
}
|
|
16158
|
+
}
|
|
16159
|
+
}
|
|
16160
|
+
import_typescript3.default.forEachChild(node, visit);
|
|
16161
|
+
};
|
|
16162
|
+
visit(file);
|
|
16163
|
+
}
|
|
16164
|
+
}
|
|
16165
|
+
}
|
|
16166
|
+
return this.methodIndex.get(name) ?? [];
|
|
16167
|
+
}
|
|
16168
|
+
indexCallers() {
|
|
16169
|
+
if (this.callersIndexed)
|
|
16170
|
+
return;
|
|
16171
|
+
this.callersIndexed = true;
|
|
16172
|
+
for (const file of this.sourceFiles()) {
|
|
16173
|
+
{
|
|
16174
|
+
const visit = (node) => {
|
|
16175
|
+
if (import_typescript3.default.isCallExpression(node)) {
|
|
16176
|
+
const callee = import_typescript3.default.isPropertyAccessExpression(node.expression) ? node.expression.name : node.expression;
|
|
16177
|
+
if (import_typescript3.default.isIdentifier(callee)) {
|
|
16178
|
+
const list = this.callersByName.get(callee.text) ?? [];
|
|
16179
|
+
list.push(node);
|
|
16180
|
+
this.callersByName.set(callee.text, list);
|
|
16181
|
+
}
|
|
16182
|
+
}
|
|
16183
|
+
if ((import_typescript3.default.isImportSpecifier(node) || import_typescript3.default.isExportSpecifier(node)) && node.propertyName && import_typescript3.default.isIdentifier(node.propertyName)) {
|
|
16184
|
+
const aliases = this.aliasesByName.get(node.propertyName.text) ?? new Set;
|
|
16185
|
+
aliases.add(node.name.text);
|
|
16186
|
+
this.aliasesByName.set(node.propertyName.text, aliases);
|
|
16187
|
+
}
|
|
16188
|
+
import_typescript3.default.forEachChild(node, visit);
|
|
16189
|
+
};
|
|
16190
|
+
visit(file);
|
|
16191
|
+
}
|
|
16192
|
+
}
|
|
16193
|
+
}
|
|
16194
|
+
objectLiteralOf(node) {
|
|
16195
|
+
let current = unwrap(node);
|
|
16196
|
+
for (let i = 0;i < 6; i++) {
|
|
16197
|
+
if (import_typescript3.default.isObjectLiteralExpression(current) || import_typescript3.default.isArrayLiteralExpression(current))
|
|
16198
|
+
return current;
|
|
16199
|
+
const target = import_typescript3.default.isPropertyAccessExpression(current) ? current.name : current;
|
|
16200
|
+
const declaration = this.declarationsOf(target)[0];
|
|
16201
|
+
if (!declaration)
|
|
16202
|
+
return;
|
|
16203
|
+
const initializer = import_typescript3.default.isVariableDeclaration(declaration) || import_typescript3.default.isPropertyAssignment(declaration) || import_typescript3.default.isPropertyDeclaration(declaration) ? declaration.initializer : undefined;
|
|
16204
|
+
if (!initializer)
|
|
16205
|
+
return;
|
|
16206
|
+
current = unwrap(initializer);
|
|
16207
|
+
}
|
|
16208
|
+
return;
|
|
16209
|
+
}
|
|
16210
|
+
declarationsOf(node) {
|
|
16211
|
+
const path = this.relative(node.getSourceFile().fileName);
|
|
16212
|
+
const checker = this.context.checkerFor(path);
|
|
16213
|
+
if (!checker)
|
|
16214
|
+
return [];
|
|
16215
|
+
let symbol = import_typescript3.default.isShorthandPropertyAssignment(node.parent) && node.parent.name === node ? checker.getShorthandAssignmentValueSymbol(node.parent) : checker.getSymbolAtLocation(node);
|
|
16216
|
+
if (!symbol)
|
|
16217
|
+
return [];
|
|
16218
|
+
if (symbol.flags & import_typescript3.default.SymbolFlags.Alias) {
|
|
16219
|
+
try {
|
|
16220
|
+
symbol = checker.getAliasedSymbol(symbol);
|
|
16221
|
+
} catch {
|
|
16222
|
+
return [];
|
|
16223
|
+
}
|
|
16224
|
+
}
|
|
16225
|
+
return (symbol.declarations ?? []).filter((declaration) => !this.isExternal(declaration.getSourceFile()));
|
|
16226
|
+
}
|
|
16227
|
+
step(walk, node, reason) {
|
|
16228
|
+
if (walk.depth + 1 > this.maxDepth) {
|
|
16229
|
+
this.markUnresolved(node, "depth-limit", walk);
|
|
16230
|
+
return;
|
|
16231
|
+
}
|
|
16232
|
+
const hop = { path: this.relative(node.getSourceFile().fileName), line: lineOf2(node), reason };
|
|
16233
|
+
return { ...walk, depth: walk.depth + 1, hops: [...walk.hops, hop] };
|
|
16234
|
+
}
|
|
16235
|
+
text(at, text, owner, walk) {
|
|
16236
|
+
if (walk.namedOnly && !owner?.name)
|
|
16237
|
+
return;
|
|
16238
|
+
const anchor = owner?.node ?? at;
|
|
16239
|
+
const sf = anchor.getSourceFile();
|
|
16240
|
+
const path = this.relative(sf.fileName);
|
|
16241
|
+
if (TEST_SOURCE.test(path))
|
|
16242
|
+
return;
|
|
16243
|
+
if (LOCAL_ONLY_SITE.test(walk.site.path) && path !== walk.site.path)
|
|
16244
|
+
return;
|
|
16245
|
+
const line = lineOf2(anchor);
|
|
16246
|
+
const id = `${path}:${line}`;
|
|
16247
|
+
const key = owner ? `${path}@${anchor.getStart(sf)}` : id;
|
|
16248
|
+
let ref = this.refs.get(key);
|
|
16249
|
+
if (!ref) {
|
|
16250
|
+
ref = {
|
|
16251
|
+
id,
|
|
16252
|
+
path,
|
|
16253
|
+
line,
|
|
16254
|
+
endLine: sf.getLineAndCharacterOfPosition(anchor.getEnd()).line + 1,
|
|
16255
|
+
...owner?.name ? { name: owner.name } : {},
|
|
16256
|
+
kind: owner?.kind ?? "literal",
|
|
16257
|
+
role: walk.role,
|
|
16258
|
+
text: "",
|
|
16259
|
+
callSiteIds: [],
|
|
16260
|
+
hops: walk.hops,
|
|
16261
|
+
via: [...walk.flags],
|
|
16262
|
+
pieces: new Map,
|
|
16263
|
+
start: anchor.getStart(sf)
|
|
16264
|
+
};
|
|
16265
|
+
this.refs.set(key, ref);
|
|
16266
|
+
}
|
|
16267
|
+
ref.start = Math.min(ref.start, anchor.getStart(sf));
|
|
16268
|
+
if (!ref.callSiteIds.includes(walk.site.id))
|
|
16269
|
+
ref.callSiteIds.push(walk.site.id);
|
|
16270
|
+
ref.via = ref.via.filter((f) => walk.flags.includes(f));
|
|
16271
|
+
ref.pieces.set(at.getStart(sf), text);
|
|
16272
|
+
}
|
|
16273
|
+
markUnresolved(node, reason, walk) {
|
|
16274
|
+
const sf = node.getSourceFile();
|
|
16275
|
+
const path = this.relative(sf.fileName);
|
|
16276
|
+
const line = lineOf2(node);
|
|
16277
|
+
const key = `${walk.site.id}|${path}:${line}|${reason}`;
|
|
16278
|
+
if (this.unresolved.has(key))
|
|
16279
|
+
return;
|
|
16280
|
+
this.unresolved.set(key, {
|
|
16281
|
+
callSiteId: walk.site.id,
|
|
16282
|
+
role: walk.role,
|
|
16283
|
+
path,
|
|
16284
|
+
line,
|
|
16285
|
+
expression: node.getText(sf).replace(/\s+/g, " ").slice(0, 120),
|
|
16286
|
+
reason
|
|
16287
|
+
});
|
|
16288
|
+
}
|
|
16289
|
+
columnOf(path, start) {
|
|
16290
|
+
const sf = this.sourceFiles().find((file) => this.relative(file.fileName) === path);
|
|
16291
|
+
return sf ? sf.getLineAndCharacterOfPosition(start).character + 1 : undefined;
|
|
16292
|
+
}
|
|
16293
|
+
where(node) {
|
|
16294
|
+
return `${this.relative(node.getSourceFile().fileName)}:${lineOf2(node)}`;
|
|
16295
|
+
}
|
|
16296
|
+
relative(fileName) {
|
|
16297
|
+
const rel2 = relative6(this.context.rootDir, fileName).replace(/\\/g, "/");
|
|
16298
|
+
return rel2.startsWith("..") ? fileName : rel2;
|
|
16299
|
+
}
|
|
16300
|
+
isExternal(sf) {
|
|
16301
|
+
return sf.isDeclarationFile || /(?:^|\/)node_modules\//.test(sf.fileName);
|
|
16302
|
+
}
|
|
16303
|
+
}
|
|
16304
|
+
function nodeOf(ref, context) {
|
|
16305
|
+
const node = context.nodeAt(ref);
|
|
16306
|
+
return node && import_typescript3.default.isShorthandPropertyAssignment(node) ? node.name : node;
|
|
16307
|
+
}
|
|
16308
|
+
function toolName(definition) {
|
|
16309
|
+
const name = stringField(definition, "name");
|
|
16310
|
+
if (name)
|
|
16311
|
+
return name;
|
|
16312
|
+
const parent = definition.parent;
|
|
16313
|
+
if (import_typescript3.default.isPropertyAssignment(parent))
|
|
16314
|
+
return propertyName(parent);
|
|
16315
|
+
if (import_typescript3.default.isCallExpression(parent) && import_typescript3.default.isPropertyAssignment(parent.parent))
|
|
16316
|
+
return propertyName(parent.parent);
|
|
16317
|
+
if (import_typescript3.default.isCallExpression(parent) && import_typescript3.default.isVariableDeclaration(parent.parent) && import_typescript3.default.isIdentifier(parent.parent.name))
|
|
16318
|
+
return parent.parent.name.text;
|
|
16319
|
+
return;
|
|
16320
|
+
}
|
|
16321
|
+
function flag(walk, f) {
|
|
16322
|
+
return walk.flags.includes(f) ? walk : { ...walk, flags: [...walk.flags, f] };
|
|
16323
|
+
}
|
|
16324
|
+
function unwrap(node) {
|
|
16325
|
+
let current = node;
|
|
16326
|
+
for (;; ) {
|
|
16327
|
+
if (import_typescript3.default.isParenthesizedExpression(current) || import_typescript3.default.isAsExpression(current) || import_typescript3.default.isNonNullExpression(current) || import_typescript3.default.isAwaitExpression(current) || import_typescript3.default.isTypeAssertionExpression(current) || import_typescript3.default.isSatisfiesExpression(current)) {
|
|
16328
|
+
current = current.expression;
|
|
16329
|
+
continue;
|
|
16330
|
+
}
|
|
16331
|
+
return current;
|
|
16332
|
+
}
|
|
16333
|
+
}
|
|
16334
|
+
function lineOf2(node) {
|
|
16335
|
+
const sf = node.getSourceFile();
|
|
16336
|
+
return sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
|
|
16337
|
+
}
|
|
16338
|
+
function propertyName(property) {
|
|
16339
|
+
const name = property.name;
|
|
16340
|
+
if (!name)
|
|
16341
|
+
return;
|
|
16342
|
+
if (import_typescript3.default.isIdentifier(name) || import_typescript3.default.isStringLiteral(name) || import_typescript3.default.isNumericLiteral(name) || import_typescript3.default.isPrivateIdentifier(name))
|
|
16343
|
+
return name.text;
|
|
16344
|
+
return;
|
|
16345
|
+
}
|
|
16346
|
+
function stringField(object, field) {
|
|
16347
|
+
for (const property of object.properties) {
|
|
16348
|
+
if (!import_typescript3.default.isPropertyAssignment(property) || propertyName(property) !== field)
|
|
16349
|
+
continue;
|
|
16350
|
+
const value = unwrap(property.initializer);
|
|
16351
|
+
if (import_typescript3.default.isStringLiteral(value) || import_typescript3.default.isNoSubstitutionTemplateLiteral(value))
|
|
16352
|
+
return value.text;
|
|
16353
|
+
}
|
|
16354
|
+
return;
|
|
16355
|
+
}
|
|
16356
|
+
function declarationName(declaration) {
|
|
16357
|
+
const name = declaration.name;
|
|
16358
|
+
if (name && (import_typescript3.default.isIdentifier(name) || import_typescript3.default.isStringLiteral(name) || import_typescript3.default.isPrivateIdentifier(name)))
|
|
16359
|
+
return name.text;
|
|
16360
|
+
return;
|
|
16361
|
+
}
|
|
16362
|
+
function functionName(fn) {
|
|
16363
|
+
const own = declarationName(fn);
|
|
16364
|
+
if (own)
|
|
16365
|
+
return own;
|
|
16366
|
+
const parent = fn.parent;
|
|
16367
|
+
if (parent && (import_typescript3.default.isVariableDeclaration(parent) || import_typescript3.default.isPropertyAssignment(parent) || import_typescript3.default.isPropertyDeclaration(parent))) {
|
|
16368
|
+
return declarationName(parent);
|
|
16369
|
+
}
|
|
16370
|
+
return;
|
|
16371
|
+
}
|
|
16372
|
+
function functionOf(declaration) {
|
|
16373
|
+
if (import_typescript3.default.isFunctionDeclaration(declaration) || import_typescript3.default.isMethodDeclaration(declaration) || import_typescript3.default.isGetAccessorDeclaration(declaration) || import_typescript3.default.isArrowFunction(declaration) || import_typescript3.default.isFunctionExpression(declaration)) {
|
|
16374
|
+
return declaration;
|
|
16375
|
+
}
|
|
16376
|
+
if ((import_typescript3.default.isVariableDeclaration(declaration) || import_typescript3.default.isPropertyAssignment(declaration) || import_typescript3.default.isPropertyDeclaration(declaration)) && declaration.initializer) {
|
|
16377
|
+
const init = unwrap(declaration.initializer);
|
|
16378
|
+
if (import_typescript3.default.isArrowFunction(init) || import_typescript3.default.isFunctionExpression(init))
|
|
16379
|
+
return init;
|
|
16380
|
+
}
|
|
16381
|
+
return;
|
|
16382
|
+
}
|
|
16383
|
+
function hasValue(declaration) {
|
|
16384
|
+
return !import_typescript3.default.isPropertySignature(declaration) && !import_typescript3.default.isMethodSignature(declaration) && !import_typescript3.default.isIndexSignatureDeclaration(declaration);
|
|
16385
|
+
}
|
|
16386
|
+
function ownerFor(declaration, name, outer) {
|
|
16387
|
+
if (outer?.kind === "builder" && outer.node.getSourceFile() === declaration.getSourceFile() && contains(outer.node, declaration))
|
|
16388
|
+
return outer;
|
|
16389
|
+
return { node: declaration, name, kind: "literal" };
|
|
16390
|
+
}
|
|
16391
|
+
function contains(outer, inner) {
|
|
16392
|
+
return inner.getStart() >= outer.getStart() && inner.getEnd() <= outer.getEnd();
|
|
16393
|
+
}
|
|
16394
|
+
function enclosingScope(declaration) {
|
|
16395
|
+
for (let node = declaration.parent;node; node = node.parent) {
|
|
16396
|
+
if (import_typescript3.default.isBlock(node) || import_typescript3.default.isSourceFile(node) || import_typescript3.default.isModuleBlock(node))
|
|
16397
|
+
return node;
|
|
16398
|
+
}
|
|
16399
|
+
return;
|
|
16400
|
+
}
|
|
16401
|
+
function isParameterBinding(element) {
|
|
16402
|
+
return Boolean(parameterOf(element));
|
|
16403
|
+
}
|
|
16404
|
+
function parameterOf(element) {
|
|
16405
|
+
for (let node = element.parent;node; node = node.parent) {
|
|
16406
|
+
if (import_typescript3.default.isParameter(node))
|
|
16407
|
+
return node;
|
|
16408
|
+
if (!import_typescript3.default.isBindingElement(node) && !import_typescript3.default.isObjectBindingPattern(node) && !import_typescript3.default.isArrayBindingPattern(node))
|
|
16409
|
+
return;
|
|
16410
|
+
}
|
|
16411
|
+
return;
|
|
16412
|
+
}
|
|
16413
|
+
function bindingField(element) {
|
|
16414
|
+
const name = element.propertyName ?? element.name;
|
|
16415
|
+
return import_typescript3.default.isIdentifier(name) || import_typescript3.default.isStringLiteral(name) ? name.text : undefined;
|
|
16416
|
+
}
|
|
16417
|
+
function bindParameters(fn, args, outer, into) {
|
|
16418
|
+
fn.parameters.forEach((parameter, index) => {
|
|
16419
|
+
const argument = args[index];
|
|
16420
|
+
if (!argument)
|
|
16421
|
+
return;
|
|
16422
|
+
if (import_typescript3.default.isIdentifier(parameter.name)) {
|
|
16423
|
+
into.set(parameter, { expr: argument, bindings: outer });
|
|
16424
|
+
return;
|
|
16425
|
+
}
|
|
16426
|
+
if (import_typescript3.default.isObjectBindingPattern(parameter.name)) {
|
|
16427
|
+
const object = unwrap(argument);
|
|
16428
|
+
for (const element of parameter.name.elements) {
|
|
16429
|
+
const field = bindingField(element);
|
|
16430
|
+
if (!import_typescript3.default.isObjectLiteralExpression(object)) {
|
|
16431
|
+
if (field)
|
|
16432
|
+
into.set(element, { expr: argument, bindings: outer, project: [field] });
|
|
16433
|
+
continue;
|
|
16434
|
+
}
|
|
16435
|
+
const property = object.properties.find((p2) => propertyName(p2) === field);
|
|
16436
|
+
if (property && import_typescript3.default.isPropertyAssignment(property))
|
|
16437
|
+
into.set(element, { expr: property.initializer, bindings: outer });
|
|
16438
|
+
else if (property && import_typescript3.default.isShorthandPropertyAssignment(property))
|
|
16439
|
+
into.set(element, { expr: property.name, bindings: outer });
|
|
16440
|
+
}
|
|
16441
|
+
}
|
|
16442
|
+
});
|
|
16443
|
+
}
|
|
16444
|
+
|
|
16445
|
+
// src/harness-extract/prompts/assembler.ts
|
|
16446
|
+
var DIRECT_PROMPT_CONFIDENCE = 0.9;
|
|
16447
|
+
var INDIRECT_PROMPT_CONFIDENCE = 0.75;
|
|
16448
|
+
var MAX_HOP_EVIDENCE = 4;
|
|
16449
|
+
var CALL_PATH_REASON = "call path:";
|
|
16450
|
+
var MAX_BODY_CHARS = 64 * 1024;
|
|
16451
|
+
function assemblePromptArtifacts(resolution, callSites, promoted, options = {}) {
|
|
16452
|
+
const allow = new Set(options.allow ?? ["caller-argument", "dynamic-key", "interpolated", "projected"]);
|
|
16453
|
+
const sites = new Map(callSites.map((site) => [site.id, site]));
|
|
16454
|
+
const toolAgents = new Map;
|
|
16455
|
+
for (const tool of options.toolDefinitions ?? []) {
|
|
16456
|
+
const site = toolDefinitionSite(tool);
|
|
16457
|
+
sites.set(site.id, site);
|
|
16458
|
+
toolAgents.set(site.id, tool.agentIds ?? []);
|
|
16459
|
+
}
|
|
16460
|
+
const kept = resolution.refs.filter((ref) => ref.via.every((flag2) => allow.has(flag2)));
|
|
16461
|
+
const resolved = kept.map((ref) => refArtifact(ref, sites, options.agentForScope, toolAgents));
|
|
16462
|
+
const refs = new Map(resolved.map((artifact, index) => [artifact, kept[index]]));
|
|
16463
|
+
const byId = new Map;
|
|
16464
|
+
for (const artifact of resolved)
|
|
16465
|
+
byId.set(artifact.id, artifact);
|
|
16466
|
+
let merged = 0;
|
|
16467
|
+
let keptPromoted = 0;
|
|
16468
|
+
const artifacts = [...resolved];
|
|
16469
|
+
for (const artifact of promoted) {
|
|
16470
|
+
if (artifact.type !== "prompt") {
|
|
16471
|
+
artifacts.push(artifact);
|
|
16472
|
+
continue;
|
|
16473
|
+
}
|
|
16474
|
+
const same = byId.get(artifact.id) ?? sameDefinition(artifact, resolved, refs);
|
|
16475
|
+
if (same) {
|
|
16476
|
+
mergeInto(same, artifact);
|
|
16477
|
+
merged += 1;
|
|
16478
|
+
continue;
|
|
16479
|
+
}
|
|
16480
|
+
artifacts.push(artifact);
|
|
16481
|
+
keptPromoted += 1;
|
|
16482
|
+
}
|
|
16483
|
+
return {
|
|
16484
|
+
artifacts,
|
|
16485
|
+
unresolved: unresolvedReports(resolution, sites),
|
|
16486
|
+
stats: { resolved: resolved.length, merged, keptPromoted }
|
|
16487
|
+
};
|
|
16488
|
+
}
|
|
16489
|
+
function refArtifact(ref, sites, agentForScope, toolAgents = new Map) {
|
|
16490
|
+
const callSites = ref.callSiteIds.map((id) => sites.get(id)).filter((site) => Boolean(site));
|
|
16491
|
+
const agentIds = [...new Set(callSites.flatMap((site) => toolAgents.get(site.id) ?? site.agentIds ?? (site.scope && agentForScope ? agentForScope(site.scope) : [])))].sort();
|
|
16492
|
+
const first2 = callSites[0];
|
|
16493
|
+
const evidence = [{ path: ref.path, line: ref.line, reason: `prompt ${ref.kind} definition` }];
|
|
16494
|
+
for (const site of callSites.slice(0, MAX_HOP_EVIDENCE)) {
|
|
16495
|
+
evidence.push({ path: site.path, line: site.line, reason: `passed to a model call: ${site.callee} as ${ref.role}` });
|
|
16496
|
+
}
|
|
16497
|
+
for (const hop of ref.hops.slice(-MAX_HOP_EVIDENCE)) {
|
|
16498
|
+
if (hop.path === ref.path && hop.line === ref.line)
|
|
16499
|
+
continue;
|
|
16500
|
+
evidence.push({ path: hop.path, line: hop.line, reason: `${CALL_PATH_REASON} ${hop.reason}` });
|
|
16501
|
+
}
|
|
16502
|
+
const direct = ref.via.length === 0;
|
|
16503
|
+
const where = `${ref.path}:${ref.line}`;
|
|
16504
|
+
const reach = first2 ? `${first2.callee} at ${first2.path}:${first2.line}` : "a model call";
|
|
16505
|
+
return {
|
|
16506
|
+
id: stableId("prompt", `${ref.path.replace(/\.[^.]+$/, "")}:L${ref.line}${ref.column ? `C${ref.column}` : ""}`),
|
|
16507
|
+
type: "prompt",
|
|
16508
|
+
name: ref.name ? titleFromId(ref.name) : `Inline Prompt (${where})`,
|
|
16509
|
+
scope: agentIds.length === 1 ? "agent" : "shared",
|
|
16510
|
+
...agentIds.length === 1 ? { ownedByAgentId: agentIds[0] } : {},
|
|
16511
|
+
usedByAgentIds: agentIds,
|
|
16512
|
+
confidence: direct ? DIRECT_PROMPT_CONFIDENCE : INDIRECT_PROMPT_CONFIDENCE,
|
|
16513
|
+
confidenceReason: direct ? `Call site: ${ref.kind === "builder" ? "builder" : "text"} ${ref.name ?? ""} at ${where} is passed to ${reach} as ${ref.role}.`.replace(/\s+/g, " ") : `Call site: ${ref.name ?? "text"} at ${where} reaches ${reach} as ${ref.role} through ${ref.via.join(", ")}.`,
|
|
16514
|
+
evidence,
|
|
16515
|
+
body: ref.text.length > MAX_BODY_CHARS ? `${ref.text.slice(0, MAX_BODY_CHARS)}
|
|
16516
|
+
[truncated]` : ref.text
|
|
16517
|
+
};
|
|
16518
|
+
}
|
|
16519
|
+
function sameDefinition(promoted, resolved, refs) {
|
|
16520
|
+
const at = promoted.evidence[0];
|
|
16521
|
+
const line = at?.line;
|
|
16522
|
+
if (!at || line === undefined || promoted.sourcePath)
|
|
16523
|
+
return;
|
|
16524
|
+
const columned = /C\d+$/.test(promoted.id);
|
|
16525
|
+
const span = (ref) => ref.endLine - ref.line;
|
|
16526
|
+
return resolved.map((candidate) => ({ candidate, ref: refs.get(candidate) })).filter(({ ref }) => ref.path === at.path && (ref.line === line ? !columned && !ref.column : ref.line < line && line <= ref.endLine)).sort((a, b) => Number(b.ref.line === line) - Number(a.ref.line === line) || span(a.ref) - span(b.ref))[0]?.candidate;
|
|
16527
|
+
}
|
|
16528
|
+
function mergeInto(target, promoted) {
|
|
16529
|
+
const seen = new Set(target.evidence.map((e) => `${e.path}:${e.line}`));
|
|
16530
|
+
for (const evidence of promoted.evidence) {
|
|
16531
|
+
if (!seen.has(`${evidence.path}:${evidence.line}`))
|
|
16532
|
+
target.evidence.push(evidence);
|
|
16533
|
+
}
|
|
16534
|
+
target.confidence = Math.max(target.confidence, promoted.confidence);
|
|
16535
|
+
if ((promoted.body?.length ?? 0) > (target.body?.length ?? 0) && target.body?.includes("{{") !== true)
|
|
16536
|
+
target.body = promoted.body;
|
|
16537
|
+
if (target.id !== promoted.id)
|
|
16538
|
+
target.id = promoted.id;
|
|
16539
|
+
}
|
|
16540
|
+
function unresolvedReports(resolution, sites) {
|
|
16541
|
+
const resolvedSites = new Set(resolution.refs.flatMap((ref) => ref.callSiteIds.map((id) => `${id}|${ref.role}`)));
|
|
16542
|
+
const reports = new Map;
|
|
16543
|
+
for (const value of resolution.unresolved) {
|
|
16544
|
+
if (resolvedSites.has(`${value.callSiteId}|${value.role}`))
|
|
16545
|
+
continue;
|
|
16546
|
+
const site = sites.get(value.callSiteId);
|
|
16547
|
+
if (!site)
|
|
16548
|
+
continue;
|
|
16549
|
+
const key = `${value.callSiteId}|${value.role}`;
|
|
16550
|
+
const report = reports.get(key) ?? { callSiteId: site.id, path: site.path, line: site.line, role: value.role, values: [] };
|
|
16551
|
+
report.values.push({ path: value.path, line: value.line, expression: value.expression, reason: value.reason });
|
|
16552
|
+
reports.set(key, report);
|
|
16553
|
+
}
|
|
16554
|
+
return [...reports.values()];
|
|
16555
|
+
}
|
|
16556
|
+
|
|
16557
|
+
// src/harness-extract/prompts/index.ts
|
|
16558
|
+
function promptArtifactsFromCallSites(callSites, context, promoted, options = {}) {
|
|
16559
|
+
return assemblePromptArtifacts(resolvePromptArguments(callSites, context, options), callSites, promoted, options);
|
|
16560
|
+
}
|
|
16561
|
+
|
|
15473
16562
|
// src/harness-sync-limits.ts
|
|
15474
16563
|
var MAX_HARNESS_SYNC_GRAPH_BYTES = 2000000;
|
|
15475
16564
|
function assertHarnessGraphSyncSize(graph) {
|
|
@@ -15655,7 +16744,7 @@ async function runHarnessCommand(context) {
|
|
|
15655
16744
|
report: {
|
|
15656
16745
|
reportId: report.reportId,
|
|
15657
16746
|
reportHash,
|
|
15658
|
-
path: normalizePath2(
|
|
16747
|
+
path: normalizePath2(relative7(rootDir, reportPath)) || ".moda/harness-report.json"
|
|
15659
16748
|
},
|
|
15660
16749
|
validation,
|
|
15661
16750
|
approval: {
|
|
@@ -15801,7 +16890,7 @@ async function runHarnessCommand(context) {
|
|
|
15801
16890
|
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.");
|
|
15802
16891
|
}
|
|
15803
16892
|
if (context.flags["github-actions"] === "true") {
|
|
15804
|
-
const { runGithubActionsAnalyze } = await import("./harness-github-actions-
|
|
16893
|
+
const { runGithubActionsAnalyze } = await import("./harness-github-actions-vt8tt6n9.js");
|
|
15805
16894
|
const result = await runGithubActionsAnalyze(rootDir, {
|
|
15806
16895
|
writeReport: (report2) => {
|
|
15807
16896
|
const normalized = normalizeHarnessReport(report2);
|
|
@@ -15923,7 +17012,7 @@ async function runHarnessCommand(context) {
|
|
|
15923
17012
|
report: {
|
|
15924
17013
|
reportId: approval.report.reportId,
|
|
15925
17014
|
reportHash: hashHarnessReport(approval.report),
|
|
15926
|
-
path: normalizePath2(
|
|
17015
|
+
path: normalizePath2(relative7(rootDir, reportPath)) || ".moda/harness-report.json"
|
|
15927
17016
|
},
|
|
15928
17017
|
validation: approval.validation,
|
|
15929
17018
|
approval: approval.approval
|
|
@@ -15974,7 +17063,7 @@ async function runHarnessCommand(context) {
|
|
|
15974
17063
|
}
|
|
15975
17064
|
case "extract": {
|
|
15976
17065
|
writeHumanProgress(context, "Harness extract: tracing model call sites (no LLM, no network)...");
|
|
15977
|
-
const { extractHarness, serializeExtractResult } = await import("./index-
|
|
17066
|
+
const { extractHarness, serializeExtractResult } = await import("./index-xkgawks9.js");
|
|
15978
17067
|
const result = extractHarness(rootDir, { fresh: true });
|
|
15979
17068
|
writeHumanProgress(context, `Harness extract: ${result.callSites.length} call sites, ${result.roles.length} traced roles across ${result.files} files (${result.programs} programs, ${result.durationMs.toLocaleString()} ms).`);
|
|
15980
17069
|
context.output.writeData(serializeExtractResult(result));
|
|
@@ -16069,9 +17158,9 @@ async function runHarnessCommand(context) {
|
|
|
16069
17158
|
const readFlags = { list: ["limit", "offset"], show: ["version"], versions: ["limit", "offset"], diff: ["from", "to"] };
|
|
16070
17159
|
assertFlags(`harness ${subcommand}`, context.flags, [...readFlags[subcommand], "path"]);
|
|
16071
17160
|
assertPositionals(`harness ${subcommand}`, context.positionals, subcommand === "list" ? 1 : 2, `moda harness ${subcommand}${subcommand === "list" ? "" : " <harness-id-or-key>"}`);
|
|
16072
|
-
for (const
|
|
16073
|
-
if (context.flags[
|
|
16074
|
-
throw new CliInputError(`--${
|
|
17161
|
+
for (const flag2 of readFlags[subcommand]) {
|
|
17162
|
+
if (context.flags[flag2] === "true")
|
|
17163
|
+
throw new CliInputError(`--${flag2} needs a value.`);
|
|
16075
17164
|
}
|
|
16076
17165
|
const profileOptions = { profile: context.profile, env: context.env };
|
|
16077
17166
|
if (!resolveApiKey(profileOptions)) {
|
|
@@ -16530,7 +17619,7 @@ function modelIdsUsedInSource(rootDir, ids) {
|
|
|
16530
17619
|
const walk = (current) => {
|
|
16531
17620
|
if (pending.size === 0)
|
|
16532
17621
|
return false;
|
|
16533
|
-
const rel2 = normalizePath2(
|
|
17622
|
+
const rel2 = normalizePath2(relative7(rootReal, current)) || ".";
|
|
16534
17623
|
let stat;
|
|
16535
17624
|
try {
|
|
16536
17625
|
stat = lstatSync7(current);
|
|
@@ -16760,6 +17849,8 @@ function mergeDeterministicArtifacts(graph, rootDir, options = {}) {
|
|
|
16760
17849
|
let promoted;
|
|
16761
17850
|
try {
|
|
16762
17851
|
promoted = promoteHarnessCandidates(detectHarnessCandidates(rootDir), rootDir, { fullEvidence: true });
|
|
17852
|
+
if (!allowedTypes || allowedTypes.has("prompt"))
|
|
17853
|
+
promoted = withCallSitePrompts(rootDir, promoted);
|
|
16763
17854
|
} catch {
|
|
16764
17855
|
return { added: 0 };
|
|
16765
17856
|
}
|
|
@@ -16801,6 +17892,18 @@ function mergeDeterministicArtifacts(graph, rootDir, options = {}) {
|
|
|
16801
17892
|
}
|
|
16802
17893
|
return { added };
|
|
16803
17894
|
}
|
|
17895
|
+
function withCallSitePrompts(rootDir, promoted) {
|
|
17896
|
+
if (process.env.MODA_HARNESS_CALLSITE_PROMPTS === "0")
|
|
17897
|
+
return promoted;
|
|
17898
|
+
try {
|
|
17899
|
+
const { result, ctx } = extractHarnessWithContext(rootDir);
|
|
17900
|
+
const sites = result.callSites.filter((site) => !site.isTest);
|
|
17901
|
+
const toolDefinitions = result.toolDefinitions ?? [];
|
|
17902
|
+
return promptArtifactsFromCallSites(sites, ctx, promoted, { toolDefinitions }).artifacts;
|
|
17903
|
+
} catch {
|
|
17904
|
+
return promoted;
|
|
17905
|
+
}
|
|
17906
|
+
}
|
|
16804
17907
|
function backfillRefutationEvidenceReasons(graph) {
|
|
16805
17908
|
for (const unknown of graph.unknowns ?? []) {
|
|
16806
17909
|
if (!/refut/i.test(String(unknown.id ?? "")))
|
|
@@ -16907,7 +18010,7 @@ ${existing.body ?? ""}`, promoted.name)))
|
|
|
16907
18010
|
return true;
|
|
16908
18011
|
}
|
|
16909
18012
|
const promotedName = promoted.name.toLowerCase();
|
|
16910
|
-
const isDefinitionLine = (entry) => typeof entry.line === "number" && !/^(?:passed to a model call|prompt-named literal referenced)/.test(entry.reason ?? "");
|
|
18013
|
+
const isDefinitionLine = (entry) => typeof entry.line === "number" && !/^(?:passed to a model call|prompt-named literal referenced|call path:)/.test(entry.reason ?? "");
|
|
16911
18014
|
const promotedLines = promoted.evidence.filter(isDefinitionLine);
|
|
16912
18015
|
const promotedSource = artifactSourceKey(promoted);
|
|
16913
18016
|
const isWholeFilePrompt = promoted.type === "prompt" && Boolean(promoted.sourcePath);
|
|
@@ -17293,10 +18396,10 @@ function parseExternalAgentEventBody(event) {
|
|
|
17293
18396
|
const subtype = stringValue(event.subtype);
|
|
17294
18397
|
if (type === "rate_limit_event")
|
|
17295
18398
|
return { kind: "rate_limit", message: "rate limit wait" };
|
|
17296
|
-
const
|
|
17297
|
-
if (
|
|
18399
|
+
const toolName2 = stringValue(event.name) ?? stringValue(event.tool_name) ?? stringValue(event.toolName) ?? stringValue(call?.name);
|
|
18400
|
+
if (toolName2 && /tool|call|exec|command|bash/i.test(`${type ?? ""} ${subtype ?? ""}`)) {
|
|
17298
18401
|
const detail = toolInputDetail(event.input ?? event.arguments ?? call?.input ?? call?.arguments);
|
|
17299
|
-
return { kind: "tool", toolName, message: `tool ${
|
|
18402
|
+
return { kind: "tool", toolName: toolName2, message: `tool ${toolName2}`, ...detail ? { detail } : {} };
|
|
17300
18403
|
}
|
|
17301
18404
|
const directText = stringValue(event.text) ?? stringValue(event.message) ?? stringValue(event.delta) ?? stringValue(event.result);
|
|
17302
18405
|
if (directText && !isLowSignalEventType(type)) {
|
|
@@ -17653,8 +18756,8 @@ var READ_ONLY_CLAUDE_ARG_FLAGS = new Map([
|
|
|
17653
18756
|
function readOnlyClaudeExtraArgs(args) {
|
|
17654
18757
|
const kept = [];
|
|
17655
18758
|
for (let i = 0;i < args.length; i += 1) {
|
|
17656
|
-
const [
|
|
17657
|
-
const takesValue = READ_ONLY_CLAUDE_ARG_FLAGS.get(
|
|
18759
|
+
const [flag2, inline] = args[i].split(/=(.*)/s, 2);
|
|
18760
|
+
const takesValue = READ_ONLY_CLAUDE_ARG_FLAGS.get(flag2);
|
|
17658
18761
|
if (takesValue === undefined) {
|
|
17659
18762
|
if (inline === undefined && args[i + 1] !== undefined && !args[i + 1].startsWith("-"))
|
|
17660
18763
|
i += 1;
|
|
@@ -17663,7 +18766,7 @@ function readOnlyClaudeExtraArgs(args) {
|
|
|
17663
18766
|
if (takesValue && inline === undefined) {
|
|
17664
18767
|
if (args[i + 1] === undefined)
|
|
17665
18768
|
continue;
|
|
17666
|
-
kept.push(
|
|
18769
|
+
kept.push(flag2, args[i + 1]);
|
|
17667
18770
|
i += 1;
|
|
17668
18771
|
} else {
|
|
17669
18772
|
kept.push(args[i]);
|
|
@@ -18179,7 +19282,7 @@ function collectSnapshotInputs(rootDir, maxFiles, maxTextBytes) {
|
|
|
18179
19282
|
let inventoryFileCount = 0;
|
|
18180
19283
|
let inventoryTextBytes = 0;
|
|
18181
19284
|
function walk(current) {
|
|
18182
|
-
const path = normalizePath2(
|
|
19285
|
+
const path = normalizePath2(relative7(rootDir, current)) || ".";
|
|
18183
19286
|
let stat;
|
|
18184
19287
|
try {
|
|
18185
19288
|
stat = lstatSync7(current);
|
|
@@ -18250,7 +19353,7 @@ function buildSourceSnapshot(rootDir) {
|
|
|
18250
19353
|
}
|
|
18251
19354
|
function buildCommandScanPlan(context, rootDir) {
|
|
18252
19355
|
const explicitPath = context.flags.path !== undefined;
|
|
18253
|
-
const rel2 = normalizePath2(
|
|
19356
|
+
const rel2 = normalizePath2(relative7(context.cwd, rootDir)) || ".";
|
|
18254
19357
|
const scope = explicitPath && rel2 !== "." ? "narrow" : "broad";
|
|
18255
19358
|
const machineReadable = context.outputMode !== "human";
|
|
18256
19359
|
const approvalRequired = context.positional === "analyze" && scope === "broad" && !context.yes;
|
|
@@ -18335,7 +19438,7 @@ function writeHumanBlock(context, message) {
|
|
|
18335
19438
|
function buildHarnessReadPlan(rootDir, pathWasExplicit) {
|
|
18336
19439
|
return {
|
|
18337
19440
|
scope: pathWasExplicit ? "narrow" : "broad",
|
|
18338
|
-
rootPaths: [normalizePath2(
|
|
19441
|
+
rootPaths: [normalizePath2(relative7(rootDir, rootDir)) || "."],
|
|
18339
19442
|
willRead: [
|
|
18340
19443
|
"package manifests",
|
|
18341
19444
|
"source files under the selected path",
|
|
@@ -18548,7 +19651,7 @@ function findFresherHarnessReports(rootDir) {
|
|
|
18548
19651
|
const candidate = lstatSync7(join9(child, HARNESS_REPORT_PATH));
|
|
18549
19652
|
if (candidate.isFile() && candidate.mtimeMs > rootMtimeMs) {
|
|
18550
19653
|
fresher.push({
|
|
18551
|
-
path: normalizePath2(
|
|
19654
|
+
path: normalizePath2(relative7(rootDir, join9(child, HARNESS_REPORT_PATH))),
|
|
18552
19655
|
mtimeMs: candidate.mtimeMs
|
|
18553
19656
|
});
|
|
18554
19657
|
}
|
|
@@ -18560,7 +19663,7 @@ function findFresherHarnessReports(rootDir) {
|
|
|
18560
19663
|
return fresher.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
18561
19664
|
}
|
|
18562
19665
|
function warnFresherSubdirHarnessReports(context, rootDir, explicitReport) {
|
|
18563
|
-
const explicitReportPath = explicitReport && explicitReport !== "true" ? normalizePath2(
|
|
19666
|
+
const explicitReportPath = explicitReport && explicitReport !== "true" ? normalizePath2(relative7(rootDir, resolve10(rootDir, explicitReport))) : undefined;
|
|
18564
19667
|
if (explicitReportPath && explicitReportPath !== normalizePath2(HARNESS_REPORT_PATH))
|
|
18565
19668
|
return;
|
|
18566
19669
|
let fresher;
|
|
@@ -18767,7 +19870,7 @@ function inventoryFiles(rootDir, skipped, options = {}) {
|
|
|
18767
19870
|
const maxTextBytes = numericEnv("MODA_HARNESS_MAX_TEXT_BYTES", DEFAULT_MAX_INVENTORY_TEXT_BYTES);
|
|
18768
19871
|
let textBytes = 0;
|
|
18769
19872
|
function walk(current) {
|
|
18770
|
-
const rel2 = normalizePath2(
|
|
19873
|
+
const rel2 = normalizePath2(relative7(rootReal, current)) || ".";
|
|
18771
19874
|
let stat;
|
|
18772
19875
|
try {
|
|
18773
19876
|
stat = lstatSync7(current);
|
|
@@ -20118,7 +21221,7 @@ function contentHashForAnnotatedSource(sourcePath, annotation) {
|
|
|
20118
21221
|
function readSmallTextFileForHash(absPath, rootDir) {
|
|
20119
21222
|
if (!existsSync8(absPath))
|
|
20120
21223
|
return;
|
|
20121
|
-
const rel2 = normalizePath2(
|
|
21224
|
+
const rel2 = normalizePath2(relative7(rootDir, absPath));
|
|
20122
21225
|
if (isSecretishPath(rel2))
|
|
20123
21226
|
return;
|
|
20124
21227
|
let stat;
|