@moda-ai/cli 1.55.49 → 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-kw8bdf0d.js → agent-jyst7r0g.js} +10 -10
- package/dist/{cli-4kf462jq.js → cli-1ehmy9rh.js} +2 -2
- package/dist/{cli-d6gfxx8t.js → cli-3dj84cbk.js} +1 -1
- package/dist/{cli-dwfgfksb.js → cli-3pn6w6m3.js} +5 -5
- package/dist/{cli-da3h2p6w.js → cli-40fqk078.js} +1 -1
- package/dist/{cli-sqnw96gj.js → cli-4pzbgxcn.js} +2 -2
- package/dist/{cli-ns5fcnkz.js → cli-c1k20j6e.js} +2 -1
- package/dist/{cli-xctqdn42.js → cli-dxxc7tzq.js} +3 -3
- package/dist/{cli-m4474bnj.js → cli-gtke9wrw.js} +1 -1
- package/dist/{cli-hwfk2b45.js → cli-k6kydtkv.js} +878 -22
- package/dist/{cli-s7d069g0.js → cli-mf37dxpc.js} +4 -4
- package/dist/{cli-h1z9yyqk.js → cli-rdh9jjr2.js} +1 -1
- package/dist/{cli-txj43jz8.js → cli-s3bcce69.js} +8 -8
- package/dist/{cli-qpq84eee.js → cli-vswckv9g.js} +1 -1
- package/dist/{cli-jj77e5yp.js → cli-wqyrcnm1.js} +17 -2
- package/dist/{cli-j08a1mam.js → cli-wry78bg8.js} +1 -1
- package/dist/cli.js +20 -20
- package/dist/{doctor-g0nk7q45.js → doctor-0z5k6z9a.js} +8 -8
- package/dist/{harness-5bckfr6j.js → harness-0pzqswvr.js} +10 -8
- package/dist/{harness-github-actions-fndqvrg6.js → harness-github-actions-nzcpftjn.js} +8 -8
- package/dist/{harness-report-r0dkpafy.js → harness-report-d64517j4.js} +1 -1
- package/dist/{index-52facyzk.js → index-2p6x0xg2.js} +14 -14
- package/dist/{production-intelligence-fe5masaa.js → production-intelligence-zek0rkzj.js} +4 -4
- package/dist/{profile-commands-zbyn9xg2.js → profile-commands-nbaec4y9.js} +5 -5
- package/dist/{prompt-attribution-0v2vdntz.js → prompt-attribution-dfj7etks.js} +8 -8
- package/dist/prompt-source-mcp.js +8 -8
- package/dist/{prompt-sources-07tczyqa.js → prompt-sources-qw2p4t5h.js} +2 -2
- package/dist/{prompts-nah473mq.js → prompts-r7kzdnca.js} +6 -6
- package/dist/{provision-xkhwz86g.js → provision-tch8rc3y.js} +6 -6
- package/dist/{registry-d7xdm4dw.js → registry-tv8fktxc.js} +4 -4
- package/dist/{skills-zfenne8w.js → skills-mwftqzyk.js} +6 -6
- package/dist/{sync-08whcy06.js → sync-xcjye7em.js} +10 -10
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
|
@@ -13,16 +13,16 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
createCommandContext,
|
|
15
15
|
stringOption
|
|
16
|
-
} from "./cli-
|
|
16
|
+
} from "./cli-gtke9wrw.js";
|
|
17
17
|
import {
|
|
18
18
|
assertFlags,
|
|
19
19
|
assertPositionals,
|
|
20
20
|
requireTenant
|
|
21
|
-
} from "./cli-
|
|
21
|
+
} from "./cli-1ehmy9rh.js";
|
|
22
22
|
import {
|
|
23
23
|
ApiError,
|
|
24
24
|
callControlAPI
|
|
25
|
-
} from "./cli-
|
|
25
|
+
} from "./cli-wry78bg8.js";
|
|
26
26
|
import {
|
|
27
27
|
embeddedTenantIdFromApiKey,
|
|
28
28
|
getActiveProfile,
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
resolveModaBaseUrl,
|
|
33
33
|
resolveTenantId,
|
|
34
34
|
shellArg
|
|
35
|
-
} from "./cli-
|
|
35
|
+
} from "./cli-40fqk078.js";
|
|
36
36
|
import {
|
|
37
37
|
PYTHON_AGENT_MODULES,
|
|
38
38
|
TYPESCRIPT_AGENT_MODULES,
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
require_typescript,
|
|
45
45
|
resolvePromptSource,
|
|
46
46
|
validatePromptSource
|
|
47
|
-
} from "./cli-
|
|
47
|
+
} from "./cli-vswckv9g.js";
|
|
48
48
|
import {
|
|
49
49
|
$isMap,
|
|
50
50
|
$isNode,
|
|
@@ -70,7 +70,7 @@ import {
|
|
|
70
70
|
packSnapshot,
|
|
71
71
|
redactDeep,
|
|
72
72
|
shouldInventoryFile
|
|
73
|
-
} from "./cli-
|
|
73
|
+
} from "./cli-c1k20j6e.js";
|
|
74
74
|
import {
|
|
75
75
|
HARNESS_ANALYZE_CONCERNS,
|
|
76
76
|
HARNESS_REPORT_PATH,
|
|
@@ -90,7 +90,7 @@ import {
|
|
|
90
90
|
stampRemoteSnapshotTruncation,
|
|
91
91
|
validateHarnessReport,
|
|
92
92
|
writeHarnessReportArtifacts
|
|
93
|
-
} from "./cli-
|
|
93
|
+
} from "./cli-wqyrcnm1.js";
|
|
94
94
|
import {
|
|
95
95
|
CliInputError,
|
|
96
96
|
CliInputRequiredError
|
|
@@ -409,7 +409,7 @@ function stripAnsi2(value) {
|
|
|
409
409
|
// src/harness-remote.ts
|
|
410
410
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
411
411
|
import { join } from "node:path";
|
|
412
|
-
var DEFAULT_REMOTE_ANALYZE_TIMEOUT_MS =
|
|
412
|
+
var DEFAULT_REMOTE_ANALYZE_TIMEOUT_MS = 3600000;
|
|
413
413
|
var DEFAULT_REMOTE_POLL_INITIAL_MS = 3000;
|
|
414
414
|
var DEFAULT_REMOTE_POLL_MAX_MS = 15000;
|
|
415
415
|
var MIN_REMOTE_POLL_DELAY_MS = 250;
|
|
@@ -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]);
|
|
@@ -14846,17 +15618,100 @@ function mergeDeterministicArtifacts(graph, rootDir, options = {}) {
|
|
|
14846
15618
|
} catch {
|
|
14847
15619
|
return { added: 0 };
|
|
14848
15620
|
}
|
|
15621
|
+
backfillRefutationEvidenceReasons(graph);
|
|
15622
|
+
const refuted = analystRefutations(graph);
|
|
15623
|
+
const candidatePaths = new Set(promoted.flatMap((artifact) => artifact.evidence.map((entry) => typeof entry.path === "string" ? normalizePath2(entry.path) : "").filter(Boolean)));
|
|
14849
15624
|
let added = 0;
|
|
14850
15625
|
for (const artifact of promoted) {
|
|
14851
15626
|
if (allowedTypes && !allowedTypes.has(artifact.type))
|
|
14852
15627
|
continue;
|
|
14853
15628
|
if (graphCoversPromotedArtifact(graph, artifact))
|
|
14854
15629
|
continue;
|
|
15630
|
+
if (isRefutedByAnalyst(artifact, refuted, candidatePaths))
|
|
15631
|
+
continue;
|
|
14855
15632
|
graph.artifacts.push(artifact);
|
|
14856
15633
|
added += 1;
|
|
14857
15634
|
}
|
|
14858
15635
|
return { added };
|
|
14859
15636
|
}
|
|
15637
|
+
function backfillRefutationEvidenceReasons(graph) {
|
|
15638
|
+
for (const unknown of graph.unknowns ?? []) {
|
|
15639
|
+
if (!/refut/i.test(String(unknown.id ?? "")))
|
|
15640
|
+
continue;
|
|
15641
|
+
for (const entry of unknown.evidence ?? []) {
|
|
15642
|
+
if (entry && typeof entry.path === "string" && (typeof entry.reason !== "string" || !entry.reason.trim())) {
|
|
15643
|
+
entry.reason = "Refuted deterministic candidate";
|
|
15644
|
+
}
|
|
15645
|
+
}
|
|
15646
|
+
}
|
|
15647
|
+
}
|
|
15648
|
+
var DETECTOR_ARTIFACT_TYPES = {
|
|
15649
|
+
prompt_literal: "prompt",
|
|
15650
|
+
prompt_file: "prompt",
|
|
15651
|
+
message_construction: "prompt",
|
|
15652
|
+
tool_definition: "tool",
|
|
15653
|
+
tool_schema: "tool",
|
|
15654
|
+
model_config: "model_config"
|
|
15655
|
+
};
|
|
15656
|
+
function refutedTypes(...texts) {
|
|
15657
|
+
const types = new Set;
|
|
15658
|
+
for (const text of texts) {
|
|
15659
|
+
for (const match of String(text ?? "").matchAll(/\b(prompt_literal|prompt_file|message_construction|tool_definition|tool_schema|model_config)\b/g)) {
|
|
15660
|
+
types.add(DETECTOR_ARTIFACT_TYPES[match[1]]);
|
|
15661
|
+
}
|
|
15662
|
+
}
|
|
15663
|
+
return types.size > 0 ? types : undefined;
|
|
15664
|
+
}
|
|
15665
|
+
function analystRefutations(graph) {
|
|
15666
|
+
const result = { candidateIds: new Set, locations: [] };
|
|
15667
|
+
for (const unknown of graph.unknowns ?? []) {
|
|
15668
|
+
const id = String(unknown.id ?? "");
|
|
15669
|
+
const question = String(unknown.question ?? "");
|
|
15670
|
+
if (!/refut/i.test(id) && !/refut/i.test(question))
|
|
15671
|
+
continue;
|
|
15672
|
+
for (const candidateId of unknown.candidateIds ?? [])
|
|
15673
|
+
result.candidateIds.add(String(candidateId));
|
|
15674
|
+
for (const entry of unknown.evidence ?? []) {
|
|
15675
|
+
if (typeof entry?.path !== "string" || !entry.path)
|
|
15676
|
+
continue;
|
|
15677
|
+
const line = typeof entry.line === "number" ? entry.line : undefined;
|
|
15678
|
+
result.locations.push({ path: normalizePath2(entry.path), start: line, end: line, types: refutedTypes(entry.reason, question) });
|
|
15679
|
+
}
|
|
15680
|
+
for (const match of question.matchAll(/([\w./-]+\.[a-z0-9]{1,5})(?::|\s+(?:lines?\s+)?)(\d+)(?:\s*[-\u2013]\s*(\d+))?/gi)) {
|
|
15681
|
+
const start = Number(match[2]);
|
|
15682
|
+
result.locations.push({ path: normalizePath2(match[1]), start, end: match[3] ? Number(match[3]) : start, types: refutedTypes(question) });
|
|
15683
|
+
}
|
|
15684
|
+
}
|
|
15685
|
+
return result;
|
|
15686
|
+
}
|
|
15687
|
+
function refutationMatchesPath(location, path, candidatePaths) {
|
|
15688
|
+
if (location === path)
|
|
15689
|
+
return true;
|
|
15690
|
+
if (location.includes("/"))
|
|
15691
|
+
return false;
|
|
15692
|
+
const matches = [...candidatePaths].filter((candidate) => candidate === location || candidate.endsWith(`/${location}`));
|
|
15693
|
+
return matches.length === 1 && matches[0] === path;
|
|
15694
|
+
}
|
|
15695
|
+
function isRefutedByAnalyst(artifact, refuted, candidatePaths) {
|
|
15696
|
+
if (refuted.candidateIds.has(artifact.id))
|
|
15697
|
+
return true;
|
|
15698
|
+
return artifact.evidence.some((entry) => {
|
|
15699
|
+
if (typeof entry.path !== "string")
|
|
15700
|
+
return false;
|
|
15701
|
+
const path = normalizePath2(entry.path);
|
|
15702
|
+
return refuted.locations.some((location) => {
|
|
15703
|
+
if (location.types && !location.types.has(artifact.type))
|
|
15704
|
+
return false;
|
|
15705
|
+
if (!refutationMatchesPath(location.path, path, candidatePaths))
|
|
15706
|
+
return false;
|
|
15707
|
+
if (location.start === undefined)
|
|
15708
|
+
return typeof entry.line !== "number";
|
|
15709
|
+
if (typeof entry.line !== "number")
|
|
15710
|
+
return false;
|
|
15711
|
+
return entry.line >= location.start && entry.line <= (location.end ?? location.start);
|
|
15712
|
+
});
|
|
15713
|
+
});
|
|
15714
|
+
}
|
|
14860
15715
|
function artifactSourceKey(artifact) {
|
|
14861
15716
|
if (artifact.sourcePath)
|
|
14862
15717
|
return normalizePath2(artifact.sourcePath);
|
|
@@ -14981,7 +15836,7 @@ function extractTextFromAgentEvent(event) {
|
|
|
14981
15836
|
return textParts.length > 0 ? textParts.join(`
|
|
14982
15837
|
`) : undefined;
|
|
14983
15838
|
}
|
|
14984
|
-
function
|
|
15839
|
+
function escapeRegExp2(value) {
|
|
14985
15840
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
14986
15841
|
}
|
|
14987
15842
|
var EVENT_CARD_MAX = 100;
|
|
@@ -15735,6 +16590,7 @@ function renderExternalHarnessAnalystPrompt(options) {
|
|
|
15735
16590
|
"- unknowns: report-level open questions with id, question, and citationIds",
|
|
15736
16591
|
"",
|
|
15737
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."',
|
|
15738
16594
|
"Each graph item with evidence must use evidence: [{ path, reason }], not citationIds/citations.",
|
|
15739
16595
|
...spec ? spec.contractLines : [
|
|
15740
16596
|
'Runtime agents must include id, name, kind:"runtime_agent", root, entrypointIds, channelAdapterIds, artifactIds, identityNamespaceIds, deploymentIds, frameworkIds, modelProviderIds, confidence, evidence.',
|
|
@@ -15872,7 +16728,7 @@ function renderAnalystCandidateLines(report, concern) {
|
|
|
15872
16728
|
const lines = [
|
|
15873
16729
|
"",
|
|
15874
16730
|
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):`,
|
|
15875
|
-
concern ?
|
|
16731
|
+
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.'
|
|
15876
16732
|
];
|
|
15877
16733
|
if (concern === "evals") {
|
|
15878
16734
|
lines.push("Note: evals, guardrails, and memory/retrieval stores have no deterministic detector — only model_config candidates are seeded. Discover the rest by investigation.");
|
|
@@ -18138,4 +18994,4 @@ function hashText(text) {
|
|
|
18138
18994
|
return createHash5("sha256").update(text).digest("hex");
|
|
18139
18995
|
}
|
|
18140
18996
|
|
|
18141
|
-
export { startRemoteAnalyze, pollRemoteAnalyzeUntilDone, isRecoverableRemoteRun, checkPromptMapping, safePromptEvidencePath, discoverHarnessPromptSources, runHarnessCommand, writeHarnessAnalyzeResult, emitWrittenArtifacts, analyzeHarnessPrompts, repairExternalAnalystReport, deriveRelationshipsFromGraph, mergeDeterministicArtifacts, describeCodingAgentEvent, analystEventProgress, isRetryableExternalAnalystFailure, sleep, summarizeInvalidAnalystReport, isDeterministicLocalAnalyst, resolveHarnessAnalyzeConcern, detectAvailableCodingAgents, codingAgentDisplayName, runCodingAgent, resolveAnalystModel, renderExternalHarnessAnalystPrompt, CONCERN_CANDIDATE_KINDS, SEED_CANDIDATE_KIND_LABELS, renderAnalystCandidateLines, renderAnalystSeedLines, truncateText, scanHarness, summarizeHarness, buildSourceSnapshot, writeHumanProgress, describeSyncIdentity, describeSyncTenantLabel, findFresherHarnessReports, writeHarnessArtifacts, assertHarnessGraphSyncQuality, graphForSync, inventoryFiles, numericEnv, numericEnvAllowZero, computeDeterministicFloor, stableId, titleFromId, promptNameFromPath };
|
|
18997
|
+
export { startRemoteAnalyze, pollRemoteAnalyzeUntilDone, isRecoverableRemoteRun, checkPromptMapping, safePromptEvidencePath, discoverHarnessPromptSources, runHarnessCommand, writeHarnessAnalyzeResult, emitWrittenArtifacts, analyzeHarnessPrompts, repairExternalAnalystReport, deriveRelationshipsFromGraph, mergeDeterministicArtifacts, analystRefutations, describeCodingAgentEvent, analystEventProgress, isRetryableExternalAnalystFailure, sleep, summarizeInvalidAnalystReport, isDeterministicLocalAnalyst, resolveHarnessAnalyzeConcern, detectAvailableCodingAgents, codingAgentDisplayName, runCodingAgent, resolveAnalystModel, renderExternalHarnessAnalystPrompt, CONCERN_CANDIDATE_KINDS, SEED_CANDIDATE_KIND_LABELS, renderAnalystCandidateLines, renderAnalystSeedLines, truncateText, scanHarness, summarizeHarness, buildSourceSnapshot, writeHumanProgress, describeSyncIdentity, describeSyncTenantLabel, findFresherHarnessReports, writeHarnessArtifacts, assertHarnessGraphSyncQuality, graphForSync, inventoryFiles, numericEnv, numericEnvAllowZero, computeDeterministicFloor, stableId, titleFromId, promptNameFromPath };
|