@moda-ai/cli 1.55.84 → 1.55.86
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-hz25kpt7.js → agent-515pvq3z.js} +3 -3
- package/dist/{cli-fem792g7.js → cli-gevrs592.js} +2 -2
- package/dist/{cli-ynt9zjkk.js → cli-gqrt2rbm.js} +3 -3
- package/dist/{cli-pjat0vfe.js → cli-py31vwrx.js} +543 -140
- package/dist/cli.js +7 -7
- package/dist/{doctor-dvva8w4d.js → doctor-k2xv4n03.js} +2 -2
- package/dist/{harness-github-actions-gt4qawvp.js → harness-github-actions-x2jgh0e8.js} +1 -1
- package/dist/{harness-t52n8rap.js → harness-tnhe63n3.js} +1 -1
- package/dist/{index-n43wbr24.js → index-69xwrmrh.js} +1 -1
- package/dist/{index-xhcqg43k.js → index-h9r08433.js} +1 -1
- package/dist/{index-3c8srf3s.js → index-zfg5y1b9.js} +3 -3
- package/dist/{prompt-attribution-3110zq79.js → prompt-attribution-v6c51r59.js} +1 -1
- package/dist/prompt-source-mcp.js +1 -1
- package/dist/{prompts-tvvpx1hd.js → prompts-gsyrzgmg.js} +1 -1
- package/dist/{sync-h9nymr41.js → sync-60t12kz3.js} +2 -2
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
|
@@ -3947,6 +3947,121 @@ import {
|
|
|
3947
3947
|
import { basename as basename6, delimiter, dirname as dirname8, join as join11, relative as relative9, resolve as resolve9, sep as sep5 } from "node:path";
|
|
3948
3948
|
import { confirm, select } from "@inquirer/prompts";
|
|
3949
3949
|
|
|
3950
|
+
// ../../packages/harness-bundle/src/agent-identity.ts
|
|
3951
|
+
var normalizeName = (value) => (value ?? "").split(/\s*\(/)[0].replace(/[^a-z0-9]/gi, "").toLowerCase();
|
|
3952
|
+
var normalizePath2 = (value) => value.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/$/, "");
|
|
3953
|
+
var sourceFile = (value) => /\.[cm]?[jt]sx?$|\.py$/.test(value);
|
|
3954
|
+
var DECLARATION = /^\s*(?:export\s+)?(?:default\s+)?(?:(?:abstract|async)\s+)?(class|function)\s+([\w$]+)(?=\s*(?:extends\b|implements\b|[{(<]))/i;
|
|
3955
|
+
var isDefinitionEvidence = (reason) => /^\s*(?:class|entrypoint)\s*$|(?:class|function|route) (?:definition|declaration)|concrete agent|function or route owns|entrypoint definition/i.test(reason ?? "") || DECLARATION.test(reason ?? "");
|
|
3956
|
+
function definingEvidence(agent) {
|
|
3957
|
+
const root = agent.root && sourceFile(agent.root) ? normalizePath2(agent.root) : undefined;
|
|
3958
|
+
let definitions = (agent.evidence ?? []).filter((entry) => isDefinitionEvidence(entry.reason) && entry.path && sourceFile(entry.path) && (!root || normalizePath2(entry.path) === root));
|
|
3959
|
+
const ownNames = new Set([agent.name, agent.className ?? ""].map(normalizeName).filter(Boolean));
|
|
3960
|
+
const named = definitions.filter((entry) => {
|
|
3961
|
+
const symbol = DECLARATION.exec(entry.reason ?? "")?.[2];
|
|
3962
|
+
return symbol && ownNames.has(normalizeName(symbol));
|
|
3963
|
+
});
|
|
3964
|
+
if (named.length)
|
|
3965
|
+
definitions = named;
|
|
3966
|
+
const files = new Set(definitions.map((entry) => normalizePath2(entry.path)));
|
|
3967
|
+
const lines = new Set(definitions.flatMap((entry) => entry.line !== undefined ? [entry.line] : []));
|
|
3968
|
+
const symbols = new Set(definitions.flatMap((entry) => DECLARATION.exec(entry.reason ?? "")?.[2] ?? []));
|
|
3969
|
+
if (files.size > 1 || lines.size > 1 || symbols.size > 1)
|
|
3970
|
+
return;
|
|
3971
|
+
return definitions;
|
|
3972
|
+
}
|
|
3973
|
+
function definitionKinds(agent) {
|
|
3974
|
+
const kinds = new Set;
|
|
3975
|
+
for (const evidence of definingEvidence(agent) ?? []) {
|
|
3976
|
+
const reason = evidence.reason?.trim() ?? "";
|
|
3977
|
+
const declared = DECLARATION.exec(reason)?.[1]?.toLowerCase();
|
|
3978
|
+
if (declared)
|
|
3979
|
+
kinds.add(declared);
|
|
3980
|
+
else if (/^class\b|^concrete agent.*class\b/i.test(reason))
|
|
3981
|
+
kinds.add("class");
|
|
3982
|
+
else if (/^(?:function|route)\b/i.test(reason))
|
|
3983
|
+
kinds.add("function");
|
|
3984
|
+
}
|
|
3985
|
+
return kinds;
|
|
3986
|
+
}
|
|
3987
|
+
function identityNames(agent) {
|
|
3988
|
+
return new Set([agent.name, agent.className ?? ""].map(normalizeName).filter(Boolean));
|
|
3989
|
+
}
|
|
3990
|
+
function paths(agent) {
|
|
3991
|
+
const definitions = definingEvidence(agent);
|
|
3992
|
+
if (!definitions)
|
|
3993
|
+
return new Set;
|
|
3994
|
+
if (agent.root && sourceFile(agent.root))
|
|
3995
|
+
return new Set([normalizePath2(agent.root)]);
|
|
3996
|
+
return new Set(definitions.flatMap((entry) => entry.path ? [normalizePath2(entry.path)] : []));
|
|
3997
|
+
}
|
|
3998
|
+
function matchHarnessAgentIds(source, target) {
|
|
3999
|
+
const mapping = new Map;
|
|
4000
|
+
const sourcePaths = new Map(source.map((agent) => [agent.id, paths(agent)]));
|
|
4001
|
+
const targetPaths = new Map(target.map((agent) => [agent.id, paths(agent)]));
|
|
4002
|
+
const targetIds = new Set(target.map((agent) => agent.id));
|
|
4003
|
+
const kinds = new Map([...source, ...target].map((agent) => [agent, definitionKinds(agent)]));
|
|
4004
|
+
const names = new Map([...source, ...target].map((agent) => [agent, identityNames(agent)]));
|
|
4005
|
+
for (const agent of source) {
|
|
4006
|
+
if (targetIds.has(agent.id)) {
|
|
4007
|
+
mapping.set(agent.id, agent.id);
|
|
4008
|
+
continue;
|
|
4009
|
+
}
|
|
4010
|
+
const ownPaths = sourcePaths.get(agent.id);
|
|
4011
|
+
const ownKinds = kinds.get(agent);
|
|
4012
|
+
const overlapping = target.filter((candidate) => {
|
|
4013
|
+
const otherKinds = kinds.get(candidate);
|
|
4014
|
+
const compatible = ownKinds.size === 0 || otherKinds.size === 0 || [...ownKinds].some((kind) => otherKinds.has(kind));
|
|
4015
|
+
return compatible && [...targetPaths.get(candidate.id)].some((path) => ownPaths.has(path));
|
|
4016
|
+
});
|
|
4017
|
+
const ownNames = names.get(agent);
|
|
4018
|
+
const named = overlapping.filter((candidate) => [...names.get(candidate)].some((name) => ownNames.has(name)));
|
|
4019
|
+
if (named.length === 1 && source.filter((other) => [...names.get(other)].some((name) => ownNames.has(name)) && [...sourcePaths.get(other.id)].some((path) => targetPaths.get(named[0].id).has(path))).length === 1) {
|
|
4020
|
+
mapping.set(agent.id, named[0].id);
|
|
4021
|
+
continue;
|
|
4022
|
+
}
|
|
4023
|
+
const anchored = overlapping.filter((candidate) => (definingEvidence(agent) ?? []).some((entry) => isDefinitionEvidence(entry.reason) && entry.path && entry.line !== undefined && (definingEvidence(candidate) ?? []).some((other) => isDefinitionEvidence(other.reason) && other.line === entry.line && other.path && normalizePath2(other.path) === normalizePath2(entry.path)) && source.filter((identity) => (definingEvidence(identity) ?? []).some((definition) => isDefinitionEvidence(definition.reason) && definition.path && definition.line === entry.line && normalizePath2(definition.path) === normalizePath2(entry.path))).length === 1));
|
|
4024
|
+
if (anchored.length === 1) {
|
|
4025
|
+
mapping.set(agent.id, anchored[0].id);
|
|
4026
|
+
continue;
|
|
4027
|
+
}
|
|
4028
|
+
if (named.length > 1)
|
|
4029
|
+
continue;
|
|
4030
|
+
const coordinateConflict = overlapping.length === 1 && (definingEvidence(agent) ?? []).some((entry) => entry.line !== undefined) && (definingEvidence(overlapping[0]) ?? []).some((entry) => entry.line !== undefined) && !(definingEvidence(agent) ?? []).some((entry) => entry.path && entry.line !== undefined && (definingEvidence(overlapping[0]) ?? []).some((other) => other.path && other.line === entry.line && normalizePath2(other.path) === normalizePath2(entry.path)));
|
|
4031
|
+
if (!coordinateConflict && overlapping.length === 1 && overlapping[0].root && sourceFile(overlapping[0].root) && [...ownPaths].some((path) => targetPaths.get(overlapping[0].id).has(path) && source.filter((other) => sourcePaths.get(other.id).has(path)).length === 1)) {
|
|
4032
|
+
mapping.set(agent.id, overlapping[0].id);
|
|
4033
|
+
}
|
|
4034
|
+
}
|
|
4035
|
+
return mapping;
|
|
4036
|
+
}
|
|
4037
|
+
function harnessAgentIdentities(value) {
|
|
4038
|
+
if (!Array.isArray(value))
|
|
4039
|
+
return [];
|
|
4040
|
+
return value.flatMap((entry) => {
|
|
4041
|
+
if (!entry || typeof entry !== "object")
|
|
4042
|
+
return [];
|
|
4043
|
+
const item = entry;
|
|
4044
|
+
if (typeof item.id !== "string" || typeof item.name !== "string")
|
|
4045
|
+
return [];
|
|
4046
|
+
return [{
|
|
4047
|
+
id: item.id,
|
|
4048
|
+
name: item.name,
|
|
4049
|
+
...typeof item.root === "string" ? { root: item.root } : {},
|
|
4050
|
+
...typeof item.className === "string" ? { className: item.className } : {},
|
|
4051
|
+
evidence: Array.isArray(item.evidence) ? item.evidence.flatMap((raw) => {
|
|
4052
|
+
if (!raw || typeof raw !== "object")
|
|
4053
|
+
return [];
|
|
4054
|
+
const ev = raw;
|
|
4055
|
+
return typeof ev.path === "string" ? [{
|
|
4056
|
+
path: ev.path,
|
|
4057
|
+
...typeof ev.line === "number" ? { line: ev.line } : {},
|
|
4058
|
+
...typeof ev.reason === "string" ? { reason: ev.reason } : {}
|
|
4059
|
+
}] : [];
|
|
4060
|
+
}) : []
|
|
4061
|
+
}];
|
|
4062
|
+
});
|
|
4063
|
+
}
|
|
4064
|
+
|
|
3950
4065
|
// src/analyst-tui.ts
|
|
3951
4066
|
class AnalystTui {
|
|
3952
4067
|
state;
|
|
@@ -6017,10 +6132,10 @@ function ignoredPaths(root) {
|
|
|
6017
6132
|
}
|
|
6018
6133
|
function locallyIgnored(root, entries) {
|
|
6019
6134
|
const out = new Map;
|
|
6020
|
-
const
|
|
6021
|
-
if (
|
|
6135
|
+
const paths2 = entries.map((entry) => entry.replace(/\/+$/, "")).filter((entry) => entry !== "");
|
|
6136
|
+
if (paths2.length === 0)
|
|
6022
6137
|
return out;
|
|
6023
|
-
const result = git(root, ["check-ignore", "--verbose", "-z", "--stdin"], `${
|
|
6138
|
+
const result = git(root, ["check-ignore", "--verbose", "-z", "--stdin"], `${paths2.join("\x00")}\x00`);
|
|
6024
6139
|
if (result.status === 1)
|
|
6025
6140
|
return out;
|
|
6026
6141
|
if (result.status !== 0)
|
|
@@ -7458,17 +7573,17 @@ var LANGUAGE_BY_EXT = {
|
|
|
7458
7573
|
sol: "solidity",
|
|
7459
7574
|
gleam: "gleam"
|
|
7460
7575
|
};
|
|
7461
|
-
function detectToolchain(
|
|
7462
|
-
const pathSet = new Set(
|
|
7576
|
+
function detectToolchain(paths2, readText, harnessRoot) {
|
|
7577
|
+
const pathSet = new Set(paths2);
|
|
7463
7578
|
return {
|
|
7464
|
-
languages: detectLanguages(
|
|
7465
|
-
packageManagers: detectPackageManagers(
|
|
7466
|
-
...detectVersions(
|
|
7579
|
+
languages: detectLanguages(paths2),
|
|
7580
|
+
packageManagers: detectPackageManagers(paths2, pathSet, readText),
|
|
7581
|
+
...detectVersions(paths2, readText, harnessRoot)
|
|
7467
7582
|
};
|
|
7468
7583
|
}
|
|
7469
|
-
function detectLanguages(
|
|
7584
|
+
function detectLanguages(paths2) {
|
|
7470
7585
|
const counts = new Map;
|
|
7471
|
-
for (const path of
|
|
7586
|
+
for (const path of paths2) {
|
|
7472
7587
|
const categories = categorize({ path, encoding: "text" });
|
|
7473
7588
|
if (categories.includes("generated"))
|
|
7474
7589
|
continue;
|
|
@@ -7544,10 +7659,10 @@ function resolveMembers(rootDir, patterns, manifestDirs) {
|
|
|
7544
7659
|
}
|
|
7545
7660
|
return [...members].sort();
|
|
7546
7661
|
}
|
|
7547
|
-
function detectPackageManagers(
|
|
7662
|
+
function detectPackageManagers(paths2, pathSet, readText) {
|
|
7548
7663
|
const out = [];
|
|
7549
7664
|
const memberOf = new Set;
|
|
7550
|
-
const byName = (name) =>
|
|
7665
|
+
const byName = (name) => paths2.filter((p) => basenameOf(p) === name).map(dirnameOf).sort((a, b) => a.length - b.length || (a < b ? -1 : 1));
|
|
7551
7666
|
const firstExisting = (dir, names) => names.map((n) => join3(dir, n)).find((p) => pathSet.has(p));
|
|
7552
7667
|
const nodeDirs = byName("package.json");
|
|
7553
7668
|
for (const dir of nodeDirs) {
|
|
@@ -7604,7 +7719,7 @@ function detectPackageManagers(paths, pathSet, readText) {
|
|
|
7604
7719
|
for (const dir of byName(name))
|
|
7605
7720
|
pyDirs.add(dir);
|
|
7606
7721
|
}
|
|
7607
|
-
for (const path of
|
|
7722
|
+
for (const path of paths2) {
|
|
7608
7723
|
if (/^requirements([-_.].+)?\.txt$/i.test(basenameOf(path)))
|
|
7609
7724
|
pyDirs.add(dirnameOf(path));
|
|
7610
7725
|
}
|
|
@@ -7615,7 +7730,7 @@ function detectPackageManagers(paths, pathSet, readText) {
|
|
|
7615
7730
|
continue;
|
|
7616
7731
|
const pyproject = readText(join3(dir, "pyproject.toml"));
|
|
7617
7732
|
let kind = "pip";
|
|
7618
|
-
let manifest = firstExisting(dir, ["pyproject.toml", "Pipfile", "requirements.txt", "setup.py", "environment.yml", "environment.yaml"]) ??
|
|
7733
|
+
let manifest = firstExisting(dir, ["pyproject.toml", "Pipfile", "requirements.txt", "setup.py", "environment.yml", "environment.yaml"]) ?? paths2.find((p) => dirnameOf(p) === dir && /^requirements([-_.].+)?\.txt$/i.test(basenameOf(p)));
|
|
7619
7734
|
let lockfile;
|
|
7620
7735
|
if (pathSet.has(join3(dir, "uv.lock")) || /^\[tool\.uv/m.test(pyproject ?? "")) {
|
|
7621
7736
|
kind = "uv";
|
|
@@ -7706,7 +7821,7 @@ function detectPackageManagers(paths, pathSet, readText) {
|
|
|
7706
7821
|
out.push({ kind, root: rootLabel(dir), manifest, ...lockfile ? { lockfile } : {} });
|
|
7707
7822
|
}
|
|
7708
7823
|
}
|
|
7709
|
-
for (const path of
|
|
7824
|
+
for (const path of paths2) {
|
|
7710
7825
|
if (/\.(csproj|fsproj)$/i.test(path)) {
|
|
7711
7826
|
const dir = dirnameOf(path);
|
|
7712
7827
|
const lockfile = firstExisting(dir, ["packages.lock.json"]);
|
|
@@ -7782,7 +7897,7 @@ function flowSequence(src) {
|
|
|
7782
7897
|
function cleanVersion(raw) {
|
|
7783
7898
|
return raw.trim().replace(/^["']|["']$/g, "").replace(/^v(?=\d)/, "");
|
|
7784
7899
|
}
|
|
7785
|
-
function detectVersions(
|
|
7900
|
+
function detectVersions(paths2, readText, harnessRoot) {
|
|
7786
7901
|
const candidates = [];
|
|
7787
7902
|
const push = (key, value, source, priority) => {
|
|
7788
7903
|
if (!value)
|
|
@@ -7793,7 +7908,7 @@ function detectVersions(paths, readText, harnessRoot) {
|
|
|
7793
7908
|
candidates.push({ key, value: cleaned, source, priority });
|
|
7794
7909
|
}
|
|
7795
7910
|
};
|
|
7796
|
-
for (const path of
|
|
7911
|
+
for (const path of paths2) {
|
|
7797
7912
|
const name = basenameOf(path).toLowerCase();
|
|
7798
7913
|
const isWorkflow = /^\.github\/workflows\/[^/]+\.ya?ml$/.test(path);
|
|
7799
7914
|
const isDocker = /^(dockerfile|containerfile)([.-].+)?$/.test(name) || /\.dockerfile$/.test(name);
|
|
@@ -14485,8 +14600,8 @@ function inferAgentEntrypoints(input, map, roots) {
|
|
|
14485
14600
|
set.add(hit.path);
|
|
14486
14601
|
byRoot.set(root, set);
|
|
14487
14602
|
}
|
|
14488
|
-
for (const [root,
|
|
14489
|
-
const files = [...
|
|
14603
|
+
for (const [root, paths2] of [...byRoot.entries()].sort(([a], [b]) => cmp(a, b))) {
|
|
14604
|
+
const files = [...paths2].sort();
|
|
14490
14605
|
const mains = files.filter((f) => MAIN_FILE.test(f));
|
|
14491
14606
|
const pick = mains.sort((a, b) => a.split("/").length - b.split("/").length)[0] ?? (files.length === 1 ? files[0] : undefined);
|
|
14492
14607
|
const isPy = (pick ?? files[0]).endsWith(".py");
|
|
@@ -14784,8 +14899,8 @@ function moduleSpecifiers(source, braceStartsRegex = false) {
|
|
|
14784
14899
|
}
|
|
14785
14900
|
return out;
|
|
14786
14901
|
}
|
|
14787
|
-
function readOptions(cfg,
|
|
14788
|
-
if (depth > 8 || !
|
|
14902
|
+
function readOptions(cfg, paths2, read, depth = 0) {
|
|
14903
|
+
if (depth > 8 || !paths2.has(cfg))
|
|
14789
14904
|
return null;
|
|
14790
14905
|
const json = parseJsonLoose(read(cfg) ?? "");
|
|
14791
14906
|
if (!isRecord(json))
|
|
@@ -14795,7 +14910,7 @@ function readOptions(cfg, paths, read, depth = 0) {
|
|
|
14795
14910
|
const extendsList = (Array.isArray(json.extends) ? json.extends : [json.extends]).filter((e) => typeof e === "string" && e.startsWith("."));
|
|
14796
14911
|
for (const e of extendsList) {
|
|
14797
14912
|
const target = joinPath(dir, e);
|
|
14798
|
-
const parent = readOptions(target.endsWith(".json") ? target : `${target}.json`,
|
|
14913
|
+
const parent = readOptions(target.endsWith(".json") ? target : `${target}.json`, paths2, read, depth + 1);
|
|
14799
14914
|
if (parent?.baseUrl !== undefined)
|
|
14800
14915
|
merged.baseUrl = parent.baseUrl;
|
|
14801
14916
|
if (parent?.paths !== undefined)
|
|
@@ -14820,36 +14935,36 @@ function readOptions(cfg, paths, read, depth = 0) {
|
|
|
14820
14935
|
}
|
|
14821
14936
|
return merged;
|
|
14822
14937
|
}
|
|
14823
|
-
function readTsconfig(cfg,
|
|
14824
|
-
const options = readOptions(cfg,
|
|
14938
|
+
function readTsconfig(cfg, paths2, read) {
|
|
14939
|
+
const options = readOptions(cfg, paths2, read);
|
|
14825
14940
|
if (!options || options.baseUrl === undefined && options.paths === undefined)
|
|
14826
14941
|
return null;
|
|
14827
14942
|
return { baseUrl: options.baseUrl, pathsBase: options.paths?.base ?? options.baseUrl ?? dirname5(cfg), paths: options.paths?.list ?? [] };
|
|
14828
14943
|
}
|
|
14829
|
-
function aliasesFor(dir,
|
|
14944
|
+
function aliasesFor(dir, paths2, read, cache) {
|
|
14830
14945
|
for (let d = dir;; d = dirname5(d)) {
|
|
14831
14946
|
const cfg = joinPath(d, "tsconfig.json");
|
|
14832
14947
|
if (!cache.has(cfg))
|
|
14833
|
-
cache.set(cfg, readTsconfig(cfg,
|
|
14948
|
+
cache.set(cfg, readTsconfig(cfg, paths2, read));
|
|
14834
14949
|
const hit = cache.get(cfg);
|
|
14835
14950
|
if (hit)
|
|
14836
14951
|
return hit;
|
|
14837
|
-
if (
|
|
14952
|
+
if (paths2.has(cfg))
|
|
14838
14953
|
return null;
|
|
14839
14954
|
if (d === "." || d === "")
|
|
14840
14955
|
return null;
|
|
14841
14956
|
}
|
|
14842
14957
|
}
|
|
14843
|
-
function resolveFile(candidate,
|
|
14958
|
+
function resolveFile(candidate, paths2) {
|
|
14844
14959
|
const base = candidate.replace(/\?.*$/, "");
|
|
14845
|
-
if (
|
|
14960
|
+
if (paths2.has(base))
|
|
14846
14961
|
return base;
|
|
14847
14962
|
const stem = base.replace(/\.(?:[cm]?js|jsx)$/, "");
|
|
14848
14963
|
for (const ext of EXTENSIONS)
|
|
14849
|
-
if (
|
|
14964
|
+
if (paths2.has(`${stem}${ext}`))
|
|
14850
14965
|
return `${stem}${ext}`;
|
|
14851
14966
|
for (const ext of EXTENSIONS)
|
|
14852
|
-
if (
|
|
14967
|
+
if (paths2.has(`${base}/index${ext}`))
|
|
14853
14968
|
return `${base}/index${ext}`;
|
|
14854
14969
|
return;
|
|
14855
14970
|
}
|
|
@@ -14862,7 +14977,7 @@ function exportTargets(value) {
|
|
|
14862
14977
|
return Object.values(value).flatMap(exportTargets);
|
|
14863
14978
|
return [];
|
|
14864
14979
|
}
|
|
14865
|
-
function packageEntry(dir, sub,
|
|
14980
|
+
function packageEntry(dir, sub, paths2, read) {
|
|
14866
14981
|
const json = parseJsonLoose(read(joinPath(dir, "package.json")) ?? "");
|
|
14867
14982
|
const fields = [];
|
|
14868
14983
|
if (isRecord(json)) {
|
|
@@ -14892,20 +15007,20 @@ function packageEntry(dir, sub, paths, read) {
|
|
|
14892
15007
|
fields.push(json[k]);
|
|
14893
15008
|
}
|
|
14894
15009
|
}
|
|
14895
|
-
const found = fields.map((f) => resolveFile(joinPath(dir, f),
|
|
15010
|
+
const found = fields.map((f) => resolveFile(joinPath(dir, f), paths2)).filter((f) => f !== undefined);
|
|
14896
15011
|
if (found.length > 0)
|
|
14897
15012
|
return [...new Set(found)];
|
|
14898
|
-
const fallback = sub ? resolveFile(joinPath(dir, sub),
|
|
15013
|
+
const fallback = sub ? resolveFile(joinPath(dir, sub), paths2) ?? resolveFile(joinPath(dir, "src", sub), paths2) : resolveFile(joinPath(dir, "src/index"), paths2) ?? resolveFile(joinPath(dir, "index"), paths2);
|
|
14899
15014
|
return fallback ? [fallback] : [];
|
|
14900
15015
|
}
|
|
14901
15016
|
function dynamicImports(source) {
|
|
14902
15017
|
const text = stripJsComments(source);
|
|
14903
15018
|
return [...text.matchAll(CALL_RE)].map((m) => m[1].trim()).filter((arg) => arg !== "" && !STATIC_ARG.test(arg));
|
|
14904
15019
|
}
|
|
14905
|
-
function packageImportTargets(spec, from,
|
|
15020
|
+
function packageImportTargets(spec, from, paths2, read) {
|
|
14906
15021
|
for (let d = dirname5(from);; d = dirname5(d)) {
|
|
14907
15022
|
const manifest = joinPath(d, "package.json");
|
|
14908
|
-
if (
|
|
15023
|
+
if (paths2.has(manifest)) {
|
|
14909
15024
|
const json = parseJsonLoose(read(manifest) ?? "");
|
|
14910
15025
|
const imports = isRecord(json) && isRecord(json.imports) ? json.imports : undefined;
|
|
14911
15026
|
if (imports) {
|
|
@@ -14947,13 +15062,13 @@ function packageImport(spec, from, input) {
|
|
|
14947
15062
|
return [];
|
|
14948
15063
|
}
|
|
14949
15064
|
function importClosure(input) {
|
|
14950
|
-
const { paths, read } = input;
|
|
15065
|
+
const { paths: paths2, read } = input;
|
|
14951
15066
|
const max = input.maxFiles ?? 20000;
|
|
14952
15067
|
const files = new Set;
|
|
14953
15068
|
const unresolved = [];
|
|
14954
15069
|
const dynamic = [];
|
|
14955
15070
|
const aliasCache = new Map;
|
|
14956
|
-
const queue = input.entries.filter((e) =>
|
|
15071
|
+
const queue = input.entries.filter((e) => paths2.has(e));
|
|
14957
15072
|
let imports = 0;
|
|
14958
15073
|
while (queue.length > 0 && files.size < max) {
|
|
14959
15074
|
const file = queue.shift();
|
|
@@ -14991,28 +15106,28 @@ function importClosure(input) {
|
|
|
14991
15106
|
return { entries: input.entries, files, unresolved, imports, dynamic, truncated };
|
|
14992
15107
|
}
|
|
14993
15108
|
function resolveSpecifier(spec, from, input, aliasCache) {
|
|
14994
|
-
const { paths, read } = input;
|
|
15109
|
+
const { paths: paths2, read } = input;
|
|
14995
15110
|
if (spec.startsWith(".")) {
|
|
14996
|
-
const hit = resolveFile(joinPath(dirname5(from), spec),
|
|
15111
|
+
const hit = resolveFile(joinPath(dirname5(from), spec), paths2);
|
|
14997
15112
|
return hit ? [hit] : [];
|
|
14998
15113
|
}
|
|
14999
15114
|
if (spec.startsWith("/") || /^(?:node|bun|cloudflare|workers|https?|data):/.test(spec))
|
|
15000
15115
|
return;
|
|
15001
|
-
const aliases = aliasesFor(dirname5(from),
|
|
15116
|
+
const aliases = aliasesFor(dirname5(from), paths2, read, aliasCache);
|
|
15002
15117
|
for (const alias of aliases?.paths ?? []) {
|
|
15003
15118
|
const matches = alias.wildcard ? spec.startsWith(alias.prefix) && spec.endsWith(alias.suffix) : spec === alias.prefix;
|
|
15004
15119
|
if (!matches)
|
|
15005
15120
|
continue;
|
|
15006
15121
|
const middle = alias.wildcard ? spec.slice(alias.prefix.length, spec.length - alias.suffix.length) : "";
|
|
15007
15122
|
for (const target of alias.targets) {
|
|
15008
|
-
const hit = resolveFile(joinPath(aliases.pathsBase, target.replace("*", middle)),
|
|
15123
|
+
const hit = resolveFile(joinPath(aliases.pathsBase, target.replace("*", middle)), paths2);
|
|
15009
15124
|
if (hit)
|
|
15010
15125
|
return [hit];
|
|
15011
15126
|
}
|
|
15012
15127
|
return [];
|
|
15013
15128
|
}
|
|
15014
15129
|
if (aliases?.baseUrl) {
|
|
15015
|
-
const hit = resolveFile(joinPath(aliases.baseUrl, spec),
|
|
15130
|
+
const hit = resolveFile(joinPath(aliases.baseUrl, spec), paths2);
|
|
15016
15131
|
if (hit)
|
|
15017
15132
|
return [hit];
|
|
15018
15133
|
}
|
|
@@ -15024,7 +15139,7 @@ function resolveSpecifier(spec, from, input, aliasCache) {
|
|
|
15024
15139
|
if (dir === undefined)
|
|
15025
15140
|
return /^(?:@\/|~\/)/.test(spec) ? [] : undefined;
|
|
15026
15141
|
const sub = parts.slice(spec.startsWith("@") ? 2 : 1).join("/");
|
|
15027
|
-
const entry = packageEntry(dir, sub,
|
|
15142
|
+
const entry = packageEntry(dir, sub, paths2, read);
|
|
15028
15143
|
return entry.length > 0 ? entry : [];
|
|
15029
15144
|
}
|
|
15030
15145
|
function isRuntimeConfigFile(path, root) {
|
|
@@ -15045,7 +15160,7 @@ var DOC_DIR2 = /(^|\/)(docs?|documentation|website)(\/|$)/;
|
|
|
15045
15160
|
var AUXILIARY_DIR = /(^|\/)(vendor|third_party|examples?|samples?|demos?|\.devops|cloud-deployments|hack|playground)(\/|$)/;
|
|
15046
15161
|
var BUNDLED_KINDS = new Set(["cloudflare_workers"]);
|
|
15047
15162
|
function runtimeFiles(ctx, runtimes, packageJsons, harnessRoot, launchedScript) {
|
|
15048
|
-
const
|
|
15163
|
+
const paths2 = new Set(ctx.files.map((f) => f.path));
|
|
15049
15164
|
const read = (p2) => ctx.byPath.get(p2)?.text;
|
|
15050
15165
|
const workspacePackages = new Map;
|
|
15051
15166
|
for (const p2 of packageJsons)
|
|
@@ -15056,10 +15171,10 @@ function runtimeFiles(ctx, runtimes, packageJsons, harnessRoot, launchedScript)
|
|
|
15056
15171
|
for (const rt of runtimes) {
|
|
15057
15172
|
if (!BUNDLED_KINDS.has(rt.kind))
|
|
15058
15173
|
continue;
|
|
15059
|
-
const entries = uniqSorted(rt.entrypoints.map((e) => (e.handler ?? "").split("#")[0]).filter((p2) =>
|
|
15174
|
+
const entries = uniqSorted(rt.entrypoints.map((e) => (e.handler ?? "").split("#")[0]).filter((p2) => paths2.has(p2) && languageOf(p2) === "js"));
|
|
15060
15175
|
if (entries.length === 0)
|
|
15061
15176
|
continue;
|
|
15062
|
-
const closure = importClosure({ entries, paths, read, workspacePackages });
|
|
15177
|
+
const closure = importClosure({ entries, paths: paths2, read, workspacePackages });
|
|
15063
15178
|
const relative6 = closure.unresolved.length;
|
|
15064
15179
|
if (closure.files.size <= entries.length && relative6 > 0)
|
|
15065
15180
|
continue;
|
|
@@ -15077,7 +15192,7 @@ function runtimeFiles(ctx, runtimes, packageJsons, harnessRoot, launchedScript)
|
|
|
15077
15192
|
if (!/^[./~#]/.test(spec))
|
|
15078
15193
|
pkgs.add(npmPackageOf(spec));
|
|
15079
15194
|
else if (spec.startsWith("#")) {
|
|
15080
|
-
for (const t of packageImportTargets(spec, f,
|
|
15195
|
+
for (const t of packageImportTargets(spec, f, paths2, read)?.targets ?? [])
|
|
15081
15196
|
if (!t.startsWith(".") && !t.startsWith("#"))
|
|
15082
15197
|
pkgs.add(npmPackageOf(t));
|
|
15083
15198
|
}
|
|
@@ -15865,16 +15980,16 @@ function detectDependencies(input) {
|
|
|
15865
15980
|
if (loaded.skipped.length > 0) {
|
|
15866
15981
|
const byReason = new Map;
|
|
15867
15982
|
for (const sk of loaded.skipped) {
|
|
15868
|
-
let
|
|
15869
|
-
if (!
|
|
15870
|
-
byReason.set(sk.reason,
|
|
15871
|
-
|
|
15983
|
+
let paths2 = byReason.get(sk.reason);
|
|
15984
|
+
if (!paths2)
|
|
15985
|
+
byReason.set(sk.reason, paths2 = []);
|
|
15986
|
+
paths2.push(sk.path);
|
|
15872
15987
|
}
|
|
15873
|
-
for (const [reason,
|
|
15988
|
+
for (const [reason, paths2] of [...byReason.entries()].sort(([a], [b]) => cmp(a, b))) {
|
|
15874
15989
|
ctx.gaps.push({
|
|
15875
15990
|
kind: "skipped_files",
|
|
15876
|
-
message: `${
|
|
15877
|
-
evidence:
|
|
15991
|
+
message: `${paths2.length} file(s) not analyzed (${reason}): ${paths2.slice(0, 5).map(redact).join(", ")}${paths2.length > 5 ? ", ..." : ""}`,
|
|
15992
|
+
evidence: paths2.slice(0, 3).map((path) => ({ path: redact(path), detector: "files" }))
|
|
15878
15993
|
});
|
|
15879
15994
|
}
|
|
15880
15995
|
}
|
|
@@ -16063,7 +16178,7 @@ var RUNTIME_CATEGORIES = new Set(["prompt", "schema", "migration", "seed_data",
|
|
|
16063
16178
|
var INERT = new Set(["test", "ci"]);
|
|
16064
16179
|
var INERT_DIR = /(^|\/)(\.github|\.gitlab|\.circleci|\.buildkite|\.devcontainer|\.vscode|\.idea|\.cursor|\.claude|\.codex|\.windsurf|\.agents|\.husky|\.changeset|evals?|evaluations?|benchmarks?|\.?screenshots?|[\w.-]+-out)(\/|$)/;
|
|
16065
16180
|
function harnessFiles(manifest, map, read) {
|
|
16066
|
-
const
|
|
16181
|
+
const paths2 = new Set(manifest.files.map((f) => f.path));
|
|
16067
16182
|
const root = map?.harness?.root ?? (manifest.harness.root || ".");
|
|
16068
16183
|
const runtime = map?.runtimes.find((r) => r.root === root && r.kind === map.harness?.runtimeKind);
|
|
16069
16184
|
const reached = new Set;
|
|
@@ -16073,27 +16188,27 @@ function harnessFiles(manifest, map, read) {
|
|
|
16073
16188
|
if (d === "." || d === "")
|
|
16074
16189
|
break;
|
|
16075
16190
|
}
|
|
16076
|
-
for (const p2 of
|
|
16191
|
+
for (const p2 of paths2)
|
|
16077
16192
|
if (ancestors.has(dirname5(p2)) && dirname5(p2) !== root && WORKSPACE_INPUT.test(basename3(p2)))
|
|
16078
16193
|
reached.add(p2);
|
|
16079
16194
|
for (const config of runtime?.kind === "cloudflare_workers" ? runtime.configFiles : []) {
|
|
16080
16195
|
for (const dir of wranglerAssetDirs(config, read(config) ?? ""))
|
|
16081
|
-
for (const p2 of
|
|
16196
|
+
for (const p2 of paths2)
|
|
16082
16197
|
if (isUnder2(p2, dir))
|
|
16083
16198
|
reached.add(p2);
|
|
16084
16199
|
}
|
|
16085
16200
|
if (runtime?.kind === "cloudflare_workers") {
|
|
16086
|
-
const entries = runtime.entrypoints.map((e) => (e.handler ?? "").split("#")[0]).filter((p2) =>
|
|
16201
|
+
const entries = runtime.entrypoints.map((e) => (e.handler ?? "").split("#")[0]).filter((p2) => paths2.has(p2));
|
|
16087
16202
|
if (entries.length > 0) {
|
|
16088
16203
|
const workspacePackages = new Map;
|
|
16089
|
-
for (const p2 of
|
|
16204
|
+
for (const p2 of paths2) {
|
|
16090
16205
|
if (basename3(p2) !== "package.json")
|
|
16091
16206
|
continue;
|
|
16092
16207
|
const json = parseJsonLoose(read(p2) ?? "");
|
|
16093
16208
|
if (isRecord(json) && typeof json.name === "string")
|
|
16094
16209
|
workspacePackages.set(json.name, dirname5(p2));
|
|
16095
16210
|
}
|
|
16096
|
-
for (const f of importClosure({ entries, paths, read, workspacePackages }).files)
|
|
16211
|
+
for (const f of importClosure({ entries, paths: paths2, read, workspacePackages }).files)
|
|
16097
16212
|
reached.add(f);
|
|
16098
16213
|
}
|
|
16099
16214
|
}
|
|
@@ -17769,6 +17884,8 @@ var TEXT_PRESERVING_METHODS = new Set([
|
|
|
17769
17884
|
]);
|
|
17770
17885
|
var ARRAY_ASSEMBLY_METHODS = new Set(["join", "concat", "flat", "filter", "slice", "reverse", "sort", "toSorted"]);
|
|
17771
17886
|
var CALLBACK_METHODS = new Set(["map", "flatMap", "then", "catch"]);
|
|
17887
|
+
var ARRAY_ELEMENT = "<array-element>";
|
|
17888
|
+
var FLATMAP_ELEMENT = "<flatmap-element>";
|
|
17772
17889
|
var TEST_SOURCE = /(?:^|\/)(?:__tests__|__mocks__|fixtures?|test-fixtures)\/|(?:^|\/)[^/]*\.(?:test|spec)\.[^/]+$/i;
|
|
17773
17890
|
var TEXT_MODULE = /\.(?:md|mdx|txt|prompt)(?:\?raw)?$/;
|
|
17774
17891
|
var LOCAL_ONLY_SITE = /^(?:scripts|evals?)\//;
|
|
@@ -17955,6 +18072,8 @@ class PromptResolver {
|
|
|
17955
18072
|
callersByName = new Map;
|
|
17956
18073
|
aliasesByName = new Map;
|
|
17957
18074
|
callersIndexed = false;
|
|
18075
|
+
resolvedCallers = new WeakMap;
|
|
18076
|
+
locallyWrittenParameters = new WeakMap;
|
|
17958
18077
|
methodIndex;
|
|
17959
18078
|
constructor(context, options) {
|
|
17960
18079
|
this.context = context;
|
|
@@ -18072,6 +18191,9 @@ class PromptResolver {
|
|
|
18072
18191
|
return;
|
|
18073
18192
|
}
|
|
18074
18193
|
const expr = unwrap2(node);
|
|
18194
|
+
if (walk.project[0] === FLATMAP_ELEMENT && (import_typescript8.default.isStringLiteral(expr) || import_typescript8.default.isNoSubstitutionTemplateLiteral(expr) || import_typescript8.default.isTemplateExpression(expr) || import_typescript8.default.isObjectLiteralExpression(expr))) {
|
|
18195
|
+
walk = { ...walk, project: walk.project.slice(1) };
|
|
18196
|
+
}
|
|
18075
18197
|
if (walk.project.length > 0 && (import_typescript8.default.isStringLiteral(expr) || import_typescript8.default.isNoSubstitutionTemplateLiteral(expr) || import_typescript8.default.isTemplateExpression(expr) || import_typescript8.default.isBinaryExpression(expr) && expr.operatorToken.kind === import_typescript8.default.SyntaxKind.PlusToken)) {
|
|
18076
18198
|
return;
|
|
18077
18199
|
}
|
|
@@ -18106,6 +18228,16 @@ class PromptResolver {
|
|
|
18106
18228
|
return;
|
|
18107
18229
|
}
|
|
18108
18230
|
if (import_typescript8.default.isArrayLiteralExpression(expr)) {
|
|
18231
|
+
if (walk.project[0] === ARRAY_ELEMENT || walk.project[0] === FLATMAP_ELEMENT) {
|
|
18232
|
+
const inner = { ...walk, project: walk.project.slice(1) };
|
|
18233
|
+
for (const element of expr.elements) {
|
|
18234
|
+
if (import_typescript8.default.isSpreadElement(element))
|
|
18235
|
+
this.value(element.expression, owner, walk);
|
|
18236
|
+
else
|
|
18237
|
+
this.value(element, owner, inner);
|
|
18238
|
+
}
|
|
18239
|
+
return;
|
|
18240
|
+
}
|
|
18109
18241
|
if (/^\d+$/.test(walk.project[0] ?? "")) {
|
|
18110
18242
|
const [index, ...rest] = walk.project;
|
|
18111
18243
|
const selected = Number(index);
|
|
@@ -18300,7 +18432,7 @@ class PromptResolver {
|
|
|
18300
18432
|
}
|
|
18301
18433
|
const table = this.objectLiteralOf(access.expression);
|
|
18302
18434
|
if (!table) {
|
|
18303
|
-
this.value(access.expression, owner, walk);
|
|
18435
|
+
this.value(access.expression, owner, literalKey === undefined ? walk : { ...flag(walk, "projected"), project: [literalKey, ...walk.project] });
|
|
18304
18436
|
return;
|
|
18305
18437
|
}
|
|
18306
18438
|
const next = this.step(literalKey ? walk : flag(walk, "dynamic-key"), access, literalKey ? `table field ${literalKey}` : "every field of a table read with a dynamic key");
|
|
@@ -18332,6 +18464,89 @@ class PromptResolver {
|
|
|
18332
18464
|
this.value(callee.expression, owner, walk);
|
|
18333
18465
|
return;
|
|
18334
18466
|
}
|
|
18467
|
+
const checker = this.context.checkerFor(this.relative(callee.expression.getSourceFile().fileName));
|
|
18468
|
+
const arrayType = (type, awaited = false) => {
|
|
18469
|
+
if (!type)
|
|
18470
|
+
return false;
|
|
18471
|
+
if (import_typescript8.default.isArrayTypeNode(type) || import_typescript8.default.isTupleTypeNode(type))
|
|
18472
|
+
return true;
|
|
18473
|
+
if (import_typescript8.default.isTypeOperatorNode(type))
|
|
18474
|
+
return arrayType(type.type, awaited);
|
|
18475
|
+
if (!import_typescript8.default.isTypeReferenceNode(type))
|
|
18476
|
+
return false;
|
|
18477
|
+
const name = type.typeName.getText();
|
|
18478
|
+
return /^(?:Readonly)?Array$/.test(name) || awaited && name === "Promise" && arrayType(type.typeArguments?.[0]);
|
|
18479
|
+
};
|
|
18480
|
+
const arraySeen = new Set;
|
|
18481
|
+
const isArrayReceiver = (expression, awaited = false) => {
|
|
18482
|
+
const raw = unwrapNode(expression);
|
|
18483
|
+
if (import_typescript8.default.isAwaitExpression(raw))
|
|
18484
|
+
return isArrayReceiver(raw.expression, true);
|
|
18485
|
+
const receiver = unwrap2(expression);
|
|
18486
|
+
if (arraySeen.has(receiver))
|
|
18487
|
+
return false;
|
|
18488
|
+
arraySeen.add(receiver);
|
|
18489
|
+
if (import_typescript8.default.isAwaitExpression(receiver))
|
|
18490
|
+
return isArrayReceiver(receiver.expression, true);
|
|
18491
|
+
if (import_typescript8.default.isIdentifier(receiver)) {
|
|
18492
|
+
for (const declaration of this.declarationsOf(receiver)) {
|
|
18493
|
+
if ((import_typescript8.default.isVariableDeclaration(declaration) || import_typescript8.default.isParameter(declaration)) && (arrayType(declaration.type) || declaration.initializer && isArrayReceiver(declaration.initializer)))
|
|
18494
|
+
return true;
|
|
18495
|
+
}
|
|
18496
|
+
}
|
|
18497
|
+
if (import_typescript8.default.isCallExpression(receiver)) {
|
|
18498
|
+
for (const declaration of this.declarationsOf(import_typescript8.default.isPropertyAccessExpression(receiver.expression) ? receiver.expression.name : receiver.expression)) {
|
|
18499
|
+
const fn = functionOf(declaration);
|
|
18500
|
+
if (fn && arrayType(fn.type, awaited))
|
|
18501
|
+
return true;
|
|
18502
|
+
}
|
|
18503
|
+
}
|
|
18504
|
+
const type = checker?.getTypeAtLocation(receiver);
|
|
18505
|
+
if (import_typescript8.default.isArrayLiteralExpression(this.objectLiteralOf(receiver) ?? receiver) || !!checker && !!type && (type.isUnion() ? type.types : [type]).every((item) => checker.isArrayType(item) || checker.isTupleType(item)))
|
|
18506
|
+
return true;
|
|
18507
|
+
return import_typescript8.default.isCallExpression(receiver) && import_typescript8.default.isPropertyAccessExpression(receiver.expression) && ARRAY_ASSEMBLY_METHODS.has(receiver.expression.name.text) && receiver.expression.name.text !== "join" && isArrayReceiver(receiver.expression.expression);
|
|
18508
|
+
};
|
|
18509
|
+
const arrayReceiver = isArrayReceiver(callee.expression);
|
|
18510
|
+
if ((method === "find" || method === "findLast") && arrayReceiver) {
|
|
18511
|
+
this.value(callee.expression, owner, { ...flag(walk, "dynamic-key"), project: [ARRAY_ELEMENT, ...walk.project] });
|
|
18512
|
+
return;
|
|
18513
|
+
}
|
|
18514
|
+
if ((method === "map" || method === "flatMap") && arrayReceiver && call.arguments[0]) {
|
|
18515
|
+
const callback = unwrap2(call.arguments[0]);
|
|
18516
|
+
const functions2 = import_typescript8.default.isArrowFunction(callback) || import_typescript8.default.isFunctionExpression(callback) ? [callback] : this.declarationsOf(callback).map(functionOf).filter((fn) => !!fn?.body);
|
|
18517
|
+
const output = walk.project[0];
|
|
18518
|
+
const indexed = /^\d+$/.test(output ?? "");
|
|
18519
|
+
if (method === "flatMap" && indexed) {
|
|
18520
|
+
this.markUnresolved(call, "dynamic-key", walk);
|
|
18521
|
+
return;
|
|
18522
|
+
}
|
|
18523
|
+
const eachOutput = output === ARRAY_ELEMENT || output === FLATMAP_ELEMENT;
|
|
18524
|
+
const callbackProject = eachOutput ? method === "flatMap" ? [FLATMAP_ELEMENT, ...walk.project.slice(1)] : walk.project.slice(1) : indexed ? walk.project.slice(1) : walk.project;
|
|
18525
|
+
const sourceProject = method === "map" && indexed ? output : ARRAY_ELEMENT;
|
|
18526
|
+
for (const fn of functions2) {
|
|
18527
|
+
const next = this.step({ ...walk, project: callbackProject }, fn, `array callback at ${this.where(call)}`);
|
|
18528
|
+
if (!next || walk.seen.has(fn))
|
|
18529
|
+
continue;
|
|
18530
|
+
next.bindings = new Map(next.bindings);
|
|
18531
|
+
bindParameters(fn, [callee.expression], walk.bindings, next.bindings);
|
|
18532
|
+
const first2 = fn.parameters[0];
|
|
18533
|
+
if (first2 && import_typescript8.default.isArrayBindingPattern(first2.name)) {
|
|
18534
|
+
first2.name.elements.forEach((element, index) => {
|
|
18535
|
+
if (import_typescript8.default.isBindingElement(element) && !element.dotDotDotToken && !element.initializer) {
|
|
18536
|
+
next.bindings.set(element, { expr: callee.expression, bindings: walk.bindings, project: [String(index)] });
|
|
18537
|
+
}
|
|
18538
|
+
});
|
|
18539
|
+
}
|
|
18540
|
+
for (const [declaration, binding] of next.bindings) {
|
|
18541
|
+
if (declaration === first2 || import_typescript8.default.isBindingElement(declaration) && parameterOf(declaration) === first2) {
|
|
18542
|
+
next.bindings.set(declaration, { ...binding, project: [sourceProject, ...binding.project ?? []] });
|
|
18543
|
+
}
|
|
18544
|
+
}
|
|
18545
|
+
this.builderBody(fn, owner ?? { node: fn, kind: "builder" }, next);
|
|
18546
|
+
}
|
|
18547
|
+
if (functions2.length)
|
|
18548
|
+
return;
|
|
18549
|
+
}
|
|
18335
18550
|
if (CALLBACK_METHODS.has(method)) {
|
|
18336
18551
|
const callbacks = call.arguments.map(unwrap2).filter((a) => import_typescript8.default.isArrowFunction(a) || import_typescript8.default.isFunctionExpression(a));
|
|
18337
18552
|
for (const callback of callbacks)
|
|
@@ -18343,6 +18558,10 @@ class PromptResolver {
|
|
|
18343
18558
|
this.value(callee.expression, owner, walk);
|
|
18344
18559
|
return;
|
|
18345
18560
|
}
|
|
18561
|
+
if (ARRAY_ASSEMBLY_METHODS.has(method) && /^\d+$/.test(walk.project[0] ?? "")) {
|
|
18562
|
+
this.markUnresolved(call, "dynamic-key", walk);
|
|
18563
|
+
return;
|
|
18564
|
+
}
|
|
18346
18565
|
if (TEXT_PRESERVING_METHODS.has(method) || ARRAY_ASSEMBLY_METHODS.has(method)) {
|
|
18347
18566
|
this.value(callee.expression, owner, walk);
|
|
18348
18567
|
if (method === "concat")
|
|
@@ -18393,6 +18612,10 @@ class PromptResolver {
|
|
|
18393
18612
|
if (walk.seen.has(fn))
|
|
18394
18613
|
continue;
|
|
18395
18614
|
const name = functionName2(fn);
|
|
18615
|
+
if (walk.depth + 1 > this.maxDepth) {
|
|
18616
|
+
this.markUnresolved(call, "depth-limit", walk);
|
|
18617
|
+
continue;
|
|
18618
|
+
}
|
|
18396
18619
|
const next = this.step(walk, fn, `builder ${name ?? "function"} called at ${this.where(call)}`);
|
|
18397
18620
|
if (!next)
|
|
18398
18621
|
continue;
|
|
@@ -18499,6 +18722,8 @@ class PromptResolver {
|
|
|
18499
18722
|
return;
|
|
18500
18723
|
}
|
|
18501
18724
|
if (import_typescript8.default.isVariableDeclaration(declaration)) {
|
|
18725
|
+
if (/^\d+$/.test(next.project[0] ?? "") && this.assembly(declaration, ownerFor(declaration, name, owner), next, at, true))
|
|
18726
|
+
return;
|
|
18502
18727
|
if (!owner && next.flags.includes("interpolated") && declaration.initializer) {
|
|
18503
18728
|
let scope = declaration.parent;
|
|
18504
18729
|
while (scope && !import_typescript8.default.isFunctionLike(scope))
|
|
@@ -18572,12 +18797,12 @@ class PromptResolver {
|
|
|
18572
18797
|
if (fn)
|
|
18573
18798
|
this.builderBody(fn, { node: declaration, name, kind: "builder" }, next);
|
|
18574
18799
|
}
|
|
18575
|
-
assembly(declaration, owner, walk, at) {
|
|
18800
|
+
assembly(declaration, owner, walk, at, probe = false) {
|
|
18576
18801
|
if (!import_typescript8.default.isIdentifier(declaration.name))
|
|
18577
|
-
return;
|
|
18802
|
+
return false;
|
|
18578
18803
|
const scope = enclosingScope2(declaration);
|
|
18579
18804
|
if (!scope)
|
|
18580
|
-
return;
|
|
18805
|
+
return false;
|
|
18581
18806
|
const assignments = [];
|
|
18582
18807
|
const findRebinding = (node) => {
|
|
18583
18808
|
if (import_typescript8.default.isFunctionLike(node))
|
|
@@ -18623,7 +18848,7 @@ class PromptResolver {
|
|
|
18623
18848
|
return new Set;
|
|
18624
18849
|
const next = new Set(seen).add(value);
|
|
18625
18850
|
if (import_typescript8.default.isIdentifier(value)) {
|
|
18626
|
-
const entry = this.declarationsOf(value).find((item) => import_typescript8.default.isVariableDeclaration(item));
|
|
18851
|
+
const entry = this.declarationsOf(value).find((item) => import_typescript8.default.isVariableDeclaration(item) || import_typescript8.default.isParameter(item));
|
|
18627
18852
|
if (entry === declaration)
|
|
18628
18853
|
return versionsAt(value);
|
|
18629
18854
|
if (entry && import_typescript8.default.isVariableDeclaration(entry) && entry.initializer && entry.parent.flags & import_typescript8.default.NodeFlags.Const)
|
|
@@ -18734,15 +18959,24 @@ class PromptResolver {
|
|
|
18734
18959
|
});
|
|
18735
18960
|
};
|
|
18736
18961
|
const isThis = (identifier) => references(identifier);
|
|
18962
|
+
let indexedMutation = false;
|
|
18737
18963
|
const visit = (node) => {
|
|
18738
18964
|
if (import_typescript8.default.isFunctionLike(node) && !invoked(node))
|
|
18739
18965
|
return;
|
|
18740
18966
|
if (import_typescript8.default.isCallExpression(node) && import_typescript8.default.isPropertyAccessExpression(node.expression) && references(node.expression.expression) && /^(?:push|unshift|splice)$/.test(node.expression.name.text)) {
|
|
18967
|
+
if (/^\d+$/.test(walk.project[0] ?? "")) {
|
|
18968
|
+
indexedMutation = true;
|
|
18969
|
+
this.markUnresolved(node, "dynamic-key", walk);
|
|
18970
|
+
return;
|
|
18971
|
+
}
|
|
18972
|
+
if (probe)
|
|
18973
|
+
return;
|
|
18741
18974
|
const args = node.expression.name.text === "splice" ? node.arguments.slice(2) : node.arguments;
|
|
18975
|
+
const elementWalk = walk.project[0] === ARRAY_ELEMENT || walk.project[0] === FLATMAP_ELEMENT ? { ...walk, project: walk.project.slice(1) } : walk;
|
|
18742
18976
|
for (const argument of args)
|
|
18743
|
-
this.value(argument, owner,
|
|
18977
|
+
this.value(argument, owner, elementWalk);
|
|
18744
18978
|
}
|
|
18745
|
-
if (import_typescript8.default.isBinaryExpression(node) && import_typescript8.default.isIdentifier(node.left) && (isThis(node.left) || readVersions.has(node))) {
|
|
18979
|
+
if (!probe && import_typescript8.default.isBinaryExpression(node) && import_typescript8.default.isIdentifier(node.left) && (isThis(node.left) || readVersions.has(node))) {
|
|
18746
18980
|
if (node.operatorToken.kind === import_typescript8.default.SyntaxKind.PlusEqualsToken)
|
|
18747
18981
|
this.value(node.right, owner, walk);
|
|
18748
18982
|
if (node.operatorToken.kind === import_typescript8.default.SyntaxKind.EqualsToken && node.right !== declaration.initializer)
|
|
@@ -18751,11 +18985,52 @@ class PromptResolver {
|
|
|
18751
18985
|
import_typescript8.default.forEachChild(node, visit);
|
|
18752
18986
|
};
|
|
18753
18987
|
visit(scope);
|
|
18988
|
+
return indexedMutation;
|
|
18989
|
+
}
|
|
18990
|
+
parameterHasLocalWrites(parameter) {
|
|
18991
|
+
const cached = this.locallyWrittenParameters.get(parameter);
|
|
18992
|
+
if (cached !== undefined)
|
|
18993
|
+
return cached;
|
|
18994
|
+
let written = false;
|
|
18995
|
+
const name = import_typescript8.default.isIdentifier(parameter.name) ? parameter.name.text : undefined;
|
|
18996
|
+
const scope = enclosingScope2(parameter);
|
|
18997
|
+
const isParameter = (expression) => import_typescript8.default.isIdentifier(expression) && expression.text === name && this.declarationsOf(expression).includes(parameter);
|
|
18998
|
+
const visit = (node) => {
|
|
18999
|
+
if (written)
|
|
19000
|
+
return;
|
|
19001
|
+
if (import_typescript8.default.isBinaryExpression(node) && [import_typescript8.default.SyntaxKind.EqualsToken, import_typescript8.default.SyntaxKind.PlusEqualsToken].includes(node.operatorToken.kind)) {
|
|
19002
|
+
written = isParameter(node.left) || import_typescript8.default.isElementAccessExpression(node.left) && isParameter(node.left.expression);
|
|
19003
|
+
} else if (import_typescript8.default.isCallExpression(node) && import_typescript8.default.isPropertyAccessExpression(node.expression) && /^(?:push|unshift|splice)$/.test(node.expression.name.text)) {
|
|
19004
|
+
written = isParameter(node.expression.expression);
|
|
19005
|
+
}
|
|
19006
|
+
if (!written)
|
|
19007
|
+
import_typescript8.default.forEachChild(node, visit);
|
|
19008
|
+
};
|
|
19009
|
+
if (scope)
|
|
19010
|
+
visit(scope);
|
|
19011
|
+
this.locallyWrittenParameters.set(parameter, written);
|
|
19012
|
+
return written;
|
|
18754
19013
|
}
|
|
18755
19014
|
parameter(declaration, at, owner, walk) {
|
|
19015
|
+
if (import_typescript8.default.isParameter(declaration) && import_typescript8.default.isIdentifier(declaration.name) && !walk.seen.has(declaration) && this.parameterHasLocalWrites(declaration)) {
|
|
19016
|
+
const local = { ...walk, seen: new Set(walk.seen).add(declaration) };
|
|
19017
|
+
this.assembly(declaration, owner, local, at);
|
|
19018
|
+
}
|
|
18756
19019
|
const bound = walk.bindings.get(declaration);
|
|
18757
19020
|
if (bound) {
|
|
18758
|
-
|
|
19021
|
+
const project = [...bound.project ?? [], ...walk.project];
|
|
19022
|
+
if (bound.rest) {
|
|
19023
|
+
const each = project[0] === ARRAY_ELEMENT;
|
|
19024
|
+
const index2 = /^\d+$/.test(project[0] ?? "") ? Number(project[0]) : undefined;
|
|
19025
|
+
const values = index2 === undefined ? bound.rest : bound.rest.slice(index2, index2 + 1);
|
|
19026
|
+
for (const value of values)
|
|
19027
|
+
this.value(value, undefined, {
|
|
19028
|
+
...walk,
|
|
19029
|
+
bindings: bound.bindings,
|
|
19030
|
+
project: each || index2 !== undefined ? project.slice(1) : project
|
|
19031
|
+
});
|
|
19032
|
+
} else
|
|
19033
|
+
this.value(bound.expr, undefined, { ...walk, bindings: bound.bindings, project });
|
|
18759
19034
|
return;
|
|
18760
19035
|
}
|
|
18761
19036
|
const parameter = import_typescript8.default.isParameter(declaration) ? declaration : parameterOf(declaration);
|
|
@@ -18802,6 +19077,9 @@ class PromptResolver {
|
|
|
18802
19077
|
}
|
|
18803
19078
|
}
|
|
18804
19079
|
callersOf(fn) {
|
|
19080
|
+
const cached = this.resolvedCallers.get(fn);
|
|
19081
|
+
if (cached)
|
|
19082
|
+
return cached;
|
|
18805
19083
|
const name = functionName2(fn);
|
|
18806
19084
|
if (!name)
|
|
18807
19085
|
return [];
|
|
@@ -18809,12 +19087,14 @@ class PromptResolver {
|
|
|
18809
19087
|
const names = [name, ...this.aliasesByName.get(name) ?? []];
|
|
18810
19088
|
const candidates = names.flatMap((alias) => this.callersByName.get(alias) ?? []);
|
|
18811
19089
|
const signatures = this.implementedSignatures(fn, name);
|
|
18812
|
-
|
|
19090
|
+
const callers = candidates.filter((call) => {
|
|
18813
19091
|
const callee = import_typescript8.default.isPropertyAccessExpression(call.expression) ? call.expression.name : call.expression;
|
|
18814
19092
|
const checker = this.context.checkerFor(this.relative(call.getSourceFile().fileName));
|
|
18815
19093
|
const members = checker && import_typescript8.default.isPropertyAccessExpression(call.expression) ? receiverClasses(call.expression.expression, checker).flatMap((cls) => cls.members.filter((member) => member.name?.getText() === name)) : [];
|
|
18816
19094
|
return [...this.declarationsOf(callee), ...members].some((declaration) => functionOf(declaration) === fn || declaration === fn || signatures.has(declaration) && !!checker && contextualReceiverMatches(call, fn, checker));
|
|
18817
19095
|
});
|
|
19096
|
+
this.resolvedCallers.set(fn, callers);
|
|
19097
|
+
return callers;
|
|
18818
19098
|
}
|
|
18819
19099
|
implementedSignatures(fn, name) {
|
|
18820
19100
|
const checker = this.context.checkerFor(this.relative(fn.getSourceFile().fileName));
|
|
@@ -19116,6 +19396,8 @@ function contains(outer, inner) {
|
|
|
19116
19396
|
return inner.getStart() >= outer.getStart() && inner.getEnd() <= outer.getEnd();
|
|
19117
19397
|
}
|
|
19118
19398
|
function enclosingScope2(declaration) {
|
|
19399
|
+
if (import_typescript8.default.isParameter(declaration) && import_typescript8.default.isFunctionLike(declaration.parent) && "body" in declaration.parent)
|
|
19400
|
+
return declaration.parent.body;
|
|
19119
19401
|
for (let node = declaration.parent;node; node = node.parent) {
|
|
19120
19402
|
if (import_typescript8.default.isBlock(node) || import_typescript8.default.isSourceFile(node) || import_typescript8.default.isModuleBlock(node))
|
|
19121
19403
|
return node;
|
|
@@ -19141,6 +19423,10 @@ function bindingField(element) {
|
|
|
19141
19423
|
function bindParameters(fn, args, outer, into) {
|
|
19142
19424
|
fn.parameters.forEach((parameter, index) => {
|
|
19143
19425
|
const argument = args[index];
|
|
19426
|
+
if (parameter.dotDotDotToken && import_typescript8.default.isIdentifier(parameter.name)) {
|
|
19427
|
+
into.set(parameter, { expr: argument ?? parameter.name, bindings: outer, rest: args.slice(index) });
|
|
19428
|
+
return;
|
|
19429
|
+
}
|
|
19144
19430
|
if (!argument)
|
|
19145
19431
|
return;
|
|
19146
19432
|
if (import_typescript8.default.isIdentifier(parameter.name)) {
|
|
@@ -19279,7 +19565,7 @@ function unresolvedReports(resolution, sites) {
|
|
|
19279
19565
|
const resolvedSites = new Set(resolution.refs.flatMap((ref) => ref.callSiteIds.map((id) => `${id}|${ref.role}`)));
|
|
19280
19566
|
const reports = new Map;
|
|
19281
19567
|
for (const value of resolution.unresolved) {
|
|
19282
|
-
if (resolvedSites.has(`${value.callSiteId}|${value.role}`))
|
|
19568
|
+
if (value.reason !== "depth-limit" && resolvedSites.has(`${value.callSiteId}|${value.role}`))
|
|
19283
19569
|
continue;
|
|
19284
19570
|
const site = sites.get(value.callSiteId);
|
|
19285
19571
|
if (!site)
|
|
@@ -19484,7 +19770,7 @@ async function runHarnessCommand(context) {
|
|
|
19484
19770
|
report: {
|
|
19485
19771
|
reportId: report.reportId,
|
|
19486
19772
|
reportHash,
|
|
19487
|
-
path:
|
|
19773
|
+
path: normalizePath3(relative9(rootDir, reportPath)) || ".moda/harness-report.json"
|
|
19488
19774
|
},
|
|
19489
19775
|
validation,
|
|
19490
19776
|
approval: {
|
|
@@ -19630,7 +19916,7 @@ async function runHarnessCommand(context) {
|
|
|
19630
19916
|
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.");
|
|
19631
19917
|
}
|
|
19632
19918
|
if (context.flags["github-actions"] === "true") {
|
|
19633
|
-
const { runGithubActionsAnalyze } = await import("./harness-github-actions-
|
|
19919
|
+
const { runGithubActionsAnalyze } = await import("./harness-github-actions-x2jgh0e8.js");
|
|
19634
19920
|
const result = await runGithubActionsAnalyze(rootDir, {
|
|
19635
19921
|
writeReport: (report2) => {
|
|
19636
19922
|
const normalized = normalizeHarnessReport(report2);
|
|
@@ -19757,7 +20043,7 @@ async function runHarnessCommand(context) {
|
|
|
19757
20043
|
report: {
|
|
19758
20044
|
reportId: approval.report.reportId,
|
|
19759
20045
|
reportHash: hashHarnessReport(approval.report),
|
|
19760
|
-
path:
|
|
20046
|
+
path: normalizePath3(relative9(rootDir, reportPath)) || ".moda/harness-report.json"
|
|
19761
20047
|
},
|
|
19762
20048
|
validation: approval.validation,
|
|
19763
20049
|
approval: approval.approval
|
|
@@ -19779,17 +20065,17 @@ async function runHarnessCommand(context) {
|
|
|
19779
20065
|
if (promoteOut === "true") {
|
|
19780
20066
|
throw new CliInputError("Missing output path for --out.", "Usage: moda harness candidates --promote=<concern|all> --out=<file>");
|
|
19781
20067
|
}
|
|
19782
|
-
const { artifacts, unknowns } = deterministicGraphItems(rootDir, promote === "all" ? undefined : promote);
|
|
20068
|
+
const { artifacts, unknowns, canonicalAgentIdentities } = deterministicGraphItems(rootDir, promote === "all" ? undefined : promote);
|
|
19783
20069
|
tagComponentStatus({ runtimeAgents: [], artifacts }, rootDir);
|
|
19784
|
-
const { extractHarnessWithContext: extractHarnessWithContext2 } = await import("./index-
|
|
19785
|
-
const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-
|
|
20070
|
+
const { extractHarnessWithContext: extractHarnessWithContext2 } = await import("./index-h9r08433.js");
|
|
20071
|
+
const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-69xwrmrh.js");
|
|
19786
20072
|
let components = { runtimeAgents: [], artifacts: [], warnings: [] };
|
|
19787
20073
|
if (promote === "all" || promote === "topology" || promote === "tools") {
|
|
19788
20074
|
const { result, ctx } = extractHarnessWithContext2(rootDir);
|
|
19789
20075
|
const found = enumerateHarnessComponents(result, ctx);
|
|
19790
20076
|
components = promote === "tools" ? { ...found, artifacts: found.artifacts.filter((entry) => entry.type === "tool") } : promote === "topology" ? { ...found, artifacts: found.artifacts.filter((entry) => entry.type !== "tool") } : found;
|
|
19791
20077
|
}
|
|
19792
|
-
const promoted = { concern: promote, unknowns, ...mergeEnumeratedComponents(artifacts, components) };
|
|
20078
|
+
const promoted = { concern: promote, unknowns, canonicalAgentIdentities, ...mergeEnumeratedComponents(artifacts, components) };
|
|
19793
20079
|
const promoteWritten = [];
|
|
19794
20080
|
if (promoteOut && !context.dryRun) {
|
|
19795
20081
|
const target = resolve9(context.cwd, promoteOut);
|
|
@@ -19816,12 +20102,16 @@ async function runHarnessCommand(context) {
|
|
|
19816
20102
|
}
|
|
19817
20103
|
case "extract": {
|
|
19818
20104
|
writeHumanProgress(context, "Harness extract: tracing model call sites (no LLM, no network)...");
|
|
19819
|
-
const { extractHarnessWithContext: extractHarnessWithContext2, serializeExtractResult } = await import("./index-
|
|
19820
|
-
const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-
|
|
20105
|
+
const { extractHarnessWithContext: extractHarnessWithContext2, serializeExtractResult } = await import("./index-h9r08433.js");
|
|
20106
|
+
const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-69xwrmrh.js");
|
|
19821
20107
|
const { result, ctx } = extractHarnessWithContext2(rootDir, { fresh: true });
|
|
19822
|
-
const
|
|
20108
|
+
const items = deterministicGraphItems(rootDir);
|
|
20109
|
+
const artifacts = items.artifacts;
|
|
19823
20110
|
tagComponentStatus({ runtimeAgents: [], artifacts }, rootDir);
|
|
19824
|
-
const graph =
|
|
20111
|
+
const graph = {
|
|
20112
|
+
...mergeEnumeratedComponents(artifacts, enumerateHarnessComponents(result, ctx)),
|
|
20113
|
+
unknowns: items.unknowns.filter((item) => item.id.startsWith("unresolved_prompt_depth_"))
|
|
20114
|
+
};
|
|
19825
20115
|
writeHumanProgress(context, `Harness extract: ${result.callSites.length} call sites, ${result.roles.length} traced roles across ${result.files} files (${result.programs} programs, ${result.durationMs.toLocaleString()} ms).`);
|
|
19826
20116
|
context.output.writeData({ ...serializeExtractResult(result), graph }, {
|
|
19827
20117
|
status: result.warnings.length > 0 ? "degraded" : "success",
|
|
@@ -20379,7 +20669,7 @@ function modelIdsUsedInSource(rootDir, ids) {
|
|
|
20379
20669
|
const walk = (current) => {
|
|
20380
20670
|
if (pending.size === 0)
|
|
20381
20671
|
return false;
|
|
20382
|
-
const rel2 =
|
|
20672
|
+
const rel2 = normalizePath3(relative9(rootReal, current)) || ".";
|
|
20383
20673
|
let stat;
|
|
20384
20674
|
try {
|
|
20385
20675
|
stat = lstatSync7(current);
|
|
@@ -20463,9 +20753,9 @@ function mergeDeterministicReplacement(report, rootDir, options) {
|
|
|
20463
20753
|
mergeDeterministicArtifacts(report.graph, rootDir, options);
|
|
20464
20754
|
const replacements = new Map;
|
|
20465
20755
|
for (const artifact of old) {
|
|
20466
|
-
const
|
|
20467
|
-
const exact = report.graph.artifacts.filter((candidate) => candidate.type === artifact.type && artifactPaths(candidate).some((path) =>
|
|
20468
|
-
const matches = exact.length ? exact : report.graph.artifacts.filter((candidate) => candidate.type === artifact.type && candidate.type === "eval" && artifactPaths(candidate).some((path) =>
|
|
20756
|
+
const paths2 = artifactPaths(artifact);
|
|
20757
|
+
const exact = report.graph.artifacts.filter((candidate) => candidate.type === artifact.type && artifactPaths(candidate).some((path) => paths2.includes(path)));
|
|
20758
|
+
const matches = exact.length ? exact : report.graph.artifacts.filter((candidate) => candidate.type === artifact.type && candidate.type === "eval" && artifactPaths(candidate).some((path) => paths2.some((source) => evalSuiteKey(source) !== undefined && evalSuiteKey(source) === evalSuiteKey(path))));
|
|
20469
20759
|
replacements.set(artifact.id, matches);
|
|
20470
20760
|
const owners = new Set([...artifact.usedByAgentIds ?? [], ...artifact.ownedByAgentId ? [artifact.ownedByAgentId] : []]);
|
|
20471
20761
|
for (const link of agentLinks)
|
|
@@ -20537,6 +20827,7 @@ function repairExternalAnalystReport(report, rootDir, options = {}) {
|
|
|
20537
20827
|
mergeDeterministicReplacement(normalized, rootDir, options);
|
|
20538
20828
|
if (!options.concern || options.concern === "topology")
|
|
20539
20829
|
mergeBoundRuntimeClasses(normalized.graph, rootDir);
|
|
20830
|
+
remapCanonicalArtifactAgents(normalized.graph, normalized.graph.artifacts, !options.concern);
|
|
20540
20831
|
tagComponentStatus(normalized.graph, rootDir);
|
|
20541
20832
|
hydratePromptAndToolBodies(normalized.graph, rootDir);
|
|
20542
20833
|
const unverified = new Set;
|
|
@@ -20570,8 +20861,8 @@ function repairExternalAnalystReport(report, rootDir, options = {}) {
|
|
|
20570
20861
|
const testOnlyModels = normalized.graph.artifacts.filter((artifact) => {
|
|
20571
20862
|
if (artifact.type !== "model_config" || unverified.has(artifact.id))
|
|
20572
20863
|
return false;
|
|
20573
|
-
const
|
|
20574
|
-
return
|
|
20864
|
+
const paths2 = artifact.evidence.map((entry) => entry.path).filter((path) => typeof path === "string" && path.length > 0);
|
|
20865
|
+
return paths2.length > 0 && paths2.every((path) => TEST_PATH3.test(path));
|
|
20575
20866
|
});
|
|
20576
20867
|
const usedInSource = testOnlyModels.length > 0 ? modelIdsUsedInSource(rootDir, testOnlyModels.map((artifact) => (artifact.name ?? "").trim())) : new Set;
|
|
20577
20868
|
for (const artifact of testOnlyModels) {
|
|
@@ -20601,6 +20892,29 @@ function repairExternalAnalystReport(report, rootDir, options = {}) {
|
|
|
20601
20892
|
if (unverified.size > 0)
|
|
20602
20893
|
removeArtifacts(normalized, unverified);
|
|
20603
20894
|
deriveRelationshipsFromGraph(normalized.graph);
|
|
20895
|
+
if (!options.concern) {
|
|
20896
|
+
const knownAgents = new Set(normalized.graph.runtimeAgents.map((agent) => agent.id));
|
|
20897
|
+
for (const artifact of normalized.graph.artifacts) {
|
|
20898
|
+
if (artifact.type !== "tool" || !["in_prod", "reachable"].includes(artifact.status ?? ""))
|
|
20899
|
+
continue;
|
|
20900
|
+
const owners = [
|
|
20901
|
+
...artifact.usedByAgentIds ?? [],
|
|
20902
|
+
...artifact.ownedByAgentId ? [artifact.ownedByAgentId] : [],
|
|
20903
|
+
...normalized.graph.runtimeAgents.filter((agent) => agent.artifactIds?.includes(artifact.id)).map((agent) => agent.id),
|
|
20904
|
+
...normalized.graph.relationships.filter((edge) => edge.to === artifact.id && ["uses_artifact", "owns_artifact"].includes(edge.type)).map((edge) => edge.from)
|
|
20905
|
+
];
|
|
20906
|
+
if (owners.some((owner) => knownAgents.has(owner)))
|
|
20907
|
+
continue;
|
|
20908
|
+
const id = `unresolved_tool_owner_${createHash7("sha256").update(artifact.id).digest("hex").slice(0, 16)}`;
|
|
20909
|
+
if (!normalized.graph.unknowns.some((unknown) => unknown.id === id))
|
|
20910
|
+
normalized.graph.unknowns.push({
|
|
20911
|
+
id,
|
|
20912
|
+
question: `Tool ${artifact.name} has a source definition but no source-proven owner in the hosted topology; trace evidence is required to resolve its agent.`,
|
|
20913
|
+
candidateIds: [artifact.id],
|
|
20914
|
+
evidence: artifact.evidence
|
|
20915
|
+
});
|
|
20916
|
+
}
|
|
20917
|
+
}
|
|
20604
20918
|
dropUnlocatedAgentCitations(normalized);
|
|
20605
20919
|
if ((normalized.claims?.length ?? 0) === 0 && deterministicOnlyArtifactTypes().has("eval")) {
|
|
20606
20920
|
const grounded = createHarnessReport({ graph: {
|
|
@@ -20696,8 +21010,8 @@ var CONCERN_PROMOTED_ARTIFACT_TYPES = {
|
|
|
20696
21010
|
evals: new Set(["model_config", "eval"])
|
|
20697
21011
|
};
|
|
20698
21012
|
async function deterministicFloorGraph(rootDir, options = {}) {
|
|
20699
|
-
const { extractHarnessWithContext: extractHarnessWithContext2 } = await import("./index-
|
|
20700
|
-
const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-
|
|
21013
|
+
const { extractHarnessWithContext: extractHarnessWithContext2 } = await import("./index-h9r08433.js");
|
|
21014
|
+
const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-69xwrmrh.js");
|
|
20701
21015
|
const { result, ctx } = extractHarnessWithContext2(rootDir);
|
|
20702
21016
|
const items = deterministicGraphItems(rootDir);
|
|
20703
21017
|
const components = mergeEnumeratedComponents(items.artifacts, enumerateHarnessComponents(result, ctx));
|
|
@@ -20726,7 +21040,7 @@ function deterministicGraphItems(rootDir, concern) {
|
|
|
20726
21040
|
const graph = { artifacts: [], unknowns: [] };
|
|
20727
21041
|
mergeDeterministicArtifacts(graph, rootDir, { concern });
|
|
20728
21042
|
hydratePromptAndToolBodies(graph, rootDir);
|
|
20729
|
-
return { artifacts: graph.artifacts, unknowns: graph.unknowns };
|
|
21043
|
+
return { artifacts: graph.artifacts, unknowns: graph.unknowns, canonicalAgentIdentities: graph.scan?.canonicalAgentIdentities ?? [] };
|
|
20730
21044
|
}
|
|
20731
21045
|
var extractedModelsCache = new WeakMap;
|
|
20732
21046
|
function extractedModelItems(rootDir) {
|
|
@@ -20845,7 +21159,7 @@ function mergeDeterministicArtifacts(graph, rootDir, options = {}) {
|
|
|
20845
21159
|
try {
|
|
20846
21160
|
promoted = promoteHarnessCandidates(detectHarnessCandidates(rootDir), rootDir, { fullEvidence: true });
|
|
20847
21161
|
if (!allowedTypes || allowedTypes.has("prompt"))
|
|
20848
|
-
promoted = withCallSitePrompts(rootDir, promoted);
|
|
21162
|
+
promoted = withCallSitePrompts(rootDir, promoted, graph.unknowns ??= []);
|
|
20849
21163
|
} catch {
|
|
20850
21164
|
promoted = [];
|
|
20851
21165
|
}
|
|
@@ -20861,9 +21175,16 @@ function mergeDeterministicArtifacts(graph, rootDir, options = {}) {
|
|
|
20861
21175
|
} catch {}
|
|
20862
21176
|
}
|
|
20863
21177
|
const extractedIds = new Set(extracted.artifacts.map((artifact) => artifact.id));
|
|
21178
|
+
try {
|
|
21179
|
+
const { result, ctx } = extractHarnessWithContext(rootDir);
|
|
21180
|
+
const identities = harnessAgentIdentities(enumerateAgents(result, ctx).runtimeAgents);
|
|
21181
|
+
graph.scan ??= {};
|
|
21182
|
+
graph.scan.canonicalAgentIdentities = identities;
|
|
21183
|
+
remapCanonicalArtifactAgents(graph, promoted);
|
|
21184
|
+
} catch {}
|
|
20864
21185
|
backfillRefutationEvidenceReasons(graph);
|
|
20865
21186
|
const refuted = analystRefutations(graph);
|
|
20866
|
-
const candidatePaths = new Set(promoted.flatMap((artifact) => artifact.evidence.map((entry) => typeof entry.path === "string" ?
|
|
21187
|
+
const candidatePaths = new Set(promoted.flatMap((artifact) => artifact.evidence.map((entry) => typeof entry.path === "string" ? normalizePath3(entry.path) : "").filter(Boolean)));
|
|
20867
21188
|
const modelLineCounts = new Map;
|
|
20868
21189
|
for (const artifact of promoted) {
|
|
20869
21190
|
if (artifact.type !== "model_config")
|
|
@@ -20888,6 +21209,26 @@ function mergeDeterministicArtifacts(graph, rootDir, options = {}) {
|
|
|
20888
21209
|
added += 1;
|
|
20889
21210
|
continue;
|
|
20890
21211
|
}
|
|
21212
|
+
if (artifact.type === "prompt" && artifact.usedByAgentIds.length > 0) {
|
|
21213
|
+
const existing = graph.artifacts.find((candidate) => candidate.type === "prompt" && candidate.id === artifact.id);
|
|
21214
|
+
if (existing && !isRefutedByAnalyst(artifact, refuted, candidatePaths)) {
|
|
21215
|
+
const definition = artifact.evidence[0];
|
|
21216
|
+
const stored = existing.evidence?.[0];
|
|
21217
|
+
if (definition && (!stored || stored.path === definition.path && stored.line === definition.line)) {
|
|
21218
|
+
existing.usedByAgentIds = [...new Set([...existing.usedByAgentIds ?? [], ...artifact.usedByAgentIds])];
|
|
21219
|
+
if (Array.isArray(existing.staticUsedByAgentIds))
|
|
21220
|
+
existing.staticUsedByAgentIds = [...new Set([...existing.staticUsedByAgentIds, ...artifact.usedByAgentIds])];
|
|
21221
|
+
if (existing.usedByAgentIds.length > 1)
|
|
21222
|
+
existing.scope = "shared";
|
|
21223
|
+
existing.evidence ??= [];
|
|
21224
|
+
for (const entry of artifact.evidence) {
|
|
21225
|
+
if (!existing.evidence.some((known) => known.path === entry.path && known.line === entry.line && known.reason === entry.reason))
|
|
21226
|
+
existing.evidence.push(entry);
|
|
21227
|
+
}
|
|
21228
|
+
continue;
|
|
21229
|
+
}
|
|
21230
|
+
}
|
|
21231
|
+
}
|
|
20891
21232
|
if (graphCoversPromotedArtifact(graph, artifact, sharedModelLines))
|
|
20892
21233
|
continue;
|
|
20893
21234
|
if ((artifact.type === "model_config" || artifact.type === "eval") && artifact.evidence.length > 1 && !refuted.candidateIds.has(artifact.id)) {
|
|
@@ -20915,14 +21256,76 @@ function mergeDeterministicArtifacts(graph, rootDir, options = {}) {
|
|
|
20915
21256
|
}
|
|
20916
21257
|
return { added };
|
|
20917
21258
|
}
|
|
20918
|
-
function
|
|
21259
|
+
function remapCanonicalArtifactAgents(graph, artifacts = graph.artifacts, dropUnmapped = false) {
|
|
21260
|
+
const identities = harnessAgentIdentities(graph.scan?.canonicalAgentIdentities);
|
|
21261
|
+
const mapping = matchHarnessAgentIds(identities, graph.runtimeAgents ?? []);
|
|
21262
|
+
const canonical = new Map(identities.map((identity2) => [identity2.id, identity2]));
|
|
21263
|
+
const unresolved = new Map;
|
|
21264
|
+
const translate = (id, artifactId) => {
|
|
21265
|
+
const mapped = mapping.get(id);
|
|
21266
|
+
if (mapped || !dropUnmapped || !canonical.has(id))
|
|
21267
|
+
return mapped ?? id;
|
|
21268
|
+
const affected = unresolved.get(id) ?? [];
|
|
21269
|
+
if (!affected.includes(artifactId))
|
|
21270
|
+
affected.push(artifactId);
|
|
21271
|
+
unresolved.set(id, affected);
|
|
21272
|
+
return;
|
|
21273
|
+
};
|
|
21274
|
+
for (const artifact of artifacts) {
|
|
21275
|
+
artifact.usedByAgentIds = [...new Set((artifact.usedByAgentIds ?? []).flatMap((id) => translate(id, artifact.id) ?? []))];
|
|
21276
|
+
for (const field of ["staticUsedByAgentIds", "traceUsedByAgentIds"]) {
|
|
21277
|
+
if (Array.isArray(artifact[field]))
|
|
21278
|
+
artifact[field] = [...new Set(artifact[field].flatMap((id) => translate(id, artifact.id) ?? []))];
|
|
21279
|
+
}
|
|
21280
|
+
if (artifact.ownedByAgentId) {
|
|
21281
|
+
const owner = translate(artifact.ownedByAgentId, artifact.id);
|
|
21282
|
+
if (owner)
|
|
21283
|
+
artifact.ownedByAgentId = owner;
|
|
21284
|
+
else {
|
|
21285
|
+
delete artifact.ownedByAgentId;
|
|
21286
|
+
artifact.scope = "shared";
|
|
21287
|
+
}
|
|
21288
|
+
}
|
|
21289
|
+
}
|
|
21290
|
+
for (const [agentId, artifactIds] of unresolved) {
|
|
21291
|
+
const identity2 = canonical.get(agentId);
|
|
21292
|
+
const id = `unresolved_agent_links_${createHash7("sha256").update(agentId).digest("hex").slice(0, 16)}`;
|
|
21293
|
+
if (graph.unknowns.some((unknown) => unknown.id === id))
|
|
21294
|
+
continue;
|
|
21295
|
+
graph.unknowns.push({
|
|
21296
|
+
id,
|
|
21297
|
+
question: `Ownership for ${identity2.name} could not be matched uniquely to the hosted topology; its unresolved artifact links were omitted.`,
|
|
21298
|
+
candidateIds: artifactIds,
|
|
21299
|
+
evidence: (identity2.evidence ?? []).flatMap((entry) => entry.path ? [{ path: entry.path, ...entry.line !== undefined ? { line: entry.line } : {}, reason: entry.reason ?? "Extractor agent identity" }] : [])
|
|
21300
|
+
});
|
|
21301
|
+
}
|
|
21302
|
+
}
|
|
21303
|
+
function withCallSitePrompts(rootDir, promoted, unknowns = []) {
|
|
20919
21304
|
if (process.env.MODA_HARNESS_CALLSITE_PROMPTS === "0")
|
|
20920
21305
|
return promoted;
|
|
20921
21306
|
try {
|
|
20922
21307
|
const { result, ctx } = extractHarnessWithContext(rootDir);
|
|
20923
21308
|
const sites = result.callSites.filter((site) => !site.isTest);
|
|
20924
21309
|
const toolDefinitions = result.toolDefinitions ?? [];
|
|
20925
|
-
|
|
21310
|
+
const assembled = promptArtifactsFromCallSites(sites, ctx, promoted, { toolDefinitions, agentForScope: createAgentScopeResolver(result, ctx) });
|
|
21311
|
+
for (const report of assembled.unresolved) {
|
|
21312
|
+
const limited = report.values.filter((value) => value.reason === "depth-limit");
|
|
21313
|
+
if (!limited.length)
|
|
21314
|
+
continue;
|
|
21315
|
+
const id = stableId("unresolved_prompt_depth", `${report.callSiteId}:${report.role}`);
|
|
21316
|
+
if (unknowns.some((unknown) => unknown.id === id))
|
|
21317
|
+
continue;
|
|
21318
|
+
unknowns.push({
|
|
21319
|
+
id,
|
|
21320
|
+
question: `trace depth limit: ${report.role} prompt at ${report.path}:${report.line} has unresolved source paths.`,
|
|
21321
|
+
candidateIds: [],
|
|
21322
|
+
evidence: [
|
|
21323
|
+
{ path: report.path, line: report.line, reason: "trace depth limit at model call site" },
|
|
21324
|
+
...limited.map((value) => ({ path: value.path, line: value.line, reason: `trace depth limit: ${value.expression}` }))
|
|
21325
|
+
]
|
|
21326
|
+
});
|
|
21327
|
+
}
|
|
21328
|
+
return assembled.artifacts;
|
|
20926
21329
|
} catch {
|
|
20927
21330
|
return promoted;
|
|
20928
21331
|
}
|
|
@@ -20985,11 +21388,11 @@ function analystRefutations(graph) {
|
|
|
20985
21388
|
if (typeof entry?.path !== "string" || !entry.path)
|
|
20986
21389
|
continue;
|
|
20987
21390
|
const line = typeof entry.line === "number" ? entry.line : undefined;
|
|
20988
|
-
result.locations.push({ path:
|
|
21391
|
+
result.locations.push({ path: normalizePath3(entry.path), start: line, end: line, types: refutedTypes(entry.reason, question) });
|
|
20989
21392
|
}
|
|
20990
21393
|
for (const match of question.matchAll(/([\w./-]+\.[a-z0-9]{1,5})(?::|\s+(?:lines?\s+)?)(\d+)(?:\s*[-\u2013]\s*(\d+))?/gi)) {
|
|
20991
21394
|
const start = Number(match[2]);
|
|
20992
|
-
result.locations.push({ path:
|
|
21395
|
+
result.locations.push({ path: normalizePath3(match[1]), start, end: match[3] ? Number(match[3]) : start, types: refutedTypes(question) });
|
|
20993
21396
|
}
|
|
20994
21397
|
}
|
|
20995
21398
|
return result;
|
|
@@ -21008,7 +21411,7 @@ function isRefutedByAnalyst(artifact, refuted, candidatePaths) {
|
|
|
21008
21411
|
return artifact.evidence.some((entry) => {
|
|
21009
21412
|
if (typeof entry.path !== "string")
|
|
21010
21413
|
return false;
|
|
21011
|
-
const path =
|
|
21414
|
+
const path = normalizePath3(entry.path);
|
|
21012
21415
|
return refuted.locations.some((location) => {
|
|
21013
21416
|
if (location.types && !location.types.has(artifact.type))
|
|
21014
21417
|
return false;
|
|
@@ -21024,9 +21427,9 @@ function isRefutedByAnalyst(artifact, refuted, candidatePaths) {
|
|
|
21024
21427
|
}
|
|
21025
21428
|
function artifactSourceKey(artifact) {
|
|
21026
21429
|
if (artifact.sourcePath)
|
|
21027
|
-
return
|
|
21430
|
+
return normalizePath3(artifact.sourcePath);
|
|
21028
21431
|
const pinned = Array.isArray(artifact.evidence) ? artifact.evidence.find((entry) => typeof entry.path === "string" && entry.path.length > 0) : undefined;
|
|
21029
|
-
return pinned ?
|
|
21432
|
+
return pinned ? normalizePath3(pinned.path) : undefined;
|
|
21030
21433
|
}
|
|
21031
21434
|
function mentionsModelId(text, id) {
|
|
21032
21435
|
if (!id)
|
|
@@ -21035,8 +21438,8 @@ function mentionsModelId(text, id) {
|
|
|
21035
21438
|
return new RegExp(`(?<![\\w./@-])${escaped}(?![\\w/-]|\\.\\w)`, "i").test(text);
|
|
21036
21439
|
}
|
|
21037
21440
|
function artifactPaths(artifact) {
|
|
21038
|
-
const
|
|
21039
|
-
return artifact.sourcePath ? [
|
|
21441
|
+
const paths2 = Array.isArray(artifact.evidence) ? artifact.evidence.map((entry) => typeof entry.path === "string" ? normalizePath3(entry.path) : "").filter(Boolean) : [];
|
|
21442
|
+
return artifact.sourcePath ? [normalizePath3(artifact.sourcePath), ...paths2] : paths2;
|
|
21040
21443
|
}
|
|
21041
21444
|
function graphCoversPromotedArtifact(graph, promoted, sharedModelLines = new Set) {
|
|
21042
21445
|
if (promoted.type === "model_config" && graph.artifacts.some((existing) => existing.type === "model_config" && mentionsModelId(`${existing.name ?? ""}
|
|
@@ -21044,7 +21447,7 @@ ${existing.body ?? ""}`, promoted.name)))
|
|
|
21044
21447
|
return true;
|
|
21045
21448
|
if (promoted.type === "eval") {
|
|
21046
21449
|
const suite = new Set(artifactPaths(promoted));
|
|
21047
|
-
const suiteKey = promoted.sourcePath ? evalSuiteKey(
|
|
21450
|
+
const suiteKey = promoted.sourcePath ? evalSuiteKey(normalizePath3(promoted.sourcePath)) : undefined;
|
|
21048
21451
|
if (graph.artifacts.some((existing) => existing.type === "eval" && artifactPaths(existing).some((path) => suite.has(path) || suiteKey !== undefined && evalSuiteKey(path.replace(/\/+$/, "")) === suiteKey)))
|
|
21049
21452
|
return true;
|
|
21050
21453
|
}
|
|
@@ -22042,15 +22445,15 @@ function renderExternalAnalystProtocol(concern) {
|
|
|
22042
22445
|
function renderAnalystPreflightSection(rootDir) {
|
|
22043
22446
|
if (process.env.MODA_HARNESS_ANALYST_PREFLIGHT === "0")
|
|
22044
22447
|
return "";
|
|
22045
|
-
const
|
|
22046
|
-
if (
|
|
22448
|
+
const paths2 = listAnalystPreflightPaths(rootDir);
|
|
22449
|
+
if (paths2.length === 0)
|
|
22047
22450
|
return "";
|
|
22048
22451
|
const groups = {
|
|
22049
|
-
manifests:
|
|
22050
|
-
docs:
|
|
22051
|
-
source:
|
|
22052
|
-
deploy:
|
|
22053
|
-
evals:
|
|
22452
|
+
manifests: paths2.filter((path) => isManifestLikePath(path)).slice(0, 60),
|
|
22453
|
+
docs: paths2.filter((path) => isDocLikePath(path)).slice(0, 40),
|
|
22454
|
+
source: paths2.filter((path) => isAgentNavigationPath(path)).slice(0, 160),
|
|
22455
|
+
deploy: paths2.filter((path) => isPreflightDeployLikePath(path)).slice(0, 50),
|
|
22456
|
+
evals: paths2.filter((path) => isPreflightEvalLikePath(path)).slice(0, 50)
|
|
22054
22457
|
};
|
|
22055
22458
|
const lines = [
|
|
22056
22459
|
"",
|
|
@@ -22065,10 +22468,10 @@ function renderAnalystPreflightSection(rootDir) {
|
|
|
22065
22468
|
return lines.join(`
|
|
22066
22469
|
`);
|
|
22067
22470
|
}
|
|
22068
|
-
function renderPreflightGroup(label,
|
|
22069
|
-
if (
|
|
22471
|
+
function renderPreflightGroup(label, paths2) {
|
|
22472
|
+
if (paths2.length === 0)
|
|
22070
22473
|
return [];
|
|
22071
|
-
return [`${label}:`, ...
|
|
22474
|
+
return [`${label}:`, ...paths2.map((path) => `- ${path}`)];
|
|
22072
22475
|
}
|
|
22073
22476
|
var MAX_SEED_ARTIFACT_LINES = 150;
|
|
22074
22477
|
function renderAnalystSeedSection(rootDir, concern) {
|
|
@@ -22172,8 +22575,8 @@ function renderAnalystSeedLines(graph) {
|
|
|
22172
22575
|
}
|
|
22173
22576
|
function listAnalystPreflightPaths(rootDir) {
|
|
22174
22577
|
const gitPaths = readGitTrackedPaths(rootDir);
|
|
22175
|
-
const
|
|
22176
|
-
return [...new Set(
|
|
22578
|
+
const paths2 = gitPaths.length > 0 ? gitPaths : readDirectoryPreflightPaths(rootDir);
|
|
22579
|
+
return [...new Set(paths2.map(normalizePath3))].filter((path) => path && !shouldSkipPreflightPath(path)).sort();
|
|
22177
22580
|
}
|
|
22178
22581
|
function readGitTrackedPaths(rootDir) {
|
|
22179
22582
|
try {
|
|
@@ -22187,9 +22590,9 @@ function readGitTrackedPaths(rootDir) {
|
|
|
22187
22590
|
}
|
|
22188
22591
|
}
|
|
22189
22592
|
function readDirectoryPreflightPaths(rootDir) {
|
|
22190
|
-
const
|
|
22593
|
+
const paths2 = [];
|
|
22191
22594
|
const stack = ["."];
|
|
22192
|
-
while (stack.length > 0 &&
|
|
22595
|
+
while (stack.length > 0 && paths2.length < 2000) {
|
|
22193
22596
|
const current = stack.pop() ?? ".";
|
|
22194
22597
|
const absolute = current === "." ? rootDir : join11(rootDir, current);
|
|
22195
22598
|
let entries;
|
|
@@ -22214,14 +22617,14 @@ function readDirectoryPreflightPaths(rootDir) {
|
|
|
22214
22617
|
if (stat.isDirectory()) {
|
|
22215
22618
|
stack.push(child);
|
|
22216
22619
|
} else {
|
|
22217
|
-
|
|
22620
|
+
paths2.push(child);
|
|
22218
22621
|
}
|
|
22219
22622
|
}
|
|
22220
22623
|
}
|
|
22221
|
-
return
|
|
22624
|
+
return paths2;
|
|
22222
22625
|
}
|
|
22223
22626
|
function shouldSkipPreflightPath(path) {
|
|
22224
|
-
const normalized =
|
|
22627
|
+
const normalized = normalizePath3(path);
|
|
22225
22628
|
if (!normalized || normalized.startsWith(".moda/"))
|
|
22226
22629
|
return true;
|
|
22227
22630
|
const parts = normalized.split("/");
|
|
@@ -22346,7 +22749,7 @@ function collectSnapshotInputs(rootDir, maxFiles, maxTextBytes) {
|
|
|
22346
22749
|
let inventoryFileCount = 0;
|
|
22347
22750
|
let inventoryTextBytes = 0;
|
|
22348
22751
|
function walk(current) {
|
|
22349
|
-
const path =
|
|
22752
|
+
const path = normalizePath3(relative9(rootDir, current)) || ".";
|
|
22350
22753
|
let stat;
|
|
22351
22754
|
try {
|
|
22352
22755
|
stat = lstatSync7(current);
|
|
@@ -22417,7 +22820,7 @@ function buildSourceSnapshot(rootDir) {
|
|
|
22417
22820
|
}
|
|
22418
22821
|
function buildCommandScanPlan(context, rootDir) {
|
|
22419
22822
|
const explicitPath = context.flags.path !== undefined;
|
|
22420
|
-
const rel2 =
|
|
22823
|
+
const rel2 = normalizePath3(relative9(context.cwd, rootDir)) || ".";
|
|
22421
22824
|
const scope = explicitPath && rel2 !== "." ? "narrow" : "broad";
|
|
22422
22825
|
const machineReadable = context.outputMode !== "human";
|
|
22423
22826
|
const approvalRequired = context.positional === "analyze" && scope === "broad" && !context.yes;
|
|
@@ -22502,7 +22905,7 @@ function writeHumanBlock(context, message) {
|
|
|
22502
22905
|
function buildHarnessReadPlan(rootDir, pathWasExplicit) {
|
|
22503
22906
|
return {
|
|
22504
22907
|
scope: pathWasExplicit ? "narrow" : "broad",
|
|
22505
|
-
rootPaths: [
|
|
22908
|
+
rootPaths: [normalizePath3(relative9(rootDir, rootDir)) || "."],
|
|
22506
22909
|
willRead: [
|
|
22507
22910
|
"package manifests",
|
|
22508
22911
|
"source files under the selected path",
|
|
@@ -22715,7 +23118,7 @@ function findFresherHarnessReports(rootDir) {
|
|
|
22715
23118
|
const candidate = lstatSync7(join11(child, HARNESS_REPORT_PATH));
|
|
22716
23119
|
if (candidate.isFile() && candidate.mtimeMs > rootMtimeMs) {
|
|
22717
23120
|
fresher.push({
|
|
22718
|
-
path:
|
|
23121
|
+
path: normalizePath3(relative9(rootDir, join11(child, HARNESS_REPORT_PATH))),
|
|
22719
23122
|
mtimeMs: candidate.mtimeMs
|
|
22720
23123
|
});
|
|
22721
23124
|
}
|
|
@@ -22727,8 +23130,8 @@ function findFresherHarnessReports(rootDir) {
|
|
|
22727
23130
|
return fresher.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
22728
23131
|
}
|
|
22729
23132
|
function warnFresherSubdirHarnessReports(context, rootDir, explicitReport) {
|
|
22730
|
-
const explicitReportPath = explicitReport && explicitReport !== "true" ?
|
|
22731
|
-
if (explicitReportPath && explicitReportPath !==
|
|
23133
|
+
const explicitReportPath = explicitReport && explicitReport !== "true" ? normalizePath3(relative9(rootDir, resolve9(rootDir, explicitReport))) : undefined;
|
|
23134
|
+
if (explicitReportPath && explicitReportPath !== normalizePath3(HARNESS_REPORT_PATH))
|
|
22732
23135
|
return;
|
|
22733
23136
|
let fresher;
|
|
22734
23137
|
try {
|
|
@@ -22739,7 +23142,7 @@ function warnFresherSubdirHarnessReports(context, rootDir, explicitReport) {
|
|
|
22739
23142
|
if (fresher.length === 0)
|
|
22740
23143
|
return;
|
|
22741
23144
|
const newest = fresher[0];
|
|
22742
|
-
const subdir =
|
|
23145
|
+
const subdir = normalizePath3(dirname8(dirname8(newest.path)));
|
|
22743
23146
|
const rootState = existsSync8(join11(rootDir, HARNESS_REPORT_PATH)) ? `older ${HARNESS_REPORT_PATH}` : `no ${HARNESS_REPORT_PATH}`;
|
|
22744
23147
|
writeHarnessNotice(context, `A fresher harness report exists at ${newest.path} (this directory has ${rootState}). If you meant that report, re-run with --path=${subdir}.`);
|
|
22745
23148
|
}
|
|
@@ -22934,7 +23337,7 @@ function inventoryFiles(rootDir, skipped, options = {}) {
|
|
|
22934
23337
|
const maxTextBytes = numericEnv("MODA_HARNESS_MAX_TEXT_BYTES", DEFAULT_MAX_INVENTORY_TEXT_BYTES);
|
|
22935
23338
|
let textBytes = 0;
|
|
22936
23339
|
function walk(current) {
|
|
22937
|
-
const rel2 =
|
|
23340
|
+
const rel2 = normalizePath3(relative9(rootReal, current)) || ".";
|
|
22938
23341
|
let stat;
|
|
22939
23342
|
try {
|
|
22940
23343
|
stat = lstatSync7(current);
|
|
@@ -23150,7 +23553,7 @@ function runtimeAgentFromAnnotation(annotation) {
|
|
|
23150
23553
|
kind: "runtime_agent",
|
|
23151
23554
|
purpose: first2(values.purpose) ?? first2(values.description),
|
|
23152
23555
|
familyId: first2(values.family),
|
|
23153
|
-
root:
|
|
23556
|
+
root: normalizePath3(first2(values.root) ?? dirname8(annotation.evidence.path)),
|
|
23154
23557
|
entrypointIds: values.entrypoint ?? [stableId("entry", annotation.evidence.path)],
|
|
23155
23558
|
channelAdapterIds: values.channel ?? [],
|
|
23156
23559
|
artifactIds: [...values.artifact ?? [], ...values.prompt ?? [], ...values.tool ?? []],
|
|
@@ -23386,7 +23789,7 @@ function inferRuntimeAgent(file, graph) {
|
|
|
23386
23789
|
name: titleFromId(file.path.replace(/\.(ts|tsx|js|mjs|py)$/i, "")),
|
|
23387
23790
|
kind: "runtime_agent",
|
|
23388
23791
|
purpose: inferAgentPurpose(file),
|
|
23389
|
-
root:
|
|
23792
|
+
root: normalizePath3(dirname8(file.path)),
|
|
23390
23793
|
entrypointIds: [entryId],
|
|
23391
23794
|
channelAdapterIds: channelIds,
|
|
23392
23795
|
artifactIds,
|
|
@@ -24285,7 +24688,7 @@ function contentHashForAnnotatedSource(sourcePath, annotation) {
|
|
|
24285
24688
|
function readSmallTextFileForHash(absPath, rootDir) {
|
|
24286
24689
|
if (!existsSync8(absPath))
|
|
24287
24690
|
return;
|
|
24288
|
-
const rel2 =
|
|
24691
|
+
const rel2 = normalizePath3(relative9(rootDir, absPath));
|
|
24289
24692
|
if (isSecretishPath(rel2))
|
|
24290
24693
|
return;
|
|
24291
24694
|
let stat;
|
|
@@ -24386,7 +24789,7 @@ function titleFromId(id) {
|
|
|
24386
24789
|
function promptNameFromPath(path) {
|
|
24387
24790
|
return titleFromId(basename6(path).replace(/\.(prompt\.)?(md|json|ya?ml)$/i, ""));
|
|
24388
24791
|
}
|
|
24389
|
-
function
|
|
24792
|
+
function normalizePath3(path) {
|
|
24390
24793
|
return path.split(sep5).join("/");
|
|
24391
24794
|
}
|
|
24392
24795
|
function hashText(text) {
|
|
@@ -27112,8 +27515,8 @@ function collectModels(result, ctx) {
|
|
|
27112
27515
|
const context = modelPathContext(result.rootDir);
|
|
27113
27516
|
const harnessPath = (path) => isHarnessModelPath(path, context);
|
|
27114
27517
|
for (const [id, entry] of byId) {
|
|
27115
|
-
const
|
|
27116
|
-
if (!
|
|
27518
|
+
const paths2 = [...entry.definitions.map((at) => at.path), ...entry.sites.map((site) => site.path)];
|
|
27519
|
+
if (!paths2.some(harnessPath))
|
|
27117
27520
|
byId.delete(id);
|
|
27118
27521
|
}
|
|
27119
27522
|
const kept = unresolved.filter((entry) => harnessPath(entry.path));
|
|
@@ -27430,7 +27833,7 @@ function enumerationRepository(ctx) {
|
|
|
27430
27833
|
};
|
|
27431
27834
|
walk(ctx.rootDir);
|
|
27432
27835
|
const workers = [];
|
|
27433
|
-
const
|
|
27836
|
+
const paths2 = new Set(files.map((file) => file.path));
|
|
27434
27837
|
const closure = (main) => {
|
|
27435
27838
|
const found = new Set, pending = [main];
|
|
27436
27839
|
for (let index = 0;index < pending.length; index++) {
|
|
@@ -27445,7 +27848,7 @@ function enumerationRepository(ctx) {
|
|
|
27445
27848
|
if (!ref.fileName.startsWith("."))
|
|
27446
27849
|
continue;
|
|
27447
27850
|
const base = posix2.normalize(posix2.join(posix2.dirname(path), ref.fileName)).replace(/\.[cm]?js$/, "");
|
|
27448
|
-
const target = [base, ...[".ts", ".tsx", ".js", ".mjs", "/index.ts", "/index.js"].map((suffix) => base + suffix)].find((candidate) =>
|
|
27851
|
+
const target = [base, ...[".ts", ".tsx", ".js", ".mjs", "/index.ts", "/index.js"].map((suffix) => base + suffix)].find((candidate) => paths2.has(candidate));
|
|
27449
27852
|
if (target)
|
|
27450
27853
|
pending.push(target);
|
|
27451
27854
|
}
|
|
@@ -29046,7 +29449,7 @@ function runExtract(rootDir, options) {
|
|
|
29046
29449
|
return /\.svelte$/i.test(abs) ? svelteVirtualName(abs) : abs;
|
|
29047
29450
|
};
|
|
29048
29451
|
const lookup = (path) => repo?.owner.get(fileKey(path));
|
|
29049
|
-
const
|
|
29452
|
+
const sourceFile2 = (path) => lookup(path)?.program.getSourceFile(fileKey(path));
|
|
29050
29453
|
let files;
|
|
29051
29454
|
const ctx = {
|
|
29052
29455
|
rootDir,
|
|
@@ -29055,7 +29458,7 @@ function runExtract(rootDir, options) {
|
|
|
29055
29458
|
checkerFor: (path) => lookup(path)?.checker(),
|
|
29056
29459
|
sourceFiles: () => files ??= [...repo?.owner.entries() ?? []].filter(([file]) => !isTestPath(relPath(rootDir, file))).map(([file, entry]) => entry.program.getSourceFile(file)).filter((file) => Boolean(file)),
|
|
29057
29460
|
nodeAt: (ref) => {
|
|
29058
|
-
const source =
|
|
29461
|
+
const source = sourceFile2(ref.path);
|
|
29059
29462
|
return source ? nodeSpanning(source, ref.start, ref.end) : undefined;
|
|
29060
29463
|
}
|
|
29061
29464
|
};
|
|
@@ -30009,8 +30412,8 @@ function mergeEnumeratedComponents(artifacts, components) {
|
|
|
30009
30412
|
const candidates = extractedByName.get(item.name) ?? [];
|
|
30010
30413
|
if (candidates.length === 0)
|
|
30011
30414
|
return item.id.startsWith("tool:catalog:") ? `tool:${item.id}` : `tool:${item.name}`;
|
|
30012
|
-
const
|
|
30013
|
-
const target = candidates.find((candidate) => candidate.sourcePath &&
|
|
30415
|
+
const paths2 = new Set([item.sourcePath, ...item.evidence.map((entry) => entry.path)].filter(Boolean));
|
|
30416
|
+
const target = candidates.find((candidate) => candidate.sourcePath && paths2.has(candidate.sourcePath) || candidate.definitionVariants?.some((variant) => variant.sourcePath && paths2.has(variant.sourcePath))) ?? candidates.find((candidate) => !candidate.id.includes("@")) ?? candidates[0];
|
|
30014
30417
|
return `tool:${target.id}`;
|
|
30015
30418
|
};
|
|
30016
30419
|
for (const item of [...registry, ...artifacts, ...components.artifacts.filter((item2) => !registry.includes(item2))]) {
|