@moda-ai/cli 1.55.50 → 1.55.51
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-vdqppnq3.js → agent-jyst7r0g.js} +3 -3
- package/dist/{cli-73x2yznb.js → cli-3pn6w6m3.js} +2 -2
- package/dist/{cli-n3bjh1pc.js → cli-k6kydtkv.js} +785 -12
- package/dist/{cli-79pzgqtj.js → cli-s3bcce69.js} +3 -3
- package/dist/cli.js +7 -7
- package/dist/{doctor-dz8gfz2h.js → doctor-0z5k6z9a.js} +2 -2
- package/dist/{harness-fx091nmr.js → harness-0pzqswvr.js} +1 -1
- package/dist/{harness-github-actions-jfbcsx2s.js → harness-github-actions-nzcpftjn.js} +1 -1
- package/dist/{index-q2d1fva7.js → index-2p6x0xg2.js} +3 -3
- package/dist/{prompt-attribution-avvkfq8c.js → prompt-attribution-dfj7etks.js} +1 -1
- package/dist/prompt-source-mcp.js +1 -1
- package/dist/{prompts-hcecy2na.js → prompts-r7kzdnca.js} +1 -1
- package/dist/{sync-v0me021f.js → sync-xcjye7em.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-3pn6w6m3.js";
|
|
4
4
|
import"./cli-rdh9jjr2.js";
|
|
5
|
-
import"./cli-
|
|
5
|
+
import"./cli-s3bcce69.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-0pzqswvr.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),
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./cli-rdh9jjr2.js";
|
|
5
5
|
import {
|
|
6
6
|
inspectPromptManifest
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-s3bcce69.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-0pzqswvr.js");
|
|
399
399
|
const current = scanHarness({
|
|
400
400
|
rootDir: cwd,
|
|
401
401
|
scannerVersion: "doctor",
|
|
@@ -13554,7 +13554,7 @@ function applyPromptDiscovery(graph, discovery) {
|
|
|
13554
13554
|
|
|
13555
13555
|
// src/harness-candidate-promotion.ts
|
|
13556
13556
|
import { readFileSync as readFileSync11 } from "node:fs";
|
|
13557
|
-
import { resolve as resolve9 } from "node:path";
|
|
13557
|
+
import { extname as extname7, posix, resolve as resolve9 } from "node:path";
|
|
13558
13558
|
var PROMOTED_CONFIDENCE = {
|
|
13559
13559
|
high: 0.85,
|
|
13560
13560
|
medium: 0.6
|
|
@@ -13566,7 +13566,6 @@ var JS_ASSIGNMENT_NAME = /(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=/;
|
|
|
13566
13566
|
var JS_PROPERTY_NAME = /^\s*(?:public\s+|readonly\s+)?([A-Za-z_$][\w$]*)\s*:\s*(?:new\s+)?(?:[\w.$]*\.)?(?:tool|functionTool|createTool|dynamicTool|DynamicStructuredTool)\s*\(/;
|
|
13567
13567
|
var JS_TRAILING_ASSIGNMENT_NAME = /(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:new\s+)?$/;
|
|
13568
13568
|
var REGISTRY_CALL_NAME = /\b(?:register_tool|registerTool|add_tool)\s*\(\s*["']?([A-Za-z_$][\w$]*)/;
|
|
13569
|
-
var PROMPT_ASSIGNMENT_NAME = /^\s*(?:export\s+)?(?:(?:const|let|var)\s+)?([A-Za-z_$][\w$]*)\s*[:=]/;
|
|
13570
13569
|
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;
|
|
13571
13570
|
function candidateEvidence(candidate) {
|
|
13572
13571
|
return [{
|
|
@@ -13641,17 +13640,786 @@ function promotePromptFileCandidate(candidate, confidence2) {
|
|
|
13641
13640
|
evidence: candidateEvidence(candidate)
|
|
13642
13641
|
};
|
|
13643
13642
|
}
|
|
13644
|
-
|
|
13643
|
+
var MODEL_INPUT_KEYS = [
|
|
13644
|
+
"system",
|
|
13645
|
+
"systemPrompt",
|
|
13646
|
+
"system_prompt",
|
|
13647
|
+
"systemMessage",
|
|
13648
|
+
"system_message",
|
|
13649
|
+
"systemInstruction",
|
|
13650
|
+
"system_instruction",
|
|
13651
|
+
"instructions",
|
|
13652
|
+
"prompt",
|
|
13653
|
+
"userPrompt",
|
|
13654
|
+
"user_prompt",
|
|
13655
|
+
"backstory",
|
|
13656
|
+
"content",
|
|
13657
|
+
"input",
|
|
13658
|
+
"template",
|
|
13659
|
+
"text"
|
|
13660
|
+
];
|
|
13661
|
+
var DIRECT_PROMPT_KEYS = new Set([
|
|
13662
|
+
"system",
|
|
13663
|
+
"systemPrompt",
|
|
13664
|
+
"system_prompt",
|
|
13665
|
+
"systemMessage",
|
|
13666
|
+
"system_message",
|
|
13667
|
+
"systemInstruction",
|
|
13668
|
+
"system_instruction",
|
|
13669
|
+
"instructions",
|
|
13670
|
+
"prompt",
|
|
13671
|
+
"userPrompt",
|
|
13672
|
+
"user_prompt",
|
|
13673
|
+
"backstory",
|
|
13674
|
+
"system_template",
|
|
13675
|
+
"instance_template"
|
|
13676
|
+
]);
|
|
13677
|
+
var GENERIC_IDENTIFIERS = new Set([
|
|
13678
|
+
"prompt",
|
|
13679
|
+
"template",
|
|
13680
|
+
"system",
|
|
13681
|
+
"instructions",
|
|
13682
|
+
"content",
|
|
13683
|
+
"text",
|
|
13684
|
+
"message",
|
|
13685
|
+
"input",
|
|
13686
|
+
"body",
|
|
13687
|
+
"value"
|
|
13688
|
+
]);
|
|
13689
|
+
var CONFIG_EXTENSIONS = new Set([".json", ".yaml", ".yml"]);
|
|
13690
|
+
var PROMPT_NAMED_IDENTIFIER = /prompt|system|instruction/i;
|
|
13691
|
+
var SECOND_PERSON_OPENING = /^\s*(?:\[[A-Z]+:\s*|<\w+>\s*)*(?:you|your)\b/i;
|
|
13692
|
+
var MIN_UNNAMED_REFERENCED_PROMPT_CHARS = 200;
|
|
13693
|
+
var REFERENCED_PROMPT_CONFIDENCE = 0.7;
|
|
13694
|
+
var MIN_RESOLVED_PROMPT_CHARS = 20;
|
|
13695
|
+
var MIN_CONFIG_PROMPT_CHARS = 40;
|
|
13696
|
+
var MAX_BUILDER_LOOKBEHIND_LINES = 40;
|
|
13697
|
+
var DEFINITION_HEAD = /^\s*(?:export\s+)?(?:(?:const|let|var|readonly|static|public|private)\s+)*["']?([A-Za-z_$][\w$]*)["']?\s*(?:(?::\s*[\w$.<>[\]|, ]+?)?\s*(=)(?![=>])|(:))\s*(.*)$/;
|
|
13698
|
+
var VALUE_WRAPPERS = /^(?:\(|\[|(?:textwrap\.)?dedent\(|inspect\.cleandoc\(|outdent|stripIndent)\s*/;
|
|
13699
|
+
var STRING_OPENER = /^(?:[fFrRbBuU]{1,2})?("""|\'\'\'|"|'|`)/;
|
|
13700
|
+
var BUILDER_HEAD = /^\s*(?:export\s+)?(?:async\s+)?(?:function\s+([A-Za-z_$][\w$]*)\s*\(|def\s+([A-Za-z_]\w*)\s*\(|(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:async\s+)?(?:\([^)]*\)|[A-Za-z_$][\w$]*)\s*=>)/;
|
|
13701
|
+
var CODE_LIKE_CONTENT = [
|
|
13702
|
+
/^\s*(?:SELECT|WITH|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP)\b[\s\S]*\b(?:FROM|INTO|SET|TABLE|AS)\b/i,
|
|
13703
|
+
/^\s*[a-z][\w+.-]*:\/\/\S*$/i,
|
|
13704
|
+
/^\s*(?:<![Dd][Oo][Cc][Tt][Yy][Pp][Ee]\b|<(?:html|head|body|div|span|p|a|ul|ol|li|table|tr|td|th|button|img|svg|path|section|header|footer|nav|main|form|input|label|select|option|textarea|h[1-6]|br|hr|meta|link|script|style|template|iframe|video)[\s/>]|<[A-Z][\w.]*[\s/>]|<[A-Za-z][\w.-]*\s+[\w:-]+=)/
|
|
13705
|
+
];
|
|
13706
|
+
var INLINE_PROMPT_KEY = new RegExp(`(?<![\\w$.])["']?(${[...new Set([...MODEL_INPUT_KEYS, ...DIRECT_PROMPT_KEYS])].join("|")})["']?\\s*(?::|=(?![=>]))\\s*`, "g");
|
|
13707
|
+
function escapeRegExp(value) {
|
|
13708
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
13709
|
+
}
|
|
13710
|
+
function readStringLiteral(text, start) {
|
|
13711
|
+
const opener = text.startsWith('"""', start) || text.startsWith("'''", start) ? text.slice(start, start + 3) : text[start];
|
|
13712
|
+
let i = start + opener.length;
|
|
13713
|
+
while (i < text.length) {
|
|
13714
|
+
const char = text[i];
|
|
13715
|
+
if (char === "\\") {
|
|
13716
|
+
i += 2;
|
|
13717
|
+
continue;
|
|
13718
|
+
}
|
|
13719
|
+
if (opener.length === 1 && opener !== "`" && char === `
|
|
13720
|
+
`)
|
|
13721
|
+
return;
|
|
13722
|
+
if (opener === "`" && char === "$" && text[i + 1] === "{") {
|
|
13723
|
+
let depth = 1;
|
|
13724
|
+
i += 2;
|
|
13725
|
+
while (i < text.length && depth > 0) {
|
|
13726
|
+
if (text[i] === "`" || text[i] === '"' || text[i] === "'") {
|
|
13727
|
+
const nested = readStringLiteral(text, i);
|
|
13728
|
+
if (nested) {
|
|
13729
|
+
i = nested.end;
|
|
13730
|
+
continue;
|
|
13731
|
+
}
|
|
13732
|
+
if (text[i] === "`")
|
|
13733
|
+
return;
|
|
13734
|
+
i += 1;
|
|
13735
|
+
continue;
|
|
13736
|
+
}
|
|
13737
|
+
const regexEnd = text[i] === "/" ? regexLiteralEnd(text, i) : undefined;
|
|
13738
|
+
if (regexEnd !== undefined) {
|
|
13739
|
+
i = regexEnd;
|
|
13740
|
+
continue;
|
|
13741
|
+
}
|
|
13742
|
+
if (text.startsWith("//", i)) {
|
|
13743
|
+
const newline = text.indexOf(`
|
|
13744
|
+
`, i);
|
|
13745
|
+
i = newline < 0 ? text.length : newline;
|
|
13746
|
+
continue;
|
|
13747
|
+
}
|
|
13748
|
+
if (text.startsWith("/*", i)) {
|
|
13749
|
+
const close = text.indexOf("*/", i + 2);
|
|
13750
|
+
if (close < 0)
|
|
13751
|
+
return;
|
|
13752
|
+
i = close + 2;
|
|
13753
|
+
continue;
|
|
13754
|
+
}
|
|
13755
|
+
if (text[i] === "{")
|
|
13756
|
+
depth += 1;
|
|
13757
|
+
else if (text[i] === "}")
|
|
13758
|
+
depth -= 1;
|
|
13759
|
+
i += 1;
|
|
13760
|
+
}
|
|
13761
|
+
continue;
|
|
13762
|
+
}
|
|
13763
|
+
if (text.startsWith(opener, i))
|
|
13764
|
+
return { value: text.slice(start + opener.length, i), end: i + opener.length };
|
|
13765
|
+
i += 1;
|
|
13766
|
+
}
|
|
13767
|
+
return;
|
|
13768
|
+
}
|
|
13769
|
+
var EXPRESSION_KEYWORDS = new Set([
|
|
13770
|
+
"return",
|
|
13771
|
+
"typeof",
|
|
13772
|
+
"instanceof",
|
|
13773
|
+
"in",
|
|
13774
|
+
"of",
|
|
13775
|
+
"new",
|
|
13776
|
+
"delete",
|
|
13777
|
+
"void",
|
|
13778
|
+
"throw",
|
|
13779
|
+
"case",
|
|
13780
|
+
"do",
|
|
13781
|
+
"else",
|
|
13782
|
+
"yield",
|
|
13783
|
+
"await"
|
|
13784
|
+
]);
|
|
13785
|
+
function endsWithOperand(text, end) {
|
|
13786
|
+
let i = end;
|
|
13787
|
+
while (i > 0 && /\s/.test(text[i - 1]))
|
|
13788
|
+
i -= 1;
|
|
13789
|
+
if (i === 0)
|
|
13790
|
+
return false;
|
|
13791
|
+
const char = text[i - 1];
|
|
13792
|
+
if (char === ")" || char === "]" || char === '"' || char === "'" || char === "`")
|
|
13793
|
+
return true;
|
|
13794
|
+
if (/[\w$]/.test(char)) {
|
|
13795
|
+
let wordStart = i;
|
|
13796
|
+
while (wordStart > 0 && /[\w$]/.test(text[wordStart - 1]))
|
|
13797
|
+
wordStart -= 1;
|
|
13798
|
+
const word = text.slice(wordStart, i);
|
|
13799
|
+
if (/^\d/.test(word))
|
|
13800
|
+
return true;
|
|
13801
|
+
let before = wordStart;
|
|
13802
|
+
while (before > 0 && /\s/.test(text[before - 1]))
|
|
13803
|
+
before -= 1;
|
|
13804
|
+
const isProperty = text[before - 1] === "." && text[before - 2] !== ".";
|
|
13805
|
+
return isProperty || !EXPRESSION_KEYWORDS.has(word);
|
|
13806
|
+
}
|
|
13807
|
+
if ((char === "+" || char === "-") && text[i - 2] === char)
|
|
13808
|
+
return endsWithOperand(text, i - 2);
|
|
13809
|
+
if (char === "!" && i >= 2 && /[\w$)\]]/.test(text[i - 2]))
|
|
13810
|
+
return endsWithOperand(text, i - 1);
|
|
13811
|
+
return false;
|
|
13812
|
+
}
|
|
13813
|
+
function regexLiteralEnd(text, start) {
|
|
13814
|
+
if (text[start + 1] === "/" || text[start + 1] === "*")
|
|
13815
|
+
return;
|
|
13816
|
+
if (endsWithOperand(text, start))
|
|
13817
|
+
return;
|
|
13818
|
+
let inClass = false;
|
|
13819
|
+
for (let i = start + 1;i < text.length; i += 1) {
|
|
13820
|
+
const char = text[i];
|
|
13821
|
+
if (char === `
|
|
13822
|
+
`)
|
|
13823
|
+
return;
|
|
13824
|
+
if (char === "\\") {
|
|
13825
|
+
i += 1;
|
|
13826
|
+
continue;
|
|
13827
|
+
}
|
|
13828
|
+
if (char === "[")
|
|
13829
|
+
inClass = true;
|
|
13830
|
+
else if (char === "]")
|
|
13831
|
+
inClass = false;
|
|
13832
|
+
else if (char === "/" && !inClass) {
|
|
13833
|
+
let end = i + 1;
|
|
13834
|
+
while (/[a-z]/i.test(text[end] ?? ""))
|
|
13835
|
+
end += 1;
|
|
13836
|
+
return end;
|
|
13837
|
+
}
|
|
13838
|
+
}
|
|
13839
|
+
return;
|
|
13840
|
+
}
|
|
13841
|
+
function readStringValue(text, offset) {
|
|
13842
|
+
let i = offset;
|
|
13843
|
+
const parts = [];
|
|
13844
|
+
let concatenated = false;
|
|
13845
|
+
let listed = false;
|
|
13846
|
+
for (;; ) {
|
|
13847
|
+
const opener = STRING_OPENER.exec(text.slice(i, i + 5));
|
|
13848
|
+
if (!opener)
|
|
13849
|
+
break;
|
|
13850
|
+
const literal = readStringLiteral(text, i + opener[0].length - opener[1].length);
|
|
13851
|
+
if (!literal)
|
|
13852
|
+
return;
|
|
13853
|
+
parts.push(literal.value);
|
|
13854
|
+
i = literal.end;
|
|
13855
|
+
const separator = /^[\s+,]*/.exec(text.slice(i))[0];
|
|
13856
|
+
if (!STRING_OPENER.test(text.slice(i + separator.length, i + separator.length + 5))) {
|
|
13857
|
+
if (separator.includes("+"))
|
|
13858
|
+
return;
|
|
13859
|
+
break;
|
|
13860
|
+
}
|
|
13861
|
+
if (separator.includes("+") && separator.includes(","))
|
|
13862
|
+
return;
|
|
13863
|
+
if (separator.includes(","))
|
|
13864
|
+
listed = true;
|
|
13865
|
+
else
|
|
13866
|
+
concatenated = true;
|
|
13867
|
+
i += separator.length;
|
|
13868
|
+
}
|
|
13869
|
+
if (parts.length === 0 || concatenated && listed)
|
|
13870
|
+
return;
|
|
13871
|
+
if (!listed)
|
|
13872
|
+
return parts.join("");
|
|
13873
|
+
const join9 = /^[\s,]*\]\s*\.join\(\s*(["'`])((?:\\.|(?!\1).)*)\1\s*\)/.exec(text.slice(i));
|
|
13874
|
+
const joinSeparator = join9 ? join9[2].replace(/\\n/g, `
|
|
13875
|
+
`).replace(/\\t/g, "\t") : `
|
|
13876
|
+
`;
|
|
13877
|
+
return parts.join(joinSeparator);
|
|
13878
|
+
}
|
|
13879
|
+
function textOffsetOfLine(lines, index) {
|
|
13880
|
+
let offset = 0;
|
|
13881
|
+
for (let i = 0;i < index; i += 1)
|
|
13882
|
+
offset += lines[i].length + 1;
|
|
13883
|
+
return offset;
|
|
13884
|
+
}
|
|
13885
|
+
function stringStart(rest) {
|
|
13886
|
+
let consumed = 0;
|
|
13887
|
+
let remaining = rest;
|
|
13888
|
+
for (let guard = 0;guard < 3; guard += 1) {
|
|
13889
|
+
const wrapper = VALUE_WRAPPERS.exec(remaining);
|
|
13890
|
+
if (!wrapper)
|
|
13891
|
+
break;
|
|
13892
|
+
consumed += wrapper[0].length;
|
|
13893
|
+
remaining = remaining.slice(wrapper[0].length);
|
|
13894
|
+
}
|
|
13895
|
+
return STRING_OPENER.test(remaining) ? consumed : -1;
|
|
13896
|
+
}
|
|
13897
|
+
function resolvePromptLiteralDefinition(lines, startLine) {
|
|
13898
|
+
const text = lines.join(`
|
|
13899
|
+
`);
|
|
13900
|
+
for (const index of [startLine - 1, startLine - 2]) {
|
|
13901
|
+
const line2 = lines[index];
|
|
13902
|
+
if (line2 === undefined)
|
|
13903
|
+
continue;
|
|
13904
|
+
const head = DEFINITION_HEAD.exec(line2);
|
|
13905
|
+
if (head) {
|
|
13906
|
+
const [, name, , colon, rest] = head;
|
|
13907
|
+
let valueOffset = -1;
|
|
13908
|
+
const inline = stringStart(rest);
|
|
13909
|
+
if (inline >= 0) {
|
|
13910
|
+
valueOffset = textOffsetOfLine(lines, index) + line2.length - rest.length + inline;
|
|
13911
|
+
} else if (/^(?:\(|\[|(?:textwrap\.)?dedent\(|)\s*$/.test(rest) && lines[index + 1] !== undefined) {
|
|
13912
|
+
const next = lines[index + 1];
|
|
13913
|
+
const nextStart = stringStart(next.trimStart());
|
|
13914
|
+
if (nextStart >= 0)
|
|
13915
|
+
valueOffset = textOffsetOfLine(lines, index + 1) + (next.length - next.trimStart().length) + nextStart;
|
|
13916
|
+
}
|
|
13917
|
+
if (valueOffset < 0 && colon) {
|
|
13918
|
+
const block = readYamlBlockScalar(lines, index, rest);
|
|
13919
|
+
if (block !== undefined)
|
|
13920
|
+
return { key: name, text: block, line: index + 1 };
|
|
13921
|
+
}
|
|
13922
|
+
if (valueOffset < 0)
|
|
13923
|
+
continue;
|
|
13924
|
+
let offset2 = valueOffset;
|
|
13925
|
+
while (!STRING_OPENER.test(text.slice(offset2, offset2 + 5)))
|
|
13926
|
+
offset2 += 1;
|
|
13927
|
+
const value2 = readStringValue(text, offset2);
|
|
13928
|
+
if (value2 === undefined)
|
|
13929
|
+
continue;
|
|
13930
|
+
return colon ? { key: name, text: value2, line: index + 1 } : { identifier: name, text: value2, line: index + 1 };
|
|
13931
|
+
}
|
|
13932
|
+
if (index !== startLine - 1)
|
|
13933
|
+
continue;
|
|
13934
|
+
const returned = /^\s*return\s+(.*)$/.exec(line2);
|
|
13935
|
+
if (!returned)
|
|
13936
|
+
continue;
|
|
13937
|
+
const start = stringStart(returned[1]);
|
|
13938
|
+
if (start < 0)
|
|
13939
|
+
continue;
|
|
13940
|
+
let offset = textOffsetOfLine(lines, index) + line2.length - returned[1].length + start;
|
|
13941
|
+
while (!STRING_OPENER.test(text.slice(offset, offset + 5)))
|
|
13942
|
+
offset += 1;
|
|
13943
|
+
const value = readStringValue(text, offset);
|
|
13944
|
+
if (value === undefined)
|
|
13945
|
+
continue;
|
|
13946
|
+
for (let i = index - 1;i >= Math.max(0, index - MAX_BUILDER_LOOKBEHIND_LINES); i -= 1) {
|
|
13947
|
+
const builder = BUILDER_HEAD.exec(lines[i]);
|
|
13948
|
+
if (builder)
|
|
13949
|
+
return { identifier: builder[1] ?? builder[2] ?? builder[3], text: value, line: index + 1 };
|
|
13950
|
+
}
|
|
13951
|
+
}
|
|
13952
|
+
const line = lines[startLine - 1];
|
|
13953
|
+
if (line === undefined)
|
|
13954
|
+
return;
|
|
13955
|
+
if (/^\s*(?:\/\/|\*(?!\/)|#)/.test(line))
|
|
13956
|
+
return;
|
|
13957
|
+
for (const match of line.matchAll(INLINE_PROMPT_KEY)) {
|
|
13958
|
+
if (endsInComment(line.slice(0, match.index)))
|
|
13959
|
+
break;
|
|
13960
|
+
const after = match.index + match[0].length;
|
|
13961
|
+
const start = stringStart(line.slice(after));
|
|
13962
|
+
if (start < 0)
|
|
13963
|
+
continue;
|
|
13964
|
+
let offset = textOffsetOfLine(lines, startLine - 1) + after + start;
|
|
13965
|
+
while (!STRING_OPENER.test(text.slice(offset, offset + 5)))
|
|
13966
|
+
offset += 1;
|
|
13967
|
+
const value = readStringValue(text, offset);
|
|
13968
|
+
if (value !== undefined)
|
|
13969
|
+
return { key: match[1], text: value, line: startLine };
|
|
13970
|
+
}
|
|
13971
|
+
return;
|
|
13972
|
+
}
|
|
13973
|
+
function endsInComment(prefix) {
|
|
13974
|
+
let quote;
|
|
13975
|
+
let inBlock = false;
|
|
13976
|
+
for (let i = 0;i < prefix.length; i += 1) {
|
|
13977
|
+
const char = prefix[i];
|
|
13978
|
+
if (inBlock) {
|
|
13979
|
+
if (prefix.startsWith("*/", i)) {
|
|
13980
|
+
inBlock = false;
|
|
13981
|
+
i += 1;
|
|
13982
|
+
}
|
|
13983
|
+
continue;
|
|
13984
|
+
}
|
|
13985
|
+
if (quote) {
|
|
13986
|
+
if (char === "\\")
|
|
13987
|
+
i += 1;
|
|
13988
|
+
else if (char === quote)
|
|
13989
|
+
quote = undefined;
|
|
13990
|
+
continue;
|
|
13991
|
+
}
|
|
13992
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
13993
|
+
quote = char;
|
|
13994
|
+
continue;
|
|
13995
|
+
}
|
|
13996
|
+
const regexEnd = char === "/" ? regexLiteralEnd(prefix, i) : undefined;
|
|
13997
|
+
if (regexEnd !== undefined) {
|
|
13998
|
+
i = regexEnd - 1;
|
|
13999
|
+
continue;
|
|
14000
|
+
}
|
|
14001
|
+
if (prefix.startsWith("//", i))
|
|
14002
|
+
return true;
|
|
14003
|
+
else if (prefix.startsWith("/*", i)) {
|
|
14004
|
+
inBlock = true;
|
|
14005
|
+
i += 1;
|
|
14006
|
+
}
|
|
14007
|
+
}
|
|
14008
|
+
return inBlock;
|
|
14009
|
+
}
|
|
14010
|
+
function readYamlBlockScalar(lines, index, rest) {
|
|
14011
|
+
const indicator = /^([|>])([-+]?)\s*(?:#.*)?$/.exec(rest.trim());
|
|
14012
|
+
if (!indicator)
|
|
14013
|
+
return;
|
|
14014
|
+
const [, style, chomping] = indicator;
|
|
14015
|
+
const keyIndent = lines[index].length - lines[index].trimStart().length;
|
|
14016
|
+
const body = [];
|
|
14017
|
+
let blockIndent;
|
|
14018
|
+
for (let i = index + 1;i < lines.length; i += 1) {
|
|
14019
|
+
const line = lines[i];
|
|
14020
|
+
if (!line.trim()) {
|
|
14021
|
+
body.push("");
|
|
14022
|
+
continue;
|
|
14023
|
+
}
|
|
14024
|
+
const indent = line.length - line.trimStart().length;
|
|
14025
|
+
if (indent <= keyIndent)
|
|
14026
|
+
break;
|
|
14027
|
+
blockIndent ??= indent;
|
|
14028
|
+
if (indent < blockIndent)
|
|
14029
|
+
break;
|
|
14030
|
+
body.push(line.slice(blockIndent));
|
|
14031
|
+
}
|
|
14032
|
+
let trailingBlank = 0;
|
|
14033
|
+
while (body.length > 0 && body[body.length - 1] === "") {
|
|
14034
|
+
body.pop();
|
|
14035
|
+
trailingBlank += 1;
|
|
14036
|
+
}
|
|
14037
|
+
if (body.length === 0)
|
|
14038
|
+
return;
|
|
14039
|
+
let text;
|
|
14040
|
+
if (style === "|") {
|
|
14041
|
+
text = body.join(`
|
|
14042
|
+
`);
|
|
14043
|
+
} else {
|
|
14044
|
+
if (body.some((line) => /^\s/.test(line)))
|
|
14045
|
+
return;
|
|
14046
|
+
text = "";
|
|
14047
|
+
let blanks = 0;
|
|
14048
|
+
for (const [i, line] of body.entries()) {
|
|
14049
|
+
if (line === "") {
|
|
14050
|
+
blanks += 1;
|
|
14051
|
+
continue;
|
|
14052
|
+
}
|
|
14053
|
+
text += i === 0 || text === "" ? `
|
|
14054
|
+
`.repeat(blanks) + line : blanks > 0 ? `
|
|
14055
|
+
`.repeat(blanks) + line : ` ${line}`;
|
|
14056
|
+
blanks = 0;
|
|
14057
|
+
}
|
|
14058
|
+
}
|
|
14059
|
+
if (chomping === "-")
|
|
14060
|
+
return text;
|
|
14061
|
+
return chomping === "+" ? text + `
|
|
14062
|
+
`.repeat(trailingBlank + 1) : `${text}
|
|
14063
|
+
`;
|
|
14064
|
+
}
|
|
14065
|
+
function isCodeLikeContent(text) {
|
|
14066
|
+
return CODE_LIKE_CONTENT.some((pattern) => pattern.test(text));
|
|
14067
|
+
}
|
|
14068
|
+
var SOURCE_EXTENSION = /\.(?:[cm]?[jt]sx?|py)$/;
|
|
14069
|
+
function moduleStems(definitionPath) {
|
|
14070
|
+
const stem = definitionPath.replace(/\.[^./]+$/, "");
|
|
14071
|
+
const dir = /\/(?:index|__init__)$/.test(stem) ? stem.replace(/\/[^/]+$/, "") : undefined;
|
|
14072
|
+
return dir ? [stem, dir] : [stem];
|
|
14073
|
+
}
|
|
14074
|
+
function specifierResolvesTo(spec, importerPath, definitionPath, python) {
|
|
14075
|
+
const stems = moduleStems(definitionPath);
|
|
14076
|
+
const importerDir = posix.dirname(importerPath);
|
|
14077
|
+
let target;
|
|
14078
|
+
let exact = true;
|
|
14079
|
+
if (python) {
|
|
14080
|
+
const dots = /^\.*/.exec(spec)[0].length;
|
|
14081
|
+
const rest = spec.slice(dots).split(".").filter(Boolean).join("/");
|
|
14082
|
+
if (dots > 0) {
|
|
14083
|
+
let base = importerDir;
|
|
14084
|
+
for (let i = 1;i < dots; i += 1)
|
|
14085
|
+
base = posix.dirname(base);
|
|
14086
|
+
target = posix.normalize(posix.join(base, rest));
|
|
14087
|
+
} else if (!rest.includes("/")) {
|
|
14088
|
+
return stems.some((stem) => stem === rest || stem === posix.join(importerDir, rest));
|
|
14089
|
+
} else {
|
|
14090
|
+
target = rest;
|
|
14091
|
+
exact = false;
|
|
14092
|
+
}
|
|
14093
|
+
} else if (spec.startsWith(".")) {
|
|
14094
|
+
target = posix.normalize(posix.join(importerDir, spec)).replace(SOURCE_EXTENSION, "");
|
|
14095
|
+
} else {
|
|
14096
|
+
const segments = spec.replace(SOURCE_EXTENSION, "").split("/");
|
|
14097
|
+
if (segments.length > 0 && /^[@~#$]/.test(segments[0]))
|
|
14098
|
+
segments.shift();
|
|
14099
|
+
if (segments.length < 2)
|
|
14100
|
+
return false;
|
|
14101
|
+
target = segments.join("/");
|
|
14102
|
+
exact = false;
|
|
14103
|
+
}
|
|
14104
|
+
return stems.some((stem) => stem === target || !exact && stem.endsWith(`/${target}`));
|
|
14105
|
+
}
|
|
14106
|
+
function localNameIn(specifiers, identifier) {
|
|
14107
|
+
for (const raw of specifiers.replace(/#[^\n]*|\/\/[^\n]*/g, "").replace(/[()]/g, "").split(",")) {
|
|
14108
|
+
const match = /^\s*(?:type\s+)?([A-Za-z_$][\w$]*)(?:\s*(?:\bas\b|:)\s*([A-Za-z_$][\w$]*))?\s*$/.exec(raw);
|
|
14109
|
+
if (match?.[1] === identifier)
|
|
14110
|
+
return match[2] ?? identifier;
|
|
14111
|
+
}
|
|
14112
|
+
return;
|
|
14113
|
+
}
|
|
14114
|
+
function importedLocalName(importerPath, lines, identifier, definitionPath, exportsDefault = false) {
|
|
14115
|
+
const text = lines.join(`
|
|
14116
|
+
`);
|
|
14117
|
+
const python = extname7(importerPath) === ".py";
|
|
14118
|
+
if (python) {
|
|
14119
|
+
for (const match of text.matchAll(/^[ \t]*from\s+([.\w]+)\s+import\s+(\([^)]*\)|[^\n]*)/gm)) {
|
|
14120
|
+
if (!specifierResolvesTo(match[1], importerPath, definitionPath, true))
|
|
14121
|
+
continue;
|
|
14122
|
+
const local = localNameIn(match[2].replace(/\\\n/g, " "), identifier);
|
|
14123
|
+
if (local)
|
|
14124
|
+
return local;
|
|
14125
|
+
}
|
|
14126
|
+
for (const match of text.matchAll(/^[ \t]*import\s+([.\w]+)(?:\s+as\s+(\w+))?/gm)) {
|
|
14127
|
+
if (specifierResolvesTo(match[1], importerPath, definitionPath, true))
|
|
14128
|
+
return identifier;
|
|
14129
|
+
}
|
|
14130
|
+
return;
|
|
14131
|
+
}
|
|
14132
|
+
const statements = [
|
|
14133
|
+
/\bimport\s+(?:type\s+)?(?:[A-Za-z_$][\w$]*\s*,\s*)?\{([^}]*)\}\s*from\s*["']([^"']+)["']/g,
|
|
14134
|
+
/\b(?:const|let|var)\s*\{([^}]*)\}\s*=\s*(?:await\s+)?(?:require|import)\(\s*["']([^"']+)["']\s*\)/g
|
|
14135
|
+
];
|
|
14136
|
+
for (const pattern of statements) {
|
|
14137
|
+
for (const match of text.matchAll(pattern)) {
|
|
14138
|
+
if (!specifierResolvesTo(match[2], importerPath, definitionPath, false))
|
|
14139
|
+
continue;
|
|
14140
|
+
const local = localNameIn(match[1], identifier);
|
|
14141
|
+
if (local)
|
|
14142
|
+
return local;
|
|
14143
|
+
}
|
|
14144
|
+
}
|
|
14145
|
+
if (exportsDefault) {
|
|
14146
|
+
for (const match of text.matchAll(/\bimport\s+(?:type\s+)?([A-Za-z_$][\w$]*)\s*(?:,\s*(?:\{[^}]*\}|\*\s*as\s+[A-Za-z_$][\w$]*)\s*)?from\s*["']([^"']+)["']/g)) {
|
|
14147
|
+
if (specifierResolvesTo(match[2], importerPath, definitionPath, false))
|
|
14148
|
+
return match[1];
|
|
14149
|
+
}
|
|
14150
|
+
}
|
|
14151
|
+
for (const match of text.matchAll(/\bimport\s*\*\s*as\s+[A-Za-z_$][\w$]*\s+from\s*["']([^"']+)["']/g)) {
|
|
14152
|
+
if (specifierResolvesTo(match[1], importerPath, definitionPath, false))
|
|
14153
|
+
return identifier;
|
|
14154
|
+
}
|
|
14155
|
+
return;
|
|
14156
|
+
}
|
|
14157
|
+
function importStatementLines(lines) {
|
|
14158
|
+
const text = lines.join(`
|
|
14159
|
+
`);
|
|
14160
|
+
const covered = new Set;
|
|
14161
|
+
const statement = /^[ \t]*(?:import\b[^;]*?\bfrom\s*["'][^"'\n]+["']|export\s*(?:type\s*)?\{[^}]*\}\s*from\s*["'][^"'\n]+["']|from\s+[.\w]+\s+import\s*(?:\([^)]*\)|[^\n]*))/gm;
|
|
14162
|
+
for (const match of text.matchAll(statement)) {
|
|
14163
|
+
const first2 = text.slice(0, match.index).split(`
|
|
14164
|
+
`).length - 1;
|
|
14165
|
+
const last = first2 + match[0].split(`
|
|
14166
|
+
`).length - 1;
|
|
14167
|
+
for (let i = first2;i <= last; i += 1)
|
|
14168
|
+
covered.add(i);
|
|
14169
|
+
}
|
|
14170
|
+
return covered;
|
|
14171
|
+
}
|
|
14172
|
+
var MODEL_CALLEE = /model|llm|complet|generat|chat|invoke|infer|prompt|agent|judge|claude|gpt|openai|anthropic|gemini|\.create$/i;
|
|
14173
|
+
function calleeImportedFromModelFile(callee, path, lines, modelFiles) {
|
|
14174
|
+
const base = callee.split(".")[0];
|
|
14175
|
+
const text = lines.join(`
|
|
14176
|
+
`);
|
|
14177
|
+
const python = extname7(path) === ".py";
|
|
14178
|
+
const statements = python ? [/^[ \t]*from\s+([.\w]+)\s+import\s+(\([^)]*\)|[^\n]*)/gm] : [
|
|
14179
|
+
/\bimport\s+(?:type\s+)?(?:([A-Za-z_$][\w$]*)\s*,?\s*)?(?:\{([^}]*)\}|\*\s*as\s+([A-Za-z_$][\w$]*))?\s*from\s*["']([^"']+)["']/g,
|
|
14180
|
+
/\b(?:const|let|var)\s*\{([^}]*)\}\s*=\s*(?:await\s+)?(?:require|import)\(\s*["']([^"']+)["']\s*\)/g
|
|
14181
|
+
];
|
|
14182
|
+
for (const pattern of statements) {
|
|
14183
|
+
for (const match of text.matchAll(pattern)) {
|
|
14184
|
+
let spec;
|
|
14185
|
+
let names;
|
|
14186
|
+
if (python) {
|
|
14187
|
+
spec = match[1];
|
|
14188
|
+
names = match[2].replace(/[()]/g, "").split(",").map((part) => part.trim().split(/\s+as\s+/).pop() ?? "");
|
|
14189
|
+
} else if (match.length === 5) {
|
|
14190
|
+
spec = match[4];
|
|
14191
|
+
names = [match[1] ?? "", match[3] ?? "", ...(match[2] ?? "").split(",").map((part) => part.trim().split(/\s+as\s+/).pop() ?? "")];
|
|
14192
|
+
} else {
|
|
14193
|
+
spec = match[2];
|
|
14194
|
+
names = match[1].split(",").map((part) => part.trim().split(/\s*:\s*/).pop() ?? "");
|
|
14195
|
+
}
|
|
14196
|
+
if (!names.includes(base))
|
|
14197
|
+
continue;
|
|
14198
|
+
for (const modelPath of modelFiles) {
|
|
14199
|
+
if (specifierResolvesTo(spec, path, modelPath, python))
|
|
14200
|
+
return true;
|
|
14201
|
+
}
|
|
14202
|
+
}
|
|
14203
|
+
}
|
|
14204
|
+
return false;
|
|
14205
|
+
}
|
|
14206
|
+
var INSTRUCTION_KEY = /\b(instruction|instructions|task|brief|goal|message|query|question)["']?\s*[:=]\s*$/;
|
|
14207
|
+
var MODEL_CALL_IN_BODY = /\b[\w$.]*(?:model|llm|complet|generat|chat|claude|gpt|openai|anthropic|gemini)[\w$]*\s*\(|\brole\b\s*["']?\s*[:=]\s*["'](?:system|user|assistant)["']/i;
|
|
14208
|
+
var MAX_HELPER_BODY_LINES = 80;
|
|
14209
|
+
var MAX_CALL_CONTEXT_LINES = 25;
|
|
14210
|
+
var CALL_ROLE_WINDOW_LINES = 8;
|
|
14211
|
+
function localHelperCallsModel(callee, lines) {
|
|
14212
|
+
const ident = escapeRegExp(callee.split(".").pop() ?? callee);
|
|
14213
|
+
const head = new RegExp(`^\\s*(?:export\\s+)?(?:async\\s+)?(?:function\\s+${ident}\\s*[(<]|def\\s+${ident}\\s*\\(|(?:const|let|var)\\s+${ident}\\s*=\\s*(?:async\\s+)?(?:\\(|[A-Za-z_$][\\w$]*\\s*=>)|(?:(?:private|public|protected|static|async)\\s+)*${ident}\\s*\\([^)]*\\)?\\s*[:{])`);
|
|
14214
|
+
const start = lines.findIndex((line) => head.test(line));
|
|
14215
|
+
if (start < 0)
|
|
14216
|
+
return false;
|
|
14217
|
+
return lines.slice(start + 1, start + 1 + MAX_HELPER_BODY_LINES).some((line) => MODEL_CALL_IN_BODY.test(line));
|
|
14218
|
+
}
|
|
14219
|
+
function callCarriesChatMessages(lines, index) {
|
|
14220
|
+
for (let i = Math.max(0, index - CALL_ROLE_WINDOW_LINES);i < Math.min(lines.length, index + CALL_ROLE_WINDOW_LINES + 1); i += 1) {
|
|
14221
|
+
if (/\brole\b\s*["']?\s*[:=]\s*["'](?:system|user|human|assistant)["']/.test(lines[i]))
|
|
14222
|
+
return true;
|
|
14223
|
+
}
|
|
14224
|
+
return false;
|
|
14225
|
+
}
|
|
14226
|
+
function composingPromptName(lines, index, identifier) {
|
|
14227
|
+
for (let i = index;i >= Math.max(0, index - MAX_BUILDER_LOOKBEHIND_LINES); i -= 1) {
|
|
14228
|
+
const builder = BUILDER_HEAD.exec(lines[i]);
|
|
14229
|
+
const assignment = /^\s*(?:export\s+)?(?:(?:const|let|var)\s+)?([A-Za-z_$][\w$]*)\s*(?::[^=]+)?=(?![=>])/.exec(lines[i]);
|
|
14230
|
+
const name = builder ? builder[1] ?? builder[2] ?? builder[3] : assignment?.[1];
|
|
14231
|
+
if (name)
|
|
14232
|
+
return name !== identifier && PROMPT_NAMED_IDENTIFIER.test(name) ? name : undefined;
|
|
14233
|
+
}
|
|
14234
|
+
return;
|
|
14235
|
+
}
|
|
14236
|
+
var OUTPUT_CALLEE = /^(?:console\.\w+|(?:[\w$]+\.)*(?:log|logger|logging)\.\w+|print|log|alert|toast(?:\.\w+)?|(?:[\w$]+\.)*(?:write|writeFile|writeFileSync|appendFile|send|json|setState|set[A-Z]\w*))$/;
|
|
14237
|
+
function enclosingCallee(text, index) {
|
|
14238
|
+
let depth = 0;
|
|
14239
|
+
for (let i = index - 1;i >= 0; i -= 1) {
|
|
14240
|
+
const char = text[i];
|
|
14241
|
+
if (char === ")" || char === "]" || char === "}")
|
|
14242
|
+
depth += 1;
|
|
14243
|
+
else if (char === "[" || char === "{")
|
|
14244
|
+
depth = Math.max(0, depth - 1);
|
|
14245
|
+
else if (char === "(") {
|
|
14246
|
+
if (depth > 0) {
|
|
14247
|
+
depth -= 1;
|
|
14248
|
+
continue;
|
|
14249
|
+
}
|
|
14250
|
+
return /([A-Za-z_$][\w$.]*)\s*$/.exec(text.slice(Math.max(0, i - 200), i))?.[1];
|
|
14251
|
+
}
|
|
14252
|
+
}
|
|
14253
|
+
return;
|
|
14254
|
+
}
|
|
14255
|
+
function findModelInputUse(identifier, definition, files, rootDir, fileCache, options) {
|
|
14256
|
+
const scan = (path, lines, name) => {
|
|
14257
|
+
const ident = escapeRegExp(name);
|
|
14258
|
+
const keyed = new RegExp(`\\b(${MODEL_INPUT_KEYS.join("|")})["']?\\s*[:=]\\s*(?:await\\s+)?(?:(?:this|self)\\.)?(?:[A-Za-z_$][\\w$]*\\.)?${ident}\\b`);
|
|
14259
|
+
const messageCtor = new RegExp(`\\b(SystemMessage|HumanMessage|SystemMessagePromptTemplate\\.from_template|HumanMessagePromptTemplate\\.from_template|PromptTemplate\\.from_template|ChatPromptTemplate\\.from_template)\\s*\\(\\s*(?:content\\s*=\\s*)?${ident}\\b`);
|
|
14260
|
+
const roleTuple = new RegExp(`\\(\\s*["'](system|user|human)["']\\s*,\\s*${ident}\\b`);
|
|
14261
|
+
const interpolated = new RegExp(`\\b(${MODEL_INPUT_KEYS.join("|")})["']?\\s*[:=]\\s*[fF]?[\`"'][^\`"']*(?:\\$\\{|\\{)${ident}\\b`);
|
|
14262
|
+
const shorthand = DIRECT_PROMPT_KEYS.has(name) ? new RegExp(`[{,(]\\s*${ident}\\s*[,})]`) : undefined;
|
|
14263
|
+
const isModelFile = files.model.has(path);
|
|
14264
|
+
for (let i = 0;i < lines.length; i += 1) {
|
|
14265
|
+
if (path === definition.path && i === definition.line - 1)
|
|
14266
|
+
continue;
|
|
14267
|
+
const line = lines[i];
|
|
14268
|
+
if (line.length > 4000 || !line.includes(name))
|
|
14269
|
+
continue;
|
|
14270
|
+
const fixed = messageCtor.exec(line) ?? roleTuple.exec(line);
|
|
14271
|
+
if (fixed)
|
|
14272
|
+
return { path, line: i + 1, key: fixed[1] };
|
|
14273
|
+
const match = keyed.exec(line) ?? interpolated.exec(line);
|
|
14274
|
+
if (match && (isModelFile || DIRECT_PROMPT_KEYS.has(match[1]) || match[1] === "content" && hasNearbyRole(lines, i + 1))) {
|
|
14275
|
+
return { path, line: i + 1, key: match[1] };
|
|
14276
|
+
}
|
|
14277
|
+
if (shorthand?.test(line) && isModelFile)
|
|
14278
|
+
return { path, line: i + 1, key: name };
|
|
14279
|
+
}
|
|
14280
|
+
return;
|
|
14281
|
+
};
|
|
14282
|
+
const firstReference = (path, lines, name) => {
|
|
14283
|
+
const ident = escapeRegExp(name);
|
|
14284
|
+
const reference = new RegExp(`(?<![\\w$])(?:(?:this|self|[A-Za-z_$][\\w$]*)\\.)?${ident}(?![\\w$])`, "g");
|
|
14285
|
+
const jsxAttribute = new RegExp(`[\\w-]+=\\{\\s*${ident}\\s*\\}`);
|
|
14286
|
+
const jsxChild = /\.[jt]sx$/.test(path) ? new RegExp(`(?<!\\$)\\{\\s*${ident}\\s*\\}`) : undefined;
|
|
14287
|
+
const imports = importStatementLines(lines);
|
|
14288
|
+
const isModelFile = files.model.has(path);
|
|
14289
|
+
const declaration = new RegExp(`^\\s*(?:export\\s+)?(?:default\\s+)?(?:async\\s+)?(?:function\\s*\\*?\\s*|def\\s+|(?:const|let|var)\\s+)${ident}\\b`);
|
|
14290
|
+
for (let i = 0;i < lines.length; i += 1) {
|
|
14291
|
+
if (path === definition.path && i === definition.line - 1)
|
|
14292
|
+
continue;
|
|
14293
|
+
const line = lines[i];
|
|
14294
|
+
if (line.length > 4000 || !line.includes(name))
|
|
14295
|
+
continue;
|
|
14296
|
+
if (/^\s*(?:\/\/|#|\*|import\b|export\s*\{|from\s+\S+\s+import\b)/.test(line) || jsxAttribute.test(line) || jsxChild?.test(line))
|
|
14297
|
+
continue;
|
|
14298
|
+
const context = `${lines.slice(Math.max(0, i - MAX_CALL_CONTEXT_LINES), i).join(`
|
|
14299
|
+
`)}
|
|
14300
|
+
`;
|
|
14301
|
+
if (declaration.test(line) || imports.has(i))
|
|
14302
|
+
continue;
|
|
14303
|
+
for (const match of line.matchAll(reference)) {
|
|
14304
|
+
const callee = enclosingCallee(context + line, context.length + match.index);
|
|
14305
|
+
if (callee && OUTPUT_CALLEE.test(callee))
|
|
14306
|
+
continue;
|
|
14307
|
+
const before = (context + line).slice(0, context.length + match.index);
|
|
14308
|
+
const instructionKey = INSTRUCTION_KEY.exec(before)?.[1];
|
|
14309
|
+
const after = line.slice(match.index + match[0].length);
|
|
14310
|
+
const composed = /(?:\$\{\s*|\+\s*|[[,]\s*|^\s*|[^=!<>]=\s*|\breturn\s+|\bawait\s+)$/.test(before) && /^\s*(?:\}|\+|,|\]|;|\(|$)/.test(after);
|
|
14311
|
+
const composedInto = composed ? composingPromptName(lines, i, name) : undefined;
|
|
14312
|
+
const via = isModelFile ? "a file that calls a model" : instructionKey ? `the ${instructionKey} key of an agent call` : callee && MODEL_CALLEE.test(callee) ? `the model-call helper ${callee}` : callee && localHelperCallsModel(callee, lines) ? `the local helper ${callee}, which calls a model` : callee && calleeImportedFromModelFile(callee, path, lines, files.model) ? `${callee}, imported from a module that calls a model` : callee && callCarriesChatMessages(lines, i) ? `a ${callee} call that also carries chat messages` : composedInto && `composition into ${composedInto}`;
|
|
14313
|
+
if (via)
|
|
14314
|
+
return { path, line: i + 1, key: "reference", referenceOnly: true, via };
|
|
14315
|
+
}
|
|
14316
|
+
}
|
|
14317
|
+
return;
|
|
14318
|
+
};
|
|
14319
|
+
const own = readFileLines(rootDir, definition.path, fileCache);
|
|
14320
|
+
const local = own ? scan(definition.path, own, identifier) : undefined;
|
|
14321
|
+
if (local)
|
|
14322
|
+
return local;
|
|
14323
|
+
const importers = [];
|
|
14324
|
+
if (!GENERIC_IDENTIFIERS.has(identifier)) {
|
|
14325
|
+
const ident = escapeRegExp(identifier);
|
|
14326
|
+
const exportsDefault = own?.some((line) => new RegExp(`^\\s*export\\s+default\\s+${ident}\\s*;?\\s*$|\\bexport\\s*\\{[^}]*\\b${ident}\\s+as\\s+default\\b`).test(line)) ?? false;
|
|
14327
|
+
const moduleName = posix.basename(definition.path).replace(/\.[^.]+$/, "");
|
|
14328
|
+
for (const path of files.searchable) {
|
|
14329
|
+
if (path === definition.path)
|
|
14330
|
+
continue;
|
|
14331
|
+
const lines = readFileLines(rootDir, path, fileCache);
|
|
14332
|
+
if (!lines || !lines.some((line) => line.includes(identifier) || exportsDefault && line.includes(moduleName)))
|
|
14333
|
+
continue;
|
|
14334
|
+
const name = importedLocalName(path, lines, identifier, definition.path, exportsDefault);
|
|
14335
|
+
if (!name)
|
|
14336
|
+
continue;
|
|
14337
|
+
const use = scan(path, lines, name);
|
|
14338
|
+
if (use)
|
|
14339
|
+
return use;
|
|
14340
|
+
importers.push({ path, lines, name });
|
|
14341
|
+
}
|
|
14342
|
+
}
|
|
14343
|
+
if (!options.allowReference)
|
|
14344
|
+
return;
|
|
14345
|
+
if (own) {
|
|
14346
|
+
const use = firstReference(definition.path, own, identifier);
|
|
14347
|
+
if (use)
|
|
14348
|
+
return use;
|
|
14349
|
+
}
|
|
14350
|
+
for (const importer of importers) {
|
|
14351
|
+
const use = firstReference(importer.path, importer.lines, importer.name);
|
|
14352
|
+
if (use)
|
|
14353
|
+
return use;
|
|
14354
|
+
}
|
|
14355
|
+
return;
|
|
14356
|
+
}
|
|
14357
|
+
function readsAsInstructions(identifier, text) {
|
|
14358
|
+
const score = instructionScore(text);
|
|
14359
|
+
const secondPerson = SECOND_PERSON_OPENING.test(text);
|
|
14360
|
+
if (PROMPT_NAMED_IDENTIFIER.test(identifier))
|
|
14361
|
+
return score >= 2 || secondPerson;
|
|
14362
|
+
return secondPerson && score >= 2 && text.length >= MIN_UNNAMED_REFERENCED_PROMPT_CHARS;
|
|
14363
|
+
}
|
|
14364
|
+
function hasNearbyRole(lines, line) {
|
|
14365
|
+
for (let i = Math.max(0, line - 4);i < Math.min(lines.length, line + 3); i += 1) {
|
|
14366
|
+
if (/\brole\b\s*["']?\s*[:=]/.test(lines[i]))
|
|
14367
|
+
return true;
|
|
14368
|
+
}
|
|
14369
|
+
return false;
|
|
14370
|
+
}
|
|
14371
|
+
function isDirectModelInput(key, value, path, lines, line, modelFiles) {
|
|
14372
|
+
if (CONFIG_EXTENSIONS.has(extname7(path).toLowerCase())) {
|
|
14373
|
+
return DIRECT_PROMPT_KEYS.has(key) && value.length >= MIN_CONFIG_PROMPT_CHARS;
|
|
14374
|
+
}
|
|
14375
|
+
if (modelFiles.has(path)) {
|
|
14376
|
+
return DIRECT_PROMPT_KEYS.has(key) || key === "content" && hasNearbyRole(lines, line);
|
|
14377
|
+
}
|
|
14378
|
+
return DIRECT_PROMPT_KEYS.has(key) && instructionScore(value) >= 2;
|
|
14379
|
+
}
|
|
14380
|
+
function promotePromptLiteralCandidate(candidate, rootDir, confidence2, fileCache, files) {
|
|
13645
14381
|
const lines = readFileLines(rootDir, candidate.path, fileCache);
|
|
13646
|
-
|
|
14382
|
+
if (!lines)
|
|
14383
|
+
return;
|
|
14384
|
+
const definition = resolvePromptLiteralDefinition(lines, candidate.startLine);
|
|
14385
|
+
if (!definition)
|
|
14386
|
+
return;
|
|
14387
|
+
const value = definition.text.trim();
|
|
14388
|
+
const literalText = value.replace(/\$\{[^}]*\}|\{[A-Za-z_][\w.]*\}/g, "").trim();
|
|
14389
|
+
if (literalText.length < MIN_RESOLVED_PROMPT_CHARS || isCodeLikeContent(value))
|
|
14390
|
+
return;
|
|
14391
|
+
const key = definition.key ?? (definition.identifier && DIRECT_PROMPT_KEYS.has(definition.identifier) ? definition.identifier : undefined);
|
|
14392
|
+
let use;
|
|
14393
|
+
if (key && isDirectModelInput(key, value, candidate.path, lines, definition.line, files.model)) {
|
|
14394
|
+
use = { path: candidate.path, line: definition.line, key };
|
|
14395
|
+
}
|
|
14396
|
+
if (!use && definition.identifier) {
|
|
14397
|
+
use = findModelInputUse(definition.identifier, { path: candidate.path, line: definition.line }, files, rootDir, fileCache, {
|
|
14398
|
+
allowReference: readsAsInstructions(definition.identifier, value)
|
|
14399
|
+
});
|
|
14400
|
+
}
|
|
14401
|
+
if (!use)
|
|
14402
|
+
return;
|
|
14403
|
+
const name = definition.identifier ?? definition.key;
|
|
14404
|
+
const evidence = [{ path: candidate.path, line: definition.line, reason: `deterministic detector ${candidate.signal}` }];
|
|
14405
|
+
const sameSite = use.path === candidate.path && use.line === definition.line;
|
|
14406
|
+
if (!sameSite) {
|
|
14407
|
+
evidence.push({
|
|
14408
|
+
path: use.path,
|
|
14409
|
+
line: use.line,
|
|
14410
|
+
reason: use.referenceOnly ? "prompt-named literal referenced here (positional or composed model input)" : `passed to a model call as ${use.key}`
|
|
14411
|
+
});
|
|
14412
|
+
}
|
|
13647
14413
|
return {
|
|
13648
|
-
id: stableId("prompt", `${pathStem(candidate.path)}:L${
|
|
14414
|
+
id: stableId("prompt", `${pathStem(candidate.path)}:L${definition.line}`),
|
|
13649
14415
|
type: "prompt",
|
|
13650
|
-
name:
|
|
14416
|
+
name: name ? titleFromId(name) : `Inline Prompt (${candidate.path}:${definition.line})`,
|
|
13651
14417
|
scope: "shared",
|
|
13652
14418
|
usedByAgentIds: [],
|
|
13653
|
-
confidence: confidence2,
|
|
13654
|
-
|
|
14419
|
+
confidence: use.referenceOnly ? Math.min(confidence2, REFERENCED_PROMPT_CONFIDENCE) : confidence2,
|
|
14420
|
+
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}.`,
|
|
14421
|
+
evidence,
|
|
14422
|
+
body: definition.text
|
|
13655
14423
|
};
|
|
13656
14424
|
}
|
|
13657
14425
|
function promoteModelConfigCandidate(candidate, rootDir, confidence2, fileCache) {
|
|
@@ -13683,6 +14451,10 @@ function mergePromotedDuplicate(existing, next) {
|
|
|
13683
14451
|
function promoteHarnessCandidates(report, rootDir) {
|
|
13684
14452
|
const fileCache = new Map;
|
|
13685
14453
|
const byId = new Map;
|
|
14454
|
+
const files = {
|
|
14455
|
+
model: new Set(report.candidates.filter((candidate) => candidate.kind === "llm_call_site" || candidate.kind === "framework_construct").map((candidate) => candidate.path)),
|
|
14456
|
+
searchable: new Set(report.files.map((file) => file.path))
|
|
14457
|
+
};
|
|
13686
14458
|
for (const candidate of report.candidates) {
|
|
13687
14459
|
const confidence2 = PROMOTED_CONFIDENCE[candidate.confidence];
|
|
13688
14460
|
if (confidence2 === undefined)
|
|
@@ -13697,7 +14469,7 @@ function promoteHarnessCandidates(report, rootDir) {
|
|
|
13697
14469
|
break;
|
|
13698
14470
|
case "prompt_literal":
|
|
13699
14471
|
if (candidate.confidence === "high") {
|
|
13700
|
-
artifact = promotePromptLiteralCandidate(candidate, rootDir, confidence2, fileCache);
|
|
14472
|
+
artifact = promotePromptLiteralCandidate(candidate, rootDir, confidence2, fileCache, files);
|
|
13701
14473
|
}
|
|
13702
14474
|
break;
|
|
13703
14475
|
case "model_config":
|
|
@@ -14049,7 +14821,7 @@ async function runHarnessCommand(context) {
|
|
|
14049
14821
|
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.");
|
|
14050
14822
|
}
|
|
14051
14823
|
if (context.flags["github-actions"] === "true") {
|
|
14052
|
-
const { runGithubActionsAnalyze } = await import("./harness-github-actions-
|
|
14824
|
+
const { runGithubActionsAnalyze } = await import("./harness-github-actions-nzcpftjn.js");
|
|
14053
14825
|
const result = await runGithubActionsAnalyze(rootDir, {
|
|
14054
14826
|
writeReport: (report2) => {
|
|
14055
14827
|
const normalized = normalizeHarnessReport(report2);
|
|
@@ -14656,7 +15428,7 @@ function extractHarnessReportFromText(output, rootDir, concern) {
|
|
|
14656
15428
|
}
|
|
14657
15429
|
function reportJsonCandidates(output) {
|
|
14658
15430
|
const candidates = [];
|
|
14659
|
-
const markerPattern = new RegExp(`${
|
|
15431
|
+
const markerPattern = new RegExp(`${escapeRegExp2(REPORT_JSON_BEGIN)}\\s*([\\s\\S]*?)\\s*${escapeRegExp2(REPORT_JSON_END)}`, "g");
|
|
14660
15432
|
for (const match of output.matchAll(markerPattern)) {
|
|
14661
15433
|
if (match[1])
|
|
14662
15434
|
candidates.push(match[1]);
|
|
@@ -15064,7 +15836,7 @@ function extractTextFromAgentEvent(event) {
|
|
|
15064
15836
|
return textParts.length > 0 ? textParts.join(`
|
|
15065
15837
|
`) : undefined;
|
|
15066
15838
|
}
|
|
15067
|
-
function
|
|
15839
|
+
function escapeRegExp2(value) {
|
|
15068
15840
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
15069
15841
|
}
|
|
15070
15842
|
var EVENT_CARD_MAX = 100;
|
|
@@ -15818,6 +16590,7 @@ function renderExternalHarnessAnalystPrompt(options) {
|
|
|
15818
16590
|
"- unknowns: report-level open questions with id, question, and citationIds",
|
|
15819
16591
|
"",
|
|
15820
16592
|
'Use exact field names and numeric confidence values from 0 to 1. Do not write string confidence values like "high". Do not use confidence >= 0.90 unless the claim is direct evidence from the cited line(s).',
|
|
16593
|
+
'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."',
|
|
15821
16594
|
"Each graph item with evidence must use evidence: [{ path, reason }], not citationIds/citations.",
|
|
15822
16595
|
...spec ? spec.contractLines : [
|
|
15823
16596
|
'Runtime agents must include id, name, kind:"runtime_agent", root, entrypointIds, channelAdapterIds, artifactIds, identityNamespaceIds, deploymentIds, frameworkIds, modelProviderIds, confidence, evidence.',
|
|
@@ -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-0pzqswvr.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-dfj7etks.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-0pzqswvr.js");
|
|
6106
6106
|
const result = await analyzeHarnessPrompts({
|
|
6107
6107
|
rootDir: root,
|
|
6108
6108
|
existing: manifest.sources,
|
package/dist/cli.js
CHANGED
|
@@ -2967,25 +2967,25 @@ function leafManifestFields(leaf, commands) {
|
|
|
2967
2967
|
import { fileURLToPath } from "url";
|
|
2968
2968
|
import { realpathSync } from "fs";
|
|
2969
2969
|
async function runPromptsCommand(...args) {
|
|
2970
|
-
return (await import("./prompts-
|
|
2970
|
+
return (await import("./prompts-r7kzdnca.js")).runPromptsCommand(...args);
|
|
2971
2971
|
}
|
|
2972
2972
|
async function runSkillsCommand(...args) {
|
|
2973
2973
|
return (await import("./skills-mwftqzyk.js")).runSkillsCommand(...args);
|
|
2974
2974
|
}
|
|
2975
2975
|
async function runHarnessCommand(...args) {
|
|
2976
|
-
return (await import("./harness-
|
|
2976
|
+
return (await import("./harness-0pzqswvr.js")).runHarnessCommand(...args);
|
|
2977
2977
|
}
|
|
2978
2978
|
async function runSyncCommand(...args) {
|
|
2979
|
-
return (await import("./sync-
|
|
2979
|
+
return (await import("./sync-xcjye7em.js")).runSyncCommand(...args);
|
|
2980
2980
|
}
|
|
2981
2981
|
async function runRegistryCommand(...args) {
|
|
2982
2982
|
return (await import("./registry-tv8fktxc.js")).runRegistryCommand(...args);
|
|
2983
2983
|
}
|
|
2984
2984
|
async function runDoctorCommand(...args) {
|
|
2985
|
-
return (await import("./doctor-
|
|
2985
|
+
return (await import("./doctor-0z5k6z9a.js")).runDoctorCommand(...args);
|
|
2986
2986
|
}
|
|
2987
2987
|
async function runStatusCommand(...args) {
|
|
2988
|
-
return (await import("./doctor-
|
|
2988
|
+
return (await import("./doctor-0z5k6z9a.js")).runStatusCommand(...args);
|
|
2989
2989
|
}
|
|
2990
2990
|
async function runAuthCommand(...args) {
|
|
2991
2991
|
return (await import("./profile-commands-nbaec4y9.js")).runAuthCommand(...args);
|
|
@@ -2997,7 +2997,7 @@ async function runProfilesCommand(...args) {
|
|
|
2997
2997
|
return (await import("./profile-commands-nbaec4y9.js")).runProfilesCommand(...args);
|
|
2998
2998
|
}
|
|
2999
2999
|
async function runAgentCommand(...args) {
|
|
3000
|
-
return (await import("./agent-
|
|
3000
|
+
return (await import("./agent-jyst7r0g.js")).runAgentCommand(...args);
|
|
3001
3001
|
}
|
|
3002
3002
|
async function runProductionCommand(...args) {
|
|
3003
3003
|
return (await import("./production-intelligence-zek0rkzj.js")).runProductionCommand(...args);
|
|
@@ -6761,7 +6761,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
6761
6761
|
resetApiRequestCountBeforeRun: true,
|
|
6762
6762
|
telemetry: "result-and-error",
|
|
6763
6763
|
handler: async (context) => {
|
|
6764
|
-
const { runInit } = await import("./index-
|
|
6764
|
+
const { runInit } = await import("./index-2p6x0xg2.js");
|
|
6765
6765
|
if (context.outputMode === "agent-stream") {
|
|
6766
6766
|
context.output.writeEvent({
|
|
6767
6767
|
event: "started",
|
|
@@ -3,9 +3,9 @@ import {
|
|
|
3
3
|
promptsDiscoveredCheck,
|
|
4
4
|
runDoctorCommand,
|
|
5
5
|
runStatusCommand
|
|
6
|
-
} from "./cli-
|
|
6
|
+
} from "./cli-3pn6w6m3.js";
|
|
7
7
|
import"./cli-rdh9jjr2.js";
|
|
8
|
-
import"./cli-
|
|
8
|
+
import"./cli-s3bcce69.js";
|
|
9
9
|
import"./cli-mm48br00.js";
|
|
10
10
|
import"./cli-xq45etg1.js";
|
|
11
11
|
import"./cli-gtke9wrw.js";
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
} from "./cli-hcwdz9sd.js";
|
|
22
22
|
import {
|
|
23
23
|
buildDoctorReport
|
|
24
|
-
} from "./cli-
|
|
24
|
+
} from "./cli-3pn6w6m3.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-s3bcce69.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-k6kydtkv.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-s3bcce69.js";
|
|
10
10
|
import"./cli-mm48br00.js";
|
|
11
11
|
import {
|
|
12
12
|
runHarnessCommand
|
|
13
|
-
} from "./cli-
|
|
13
|
+
} from "./cli-k6kydtkv.js";
|
|
14
14
|
import"./cli-97fnztpy.js";
|
|
15
15
|
import"./cli-xq45etg1.js";
|
|
16
16
|
import"./cli-gtke9wrw.js";
|
package/package.json
CHANGED