@moda-ai/cli 1.55.55 → 1.55.57
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-dc9zkdsm.js → agent-81f11bvs.js} +3 -3
- package/dist/{cli-px4dmcy0.js → cli-6k25gr7h.js} +619 -154
- package/dist/{cli-jnwba1f3.js → cli-8mqz9qgt.js} +3 -3
- package/dist/{cli-eqj302as.js → cli-krt4ap9y.js} +2 -2
- package/dist/cli.js +7 -7
- package/dist/{doctor-r16n0me8.js → doctor-ascpx1py.js} +2 -2
- package/dist/{harness-j0n400bv.js → harness-7cncbphq.js} +1 -1
- package/dist/{harness-github-actions-6bex338w.js → harness-github-actions-tzn5ye9e.js} +1 -1
- package/dist/{index-ecy3ntzc.js → index-zh4ygqq0.js} +3 -3
- package/dist/{prompt-attribution-x84cgdct.js → prompt-attribution-x5bzrr8n.js} +1 -1
- package/dist/prompt-source-mcp.js +1 -1
- package/dist/{prompts-r0mv69yx.js → prompts-e2nyqkyv.js} +1 -1
- package/dist/{sync-p4dz7qmn.js → sync-agcws2qn.js} +2 -2
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildDoctorReport
|
|
3
|
-
} from "./cli-
|
|
3
|
+
} from "./cli-krt4ap9y.js";
|
|
4
4
|
import"./cli-94r5x9bg.js";
|
|
5
|
-
import"./cli-
|
|
5
|
+
import"./cli-8mqz9qgt.js";
|
|
6
6
|
import"./cli-mm48br00.js";
|
|
7
7
|
import {
|
|
8
8
|
readHarnessSyncState
|
|
@@ -95,7 +95,7 @@ async function buildAgentContext(context) {
|
|
|
95
95
|
const graph = readHarnessGraphIfPresent(context.cwd);
|
|
96
96
|
const reportState = readHarnessReportState(context.cwd);
|
|
97
97
|
const syncState = readHarnessSyncState(context.cwd);
|
|
98
|
-
const harness = graph ? await import("./harness-
|
|
98
|
+
const harness = graph ? await import("./harness-7cncbphq.js") : undefined;
|
|
99
99
|
const topFindings = doctor.checks.filter((check) => check.status === "fail" || check.status === "warning").slice(0, 12).map(checkToFinding);
|
|
100
100
|
const evidenceRefs = [
|
|
101
101
|
...doctor.checks.map(checkToEvidenceRef),
|
|
@@ -12128,7 +12128,7 @@ var LINE_PATTERNS = [
|
|
|
12128
12128
|
kind: "prompt_literal",
|
|
12129
12129
|
signal: "code.prompt_configuration_field",
|
|
12130
12130
|
confidence: "high",
|
|
12131
|
-
pattern: /(?:^|[{,])\s*(?:instructions
|
|
12131
|
+
pattern: /(?:^|[{,])\s*["']?(?:instructions?|systemPrompt|system_prompt|systemMessage|system_message|systemInstruction|system_instruction|backstory)["']?\s*:/,
|
|
12132
12132
|
extensions: JS
|
|
12133
12133
|
},
|
|
12134
12134
|
{
|
|
@@ -12145,6 +12145,14 @@ var LINE_PATTERNS = [
|
|
|
12145
12145
|
pattern: /^\s*(?:export\s+)?(?:(?:const|let|var)\s+)?(?:(?:[A-Za-z_$][\w$]*)?(?:prompt|instructions|system|template)[\w$]*)\s*(?::[^=]+)?=/i,
|
|
12146
12146
|
extensions: [...JS, ...PY]
|
|
12147
12147
|
},
|
|
12148
|
+
{
|
|
12149
|
+
kind: "prompt_literal",
|
|
12150
|
+
signal: "code.system_injection",
|
|
12151
|
+
confidence: "high",
|
|
12152
|
+
pattern: /["'`]\s*\[SYSTEM:/,
|
|
12153
|
+
extensions: [...JS, ...PY],
|
|
12154
|
+
maxPerFile: 200
|
|
12155
|
+
},
|
|
12148
12156
|
{
|
|
12149
12157
|
kind: "prompt_literal",
|
|
12150
12158
|
signal: "code.prompt_builder_definition",
|
|
@@ -12311,7 +12319,13 @@ var LINE_PATTERNS = [
|
|
|
12311
12319
|
kind: "model_config",
|
|
12312
12320
|
signal: "model.assignment",
|
|
12313
12321
|
confidence: "high",
|
|
12314
|
-
pattern: /\b(model|model_name|model_id|modelName|modelId|MODEL[A-Z_]*)\s*[:=]\s*["'`][\w.:/-]*(gpt-|o[134](-mini)?\b|claude|gemini|llama|mistral|mixtral|deepseek|qwen|grok|sonnet|opus|haiku|command-r|glm|gemma)[\w.:/-]*["'`]/i
|
|
12322
|
+
pattern: /\b(model|model_name|model_id|modelName|modelId|[A-Z_]*MODEL[A-Z_]*)\s*[:=]\s*["'`][\w.:/-]*(gpt-|o[134](-mini)?\b|claude|gemini|llama|mistral|mixtral|deepseek|qwen|grok|sonnet|opus|haiku|command-r|glm|gemma)[\w.:/-]*["'`]/i
|
|
12323
|
+
},
|
|
12324
|
+
{
|
|
12325
|
+
kind: "model_config",
|
|
12326
|
+
signal: "model.registry_key",
|
|
12327
|
+
confidence: "high",
|
|
12328
|
+
pattern: /^\s*["'`](?:openai|anthropic|google|meta-llama|mistralai|deepseek|qwen|x-ai|cohere|z-ai|moonshotai)\/[\w.:-]+["'`]\s*:/i
|
|
12315
12329
|
},
|
|
12316
12330
|
{
|
|
12317
12331
|
kind: "model_config",
|
|
@@ -12396,7 +12410,7 @@ function detectLinePatterns(file, out) {
|
|
|
12396
12410
|
if (!pattern.pattern.test(line))
|
|
12397
12411
|
continue;
|
|
12398
12412
|
const seen = perSignal.get(pattern.signal) ?? 0;
|
|
12399
|
-
if (seen >= MAX_CANDIDATES_PER_FILE_PER_SIGNAL)
|
|
12413
|
+
if (seen >= (pattern.maxPerFile ?? MAX_CANDIDATES_PER_FILE_PER_SIGNAL) && pattern.kind !== "model_config")
|
|
12400
12414
|
break;
|
|
12401
12415
|
perSignal.set(pattern.signal, seen + 1);
|
|
12402
12416
|
out.push({
|
|
@@ -13560,8 +13574,349 @@ function applyPromptDiscovery(graph, discovery) {
|
|
|
13560
13574
|
}
|
|
13561
13575
|
|
|
13562
13576
|
// src/harness-candidate-promotion.ts
|
|
13563
|
-
import { readFileSync as readFileSync11 } from "node:fs";
|
|
13577
|
+
import { readFileSync as readFileSync11, statSync as statSync3 } from "node:fs";
|
|
13564
13578
|
import { extname as extname7, posix, resolve as resolve9 } from "node:path";
|
|
13579
|
+
|
|
13580
|
+
// src/harness-js-source.ts
|
|
13581
|
+
var import_typescript2 = __toESM(require_typescript(), 1);
|
|
13582
|
+
var JS_EXTENSION = /\.(?:[cm]?[jt]sx?)$/i;
|
|
13583
|
+
function isJsSourcePath(path) {
|
|
13584
|
+
return JS_EXTENSION.test(path);
|
|
13585
|
+
}
|
|
13586
|
+
function scriptKindFor(path) {
|
|
13587
|
+
const lower = path.toLowerCase();
|
|
13588
|
+
if (lower.endsWith(".tsx"))
|
|
13589
|
+
return import_typescript2.default.ScriptKind.TSX;
|
|
13590
|
+
if (lower.endsWith(".ts") || lower.endsWith(".mts") || lower.endsWith(".cts"))
|
|
13591
|
+
return import_typescript2.default.ScriptKind.TS;
|
|
13592
|
+
if (lower.endsWith(".jsx"))
|
|
13593
|
+
return import_typescript2.default.ScriptKind.JSX;
|
|
13594
|
+
return import_typescript2.default.ScriptKind.JS;
|
|
13595
|
+
}
|
|
13596
|
+
function parseJsSource(path, text) {
|
|
13597
|
+
return import_typescript2.default.createSourceFile(path, text, import_typescript2.default.ScriptTarget.Latest, true, scriptKindFor(path));
|
|
13598
|
+
}
|
|
13599
|
+
function codeOnlyLines(source) {
|
|
13600
|
+
const text = source.text;
|
|
13601
|
+
const chars = text.split("");
|
|
13602
|
+
const seen = new Set;
|
|
13603
|
+
const jsxText = [];
|
|
13604
|
+
const collectJsxText = (node) => {
|
|
13605
|
+
if (node.kind === import_typescript2.default.SyntaxKind.JsxText)
|
|
13606
|
+
jsxText.push([node.getFullStart(), node.getEnd()]);
|
|
13607
|
+
import_typescript2.default.forEachChild(node, collectJsxText);
|
|
13608
|
+
};
|
|
13609
|
+
collectJsxText(source);
|
|
13610
|
+
const blank = (range) => {
|
|
13611
|
+
if (seen.has(range.pos))
|
|
13612
|
+
return;
|
|
13613
|
+
if (jsxText.some(([start, end]) => range.pos >= start && range.pos < end))
|
|
13614
|
+
return;
|
|
13615
|
+
seen.add(range.pos);
|
|
13616
|
+
for (let i = range.pos;i < range.end; i += 1) {
|
|
13617
|
+
if (chars[i] !== `
|
|
13618
|
+
` && chars[i] !== "\r")
|
|
13619
|
+
chars[i] = " ";
|
|
13620
|
+
}
|
|
13621
|
+
};
|
|
13622
|
+
const visit = (node) => {
|
|
13623
|
+
if (node.kind === import_typescript2.default.SyntaxKind.JsxText)
|
|
13624
|
+
return;
|
|
13625
|
+
const children = node.getChildren(source);
|
|
13626
|
+
if (children.length === 0) {
|
|
13627
|
+
for (const range of import_typescript2.default.getLeadingCommentRanges(text, node.getFullStart()) ?? [])
|
|
13628
|
+
blank(range);
|
|
13629
|
+
for (const range of import_typescript2.default.getTrailingCommentRanges(text, node.getEnd()) ?? [])
|
|
13630
|
+
blank(range);
|
|
13631
|
+
return;
|
|
13632
|
+
}
|
|
13633
|
+
for (const child of children)
|
|
13634
|
+
visit(child);
|
|
13635
|
+
};
|
|
13636
|
+
visit(source);
|
|
13637
|
+
for (const range of import_typescript2.default.getLeadingCommentRanges(text, source.endOfFileToken.getFullStart()) ?? [])
|
|
13638
|
+
blank(range);
|
|
13639
|
+
return chars.join("").split(/\r?\n/);
|
|
13640
|
+
}
|
|
13641
|
+
var TRIM_METHODS = new Set(["trim", "trimStart", "trimEnd"]);
|
|
13642
|
+
var TEXT_TAGS = new Map([
|
|
13643
|
+
["dedent", stripIndent],
|
|
13644
|
+
["outdent", stripIndent],
|
|
13645
|
+
["stripIndent", stripIndent],
|
|
13646
|
+
["stripIndents", (text) => text.replace(/^[ \t]+/gm, "").trim()],
|
|
13647
|
+
["oneLine", (text) => text.replace(/(?:\n(?:\s*))+/g, " ").trim()],
|
|
13648
|
+
["oneLineTrim", (text) => text.replace(/(?:\n(?:\s*))+/g, "").trim()]
|
|
13649
|
+
]);
|
|
13650
|
+
function stripIndent(text) {
|
|
13651
|
+
const indents = text.split(`
|
|
13652
|
+
`).filter((line) => line.trim() !== "").map((line) => /^[ \t]*/.exec(line)[0].length);
|
|
13653
|
+
const common = indents.length > 0 ? Math.min(...indents) : 0;
|
|
13654
|
+
return (common > 0 ? text.replace(new RegExp(`^[ \\t]{${common}}`, "gm"), "") : text).trim();
|
|
13655
|
+
}
|
|
13656
|
+
function stringValueOf(node, source) {
|
|
13657
|
+
if (import_typescript2.default.isStringLiteral(node) || import_typescript2.default.isNoSubstitutionTemplateLiteral(node))
|
|
13658
|
+
return node.text;
|
|
13659
|
+
if (import_typescript2.default.isTemplateExpression(node)) {
|
|
13660
|
+
let out = node.head.text;
|
|
13661
|
+
for (const span of node.templateSpans)
|
|
13662
|
+
out += `\${${span.expression.getText(source)}}${span.literal.text}`;
|
|
13663
|
+
return out;
|
|
13664
|
+
}
|
|
13665
|
+
if (import_typescript2.default.isParenthesizedExpression(node) || import_typescript2.default.isAsExpression(node) || import_typescript2.default.isSatisfiesExpression(node) || import_typescript2.default.isTypeAssertionExpression(node)) {
|
|
13666
|
+
return stringValueOf(node.expression, source);
|
|
13667
|
+
}
|
|
13668
|
+
if (import_typescript2.default.isTaggedTemplateExpression(node)) {
|
|
13669
|
+
const transform = import_typescript2.default.isIdentifier(node.tag) ? TEXT_TAGS.get(node.tag.text) : undefined;
|
|
13670
|
+
const inner = transform && stringValueOf(node.template, source);
|
|
13671
|
+
return inner === undefined || !transform ? undefined : transform(inner);
|
|
13672
|
+
}
|
|
13673
|
+
if (import_typescript2.default.isBinaryExpression(node) && node.operatorToken.kind === import_typescript2.default.SyntaxKind.PlusToken) {
|
|
13674
|
+
const parts = composedParts([node.left, node.right], source);
|
|
13675
|
+
return parts?.join("");
|
|
13676
|
+
}
|
|
13677
|
+
if (import_typescript2.default.isArrayLiteralExpression(node)) {
|
|
13678
|
+
return composedParts(node.elements, source)?.join(`
|
|
13679
|
+
`);
|
|
13680
|
+
}
|
|
13681
|
+
if (import_typescript2.default.isCallExpression(node)) {
|
|
13682
|
+
const callee = node.expression;
|
|
13683
|
+
const array = import_typescript2.default.isPropertyAccessExpression(callee) && callee.name.text === "join" ? unfiltered(callee.expression) : undefined;
|
|
13684
|
+
if (array && import_typescript2.default.isArrayLiteralExpression(array)) {
|
|
13685
|
+
const separatorArg = node.arguments[0];
|
|
13686
|
+
const separator = separatorArg === undefined ? "," : import_typescript2.default.isStringLiteral(separatorArg) || import_typescript2.default.isNoSubstitutionTemplateLiteral(separatorArg) ? separatorArg.text : undefined;
|
|
13687
|
+
if (separator === undefined)
|
|
13688
|
+
return;
|
|
13689
|
+
return composedParts(array.elements, source)?.join(separator);
|
|
13690
|
+
}
|
|
13691
|
+
if (import_typescript2.default.isPropertyAccessExpression(callee) && TRIM_METHODS.has(callee.name.text) && node.arguments.length === 0) {
|
|
13692
|
+
const inner = stringValueOf(callee.expression, source);
|
|
13693
|
+
return inner === undefined ? undefined : callee.name.text === "trimStart" ? inner.trimStart() : callee.name.text === "trimEnd" ? inner.trimEnd() : inner.trim();
|
|
13694
|
+
}
|
|
13695
|
+
const transform = import_typescript2.default.isIdentifier(callee) && node.arguments.length === 1 ? TEXT_TAGS.get(callee.text) : undefined;
|
|
13696
|
+
if (transform) {
|
|
13697
|
+
const inner = stringValueOf(node.arguments[0], source);
|
|
13698
|
+
return inner === undefined ? undefined : transform(inner);
|
|
13699
|
+
}
|
|
13700
|
+
return;
|
|
13701
|
+
}
|
|
13702
|
+
return;
|
|
13703
|
+
}
|
|
13704
|
+
function composedParts(elements, source) {
|
|
13705
|
+
let literal = false;
|
|
13706
|
+
const parts = [];
|
|
13707
|
+
for (const element of elements) {
|
|
13708
|
+
if (import_typescript2.default.isOmittedExpression(element))
|
|
13709
|
+
return;
|
|
13710
|
+
const value = import_typescript2.default.isSpreadElement(element) ? undefined : stringValueOf(element, source);
|
|
13711
|
+
if (value !== undefined)
|
|
13712
|
+
literal = true;
|
|
13713
|
+
parts.push(value ?? `\${${element.getText(source)}}`);
|
|
13714
|
+
}
|
|
13715
|
+
return literal && parts.length > 0 ? parts : undefined;
|
|
13716
|
+
}
|
|
13717
|
+
function unfiltered(node) {
|
|
13718
|
+
let current = node;
|
|
13719
|
+
while (import_typescript2.default.isCallExpression(current) && import_typescript2.default.isPropertyAccessExpression(current.expression) && current.expression.name.text === "filter") {
|
|
13720
|
+
const [predicate] = current.arguments;
|
|
13721
|
+
if (current.arguments.length !== 1 || !import_typescript2.default.isIdentifier(predicate) || predicate.text !== "Boolean")
|
|
13722
|
+
return;
|
|
13723
|
+
current = current.expression.expression;
|
|
13724
|
+
}
|
|
13725
|
+
return current;
|
|
13726
|
+
}
|
|
13727
|
+
var PROMPT_NAME = /prompt|instruction|system|template|rubric|persona|backstory|content/i;
|
|
13728
|
+
function comparable(text) {
|
|
13729
|
+
return text.replace(/\\/g, "").replace(/\s+/g, " ").trim();
|
|
13730
|
+
}
|
|
13731
|
+
function jsSystemInjectionLiteralAt(source, startLine) {
|
|
13732
|
+
let found;
|
|
13733
|
+
const visit = (node) => {
|
|
13734
|
+
if (found || lineOf(source, node.getEnd()) < startLine || lineOf(source, node.getStart(source)) > startLine)
|
|
13735
|
+
return;
|
|
13736
|
+
if ((import_typescript2.default.isStringLiteral(node) || import_typescript2.default.isNoSubstitutionTemplateLiteral(node) || import_typescript2.default.isTemplateExpression(node)) && lineOf(source, node.getStart(source)) === startLine) {
|
|
13737
|
+
let outer = node;
|
|
13738
|
+
for (;; ) {
|
|
13739
|
+
const parent = outer.parent;
|
|
13740
|
+
if (import_typescript2.default.isBinaryExpression(parent) && parent.operatorToken.kind === import_typescript2.default.SyntaxKind.PlusToken && parent.left === outer) {
|
|
13741
|
+
outer = parent;
|
|
13742
|
+
} else if (import_typescript2.default.isArrayLiteralExpression(parent) && parent.elements[0] === outer && import_typescript2.default.isPropertyAccessExpression(parent.parent) && parent.parent.name.text === "join" && import_typescript2.default.isCallExpression(parent.parent.parent) && parent.parent.parent.expression === parent.parent) {
|
|
13743
|
+
outer = parent.parent.parent;
|
|
13744
|
+
} else {
|
|
13745
|
+
break;
|
|
13746
|
+
}
|
|
13747
|
+
}
|
|
13748
|
+
const text = stringValueOf(outer, source) ?? stringValueOf(node, source);
|
|
13749
|
+
if (text !== undefined && /^\s*\[SYSTEM:/.test(text)) {
|
|
13750
|
+
found = { text, line: startLine };
|
|
13751
|
+
return;
|
|
13752
|
+
}
|
|
13753
|
+
}
|
|
13754
|
+
import_typescript2.default.forEachChild(node, visit);
|
|
13755
|
+
};
|
|
13756
|
+
visit(source);
|
|
13757
|
+
return found;
|
|
13758
|
+
}
|
|
13759
|
+
function lineOf(source, position) {
|
|
13760
|
+
return source.getLineAndCharacterOfPosition(position).line + 1;
|
|
13761
|
+
}
|
|
13762
|
+
function propertyNameText(name) {
|
|
13763
|
+
if (import_typescript2.default.isIdentifier(name) || import_typescript2.default.isStringLiteral(name) || import_typescript2.default.isPrivateIdentifier(name))
|
|
13764
|
+
return name.text;
|
|
13765
|
+
return;
|
|
13766
|
+
}
|
|
13767
|
+
function enclosingFunctionName(node) {
|
|
13768
|
+
for (let current = node.parent;current; current = current.parent) {
|
|
13769
|
+
if (import_typescript2.default.isFunctionDeclaration(current) || import_typescript2.default.isMethodDeclaration(current)) {
|
|
13770
|
+
return current.name && (import_typescript2.default.isIdentifier(current.name) || import_typescript2.default.isStringLiteral(current.name)) ? current.name.text : undefined;
|
|
13771
|
+
}
|
|
13772
|
+
if (import_typescript2.default.isArrowFunction(current) || import_typescript2.default.isFunctionExpression(current)) {
|
|
13773
|
+
const holder = current.parent;
|
|
13774
|
+
if (holder && import_typescript2.default.isVariableDeclaration(holder) && import_typescript2.default.isIdentifier(holder.name))
|
|
13775
|
+
return holder.name.text;
|
|
13776
|
+
if (holder && import_typescript2.default.isPropertyAssignment(holder))
|
|
13777
|
+
return propertyNameText(holder.name);
|
|
13778
|
+
return;
|
|
13779
|
+
}
|
|
13780
|
+
}
|
|
13781
|
+
return;
|
|
13782
|
+
}
|
|
13783
|
+
function jsLiteralDefinitionAt(source, startLine, excerpt2) {
|
|
13784
|
+
const literal = excerpt2 ? comparable(excerpt2).slice(0, 120) : "";
|
|
13785
|
+
const all = [];
|
|
13786
|
+
const consider = (node, value, def, depth) => {
|
|
13787
|
+
const defLine = lineOf(source, node.getStart(source));
|
|
13788
|
+
const valueLine = lineOf(source, value.getStart(source));
|
|
13789
|
+
const valueEndLine = lineOf(source, value.getEnd());
|
|
13790
|
+
const distance = valueLine === startLine || defLine === startLine ? 0 : defLine === startLine - 1 && valueEndLine >= startLine ? 1 : -1;
|
|
13791
|
+
if (distance < 0)
|
|
13792
|
+
return;
|
|
13793
|
+
const text = stringValueOf(value, source);
|
|
13794
|
+
if (text === undefined)
|
|
13795
|
+
return;
|
|
13796
|
+
all.push({
|
|
13797
|
+
def: { ...def, text, line: defLine },
|
|
13798
|
+
start: node.getStart(source),
|
|
13799
|
+
depth,
|
|
13800
|
+
distance,
|
|
13801
|
+
matches: literal.length > 0 && comparable(value.getText(source)).includes(literal),
|
|
13802
|
+
named: PROMPT_NAME.test(def.key ?? def.identifier ?? "")
|
|
13803
|
+
});
|
|
13804
|
+
};
|
|
13805
|
+
const visit = (node, depth) => {
|
|
13806
|
+
const nodeStart = lineOf(source, node.getStart(source));
|
|
13807
|
+
const nodeEnd = lineOf(source, node.getEnd());
|
|
13808
|
+
if (nodeEnd < startLine - 1 || nodeStart > startLine)
|
|
13809
|
+
return;
|
|
13810
|
+
if (import_typescript2.default.isVariableDeclaration(node) && import_typescript2.default.isIdentifier(node.name) && node.initializer) {
|
|
13811
|
+
consider(node, node.initializer, { identifier: node.name.text }, depth);
|
|
13812
|
+
} else if (import_typescript2.default.isPropertyAssignment(node)) {
|
|
13813
|
+
const key = propertyNameText(node.name);
|
|
13814
|
+
if (key)
|
|
13815
|
+
consider(node, node.initializer, { key }, depth);
|
|
13816
|
+
} else if (import_typescript2.default.isPropertyDeclaration(node) && node.initializer) {
|
|
13817
|
+
const name = propertyNameText(node.name);
|
|
13818
|
+
if (name)
|
|
13819
|
+
consider(node, node.initializer, { identifier: name }, depth);
|
|
13820
|
+
} else if (import_typescript2.default.isBinaryExpression(node) && node.operatorToken.kind === import_typescript2.default.SyntaxKind.EqualsToken) {
|
|
13821
|
+
const target = node.left;
|
|
13822
|
+
const name = import_typescript2.default.isIdentifier(target) ? target.text : import_typescript2.default.isPropertyAccessExpression(target) ? target.name.text : undefined;
|
|
13823
|
+
if (name)
|
|
13824
|
+
consider(node, node.right, { identifier: name }, depth);
|
|
13825
|
+
} else if (import_typescript2.default.isReturnStatement(node) && node.expression) {
|
|
13826
|
+
const name = enclosingFunctionName(node);
|
|
13827
|
+
if (name)
|
|
13828
|
+
consider(node, node.expression, { identifier: name }, depth);
|
|
13829
|
+
}
|
|
13830
|
+
import_typescript2.default.forEachChild(node, (child) => visit(child, depth + 1));
|
|
13831
|
+
};
|
|
13832
|
+
visit(source, 0);
|
|
13833
|
+
const rank = (a, b) => a.distance - b.distance || Number(b.matches) - Number(a.matches) || Number(b.named) - Number(a.named) || b.def.text.length - a.def.text.length || b.depth - a.depth;
|
|
13834
|
+
const best = all.sort(rank)[0];
|
|
13835
|
+
if (!best)
|
|
13836
|
+
return;
|
|
13837
|
+
const earlier = all.some((other) => other.def.line === best.def.line && other.start < best.start);
|
|
13838
|
+
return earlier ? { ...best.def, column: source.getLineAndCharacterOfPosition(best.start).character + 1 } : best.def;
|
|
13839
|
+
}
|
|
13840
|
+
function calleeText(call, source) {
|
|
13841
|
+
return call.expression.getText(source).replace(/\s+/g, "");
|
|
13842
|
+
}
|
|
13843
|
+
function outermostContainer(node) {
|
|
13844
|
+
let current = node;
|
|
13845
|
+
while (current.parent && (import_typescript2.default.isPropertyAssignment(current.parent) || import_typescript2.default.isObjectLiteralExpression(current.parent) || import_typescript2.default.isArrayLiteralExpression(current.parent) || import_typescript2.default.isParenthesizedExpression(current.parent) || import_typescript2.default.isAsExpression(current.parent) || import_typescript2.default.isSatisfiesExpression(current.parent) || import_typescript2.default.isSpreadElement(current.parent) || import_typescript2.default.isShorthandPropertyAssignment(current.parent) || import_typescript2.default.isAwaitExpression(current.parent) || import_typescript2.default.isNonNullExpression(current.parent)))
|
|
13846
|
+
current = current.parent;
|
|
13847
|
+
return current;
|
|
13848
|
+
}
|
|
13849
|
+
function isExportedDeclaration(declaration) {
|
|
13850
|
+
const statement = declaration.parent?.parent;
|
|
13851
|
+
return Boolean(statement && import_typescript2.default.isVariableStatement(statement) && statement.modifiers?.some((modifier) => modifier.kind === import_typescript2.default.SyntaxKind.ExportKeyword));
|
|
13852
|
+
}
|
|
13853
|
+
function followValue(start, source, callees, targets, seen, out) {
|
|
13854
|
+
let current = start;
|
|
13855
|
+
for (;; ) {
|
|
13856
|
+
let parent = current.parent;
|
|
13857
|
+
while (parent && ((import_typescript2.default.isPropertyAccessExpression(parent) || import_typescript2.default.isElementAccessExpression(parent)) && parent.expression === current)) {
|
|
13858
|
+
current = parent;
|
|
13859
|
+
parent = current.parent;
|
|
13860
|
+
}
|
|
13861
|
+
const container = outermostContainer(current);
|
|
13862
|
+
const holder = container.parent;
|
|
13863
|
+
if (holder && (import_typescript2.default.isCallExpression(holder) || import_typescript2.default.isNewExpression(holder)) && (holder.arguments?.includes(container) || import_typescript2.default.isCallExpression(holder) && holder.expression === container)) {
|
|
13864
|
+
callees.push(calleeText(holder, source));
|
|
13865
|
+
targets.push(holder.arguments?.[0]?.getText(source) ?? "");
|
|
13866
|
+
current = holder;
|
|
13867
|
+
continue;
|
|
13868
|
+
}
|
|
13869
|
+
if (holder && import_typescript2.default.isVariableDeclaration(holder) && import_typescript2.default.isIdentifier(holder.name) && holder.initializer === container) {
|
|
13870
|
+
if (seen.has(holder))
|
|
13871
|
+
return;
|
|
13872
|
+
seen.add(holder);
|
|
13873
|
+
const name = holder.name.text;
|
|
13874
|
+
const declaration = holder.name;
|
|
13875
|
+
const before = out.length;
|
|
13876
|
+
if (isExportedDeclaration(holder))
|
|
13877
|
+
out.push({ callees: [...callees], targets: [...targets], display: false, escape: "export" });
|
|
13878
|
+
const visit = (node) => {
|
|
13879
|
+
if (import_typescript2.default.isIdentifier(node) && node.text === name && node !== declaration && !(node.parent && import_typescript2.default.isPropertyAccessExpression(node.parent) && node.parent.name === node)) {
|
|
13880
|
+
followValue(node, source, [...callees], [...targets], seen, out);
|
|
13881
|
+
}
|
|
13882
|
+
import_typescript2.default.forEachChild(node, visit);
|
|
13883
|
+
};
|
|
13884
|
+
visit(source);
|
|
13885
|
+
if (out.length === before)
|
|
13886
|
+
out.push({ callees: [...callees], targets: [...targets], display: false, escape: "unknown" });
|
|
13887
|
+
return;
|
|
13888
|
+
}
|
|
13889
|
+
const display = Boolean(holder && (import_typescript2.default.isJsxExpression(holder) || import_typescript2.default.isJsxSpreadAttribute(holder)));
|
|
13890
|
+
const statement = Boolean(holder && import_typescript2.default.isExpressionStatement(holder));
|
|
13891
|
+
const exported = Boolean(holder && (import_typescript2.default.isExportSpecifier(holder) || import_typescript2.default.isExportAssignment(holder)));
|
|
13892
|
+
out.push({ callees, targets, display, escape: display || statement ? undefined : exported ? "export" : "unknown" });
|
|
13893
|
+
return;
|
|
13894
|
+
}
|
|
13895
|
+
}
|
|
13896
|
+
function keyedValueConsumer(source, line, key, column) {
|
|
13897
|
+
let property;
|
|
13898
|
+
const find = (node) => {
|
|
13899
|
+
if (property)
|
|
13900
|
+
return;
|
|
13901
|
+
if (import_typescript2.default.isPropertyAssignment(node) && lineOf(source, node.getStart(source)) === line && (column === undefined || source.getLineAndCharacterOfPosition(node.getStart(source)).character + 1 === column) && (import_typescript2.default.isIdentifier(node.name) || import_typescript2.default.isStringLiteral(node.name)) && node.name.text === key) {
|
|
13902
|
+
property = node;
|
|
13903
|
+
return;
|
|
13904
|
+
}
|
|
13905
|
+
import_typescript2.default.forEachChild(node, find);
|
|
13906
|
+
};
|
|
13907
|
+
find(source);
|
|
13908
|
+
if (!property)
|
|
13909
|
+
return { kind: "uses", uses: [{ callees: [], targets: [], display: false, escape: "unknown" }] };
|
|
13910
|
+
const owner = property.parent;
|
|
13911
|
+
if (import_typescript2.default.isObjectLiteralExpression(owner) && owner.properties.some((other) => import_typescript2.default.isPropertyAssignment(other) && import_typescript2.default.isIdentifier(other.name) && other.name.text === "role" && (import_typescript2.default.isStringLiteral(other.initializer) || import_typescript2.default.isNoSubstitutionTemplateLiteral(other.initializer)) && /^(?:system|user|assistant|developer|human)$/.test(other.initializer.text))) {
|
|
13912
|
+
return { kind: "chat_message" };
|
|
13913
|
+
}
|
|
13914
|
+
const uses = [];
|
|
13915
|
+
followValue(property, source, [], [], new Set, uses);
|
|
13916
|
+
return { kind: "uses", uses };
|
|
13917
|
+
}
|
|
13918
|
+
|
|
13919
|
+
// src/harness-candidate-promotion.ts
|
|
13565
13920
|
var PROMOTED_CONFIDENCE = {
|
|
13566
13921
|
high: 0.85,
|
|
13567
13922
|
medium: 0.6
|
|
@@ -13573,7 +13928,28 @@ var JS_ASSIGNMENT_NAME = /(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=/;
|
|
|
13573
13928
|
var JS_PROPERTY_NAME = /^\s*(?:public\s+|readonly\s+)?([A-Za-z_$][\w$]*)\s*:\s*(?:new\s+)?(?:[\w.$]*\.)?(?:tool|functionTool|createTool|dynamicTool|DynamicStructuredTool)\s*\(/;
|
|
13574
13929
|
var JS_TRAILING_ASSIGNMENT_NAME = /(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:new\s+)?$/;
|
|
13575
13930
|
var REGISTRY_CALL_NAME = /\b(?:register_tool|registerTool|add_tool)\s*\(\s*["']?([A-Za-z_$][\w$]*)/;
|
|
13931
|
+
var MODEL_FAMILY_ALIAS = /^(?:opus|sonnet|haiku)(?:[-.]?(?:\d[\w.]*|low|medium|high|xhigh|max|none|fast))*$/i;
|
|
13932
|
+
var MODEL_ASSIGNMENT_VALUE = /["']?\b(model|model_name|model_id|modelName|modelId|[A-Z_]*MODEL[A-Z_]*)["']?\s*[:=]\s*(["'`][^"'`]+["'`])/i;
|
|
13933
|
+
var MODEL_PREFERENCE_FIELD = /model\w*(?:preference|choice|option|label)|(?:preferred|selected|chosen)\w*model/i;
|
|
13934
|
+
var REGISTRY_KEY = /^\s*["'`]([\w-]+\/[\w.:-]+)["'`]\s*:/;
|
|
13935
|
+
var FULL_MODEL_ID = /[\w-]+\/[\w.:-]+|\d{8}/;
|
|
13576
13936
|
var MODEL_STRING = /["'`]([\w.:/-]*(?:gpt-|o[134](?:-mini)?\b|claude|gemini|llama|mistral|mixtral|deepseek|qwen|grok|sonnet|opus|haiku|command-r|glm|gemma)[\w.:/-]*)["'`]/i;
|
|
13937
|
+
var SIGNAL_DESCRIPTIONS = {
|
|
13938
|
+
"python.tool_decorator": "a tool decorator on the function",
|
|
13939
|
+
"python.base_tool_subclass": "a BaseTool subclass",
|
|
13940
|
+
"js.ai_sdk_tool": "a tool() factory call",
|
|
13941
|
+
"tool_registry.registration": "a tool registry call",
|
|
13942
|
+
"prompt_file.name_hint": "a document named like a prompt",
|
|
13943
|
+
"prompt_file.prompts_dir": "a document under a prompts/ directory",
|
|
13944
|
+
"prompt_file.agent_dir_instruction_text": "instruction-like text in an agent directory",
|
|
13945
|
+
"prompt_file.loader_reference": "a file loaded as a prompt by code",
|
|
13946
|
+
"prompt_file.template_loader_reference": "a file loaded as a prompt template by code",
|
|
13947
|
+
"model.assignment": "a model id assigned in code"
|
|
13948
|
+
};
|
|
13949
|
+
function detectorConfidenceReason(candidate) {
|
|
13950
|
+
const what = SIGNAL_DESCRIPTIONS[candidate.signal] ?? `the ${candidate.signal} pattern`;
|
|
13951
|
+
return `Deterministic: found by ${what} at ${candidate.path}:${candidate.startLine} (${candidate.confidence}-confidence detector); not checked by the analyst.`;
|
|
13952
|
+
}
|
|
13577
13953
|
function candidateEvidence(candidate) {
|
|
13578
13954
|
return [{
|
|
13579
13955
|
path: candidate.path,
|
|
@@ -13584,13 +13960,21 @@ function candidateEvidence(candidate) {
|
|
|
13584
13960
|
function pathStem(path) {
|
|
13585
13961
|
return path.replace(/\.[^.]+$/, "");
|
|
13586
13962
|
}
|
|
13963
|
+
var jsSources = new Map;
|
|
13587
13964
|
function readFileLines(rootDir, path, cache) {
|
|
13588
13965
|
const cached = cache.get(path);
|
|
13589
13966
|
if (cached !== undefined)
|
|
13590
13967
|
return cached;
|
|
13591
13968
|
let lines;
|
|
13592
13969
|
try {
|
|
13593
|
-
|
|
13970
|
+
const text = readFileSync11(resolve9(rootDir, path), "utf8");
|
|
13971
|
+
if (isJsSourcePath(path)) {
|
|
13972
|
+
const source = parseJsSource(path, text);
|
|
13973
|
+
jsSources.set(`${rootDir}::${path}`, source);
|
|
13974
|
+
lines = codeOnlyLines(source);
|
|
13975
|
+
} else {
|
|
13976
|
+
lines = text.split(/\r?\n/);
|
|
13977
|
+
}
|
|
13594
13978
|
} catch {
|
|
13595
13979
|
lines = null;
|
|
13596
13980
|
}
|
|
@@ -13631,6 +14015,7 @@ function promoteToolCandidate(candidate, rootDir, confidence2, fileCache) {
|
|
|
13631
14015
|
sourcePath: candidate.path,
|
|
13632
14016
|
usedByAgentIds: [],
|
|
13633
14017
|
confidence: confidence2,
|
|
14018
|
+
confidenceReason: detectorConfidenceReason(candidate),
|
|
13634
14019
|
evidence: candidateEvidence(candidate),
|
|
13635
14020
|
body: extractToolBody({ path: candidate.path, rootDir }, { name, reason: candidate.signal })
|
|
13636
14021
|
};
|
|
@@ -13665,6 +14050,12 @@ function buildsPrompts(path, lines) {
|
|
|
13665
14050
|
return false;
|
|
13666
14051
|
return exportedNames(path, lines).some((name) => !UTILITY_EXPORT.test(name) && (BUILDER_VERB.test(name) || PROMPT_NOUN_LAST.test(name)));
|
|
13667
14052
|
}
|
|
14053
|
+
var TEST_FILE2 = /(?:^|\/)(?:test_[^/]*\.py|[^/]*_test\.py|conftest\.py|[^/]*\.(?:test|spec)\.[^/]+)$/i;
|
|
14054
|
+
var FIXTURE_DIR2 = /(?:^|\/)(?:fixtures?|test-fixtures|__fixtures__|__mocks__)(?:\/|$)/i;
|
|
14055
|
+
var EVAL_HARNESS_PATH = /(?:^|[\/_.-])(?:evals?|evaluations?|judges?|grader|grading|pairwise|quality|rubrics?|benchmarks?)(?:[\/_.-]|$)/i;
|
|
14056
|
+
function isTestInput(path) {
|
|
14057
|
+
return (TEST_FILE2.test(path) || FIXTURE_DIR2.test(path)) && !EVAL_HARNESS_PATH.test(path);
|
|
14058
|
+
}
|
|
13668
14059
|
function promotePromptFileCandidate(candidate, confidence2) {
|
|
13669
14060
|
return {
|
|
13670
14061
|
id: stableId("prompt", candidate.path),
|
|
@@ -13674,6 +14065,7 @@ function promotePromptFileCandidate(candidate, confidence2) {
|
|
|
13674
14065
|
sourcePath: candidate.path,
|
|
13675
14066
|
usedByAgentIds: [],
|
|
13676
14067
|
confidence: confidence2,
|
|
14068
|
+
confidenceReason: detectorConfidenceReason(candidate),
|
|
13677
14069
|
evidence: candidateEvidence(candidate)
|
|
13678
14070
|
};
|
|
13679
14071
|
}
|
|
@@ -13696,6 +14088,7 @@ var MODEL_INPUT_KEYS = [
|
|
|
13696
14088
|
"text"
|
|
13697
14089
|
];
|
|
13698
14090
|
var DIRECT_PROMPT_KEYS = new Set([
|
|
14091
|
+
"instruction",
|
|
13699
14092
|
"system",
|
|
13700
14093
|
"systemPrompt",
|
|
13701
14094
|
"system_prompt",
|
|
@@ -13727,8 +14120,12 @@ var CONFIG_EXTENSIONS = new Set([".json", ".yaml", ".yml"]);
|
|
|
13727
14120
|
var PROMPT_NAMED_IDENTIFIER = /prompt|system|instruction/i;
|
|
13728
14121
|
var SECOND_PERSON_OPENING = /^\s*(?:\[[A-Z]+:\s*|<\w+>\s*)*(?:you|your)\b/i;
|
|
13729
14122
|
var MIN_UNNAMED_REFERENCED_PROMPT_CHARS = 200;
|
|
14123
|
+
var UNUSED_PROMPT_CONFIDENCE = 0.6;
|
|
13730
14124
|
var REFERENCED_PROMPT_CONFIDENCE = 0.7;
|
|
13731
14125
|
var MIN_RESOLVED_PROMPT_CHARS = 20;
|
|
14126
|
+
var SYSTEM_INJECTION = /^\s*\[SYSTEM:/;
|
|
14127
|
+
var BARE_SYSTEM_TAG = /^\s*\[SYSTEM:[\sA-Z0-9_-]*\]\s*$/;
|
|
14128
|
+
var SYSTEM_INJECTION_LITERAL = /["'`]\s*\[SYSTEM:/;
|
|
13732
14129
|
var MIN_CONFIG_PROMPT_CHARS = 40;
|
|
13733
14130
|
var MAX_BUILDER_LOOKBEHIND_LINES = 40;
|
|
13734
14131
|
var DEFINITION_HEAD = /^\s*(?:export\s+)?(?:(?:const|let|var|readonly|static|public|private)\s+)*["']?([A-Za-z_$][\w$]*)["']?\s*(?:(?::\s*[\w$.<>[\]|, ]+?)?\s*(=)(?![=>])|(:))\s*(.*)$/;
|
|
@@ -13753,128 +14150,15 @@ function readStringLiteral(text, start) {
|
|
|
13753
14150
|
i += 2;
|
|
13754
14151
|
continue;
|
|
13755
14152
|
}
|
|
13756
|
-
if (opener.length === 1 &&
|
|
14153
|
+
if (opener.length === 1 && char === `
|
|
13757
14154
|
`)
|
|
13758
14155
|
return;
|
|
13759
|
-
if (opener === "`" && char === "$" && text[i + 1] === "{") {
|
|
13760
|
-
let depth = 1;
|
|
13761
|
-
i += 2;
|
|
13762
|
-
while (i < text.length && depth > 0) {
|
|
13763
|
-
if (text[i] === "`" || text[i] === '"' || text[i] === "'") {
|
|
13764
|
-
const nested = readStringLiteral(text, i);
|
|
13765
|
-
if (nested) {
|
|
13766
|
-
i = nested.end;
|
|
13767
|
-
continue;
|
|
13768
|
-
}
|
|
13769
|
-
if (text[i] === "`")
|
|
13770
|
-
return;
|
|
13771
|
-
i += 1;
|
|
13772
|
-
continue;
|
|
13773
|
-
}
|
|
13774
|
-
const regexEnd = text[i] === "/" ? regexLiteralEnd(text, i) : undefined;
|
|
13775
|
-
if (regexEnd !== undefined) {
|
|
13776
|
-
i = regexEnd;
|
|
13777
|
-
continue;
|
|
13778
|
-
}
|
|
13779
|
-
if (text.startsWith("//", i)) {
|
|
13780
|
-
const newline = text.indexOf(`
|
|
13781
|
-
`, i);
|
|
13782
|
-
i = newline < 0 ? text.length : newline;
|
|
13783
|
-
continue;
|
|
13784
|
-
}
|
|
13785
|
-
if (text.startsWith("/*", i)) {
|
|
13786
|
-
const close = text.indexOf("*/", i + 2);
|
|
13787
|
-
if (close < 0)
|
|
13788
|
-
return;
|
|
13789
|
-
i = close + 2;
|
|
13790
|
-
continue;
|
|
13791
|
-
}
|
|
13792
|
-
if (text[i] === "{")
|
|
13793
|
-
depth += 1;
|
|
13794
|
-
else if (text[i] === "}")
|
|
13795
|
-
depth -= 1;
|
|
13796
|
-
i += 1;
|
|
13797
|
-
}
|
|
13798
|
-
continue;
|
|
13799
|
-
}
|
|
13800
14156
|
if (text.startsWith(opener, i))
|
|
13801
14157
|
return { value: text.slice(start + opener.length, i), end: i + opener.length };
|
|
13802
14158
|
i += 1;
|
|
13803
14159
|
}
|
|
13804
14160
|
return;
|
|
13805
14161
|
}
|
|
13806
|
-
var EXPRESSION_KEYWORDS = new Set([
|
|
13807
|
-
"return",
|
|
13808
|
-
"typeof",
|
|
13809
|
-
"instanceof",
|
|
13810
|
-
"in",
|
|
13811
|
-
"of",
|
|
13812
|
-
"new",
|
|
13813
|
-
"delete",
|
|
13814
|
-
"void",
|
|
13815
|
-
"throw",
|
|
13816
|
-
"case",
|
|
13817
|
-
"do",
|
|
13818
|
-
"else",
|
|
13819
|
-
"yield",
|
|
13820
|
-
"await"
|
|
13821
|
-
]);
|
|
13822
|
-
function endsWithOperand(text, end) {
|
|
13823
|
-
let i = end;
|
|
13824
|
-
while (i > 0 && /\s/.test(text[i - 1]))
|
|
13825
|
-
i -= 1;
|
|
13826
|
-
if (i === 0)
|
|
13827
|
-
return false;
|
|
13828
|
-
const char = text[i - 1];
|
|
13829
|
-
if (char === ")" || char === "]" || char === '"' || char === "'" || char === "`")
|
|
13830
|
-
return true;
|
|
13831
|
-
if (/[\w$]/.test(char)) {
|
|
13832
|
-
let wordStart = i;
|
|
13833
|
-
while (wordStart > 0 && /[\w$]/.test(text[wordStart - 1]))
|
|
13834
|
-
wordStart -= 1;
|
|
13835
|
-
const word = text.slice(wordStart, i);
|
|
13836
|
-
if (/^\d/.test(word))
|
|
13837
|
-
return true;
|
|
13838
|
-
let before = wordStart;
|
|
13839
|
-
while (before > 0 && /\s/.test(text[before - 1]))
|
|
13840
|
-
before -= 1;
|
|
13841
|
-
const isProperty = text[before - 1] === "." && text[before - 2] !== ".";
|
|
13842
|
-
return isProperty || !EXPRESSION_KEYWORDS.has(word);
|
|
13843
|
-
}
|
|
13844
|
-
if ((char === "+" || char === "-") && text[i - 2] === char)
|
|
13845
|
-
return endsWithOperand(text, i - 2);
|
|
13846
|
-
if (char === "!" && i >= 2 && /[\w$)\]]/.test(text[i - 2]))
|
|
13847
|
-
return endsWithOperand(text, i - 1);
|
|
13848
|
-
return false;
|
|
13849
|
-
}
|
|
13850
|
-
function regexLiteralEnd(text, start) {
|
|
13851
|
-
if (text[start + 1] === "/" || text[start + 1] === "*")
|
|
13852
|
-
return;
|
|
13853
|
-
if (endsWithOperand(text, start))
|
|
13854
|
-
return;
|
|
13855
|
-
let inClass = false;
|
|
13856
|
-
for (let i = start + 1;i < text.length; i += 1) {
|
|
13857
|
-
const char = text[i];
|
|
13858
|
-
if (char === `
|
|
13859
|
-
`)
|
|
13860
|
-
return;
|
|
13861
|
-
if (char === "\\") {
|
|
13862
|
-
i += 1;
|
|
13863
|
-
continue;
|
|
13864
|
-
}
|
|
13865
|
-
if (char === "[")
|
|
13866
|
-
inClass = true;
|
|
13867
|
-
else if (char === "]")
|
|
13868
|
-
inClass = false;
|
|
13869
|
-
else if (char === "/" && !inClass) {
|
|
13870
|
-
let end = i + 1;
|
|
13871
|
-
while (/[a-z]/i.test(text[end] ?? ""))
|
|
13872
|
-
end += 1;
|
|
13873
|
-
return end;
|
|
13874
|
-
}
|
|
13875
|
-
}
|
|
13876
|
-
return;
|
|
13877
|
-
}
|
|
13878
14162
|
function readStringValue(text, offset) {
|
|
13879
14163
|
let i = offset;
|
|
13880
14164
|
const parts = [];
|
|
@@ -13931,7 +14215,9 @@ function stringStart(rest) {
|
|
|
13931
14215
|
}
|
|
13932
14216
|
return STRING_OPENER.test(remaining) ? consumed : -1;
|
|
13933
14217
|
}
|
|
13934
|
-
function resolvePromptLiteralDefinition(lines, startLine) {
|
|
14218
|
+
function resolvePromptLiteralDefinition(lines, startLine, jsSource, excerpt2) {
|
|
14219
|
+
if (jsSource)
|
|
14220
|
+
return jsLiteralDefinitionAt(jsSource, startLine, excerpt2);
|
|
13935
14221
|
const text = lines.join(`
|
|
13936
14222
|
`);
|
|
13937
14223
|
for (const index of [startLine - 1, startLine - 2]) {
|
|
@@ -14009,16 +14295,8 @@ function resolvePromptLiteralDefinition(lines, startLine) {
|
|
|
14009
14295
|
}
|
|
14010
14296
|
function endsInComment(prefix) {
|
|
14011
14297
|
let quote;
|
|
14012
|
-
let inBlock = false;
|
|
14013
14298
|
for (let i = 0;i < prefix.length; i += 1) {
|
|
14014
14299
|
const char = prefix[i];
|
|
14015
|
-
if (inBlock) {
|
|
14016
|
-
if (prefix.startsWith("*/", i)) {
|
|
14017
|
-
inBlock = false;
|
|
14018
|
-
i += 1;
|
|
14019
|
-
}
|
|
14020
|
-
continue;
|
|
14021
|
-
}
|
|
14022
14300
|
if (quote) {
|
|
14023
14301
|
if (char === "\\")
|
|
14024
14302
|
i += 1;
|
|
@@ -14026,23 +14304,14 @@ function endsInComment(prefix) {
|
|
|
14026
14304
|
quote = undefined;
|
|
14027
14305
|
continue;
|
|
14028
14306
|
}
|
|
14029
|
-
if (char === '"' || char === "'"
|
|
14307
|
+
if (char === '"' || char === "'") {
|
|
14030
14308
|
quote = char;
|
|
14031
14309
|
continue;
|
|
14032
14310
|
}
|
|
14033
|
-
|
|
14034
|
-
if (regexEnd !== undefined) {
|
|
14035
|
-
i = regexEnd - 1;
|
|
14036
|
-
continue;
|
|
14037
|
-
}
|
|
14038
|
-
if (prefix.startsWith("//", i))
|
|
14311
|
+
if (char === "#")
|
|
14039
14312
|
return true;
|
|
14040
|
-
else if (prefix.startsWith("/*", i)) {
|
|
14041
|
-
inBlock = true;
|
|
14042
|
-
i += 1;
|
|
14043
|
-
}
|
|
14044
14313
|
}
|
|
14045
|
-
return
|
|
14314
|
+
return false;
|
|
14046
14315
|
}
|
|
14047
14316
|
function readYamlBlockScalar(lines, index, rest) {
|
|
14048
14317
|
const indicator = /^([|>])([-+]?)\s*(?:#.*)?$/.exec(rest.trim());
|
|
@@ -14206,7 +14475,7 @@ function importStatementLines(lines) {
|
|
|
14206
14475
|
}
|
|
14207
14476
|
return covered;
|
|
14208
14477
|
}
|
|
14209
|
-
var MODEL_CALLEE = /model|llm|complet|generat|chat|invoke|infer|prompt|agent|judge|claude|gpt|openai|anthropic|gemini|\.create$/i;
|
|
14478
|
+
var MODEL_CALLEE = /model|llm|complet|generat|chat|invoke|infer|prompt|agent|judge|jev|claude|gpt|openai|anthropic|gemini|\.create$/i;
|
|
14210
14479
|
function calleeImportedFromModelFile(callee, path, lines, modelFiles) {
|
|
14211
14480
|
const base = callee.split(".")[0];
|
|
14212
14481
|
const text = lines.join(`
|
|
@@ -14251,7 +14520,10 @@ function localHelperCallsModel(callee, lines) {
|
|
|
14251
14520
|
const start = lines.findIndex((line) => head.test(line));
|
|
14252
14521
|
if (start < 0)
|
|
14253
14522
|
return false;
|
|
14254
|
-
|
|
14523
|
+
const match = head.exec(lines[start]);
|
|
14524
|
+
const declared = /^\s*(?:export\s+)?(?:async\s+)?(?:function|def|const|let|var)\b/.test(lines[start]);
|
|
14525
|
+
const sameLine = declared && match ? lines[start].slice(match.index + match[0].length) : "";
|
|
14526
|
+
return [sameLine, ...lines.slice(start + 1, start + 1 + MAX_HELPER_BODY_LINES)].some((line) => MODEL_CALL_IN_BODY.test(line));
|
|
14255
14527
|
}
|
|
14256
14528
|
function callCarriesChatMessages(lines, index) {
|
|
14257
14529
|
for (let i = Math.max(0, index - CALL_ROLE_WINDOW_LINES);i < Math.min(lines.length, index + CALL_ROLE_WINDOW_LINES + 1); i += 1) {
|
|
@@ -14398,6 +14670,31 @@ function readsAsInstructions(identifier, text) {
|
|
|
14398
14670
|
return score >= 2 || secondPerson;
|
|
14399
14671
|
return secondPerson && score >= 2 && text.length >= MIN_UNNAMED_REFERENCED_PROMPT_CHARS;
|
|
14400
14672
|
}
|
|
14673
|
+
function readsAsUnusedPrompt(name, text) {
|
|
14674
|
+
if (UI_COPY_NAME.test(name))
|
|
14675
|
+
return false;
|
|
14676
|
+
if (DIRECT_PROMPT_KEYS.has(name) && instructionScore(text) >= 2)
|
|
14677
|
+
return true;
|
|
14678
|
+
return readsAsInstructions(name, text);
|
|
14679
|
+
}
|
|
14680
|
+
var UI_COPY_NAME = /placeholder|label|tooltip|hint|title|caption|toast|button|error|empty_?state|copy/i;
|
|
14681
|
+
function isOnlyDisplayed(lines, identifier, definitionLine) {
|
|
14682
|
+
const ident = escapeRegExp(identifier);
|
|
14683
|
+
const reference = new RegExp(`(?<![\\w$.])${ident}(?![\\w$])`);
|
|
14684
|
+
const display = new RegExp(`\\{\\s*${ident}\\s*\\}(?!\\s*from)|[\\w-]+=\\{\\s*${ident}\\s*\\}|\\b(?:console|logger|log)\\.\\w+\\([^)]*\\b${ident}\\b|\\b(?:toast|alert|notify)\\w*\\([^)]*\\b${ident}\\b`);
|
|
14685
|
+
let references = 0;
|
|
14686
|
+
for (let index = 0;index < lines.length; index += 1) {
|
|
14687
|
+
const line = lines[index];
|
|
14688
|
+
if (index === definitionLine - 1 || !reference.test(line))
|
|
14689
|
+
continue;
|
|
14690
|
+
if (/^\s*(?:\/\/|#|\*|export\s*(?:default\s+)?\{|export\s+default\s+[\w$]+\s*;?\s*$)/.test(line))
|
|
14691
|
+
continue;
|
|
14692
|
+
references += 1;
|
|
14693
|
+
if (!display.test(line))
|
|
14694
|
+
return false;
|
|
14695
|
+
}
|
|
14696
|
+
return references > 0;
|
|
14697
|
+
}
|
|
14401
14698
|
function hasNearbyRole(lines, line) {
|
|
14402
14699
|
for (let i = Math.max(0, line - 4);i < Math.min(lines.length, line + 3); i += 1) {
|
|
14403
14700
|
if (/\brole\b\s*["']?\s*[:=]/.test(lines[i]))
|
|
@@ -14412,22 +14709,131 @@ function isDirectModelInput(key, value, path, lines, line, modelFiles) {
|
|
|
14412
14709
|
if (modelFiles.has(path)) {
|
|
14413
14710
|
return DIRECT_PROMPT_KEYS.has(key) || key === "content" && hasNearbyRole(lines, line);
|
|
14414
14711
|
}
|
|
14712
|
+
if (PROMPT_CONFIG_KEYS.has(key))
|
|
14713
|
+
return true;
|
|
14415
14714
|
return DIRECT_PROMPT_KEYS.has(key) && instructionScore(value) >= 2;
|
|
14416
14715
|
}
|
|
14716
|
+
function isModelCallee(callee, path, lines, modelFiles) {
|
|
14717
|
+
return MODEL_CALLEE.test(callee) || calleeImportedFromModelFile(callee, path, lines, modelFiles) || localHelperCallsModel(callee, lines);
|
|
14718
|
+
}
|
|
14719
|
+
function importSpecifiers(lines) {
|
|
14720
|
+
return lines.flatMap((line) => [...line.matchAll(/\bfrom\s+["']?([.\w/@$-]+)["']?|\bimport\s*\(\s*["']([^"']+)["']|\brequire\(\s*["']([^"']+)["']/g)].map((match) => match[1] ?? match[2] ?? match[3]));
|
|
14721
|
+
}
|
|
14722
|
+
var MODEL_ENDPOINT = /api\.anthropic\.com|api\.openai\.com|openrouter\.ai|generativelanguage\.googleapis\.com|api\.mistral\.ai|api\.groq\.com|api\.together\.(?:xyz|ai)|api\.deepseek\.com|\/chat\/completions\b|\/v1\/messages\b|\/v1\/responses\b/;
|
|
14723
|
+
var HTTP_CALLEE = /^(?:fetch|axios(?:\.post|\.request)?|got(?:\.post)?|ky(?:\.post)?|request|ofetch|\$fetch)$/;
|
|
14724
|
+
function targetsModelEndpoint(target, lines) {
|
|
14725
|
+
if (MODEL_ENDPOINT.test(target))
|
|
14726
|
+
return true;
|
|
14727
|
+
const name = /^(?:[A-Za-z_$][\w$]*\.)*([A-Za-z_$][\w$]*)$/.exec(target.trim())?.[1];
|
|
14728
|
+
if (!name)
|
|
14729
|
+
return false;
|
|
14730
|
+
const binding = new RegExp(`\\b${escapeRegExp(name)}\\s*[:=](?!=)`);
|
|
14731
|
+
return lines.some((line, index) => {
|
|
14732
|
+
const match = binding.exec(line);
|
|
14733
|
+
if (!match)
|
|
14734
|
+
return false;
|
|
14735
|
+
const initializer = [line.slice(match.index), ...lines.slice(index + 1, index + 4)].join(`
|
|
14736
|
+
`);
|
|
14737
|
+
const end = initializer.search(/;|,\s*$/m);
|
|
14738
|
+
return MODEL_ENDPOINT.test(end < 0 ? initializer : initializer.slice(0, end));
|
|
14739
|
+
});
|
|
14740
|
+
}
|
|
14741
|
+
function fileReachesModel(path, lines, modelFiles) {
|
|
14742
|
+
if (modelFiles.has(path))
|
|
14743
|
+
return true;
|
|
14744
|
+
if (lines.some((line) => MODEL_ENDPOINT.test(line)))
|
|
14745
|
+
return true;
|
|
14746
|
+
const python = extname7(path) === ".py";
|
|
14747
|
+
return importSpecifiers(lines).some((spec) => [...modelFiles].some((modelFile) => specifierResolvesTo(spec, path, modelFile, python)));
|
|
14748
|
+
}
|
|
14749
|
+
function modelFileImports(path, rootDir, modelFiles, fileCache) {
|
|
14750
|
+
return [...modelFiles].some((modelFile) => {
|
|
14751
|
+
if (modelFile === path)
|
|
14752
|
+
return false;
|
|
14753
|
+
const lines = readFileLines(rootDir, modelFile, fileCache);
|
|
14754
|
+
return Boolean(lines && importSpecifiers(lines).some((spec) => specifierResolvesTo(spec, modelFile, path, extname7(modelFile) === ".py")));
|
|
14755
|
+
});
|
|
14756
|
+
}
|
|
14757
|
+
var PASS_THROUGH_CALLEE = /^(?:Object\.(?:freeze|seal|assign)|structuredClone|Promise\.resolve|JSON\.stringify|(?:_\.|lodash\.)?(?:cloneDeep|clone|merge)|deepFreeze|defu)$/;
|
|
14758
|
+
function escapesAsItself(use, kind) {
|
|
14759
|
+
return use.escape !== undefined && (kind === undefined || use.escape === kind) && use.callees.every((callee) => PASS_THROUGH_CALLEE.test(callee));
|
|
14760
|
+
}
|
|
14761
|
+
function keyedObjectReachesModel(consumer, path, lines, modelFiles) {
|
|
14762
|
+
if (consumer.kind === "chat_message")
|
|
14763
|
+
return true;
|
|
14764
|
+
return consumer.uses.some((use) => escapesAsItself(use) || use.callees.some((callee, index) => isModelCallee(callee, path, lines, modelFiles) || HTTP_CALLEE.test(callee) && targetsModelEndpoint(use.targets[index] ?? "", lines)));
|
|
14765
|
+
}
|
|
14766
|
+
var PROMPT_CONFIG_KEYS = new Set([
|
|
14767
|
+
"instructions",
|
|
14768
|
+
"instruction",
|
|
14769
|
+
"systemPrompt",
|
|
14770
|
+
"system_prompt",
|
|
14771
|
+
"systemMessage",
|
|
14772
|
+
"system_message",
|
|
14773
|
+
"systemInstruction",
|
|
14774
|
+
"system_instruction",
|
|
14775
|
+
"backstory"
|
|
14776
|
+
]);
|
|
14777
|
+
function systemInjectionLiteralAt(lines, startLine, jsSource) {
|
|
14778
|
+
if (jsSource)
|
|
14779
|
+
return jsSystemInjectionLiteralAt(jsSource, startLine);
|
|
14780
|
+
const line = lines[startLine - 1];
|
|
14781
|
+
if (line === undefined || /^\s*(?:\/\/|\*(?!\/)|#)/.test(line))
|
|
14782
|
+
return;
|
|
14783
|
+
const match = SYSTEM_INJECTION_LITERAL.exec(line);
|
|
14784
|
+
if (!match || endsInComment(line.slice(0, match.index)) || opensInsideString(line.slice(0, match.index)))
|
|
14785
|
+
return;
|
|
14786
|
+
const text = readStringValue(lines.join(`
|
|
14787
|
+
`), textOffsetOfLine(lines, startLine - 1) + match.index);
|
|
14788
|
+
return text === undefined ? undefined : { text, line: startLine };
|
|
14789
|
+
}
|
|
14790
|
+
function opensInsideString(prefix) {
|
|
14791
|
+
let quote;
|
|
14792
|
+
for (let i = 0;i < prefix.length; i += 1) {
|
|
14793
|
+
const char = prefix[i];
|
|
14794
|
+
if (char === "\\")
|
|
14795
|
+
i += 1;
|
|
14796
|
+
else if (quote) {
|
|
14797
|
+
if (char === quote)
|
|
14798
|
+
quote = undefined;
|
|
14799
|
+
} else if (char === '"' || char === "'" || char === "`")
|
|
14800
|
+
quote = char;
|
|
14801
|
+
}
|
|
14802
|
+
return quote !== undefined;
|
|
14803
|
+
}
|
|
14417
14804
|
function promotePromptLiteralCandidate(candidate, rootDir, confidence2, fileCache, files) {
|
|
14418
14805
|
const lines = readFileLines(rootDir, candidate.path, fileCache);
|
|
14419
14806
|
if (!lines)
|
|
14420
14807
|
return;
|
|
14421
|
-
const definition = resolvePromptLiteralDefinition(lines, candidate.startLine);
|
|
14808
|
+
const definition = resolvePromptLiteralDefinition(lines, candidate.startLine, jsSources.get(`${rootDir}::${candidate.path}`), candidate.excerpt) ?? (candidate.signal === "code.system_injection" ? systemInjectionLiteralAt(lines, candidate.startLine, jsSources.get(`${rootDir}::${candidate.path}`)) : undefined);
|
|
14422
14809
|
if (!definition)
|
|
14423
14810
|
return;
|
|
14424
14811
|
const value = definition.text.trim();
|
|
14425
14812
|
const literalText = value.replace(/\$\{[^}]*\}|\{[A-Za-z_][\w.]*\}/g, "").trim();
|
|
14426
|
-
|
|
14813
|
+
const minChars = definition.key && PROMPT_CONFIG_KEYS.has(definition.key) ? 1 : MIN_RESOLVED_PROMPT_CHARS;
|
|
14814
|
+
if (literalText.length < minChars || isCodeLikeContent(value))
|
|
14815
|
+
return;
|
|
14816
|
+
if (isTestInput(candidate.path))
|
|
14427
14817
|
return;
|
|
14428
14818
|
const key = definition.key ?? (definition.identifier && DIRECT_PROMPT_KEYS.has(definition.identifier) ? definition.identifier : undefined);
|
|
14429
14819
|
let use;
|
|
14430
|
-
if (
|
|
14820
|
+
if (SYSTEM_INJECTION.test(value) && !BARE_SYSTEM_TAG.test(value)) {
|
|
14821
|
+
use = { path: candidate.path, line: definition.line, key: "system-injection" };
|
|
14822
|
+
}
|
|
14823
|
+
const jsSource = jsSources.get(`${rootDir}::${candidate.path}`);
|
|
14824
|
+
if (!use && definition.key && !PROMPT_CONFIG_KEYS.has(definition.key) && !CONFIG_EXTENSIONS.has(extname7(candidate.path).toLowerCase())) {
|
|
14825
|
+
const exportUsed = () => modelFileImports(candidate.path, rootDir, files.model, fileCache);
|
|
14826
|
+
if (jsSource) {
|
|
14827
|
+
const consumer = keyedValueConsumer(jsSource, definition.line, definition.key, definition.column);
|
|
14828
|
+
if (!fileReachesModel(candidate.path, lines, files.model) && !(consumer.kind === "uses" && consumer.uses.some((use2) => escapesAsItself(use2, "export")) && exportUsed()))
|
|
14829
|
+
return;
|
|
14830
|
+
if (!keyedObjectReachesModel(consumer, candidate.path, lines, files.model))
|
|
14831
|
+
return;
|
|
14832
|
+
} else if (!fileReachesModel(candidate.path, lines, files.model) && !exportUsed()) {
|
|
14833
|
+
return;
|
|
14834
|
+
}
|
|
14835
|
+
}
|
|
14836
|
+
if (!use && key && isDirectModelInput(key, value, candidate.path, lines, definition.line, files.model)) {
|
|
14431
14837
|
use = { path: candidate.path, line: definition.line, key };
|
|
14432
14838
|
}
|
|
14433
14839
|
if (!use && definition.identifier) {
|
|
@@ -14435,9 +14841,15 @@ function promotePromptLiteralCandidate(candidate, rootDir, confidence2, fileCach
|
|
|
14435
14841
|
allowReference: readsAsInstructions(definition.identifier, value)
|
|
14436
14842
|
});
|
|
14437
14843
|
}
|
|
14438
|
-
if (!use)
|
|
14439
|
-
return;
|
|
14440
14844
|
const name = definition.identifier ?? definition.key;
|
|
14845
|
+
const unused = !use;
|
|
14846
|
+
if (!use) {
|
|
14847
|
+
if (!name || !readsAsUnusedPrompt(name, value))
|
|
14848
|
+
return;
|
|
14849
|
+
if (definition.identifier && isOnlyDisplayed(lines, definition.identifier, definition.line))
|
|
14850
|
+
return;
|
|
14851
|
+
use = { path: candidate.path, line: definition.line, key: "unused" };
|
|
14852
|
+
}
|
|
14441
14853
|
const evidence = [{ path: candidate.path, line: definition.line, reason: `deterministic detector ${candidate.signal}` }];
|
|
14442
14854
|
const sameSite = use.path === candidate.path && use.line === definition.line;
|
|
14443
14855
|
if (!sameSite) {
|
|
@@ -14448,13 +14860,13 @@ function promotePromptLiteralCandidate(candidate, rootDir, confidence2, fileCach
|
|
|
14448
14860
|
});
|
|
14449
14861
|
}
|
|
14450
14862
|
return {
|
|
14451
|
-
id: stableId("prompt", `${pathStem(candidate.path)}:L${definition.line}`),
|
|
14863
|
+
id: stableId("prompt", `${pathStem(candidate.path)}:L${definition.line}${definition.column ? `C${definition.column}` : ""}`),
|
|
14452
14864
|
type: "prompt",
|
|
14453
14865
|
name: name ? titleFromId(name) : `Inline Prompt (${candidate.path}:${definition.line})`,
|
|
14454
14866
|
scope: "shared",
|
|
14455
14867
|
usedByAgentIds: [],
|
|
14456
|
-
confidence: use.referenceOnly ? Math.min(confidence2, REFERENCED_PROMPT_CONFIDENCE) : confidence2,
|
|
14457
|
-
confidenceReason: use.referenceOnly ? `Deterministic: instruction-like literal ${name} is referenced at ${use.path}:${use.line} through ${use.via}, but no prompt key (system, instructions, content) was found at the call.` : sameSite ? `Deterministic: string literal written under the ${use.key} key at ${candidate.path}:${definition.line}.` : `Deterministic: string literal ${name} passed to a model call as ${use.key} at ${use.path}:${use.line}.`,
|
|
14868
|
+
confidence: unused ? Math.min(confidence2, UNUSED_PROMPT_CONFIDENCE) : use.referenceOnly ? Math.min(confidence2, REFERENCED_PROMPT_CONFIDENCE) : confidence2,
|
|
14869
|
+
confidenceReason: unused ? `Deterministic: instruction-like literal ${name} at ${candidate.path}:${definition.line}; no model call using it was found, so it may be unused.` : use.referenceOnly ? `Deterministic: instruction-like literal ${name} is referenced at ${use.path}:${use.line} through ${use.via}, but no prompt key (system, instructions, content) was found at the call.` : use.key === "system-injection" ? `Deterministic: literal at ${candidate.path}:${definition.line} opens with [SYSTEM:, a message injected into the agent's conversation.` : sameSite ? `Deterministic: string literal written under the ${use.key} key at ${candidate.path}:${definition.line}.` : `Deterministic: string literal ${name} passed to a model call as ${use.key} at ${use.path}:${use.line}.`,
|
|
14458
14870
|
evidence,
|
|
14459
14871
|
body: definition.text
|
|
14460
14872
|
};
|
|
@@ -14462,9 +14874,18 @@ function promotePromptLiteralCandidate(candidate, rootDir, confidence2, fileCach
|
|
|
14462
14874
|
function promoteModelConfigCandidate(candidate, rootDir, confidence2, fileCache) {
|
|
14463
14875
|
const lines = readFileLines(rootDir, candidate.path, fileCache);
|
|
14464
14876
|
const sourceLine = lines?.[candidate.startLine - 1] ?? "";
|
|
14465
|
-
const
|
|
14877
|
+
const assignment = MODEL_ASSIGNMENT_VALUE.exec(sourceLine);
|
|
14878
|
+
const [field, assigned] = [assignment?.[1], assignment?.[2]];
|
|
14879
|
+
if (field && MODEL_PREFERENCE_FIELD.test(field) && !FULL_MODEL_ID.test(assigned ?? ""))
|
|
14880
|
+
return;
|
|
14881
|
+
const registryKey = candidate.signal === "model.registry_key" ? REGISTRY_KEY.exec(sourceLine)?.[1] : undefined;
|
|
14882
|
+
const model = (assigned && MODEL_STRING.exec(assigned)?.[1]) ?? registryKey ?? MODEL_STRING.exec(sourceLine)?.[1] ?? MODEL_STRING.exec(candidate.excerpt)?.[1];
|
|
14466
14883
|
if (!model)
|
|
14467
14884
|
return;
|
|
14885
|
+
if (MODEL_FAMILY_ALIAS.test(model.split("/").pop() ?? model))
|
|
14886
|
+
return;
|
|
14887
|
+
if (TEST_PATH2.test(candidate.path) && !usedOutsideTests(rootDir, model))
|
|
14888
|
+
return;
|
|
14468
14889
|
return {
|
|
14469
14890
|
id: stableId("model_config", `${pathStem(candidate.path)}:L${candidate.startLine}`),
|
|
14470
14891
|
type: "model_config",
|
|
@@ -14472,9 +14893,42 @@ function promoteModelConfigCandidate(candidate, rootDir, confidence2, fileCache)
|
|
|
14472
14893
|
scope: "shared",
|
|
14473
14894
|
usedByAgentIds: [],
|
|
14474
14895
|
confidence: confidence2,
|
|
14896
|
+
confidenceReason: detectorConfidenceReason(candidate),
|
|
14475
14897
|
evidence: candidateEvidence(candidate)
|
|
14476
14898
|
};
|
|
14477
14899
|
}
|
|
14900
|
+
var nonTestSourcePaths = new Map;
|
|
14901
|
+
var modelUsedOutsideTests = new Map;
|
|
14902
|
+
var MAX_MODEL_SOURCE_BYTES = 1024 * 1024;
|
|
14903
|
+
var MODEL_SOURCE_FILE = /\.(?:[cm]?[jt]sx?|py|json|jsonc|ya?ml|toml)$/i;
|
|
14904
|
+
var NON_SOURCE_DIR = /(^|\/)(?:docs?|\.moda)\//i;
|
|
14905
|
+
function usedOutsideTests(rootDir, modelId) {
|
|
14906
|
+
let results = modelUsedOutsideTests.get(rootDir);
|
|
14907
|
+
if (!results) {
|
|
14908
|
+
results = new Map;
|
|
14909
|
+
modelUsedOutsideTests.set(rootDir, results);
|
|
14910
|
+
}
|
|
14911
|
+
const cached = results.get(modelId);
|
|
14912
|
+
if (cached !== undefined)
|
|
14913
|
+
return cached;
|
|
14914
|
+
let paths = nonTestSourcePaths.get(rootDir);
|
|
14915
|
+
if (!paths) {
|
|
14916
|
+
paths = inventoryFiles(rootDir, [], { includeFile: (path) => MODEL_SOURCE_FILE.test(path) }).map((file) => file.path).filter((path) => !TEST_PATH2.test(path) && MODEL_SOURCE_FILE.test(path) && !NON_SOURCE_DIR.test(path));
|
|
14917
|
+
nonTestSourcePaths.set(rootDir, paths);
|
|
14918
|
+
}
|
|
14919
|
+
const used = paths.some((path) => {
|
|
14920
|
+
try {
|
|
14921
|
+
const absolute = resolve9(rootDir, path);
|
|
14922
|
+
if (statSync3(absolute).size > MAX_MODEL_SOURCE_BYTES)
|
|
14923
|
+
return false;
|
|
14924
|
+
return readFileSync11(absolute, "utf8").includes(modelId);
|
|
14925
|
+
} catch {
|
|
14926
|
+
return false;
|
|
14927
|
+
}
|
|
14928
|
+
});
|
|
14929
|
+
results.set(modelId, used);
|
|
14930
|
+
return used;
|
|
14931
|
+
}
|
|
14478
14932
|
function mergePromotedDuplicate(existing, next) {
|
|
14479
14933
|
for (const entry of next.evidence) {
|
|
14480
14934
|
const already = existing.evidence.some((candidate) => candidate.path === entry.path && candidate.line === entry.line && candidate.reason === entry.reason);
|
|
@@ -14486,6 +14940,14 @@ function mergePromotedDuplicate(existing, next) {
|
|
|
14486
14940
|
existing.body = next.body;
|
|
14487
14941
|
}
|
|
14488
14942
|
function promoteHarnessCandidates(report, rootDir) {
|
|
14943
|
+
jsSources.clear();
|
|
14944
|
+
try {
|
|
14945
|
+
return promoteAll(report, rootDir);
|
|
14946
|
+
} finally {
|
|
14947
|
+
jsSources.clear();
|
|
14948
|
+
}
|
|
14949
|
+
}
|
|
14950
|
+
function promoteAll(report, rootDir) {
|
|
14489
14951
|
const fileCache = new Map;
|
|
14490
14952
|
const byId = new Map;
|
|
14491
14953
|
const files = {
|
|
@@ -14502,7 +14964,9 @@ function promoteHarnessCandidates(report, rootDir) {
|
|
|
14502
14964
|
artifact = promoteToolCandidate(candidate, rootDir, confidence2, fileCache);
|
|
14503
14965
|
break;
|
|
14504
14966
|
case "prompt_file":
|
|
14505
|
-
if (candidate.signal === "prompt_module.name_hint" && (
|
|
14967
|
+
if (candidate.signal === "prompt_module.name_hint" && (isTestInput(candidate.path) || !buildsPrompts(candidate.path, readFileLines(rootDir, candidate.path, fileCache))))
|
|
14968
|
+
break;
|
|
14969
|
+
if (isTestInput(candidate.path))
|
|
14506
14970
|
break;
|
|
14507
14971
|
artifact = promotePromptFileCandidate(candidate, confidence2);
|
|
14508
14972
|
break;
|
|
@@ -14861,7 +15325,7 @@ async function runHarnessCommand(context) {
|
|
|
14861
15325
|
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.");
|
|
14862
15326
|
}
|
|
14863
15327
|
if (context.flags["github-actions"] === "true") {
|
|
14864
|
-
const { runGithubActionsAnalyze } = await import("./harness-github-actions-
|
|
15328
|
+
const { runGithubActionsAnalyze } = await import("./harness-github-actions-tzn5ye9e.js");
|
|
14865
15329
|
const result = await runGithubActionsAnalyze(rootDir, {
|
|
14866
15330
|
writeReport: (report2) => {
|
|
14867
15331
|
const normalized = normalizeHarnessReport(report2);
|
|
@@ -16707,6 +17171,7 @@ function renderExternalHarnessAnalystPrompt(options) {
|
|
|
16707
17171
|
"Include every real harness component in your scope whether or not anything uses it: a tool defined but never registered, a prompt file or prompt literal nothing references, an agent, Workflow, or Durable Object class defined or exported but never bound, an eval or fixture that tests the agent, a model config declared but unused. Never drop a component for being unused, dead, or legacy; Moda tags its deployment status separately. A class defined here that nothing binds or instantiates is an `entrypoint` artifact, not a runtime agent.",
|
|
16708
17172
|
'A `tool` artifact is one tool definition. Never emit a group of tools ("MCP server tools", "composio_*", "worker tools") as a tool; record a dynamic tool source (MCP servers, Composio, webhooks) as a graph unknown that cites where the tools are loaded.',
|
|
16709
17173
|
"Ignore any checked-in .moda/ directory: it is the output of an earlier Moda run and is often stale. Never cite it or reuse its entities.",
|
|
17174
|
+
"The harness includes every real harness component, used or not: a prompt, tool, or model config that is defined but never called is still part of the harness (lower its confidence and say so in confidenceReason). A false positive is only something that is not a harness component: SQL, React or UI props and display copy, URL or path templates, test fixtures, and general utilities. Refute only those; never refute a real component because it is unused.",
|
|
16710
17175
|
'Every graph item with confidence below 0.85 must also carry confidenceReason: one sentence naming what held confidence down, e.g. "Inferred from AGENTS.md:231-232 only; no source file defines this agent." or "Entrypoint read, but the tool registry was outside the snapshot."',
|
|
16711
17176
|
"Each graph item with evidence must use evidence: [{ path, reason }], not citationIds/citations.",
|
|
16712
17177
|
...spec ? spec.contractLines : [
|
|
@@ -16845,7 +17310,7 @@ function renderAnalystCandidateLines(report, concern) {
|
|
|
16845
17310
|
const lines = [
|
|
16846
17311
|
"",
|
|
16847
17312
|
concern ? `Deterministic candidate inventory for the ${concern} concern (${candidates.length} candidates, scanned in ${report.stats.durationMs}ms):` : `Deterministic candidate inventory (${candidates.length} candidates across ${report.stats.filesWithCandidates} files, scanned in ${report.stats.durationMs}ms):`,
|
|
16848
|
-
concern ? 'Each entry is path:line [detector] excerpt. Candidates are pattern matches — verify each against the real file, drop false positives (list refuted ones in unknowns: an unknown whose id starts with "refuted_", with one evidence entry {path, line, reason} per refuted candidate, using the path:line shown for that candidate and starting the reason with its [detector]), and hunt for in-concern items the patterns cannot see. Do not cite this list as evidence; cite the files.' : 'Each entry is path:line [detector] excerpt. Candidates are pattern matches — verify each against the real file and drop false positives. Verified deterministic candidates are also auto-merged into the graph after your run, so prioritize (1) agents, topology, and relationships, (2) verifying or refuting these candidates (list refuted ones in unknowns: an unknown whose id starts with "refuted_", with one evidence entry {path, line, reason} per refuted candidate, using the path:line shown for that candidate and starting the reason with its [detector]; refuted candidates are never auto-merged), and (3) artifacts the patterns cannot see (runtime agents, prompts assembled at runtime, cross-file wiring) — rather than re-listing every candidate as an artifact. Do not cite this list as evidence; cite the files.'
|
|
17313
|
+
concern ? 'Each entry is path:line [detector] excerpt. Candidates are pattern matches — verify each against the real file, drop false positives — things that are not harness components (SQL, UI props or display copy, URL templates, test fixtures, utilities), never a real component merely because it is unused (list refuted ones in unknowns: an unknown whose id starts with "refuted_", with one evidence entry {path, line, reason} per refuted candidate, using the path:line shown for that candidate and starting the reason with its [detector]), and hunt for in-concern items the patterns cannot see. Do not cite this list as evidence; cite the files.' : 'Each entry is path:line [detector] excerpt. Candidates are pattern matches — verify each against the real file and drop false positives — things that are not harness components (SQL, UI props or display copy, URL templates, test fixtures, utilities), never a real component merely because it is unused. Verified deterministic candidates are also auto-merged into the graph after your run, so prioritize (1) agents, topology, and relationships, (2) verifying or refuting these candidates (list refuted ones in unknowns: an unknown whose id starts with "refuted_", with one evidence entry {path, line, reason} per refuted candidate, using the path:line shown for that candidate and starting the reason with its [detector]; refuted candidates are never auto-merged), and (3) artifacts the patterns cannot see (runtime agents, prompts assembled at runtime, cross-file wiring) — rather than re-listing every candidate as an artifact. Do not cite this list as evidence; cite the files.'
|
|
16849
17314
|
];
|
|
16850
17315
|
if (concern === "evals") {
|
|
16851
17316
|
lines.push("Note: evals, guardrails, and memory/retrieval stores have no deterministic detector — only model_config candidates are seeded. Discover the rest by investigation.");
|
|
@@ -5768,7 +5768,7 @@ async function runPromptSyncExclusive(flags, profileOptions, options) {
|
|
|
5768
5768
|
const analyzedDefinitions = new Map;
|
|
5769
5769
|
if (flags["no-analyze"] !== "true") {
|
|
5770
5770
|
options.onProgress?.("Analyzing prompt sources before sync.");
|
|
5771
|
-
const { analyzeHarnessPrompts } = await import("./harness-
|
|
5771
|
+
const { analyzeHarnessPrompts } = await import("./harness-7cncbphq.js");
|
|
5772
5772
|
const result = await analyzeHarnessPrompts({
|
|
5773
5773
|
rootDir: process.cwd(),
|
|
5774
5774
|
existing: established.flatMap((prompt) => prompt.sourceDefinition ? [prompt.sourceDefinition.source] : []),
|
|
@@ -5796,7 +5796,7 @@ async function runPromptSyncExclusive(flags, profileOptions, options) {
|
|
|
5796
5796
|
const mergedSources = mergePromptSources(manifest.sources, extraSources);
|
|
5797
5797
|
const manifestUpdate = stableJson(mergedSources) === stableJson(mergePromptSources(manifest.sources, [])) ? undefined : $stringify({ version: 2, prompt_paths: manifest.promptPaths, sources: mergedSources });
|
|
5798
5798
|
const prompts = await discoverPrompts(extraSources);
|
|
5799
|
-
const { checkPromptAttribution } = await import("./prompt-attribution-
|
|
5799
|
+
const { checkPromptAttribution } = await import("./prompt-attribution-x5bzrr8n.js");
|
|
5800
5800
|
const attribution = checkPromptAttribution(process.cwd(), prompts.map((prompt) => prompt.key));
|
|
5801
5801
|
const brokenAttribution = attribution.references.filter((reference) => reference.status === "missing");
|
|
5802
5802
|
if (brokenAttribution.length) {
|
|
@@ -6102,7 +6102,7 @@ async function migratePromptManifest(options = {}) {
|
|
|
6102
6102
|
let addedSources = [];
|
|
6103
6103
|
let pendingSources = [];
|
|
6104
6104
|
if (options.discover) {
|
|
6105
|
-
const { analyzeHarnessPrompts } = await import("./harness-
|
|
6105
|
+
const { analyzeHarnessPrompts } = await import("./harness-7cncbphq.js");
|
|
6106
6106
|
const result = await analyzeHarnessPrompts({
|
|
6107
6107
|
rootDir: root,
|
|
6108
6108
|
existing: manifest.sources,
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./cli-94r5x9bg.js";
|
|
5
5
|
import {
|
|
6
6
|
inspectPromptManifest
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-8mqz9qgt.js";
|
|
8
8
|
import {
|
|
9
9
|
readHarnessSyncState,
|
|
10
10
|
renderDoctorHuman,
|
|
@@ -395,7 +395,7 @@ async function harnessCurrentCheck(cwd, manifestPath, manifestExists, tenantId)
|
|
|
395
395
|
};
|
|
396
396
|
}
|
|
397
397
|
try {
|
|
398
|
-
const { scanHarness } = await import("./harness-
|
|
398
|
+
const { scanHarness } = await import("./harness-7cncbphq.js");
|
|
399
399
|
const current = scanHarness({
|
|
400
400
|
rootDir: cwd,
|
|
401
401
|
scannerVersion: "doctor",
|
package/dist/cli.js
CHANGED
|
@@ -2968,25 +2968,25 @@ function leafManifestFields(leaf, commands) {
|
|
|
2968
2968
|
import { fileURLToPath } from "url";
|
|
2969
2969
|
import { realpathSync } from "fs";
|
|
2970
2970
|
async function runPromptsCommand(...args) {
|
|
2971
|
-
return (await import("./prompts-
|
|
2971
|
+
return (await import("./prompts-e2nyqkyv.js")).runPromptsCommand(...args);
|
|
2972
2972
|
}
|
|
2973
2973
|
async function runSkillsCommand(...args) {
|
|
2974
2974
|
return (await import("./skills-etzcqhp8.js")).runSkillsCommand(...args);
|
|
2975
2975
|
}
|
|
2976
2976
|
async function runHarnessCommand(...args) {
|
|
2977
|
-
return (await import("./harness-
|
|
2977
|
+
return (await import("./harness-7cncbphq.js")).runHarnessCommand(...args);
|
|
2978
2978
|
}
|
|
2979
2979
|
async function runSyncCommand(...args) {
|
|
2980
|
-
return (await import("./sync-
|
|
2980
|
+
return (await import("./sync-agcws2qn.js")).runSyncCommand(...args);
|
|
2981
2981
|
}
|
|
2982
2982
|
async function runRegistryCommand(...args) {
|
|
2983
2983
|
return (await import("./registry-wv1zzyce.js")).runRegistryCommand(...args);
|
|
2984
2984
|
}
|
|
2985
2985
|
async function runDoctorCommand(...args) {
|
|
2986
|
-
return (await import("./doctor-
|
|
2986
|
+
return (await import("./doctor-ascpx1py.js")).runDoctorCommand(...args);
|
|
2987
2987
|
}
|
|
2988
2988
|
async function runStatusCommand(...args) {
|
|
2989
|
-
return (await import("./doctor-
|
|
2989
|
+
return (await import("./doctor-ascpx1py.js")).runStatusCommand(...args);
|
|
2990
2990
|
}
|
|
2991
2991
|
async function runAuthCommand(...args) {
|
|
2992
2992
|
return (await import("./profile-commands-yvpe4d8y.js")).runAuthCommand(...args);
|
|
@@ -2998,7 +2998,7 @@ async function runProfilesCommand(...args) {
|
|
|
2998
2998
|
return (await import("./profile-commands-yvpe4d8y.js")).runProfilesCommand(...args);
|
|
2999
2999
|
}
|
|
3000
3000
|
async function runAgentCommand(...args) {
|
|
3001
|
-
return (await import("./agent-
|
|
3001
|
+
return (await import("./agent-81f11bvs.js")).runAgentCommand(...args);
|
|
3002
3002
|
}
|
|
3003
3003
|
async function runProductionCommand(...args) {
|
|
3004
3004
|
return (await import("./production-intelligence-fqvhzq6s.js")).runProductionCommand(...args);
|
|
@@ -6762,7 +6762,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
6762
6762
|
resetApiRequestCountBeforeRun: true,
|
|
6763
6763
|
telemetry: "result-and-error",
|
|
6764
6764
|
handler: async (context) => {
|
|
6765
|
-
const { runInit } = await import("./index-
|
|
6765
|
+
const { runInit } = await import("./index-zh4ygqq0.js");
|
|
6766
6766
|
if (context.outputMode === "agent-stream") {
|
|
6767
6767
|
context.output.writeEvent({
|
|
6768
6768
|
event: "started",
|
|
@@ -3,9 +3,9 @@ import {
|
|
|
3
3
|
promptsDiscoveredCheck,
|
|
4
4
|
runDoctorCommand,
|
|
5
5
|
runStatusCommand
|
|
6
|
-
} from "./cli-
|
|
6
|
+
} from "./cli-krt4ap9y.js";
|
|
7
7
|
import"./cli-94r5x9bg.js";
|
|
8
|
-
import"./cli-
|
|
8
|
+
import"./cli-8mqz9qgt.js";
|
|
9
9
|
import"./cli-mm48br00.js";
|
|
10
10
|
import"./cli-xq45etg1.js";
|
|
11
11
|
import"./cli-v2h21cgf.js";
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
} from "./cli-hcwdz9sd.js";
|
|
22
22
|
import {
|
|
23
23
|
buildDoctorReport
|
|
24
|
-
} from "./cli-
|
|
24
|
+
} from "./cli-krt4ap9y.js";
|
|
25
25
|
import {
|
|
26
26
|
ConnectCodeError,
|
|
27
27
|
connectWithCode,
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
import {
|
|
33
33
|
initPrompts,
|
|
34
34
|
runPromptSync
|
|
35
|
-
} from "./cli-
|
|
35
|
+
} from "./cli-8mqz9qgt.js";
|
|
36
36
|
import"./cli-mm48br00.js";
|
|
37
37
|
import {
|
|
38
38
|
codingAgentDisplayName,
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
runCodingAgent,
|
|
47
47
|
runHarnessCommand,
|
|
48
48
|
startRemoteAnalyze
|
|
49
|
-
} from "./cli-
|
|
49
|
+
} from "./cli-6k25gr7h.js";
|
|
50
50
|
import {
|
|
51
51
|
stripAnsi
|
|
52
52
|
} from "./cli-97fnztpy.js";
|
|
@@ -6,11 +6,11 @@ import"./cli-rjav0vj1.js";
|
|
|
6
6
|
import"./cli-hcwdz9sd.js";
|
|
7
7
|
import {
|
|
8
8
|
runPromptsCommand
|
|
9
|
-
} from "./cli-
|
|
9
|
+
} from "./cli-8mqz9qgt.js";
|
|
10
10
|
import"./cli-mm48br00.js";
|
|
11
11
|
import {
|
|
12
12
|
runHarnessCommand
|
|
13
|
-
} from "./cli-
|
|
13
|
+
} from "./cli-6k25gr7h.js";
|
|
14
14
|
import"./cli-97fnztpy.js";
|
|
15
15
|
import"./cli-xq45etg1.js";
|
|
16
16
|
import"./cli-v2h21cgf.js";
|
package/package.json
CHANGED