@moda-ai/cli 1.55.84 → 1.55.85
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-anya3x2b.js} +3 -3
- package/dist/{cli-pjat0vfe.js → cli-7vywvw8v.js} +415 -127
- package/dist/{cli-fem792g7.js → cli-aj336k6v.js} +2 -2
- package/dist/{cli-ynt9zjkk.js → cli-v43q6cg9.js} +3 -3
- package/dist/cli.js +7 -7
- package/dist/{doctor-dvva8w4d.js → doctor-sa0q9ca6.js} +2 -2
- package/dist/{harness-github-actions-gt4qawvp.js → harness-github-actions-ma33g263.js} +1 -1
- package/dist/{harness-t52n8rap.js → harness-w3fnq796.js} +1 -1
- package/dist/{index-xhcqg43k.js → index-2bctz222.js} +1 -1
- package/dist/{index-n43wbr24.js → index-jvs3ksx6.js} +1 -1
- package/dist/{index-3c8srf3s.js → index-zzyx7qgy.js} +3 -3
- package/dist/{prompt-attribution-3110zq79.js → prompt-attribution-51shashb.js} +1 -1
- package/dist/prompt-source-mcp.js +1 -1
- package/dist/{prompts-tvvpx1hd.js → prompts-d484wq58.js} +1 -1
- package/dist/{sync-h9nymr41.js → sync-tpkqgm6r.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?)\//;
|
|
@@ -18072,6 +18189,9 @@ class PromptResolver {
|
|
|
18072
18189
|
return;
|
|
18073
18190
|
}
|
|
18074
18191
|
const expr = unwrap2(node);
|
|
18192
|
+
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))) {
|
|
18193
|
+
walk = { ...walk, project: walk.project.slice(1) };
|
|
18194
|
+
}
|
|
18075
18195
|
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
18196
|
return;
|
|
18077
18197
|
}
|
|
@@ -18106,6 +18226,16 @@ class PromptResolver {
|
|
|
18106
18226
|
return;
|
|
18107
18227
|
}
|
|
18108
18228
|
if (import_typescript8.default.isArrayLiteralExpression(expr)) {
|
|
18229
|
+
if (walk.project[0] === ARRAY_ELEMENT || walk.project[0] === FLATMAP_ELEMENT) {
|
|
18230
|
+
const inner = { ...walk, project: walk.project.slice(1) };
|
|
18231
|
+
for (const element of expr.elements) {
|
|
18232
|
+
if (import_typescript8.default.isSpreadElement(element))
|
|
18233
|
+
this.value(element.expression, owner, walk);
|
|
18234
|
+
else
|
|
18235
|
+
this.value(element, owner, inner);
|
|
18236
|
+
}
|
|
18237
|
+
return;
|
|
18238
|
+
}
|
|
18109
18239
|
if (/^\d+$/.test(walk.project[0] ?? "")) {
|
|
18110
18240
|
const [index, ...rest] = walk.project;
|
|
18111
18241
|
const selected = Number(index);
|
|
@@ -18300,7 +18430,7 @@ class PromptResolver {
|
|
|
18300
18430
|
}
|
|
18301
18431
|
const table = this.objectLiteralOf(access.expression);
|
|
18302
18432
|
if (!table) {
|
|
18303
|
-
this.value(access.expression, owner, walk);
|
|
18433
|
+
this.value(access.expression, owner, literalKey === undefined ? walk : { ...flag(walk, "projected"), project: [literalKey, ...walk.project] });
|
|
18304
18434
|
return;
|
|
18305
18435
|
}
|
|
18306
18436
|
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 +18462,49 @@ class PromptResolver {
|
|
|
18332
18462
|
this.value(callee.expression, owner, walk);
|
|
18333
18463
|
return;
|
|
18334
18464
|
}
|
|
18465
|
+
const checker = this.context.checkerFor(this.relative(callee.expression.getSourceFile().fileName));
|
|
18466
|
+
const receiverType = checker?.getTypeAtLocation(callee.expression);
|
|
18467
|
+
const arrayReceiver = import_typescript8.default.isArrayLiteralExpression(this.objectLiteralOf(callee.expression) ?? callee.expression) || !!checker && !!receiverType && (receiverType.isUnion() ? receiverType.types : [receiverType]).every((type) => checker.isArrayType(type) || checker.isTupleType(type));
|
|
18468
|
+
if ((method === "find" || method === "findLast") && arrayReceiver) {
|
|
18469
|
+
this.value(callee.expression, owner, { ...flag(walk, "dynamic-key"), project: [ARRAY_ELEMENT, ...walk.project] });
|
|
18470
|
+
return;
|
|
18471
|
+
}
|
|
18472
|
+
if ((method === "map" || method === "flatMap") && arrayReceiver && call.arguments[0]) {
|
|
18473
|
+
const callback = unwrap2(call.arguments[0]);
|
|
18474
|
+
const functions2 = import_typescript8.default.isArrowFunction(callback) || import_typescript8.default.isFunctionExpression(callback) ? [callback] : this.declarationsOf(callback).map(functionOf).filter((fn) => !!fn?.body);
|
|
18475
|
+
const output = walk.project[0];
|
|
18476
|
+
const indexed = /^\d+$/.test(output ?? "");
|
|
18477
|
+
if (method === "flatMap" && indexed) {
|
|
18478
|
+
this.markUnresolved(call, "dynamic-key", walk);
|
|
18479
|
+
return;
|
|
18480
|
+
}
|
|
18481
|
+
const eachOutput = output === ARRAY_ELEMENT || output === FLATMAP_ELEMENT;
|
|
18482
|
+
const callbackProject = eachOutput ? method === "flatMap" ? [FLATMAP_ELEMENT, ...walk.project.slice(1)] : walk.project.slice(1) : indexed ? walk.project.slice(1) : walk.project;
|
|
18483
|
+
const sourceProject = method === "map" && indexed ? output : ARRAY_ELEMENT;
|
|
18484
|
+
for (const fn of functions2) {
|
|
18485
|
+
const next = this.step({ ...walk, project: callbackProject }, fn, `array callback at ${this.where(call)}`);
|
|
18486
|
+
if (!next || walk.seen.has(fn))
|
|
18487
|
+
continue;
|
|
18488
|
+
next.bindings = new Map(next.bindings);
|
|
18489
|
+
bindParameters(fn, [callee.expression], walk.bindings, next.bindings);
|
|
18490
|
+
const first2 = fn.parameters[0];
|
|
18491
|
+
if (first2 && import_typescript8.default.isArrayBindingPattern(first2.name)) {
|
|
18492
|
+
first2.name.elements.forEach((element, index) => {
|
|
18493
|
+
if (import_typescript8.default.isBindingElement(element) && !element.dotDotDotToken && !element.initializer) {
|
|
18494
|
+
next.bindings.set(element, { expr: callee.expression, bindings: walk.bindings, project: [String(index)] });
|
|
18495
|
+
}
|
|
18496
|
+
});
|
|
18497
|
+
}
|
|
18498
|
+
for (const [declaration, binding] of next.bindings) {
|
|
18499
|
+
if (declaration === first2 || import_typescript8.default.isBindingElement(declaration) && parameterOf(declaration) === first2) {
|
|
18500
|
+
next.bindings.set(declaration, { ...binding, project: [sourceProject, ...binding.project ?? []] });
|
|
18501
|
+
}
|
|
18502
|
+
}
|
|
18503
|
+
this.builderBody(fn, owner ?? { node: fn, kind: "builder" }, next);
|
|
18504
|
+
}
|
|
18505
|
+
if (functions2.length)
|
|
18506
|
+
return;
|
|
18507
|
+
}
|
|
18335
18508
|
if (CALLBACK_METHODS.has(method)) {
|
|
18336
18509
|
const callbacks = call.arguments.map(unwrap2).filter((a) => import_typescript8.default.isArrowFunction(a) || import_typescript8.default.isFunctionExpression(a));
|
|
18337
18510
|
for (const callback of callbacks)
|
|
@@ -18343,6 +18516,10 @@ class PromptResolver {
|
|
|
18343
18516
|
this.value(callee.expression, owner, walk);
|
|
18344
18517
|
return;
|
|
18345
18518
|
}
|
|
18519
|
+
if (ARRAY_ASSEMBLY_METHODS.has(method) && /^\d+$/.test(walk.project[0] ?? "")) {
|
|
18520
|
+
this.markUnresolved(call, "dynamic-key", walk);
|
|
18521
|
+
return;
|
|
18522
|
+
}
|
|
18346
18523
|
if (TEXT_PRESERVING_METHODS.has(method) || ARRAY_ASSEMBLY_METHODS.has(method)) {
|
|
18347
18524
|
this.value(callee.expression, owner, walk);
|
|
18348
18525
|
if (method === "concat")
|
|
@@ -18755,7 +18932,19 @@ class PromptResolver {
|
|
|
18755
18932
|
parameter(declaration, at, owner, walk) {
|
|
18756
18933
|
const bound = walk.bindings.get(declaration);
|
|
18757
18934
|
if (bound) {
|
|
18758
|
-
|
|
18935
|
+
const project = [...bound.project ?? [], ...walk.project];
|
|
18936
|
+
if (bound.rest) {
|
|
18937
|
+
const each = project[0] === ARRAY_ELEMENT;
|
|
18938
|
+
const index2 = /^\d+$/.test(project[0] ?? "") ? Number(project[0]) : undefined;
|
|
18939
|
+
const values = index2 === undefined ? bound.rest : bound.rest.slice(index2, index2 + 1);
|
|
18940
|
+
for (const value of values)
|
|
18941
|
+
this.value(value, undefined, {
|
|
18942
|
+
...walk,
|
|
18943
|
+
bindings: bound.bindings,
|
|
18944
|
+
project: each || index2 !== undefined ? project.slice(1) : project
|
|
18945
|
+
});
|
|
18946
|
+
} else
|
|
18947
|
+
this.value(bound.expr, undefined, { ...walk, bindings: bound.bindings, project });
|
|
18759
18948
|
return;
|
|
18760
18949
|
}
|
|
18761
18950
|
const parameter = import_typescript8.default.isParameter(declaration) ? declaration : parameterOf(declaration);
|
|
@@ -19141,6 +19330,10 @@ function bindingField(element) {
|
|
|
19141
19330
|
function bindParameters(fn, args, outer, into) {
|
|
19142
19331
|
fn.parameters.forEach((parameter, index) => {
|
|
19143
19332
|
const argument = args[index];
|
|
19333
|
+
if (parameter.dotDotDotToken && import_typescript8.default.isIdentifier(parameter.name)) {
|
|
19334
|
+
into.set(parameter, { expr: argument ?? parameter.name, bindings: outer, rest: args.slice(index) });
|
|
19335
|
+
return;
|
|
19336
|
+
}
|
|
19144
19337
|
if (!argument)
|
|
19145
19338
|
return;
|
|
19146
19339
|
if (import_typescript8.default.isIdentifier(parameter.name)) {
|
|
@@ -19484,7 +19677,7 @@ async function runHarnessCommand(context) {
|
|
|
19484
19677
|
report: {
|
|
19485
19678
|
reportId: report.reportId,
|
|
19486
19679
|
reportHash,
|
|
19487
|
-
path:
|
|
19680
|
+
path: normalizePath3(relative9(rootDir, reportPath)) || ".moda/harness-report.json"
|
|
19488
19681
|
},
|
|
19489
19682
|
validation,
|
|
19490
19683
|
approval: {
|
|
@@ -19630,7 +19823,7 @@ async function runHarnessCommand(context) {
|
|
|
19630
19823
|
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
19824
|
}
|
|
19632
19825
|
if (context.flags["github-actions"] === "true") {
|
|
19633
|
-
const { runGithubActionsAnalyze } = await import("./harness-github-actions-
|
|
19826
|
+
const { runGithubActionsAnalyze } = await import("./harness-github-actions-ma33g263.js");
|
|
19634
19827
|
const result = await runGithubActionsAnalyze(rootDir, {
|
|
19635
19828
|
writeReport: (report2) => {
|
|
19636
19829
|
const normalized = normalizeHarnessReport(report2);
|
|
@@ -19757,7 +19950,7 @@ async function runHarnessCommand(context) {
|
|
|
19757
19950
|
report: {
|
|
19758
19951
|
reportId: approval.report.reportId,
|
|
19759
19952
|
reportHash: hashHarnessReport(approval.report),
|
|
19760
|
-
path:
|
|
19953
|
+
path: normalizePath3(relative9(rootDir, reportPath)) || ".moda/harness-report.json"
|
|
19761
19954
|
},
|
|
19762
19955
|
validation: approval.validation,
|
|
19763
19956
|
approval: approval.approval
|
|
@@ -19779,17 +19972,17 @@ async function runHarnessCommand(context) {
|
|
|
19779
19972
|
if (promoteOut === "true") {
|
|
19780
19973
|
throw new CliInputError("Missing output path for --out.", "Usage: moda harness candidates --promote=<concern|all> --out=<file>");
|
|
19781
19974
|
}
|
|
19782
|
-
const { artifacts, unknowns } = deterministicGraphItems(rootDir, promote === "all" ? undefined : promote);
|
|
19975
|
+
const { artifacts, unknowns, canonicalAgentIdentities } = deterministicGraphItems(rootDir, promote === "all" ? undefined : promote);
|
|
19783
19976
|
tagComponentStatus({ runtimeAgents: [], artifacts }, rootDir);
|
|
19784
|
-
const { extractHarnessWithContext: extractHarnessWithContext2 } = await import("./index-
|
|
19785
|
-
const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-
|
|
19977
|
+
const { extractHarnessWithContext: extractHarnessWithContext2 } = await import("./index-2bctz222.js");
|
|
19978
|
+
const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-jvs3ksx6.js");
|
|
19786
19979
|
let components = { runtimeAgents: [], artifacts: [], warnings: [] };
|
|
19787
19980
|
if (promote === "all" || promote === "topology" || promote === "tools") {
|
|
19788
19981
|
const { result, ctx } = extractHarnessWithContext2(rootDir);
|
|
19789
19982
|
const found = enumerateHarnessComponents(result, ctx);
|
|
19790
19983
|
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
19984
|
}
|
|
19792
|
-
const promoted = { concern: promote, unknowns, ...mergeEnumeratedComponents(artifacts, components) };
|
|
19985
|
+
const promoted = { concern: promote, unknowns, canonicalAgentIdentities, ...mergeEnumeratedComponents(artifacts, components) };
|
|
19793
19986
|
const promoteWritten = [];
|
|
19794
19987
|
if (promoteOut && !context.dryRun) {
|
|
19795
19988
|
const target = resolve9(context.cwd, promoteOut);
|
|
@@ -19816,8 +20009,8 @@ async function runHarnessCommand(context) {
|
|
|
19816
20009
|
}
|
|
19817
20010
|
case "extract": {
|
|
19818
20011
|
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-
|
|
20012
|
+
const { extractHarnessWithContext: extractHarnessWithContext2, serializeExtractResult } = await import("./index-2bctz222.js");
|
|
20013
|
+
const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-jvs3ksx6.js");
|
|
19821
20014
|
const { result, ctx } = extractHarnessWithContext2(rootDir, { fresh: true });
|
|
19822
20015
|
const artifacts = deterministicArtifacts(rootDir);
|
|
19823
20016
|
tagComponentStatus({ runtimeAgents: [], artifacts }, rootDir);
|
|
@@ -20379,7 +20572,7 @@ function modelIdsUsedInSource(rootDir, ids) {
|
|
|
20379
20572
|
const walk = (current) => {
|
|
20380
20573
|
if (pending.size === 0)
|
|
20381
20574
|
return false;
|
|
20382
|
-
const rel2 =
|
|
20575
|
+
const rel2 = normalizePath3(relative9(rootReal, current)) || ".";
|
|
20383
20576
|
let stat;
|
|
20384
20577
|
try {
|
|
20385
20578
|
stat = lstatSync7(current);
|
|
@@ -20463,9 +20656,9 @@ function mergeDeterministicReplacement(report, rootDir, options) {
|
|
|
20463
20656
|
mergeDeterministicArtifacts(report.graph, rootDir, options);
|
|
20464
20657
|
const replacements = new Map;
|
|
20465
20658
|
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) =>
|
|
20659
|
+
const paths2 = artifactPaths(artifact);
|
|
20660
|
+
const exact = report.graph.artifacts.filter((candidate) => candidate.type === artifact.type && artifactPaths(candidate).some((path) => paths2.includes(path)));
|
|
20661
|
+
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
20662
|
replacements.set(artifact.id, matches);
|
|
20470
20663
|
const owners = new Set([...artifact.usedByAgentIds ?? [], ...artifact.ownedByAgentId ? [artifact.ownedByAgentId] : []]);
|
|
20471
20664
|
for (const link of agentLinks)
|
|
@@ -20537,6 +20730,7 @@ function repairExternalAnalystReport(report, rootDir, options = {}) {
|
|
|
20537
20730
|
mergeDeterministicReplacement(normalized, rootDir, options);
|
|
20538
20731
|
if (!options.concern || options.concern === "topology")
|
|
20539
20732
|
mergeBoundRuntimeClasses(normalized.graph, rootDir);
|
|
20733
|
+
remapCanonicalArtifactAgents(normalized.graph, normalized.graph.artifacts, !options.concern);
|
|
20540
20734
|
tagComponentStatus(normalized.graph, rootDir);
|
|
20541
20735
|
hydratePromptAndToolBodies(normalized.graph, rootDir);
|
|
20542
20736
|
const unverified = new Set;
|
|
@@ -20570,8 +20764,8 @@ function repairExternalAnalystReport(report, rootDir, options = {}) {
|
|
|
20570
20764
|
const testOnlyModels = normalized.graph.artifacts.filter((artifact) => {
|
|
20571
20765
|
if (artifact.type !== "model_config" || unverified.has(artifact.id))
|
|
20572
20766
|
return false;
|
|
20573
|
-
const
|
|
20574
|
-
return
|
|
20767
|
+
const paths2 = artifact.evidence.map((entry) => entry.path).filter((path) => typeof path === "string" && path.length > 0);
|
|
20768
|
+
return paths2.length > 0 && paths2.every((path) => TEST_PATH3.test(path));
|
|
20575
20769
|
});
|
|
20576
20770
|
const usedInSource = testOnlyModels.length > 0 ? modelIdsUsedInSource(rootDir, testOnlyModels.map((artifact) => (artifact.name ?? "").trim())) : new Set;
|
|
20577
20771
|
for (const artifact of testOnlyModels) {
|
|
@@ -20601,6 +20795,29 @@ function repairExternalAnalystReport(report, rootDir, options = {}) {
|
|
|
20601
20795
|
if (unverified.size > 0)
|
|
20602
20796
|
removeArtifacts(normalized, unverified);
|
|
20603
20797
|
deriveRelationshipsFromGraph(normalized.graph);
|
|
20798
|
+
if (!options.concern) {
|
|
20799
|
+
const knownAgents = new Set(normalized.graph.runtimeAgents.map((agent) => agent.id));
|
|
20800
|
+
for (const artifact of normalized.graph.artifacts) {
|
|
20801
|
+
if (artifact.type !== "tool" || !["in_prod", "reachable"].includes(artifact.status ?? ""))
|
|
20802
|
+
continue;
|
|
20803
|
+
const owners = [
|
|
20804
|
+
...artifact.usedByAgentIds ?? [],
|
|
20805
|
+
...artifact.ownedByAgentId ? [artifact.ownedByAgentId] : [],
|
|
20806
|
+
...normalized.graph.runtimeAgents.filter((agent) => agent.artifactIds?.includes(artifact.id)).map((agent) => agent.id),
|
|
20807
|
+
...normalized.graph.relationships.filter((edge) => edge.to === artifact.id && ["uses_artifact", "owns_artifact"].includes(edge.type)).map((edge) => edge.from)
|
|
20808
|
+
];
|
|
20809
|
+
if (owners.some((owner) => knownAgents.has(owner)))
|
|
20810
|
+
continue;
|
|
20811
|
+
const id = `unresolved_tool_owner_${createHash7("sha256").update(artifact.id).digest("hex").slice(0, 16)}`;
|
|
20812
|
+
if (!normalized.graph.unknowns.some((unknown) => unknown.id === id))
|
|
20813
|
+
normalized.graph.unknowns.push({
|
|
20814
|
+
id,
|
|
20815
|
+
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.`,
|
|
20816
|
+
candidateIds: [artifact.id],
|
|
20817
|
+
evidence: artifact.evidence
|
|
20818
|
+
});
|
|
20819
|
+
}
|
|
20820
|
+
}
|
|
20604
20821
|
dropUnlocatedAgentCitations(normalized);
|
|
20605
20822
|
if ((normalized.claims?.length ?? 0) === 0 && deterministicOnlyArtifactTypes().has("eval")) {
|
|
20606
20823
|
const grounded = createHarnessReport({ graph: {
|
|
@@ -20696,8 +20913,8 @@ var CONCERN_PROMOTED_ARTIFACT_TYPES = {
|
|
|
20696
20913
|
evals: new Set(["model_config", "eval"])
|
|
20697
20914
|
};
|
|
20698
20915
|
async function deterministicFloorGraph(rootDir, options = {}) {
|
|
20699
|
-
const { extractHarnessWithContext: extractHarnessWithContext2 } = await import("./index-
|
|
20700
|
-
const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-
|
|
20916
|
+
const { extractHarnessWithContext: extractHarnessWithContext2 } = await import("./index-2bctz222.js");
|
|
20917
|
+
const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-jvs3ksx6.js");
|
|
20701
20918
|
const { result, ctx } = extractHarnessWithContext2(rootDir);
|
|
20702
20919
|
const items = deterministicGraphItems(rootDir);
|
|
20703
20920
|
const components = mergeEnumeratedComponents(items.artifacts, enumerateHarnessComponents(result, ctx));
|
|
@@ -20726,7 +20943,7 @@ function deterministicGraphItems(rootDir, concern) {
|
|
|
20726
20943
|
const graph = { artifacts: [], unknowns: [] };
|
|
20727
20944
|
mergeDeterministicArtifacts(graph, rootDir, { concern });
|
|
20728
20945
|
hydratePromptAndToolBodies(graph, rootDir);
|
|
20729
|
-
return { artifacts: graph.artifacts, unknowns: graph.unknowns };
|
|
20946
|
+
return { artifacts: graph.artifacts, unknowns: graph.unknowns, canonicalAgentIdentities: graph.scan?.canonicalAgentIdentities ?? [] };
|
|
20730
20947
|
}
|
|
20731
20948
|
var extractedModelsCache = new WeakMap;
|
|
20732
20949
|
function extractedModelItems(rootDir) {
|
|
@@ -20861,9 +21078,16 @@ function mergeDeterministicArtifacts(graph, rootDir, options = {}) {
|
|
|
20861
21078
|
} catch {}
|
|
20862
21079
|
}
|
|
20863
21080
|
const extractedIds = new Set(extracted.artifacts.map((artifact) => artifact.id));
|
|
21081
|
+
try {
|
|
21082
|
+
const { result, ctx } = extractHarnessWithContext(rootDir);
|
|
21083
|
+
const identities = harnessAgentIdentities(enumerateAgents(result, ctx).runtimeAgents);
|
|
21084
|
+
graph.scan ??= {};
|
|
21085
|
+
graph.scan.canonicalAgentIdentities = identities;
|
|
21086
|
+
remapCanonicalArtifactAgents(graph, promoted);
|
|
21087
|
+
} catch {}
|
|
20864
21088
|
backfillRefutationEvidenceReasons(graph);
|
|
20865
21089
|
const refuted = analystRefutations(graph);
|
|
20866
|
-
const candidatePaths = new Set(promoted.flatMap((artifact) => artifact.evidence.map((entry) => typeof entry.path === "string" ?
|
|
21090
|
+
const candidatePaths = new Set(promoted.flatMap((artifact) => artifact.evidence.map((entry) => typeof entry.path === "string" ? normalizePath3(entry.path) : "").filter(Boolean)));
|
|
20867
21091
|
const modelLineCounts = new Map;
|
|
20868
21092
|
for (const artifact of promoted) {
|
|
20869
21093
|
if (artifact.type !== "model_config")
|
|
@@ -20888,6 +21112,26 @@ function mergeDeterministicArtifacts(graph, rootDir, options = {}) {
|
|
|
20888
21112
|
added += 1;
|
|
20889
21113
|
continue;
|
|
20890
21114
|
}
|
|
21115
|
+
if (artifact.type === "prompt" && artifact.usedByAgentIds.length > 0) {
|
|
21116
|
+
const existing = graph.artifacts.find((candidate) => candidate.type === "prompt" && candidate.id === artifact.id);
|
|
21117
|
+
if (existing && !isRefutedByAnalyst(artifact, refuted, candidatePaths)) {
|
|
21118
|
+
const definition = artifact.evidence[0];
|
|
21119
|
+
const stored = existing.evidence?.[0];
|
|
21120
|
+
if (definition && (!stored || stored.path === definition.path && stored.line === definition.line)) {
|
|
21121
|
+
existing.usedByAgentIds = [...new Set([...existing.usedByAgentIds ?? [], ...artifact.usedByAgentIds])];
|
|
21122
|
+
if (Array.isArray(existing.staticUsedByAgentIds))
|
|
21123
|
+
existing.staticUsedByAgentIds = [...new Set([...existing.staticUsedByAgentIds, ...artifact.usedByAgentIds])];
|
|
21124
|
+
if (existing.usedByAgentIds.length > 1)
|
|
21125
|
+
existing.scope = "shared";
|
|
21126
|
+
existing.evidence ??= [];
|
|
21127
|
+
for (const entry of artifact.evidence) {
|
|
21128
|
+
if (!existing.evidence.some((known) => known.path === entry.path && known.line === entry.line && known.reason === entry.reason))
|
|
21129
|
+
existing.evidence.push(entry);
|
|
21130
|
+
}
|
|
21131
|
+
continue;
|
|
21132
|
+
}
|
|
21133
|
+
}
|
|
21134
|
+
}
|
|
20891
21135
|
if (graphCoversPromotedArtifact(graph, artifact, sharedModelLines))
|
|
20892
21136
|
continue;
|
|
20893
21137
|
if ((artifact.type === "model_config" || artifact.type === "eval") && artifact.evidence.length > 1 && !refuted.candidateIds.has(artifact.id)) {
|
|
@@ -20915,6 +21159,50 @@ function mergeDeterministicArtifacts(graph, rootDir, options = {}) {
|
|
|
20915
21159
|
}
|
|
20916
21160
|
return { added };
|
|
20917
21161
|
}
|
|
21162
|
+
function remapCanonicalArtifactAgents(graph, artifacts = graph.artifacts, dropUnmapped = false) {
|
|
21163
|
+
const identities = harnessAgentIdentities(graph.scan?.canonicalAgentIdentities);
|
|
21164
|
+
const mapping = matchHarnessAgentIds(identities, graph.runtimeAgents ?? []);
|
|
21165
|
+
const canonical = new Map(identities.map((identity2) => [identity2.id, identity2]));
|
|
21166
|
+
const unresolved = new Map;
|
|
21167
|
+
const translate = (id, artifactId) => {
|
|
21168
|
+
const mapped = mapping.get(id);
|
|
21169
|
+
if (mapped || !dropUnmapped || !canonical.has(id))
|
|
21170
|
+
return mapped ?? id;
|
|
21171
|
+
const affected = unresolved.get(id) ?? [];
|
|
21172
|
+
if (!affected.includes(artifactId))
|
|
21173
|
+
affected.push(artifactId);
|
|
21174
|
+
unresolved.set(id, affected);
|
|
21175
|
+
return;
|
|
21176
|
+
};
|
|
21177
|
+
for (const artifact of artifacts) {
|
|
21178
|
+
artifact.usedByAgentIds = [...new Set((artifact.usedByAgentIds ?? []).flatMap((id) => translate(id, artifact.id) ?? []))];
|
|
21179
|
+
for (const field of ["staticUsedByAgentIds", "traceUsedByAgentIds"]) {
|
|
21180
|
+
if (Array.isArray(artifact[field]))
|
|
21181
|
+
artifact[field] = [...new Set(artifact[field].flatMap((id) => translate(id, artifact.id) ?? []))];
|
|
21182
|
+
}
|
|
21183
|
+
if (artifact.ownedByAgentId) {
|
|
21184
|
+
const owner = translate(artifact.ownedByAgentId, artifact.id);
|
|
21185
|
+
if (owner)
|
|
21186
|
+
artifact.ownedByAgentId = owner;
|
|
21187
|
+
else {
|
|
21188
|
+
delete artifact.ownedByAgentId;
|
|
21189
|
+
artifact.scope = "shared";
|
|
21190
|
+
}
|
|
21191
|
+
}
|
|
21192
|
+
}
|
|
21193
|
+
for (const [agentId, artifactIds] of unresolved) {
|
|
21194
|
+
const identity2 = canonical.get(agentId);
|
|
21195
|
+
const id = `unresolved_agent_links_${createHash7("sha256").update(agentId).digest("hex").slice(0, 16)}`;
|
|
21196
|
+
if (graph.unknowns.some((unknown) => unknown.id === id))
|
|
21197
|
+
continue;
|
|
21198
|
+
graph.unknowns.push({
|
|
21199
|
+
id,
|
|
21200
|
+
question: `Ownership for ${identity2.name} could not be matched uniquely to the hosted topology; its unresolved artifact links were omitted.`,
|
|
21201
|
+
candidateIds: artifactIds,
|
|
21202
|
+
evidence: (identity2.evidence ?? []).flatMap((entry) => entry.path ? [{ path: entry.path, ...entry.line !== undefined ? { line: entry.line } : {}, reason: entry.reason ?? "Extractor agent identity" }] : [])
|
|
21203
|
+
});
|
|
21204
|
+
}
|
|
21205
|
+
}
|
|
20918
21206
|
function withCallSitePrompts(rootDir, promoted) {
|
|
20919
21207
|
if (process.env.MODA_HARNESS_CALLSITE_PROMPTS === "0")
|
|
20920
21208
|
return promoted;
|
|
@@ -20985,11 +21273,11 @@ function analystRefutations(graph) {
|
|
|
20985
21273
|
if (typeof entry?.path !== "string" || !entry.path)
|
|
20986
21274
|
continue;
|
|
20987
21275
|
const line = typeof entry.line === "number" ? entry.line : undefined;
|
|
20988
|
-
result.locations.push({ path:
|
|
21276
|
+
result.locations.push({ path: normalizePath3(entry.path), start: line, end: line, types: refutedTypes(entry.reason, question) });
|
|
20989
21277
|
}
|
|
20990
21278
|
for (const match of question.matchAll(/([\w./-]+\.[a-z0-9]{1,5})(?::|\s+(?:lines?\s+)?)(\d+)(?:\s*[-\u2013]\s*(\d+))?/gi)) {
|
|
20991
21279
|
const start = Number(match[2]);
|
|
20992
|
-
result.locations.push({ path:
|
|
21280
|
+
result.locations.push({ path: normalizePath3(match[1]), start, end: match[3] ? Number(match[3]) : start, types: refutedTypes(question) });
|
|
20993
21281
|
}
|
|
20994
21282
|
}
|
|
20995
21283
|
return result;
|
|
@@ -21008,7 +21296,7 @@ function isRefutedByAnalyst(artifact, refuted, candidatePaths) {
|
|
|
21008
21296
|
return artifact.evidence.some((entry) => {
|
|
21009
21297
|
if (typeof entry.path !== "string")
|
|
21010
21298
|
return false;
|
|
21011
|
-
const path =
|
|
21299
|
+
const path = normalizePath3(entry.path);
|
|
21012
21300
|
return refuted.locations.some((location) => {
|
|
21013
21301
|
if (location.types && !location.types.has(artifact.type))
|
|
21014
21302
|
return false;
|
|
@@ -21024,9 +21312,9 @@ function isRefutedByAnalyst(artifact, refuted, candidatePaths) {
|
|
|
21024
21312
|
}
|
|
21025
21313
|
function artifactSourceKey(artifact) {
|
|
21026
21314
|
if (artifact.sourcePath)
|
|
21027
|
-
return
|
|
21315
|
+
return normalizePath3(artifact.sourcePath);
|
|
21028
21316
|
const pinned = Array.isArray(artifact.evidence) ? artifact.evidence.find((entry) => typeof entry.path === "string" && entry.path.length > 0) : undefined;
|
|
21029
|
-
return pinned ?
|
|
21317
|
+
return pinned ? normalizePath3(pinned.path) : undefined;
|
|
21030
21318
|
}
|
|
21031
21319
|
function mentionsModelId(text, id) {
|
|
21032
21320
|
if (!id)
|
|
@@ -21035,8 +21323,8 @@ function mentionsModelId(text, id) {
|
|
|
21035
21323
|
return new RegExp(`(?<![\\w./@-])${escaped}(?![\\w/-]|\\.\\w)`, "i").test(text);
|
|
21036
21324
|
}
|
|
21037
21325
|
function artifactPaths(artifact) {
|
|
21038
|
-
const
|
|
21039
|
-
return artifact.sourcePath ? [
|
|
21326
|
+
const paths2 = Array.isArray(artifact.evidence) ? artifact.evidence.map((entry) => typeof entry.path === "string" ? normalizePath3(entry.path) : "").filter(Boolean) : [];
|
|
21327
|
+
return artifact.sourcePath ? [normalizePath3(artifact.sourcePath), ...paths2] : paths2;
|
|
21040
21328
|
}
|
|
21041
21329
|
function graphCoversPromotedArtifact(graph, promoted, sharedModelLines = new Set) {
|
|
21042
21330
|
if (promoted.type === "model_config" && graph.artifacts.some((existing) => existing.type === "model_config" && mentionsModelId(`${existing.name ?? ""}
|
|
@@ -21044,7 +21332,7 @@ ${existing.body ?? ""}`, promoted.name)))
|
|
|
21044
21332
|
return true;
|
|
21045
21333
|
if (promoted.type === "eval") {
|
|
21046
21334
|
const suite = new Set(artifactPaths(promoted));
|
|
21047
|
-
const suiteKey = promoted.sourcePath ? evalSuiteKey(
|
|
21335
|
+
const suiteKey = promoted.sourcePath ? evalSuiteKey(normalizePath3(promoted.sourcePath)) : undefined;
|
|
21048
21336
|
if (graph.artifacts.some((existing) => existing.type === "eval" && artifactPaths(existing).some((path) => suite.has(path) || suiteKey !== undefined && evalSuiteKey(path.replace(/\/+$/, "")) === suiteKey)))
|
|
21049
21337
|
return true;
|
|
21050
21338
|
}
|
|
@@ -22042,15 +22330,15 @@ function renderExternalAnalystProtocol(concern) {
|
|
|
22042
22330
|
function renderAnalystPreflightSection(rootDir) {
|
|
22043
22331
|
if (process.env.MODA_HARNESS_ANALYST_PREFLIGHT === "0")
|
|
22044
22332
|
return "";
|
|
22045
|
-
const
|
|
22046
|
-
if (
|
|
22333
|
+
const paths2 = listAnalystPreflightPaths(rootDir);
|
|
22334
|
+
if (paths2.length === 0)
|
|
22047
22335
|
return "";
|
|
22048
22336
|
const groups = {
|
|
22049
|
-
manifests:
|
|
22050
|
-
docs:
|
|
22051
|
-
source:
|
|
22052
|
-
deploy:
|
|
22053
|
-
evals:
|
|
22337
|
+
manifests: paths2.filter((path) => isManifestLikePath(path)).slice(0, 60),
|
|
22338
|
+
docs: paths2.filter((path) => isDocLikePath(path)).slice(0, 40),
|
|
22339
|
+
source: paths2.filter((path) => isAgentNavigationPath(path)).slice(0, 160),
|
|
22340
|
+
deploy: paths2.filter((path) => isPreflightDeployLikePath(path)).slice(0, 50),
|
|
22341
|
+
evals: paths2.filter((path) => isPreflightEvalLikePath(path)).slice(0, 50)
|
|
22054
22342
|
};
|
|
22055
22343
|
const lines = [
|
|
22056
22344
|
"",
|
|
@@ -22065,10 +22353,10 @@ function renderAnalystPreflightSection(rootDir) {
|
|
|
22065
22353
|
return lines.join(`
|
|
22066
22354
|
`);
|
|
22067
22355
|
}
|
|
22068
|
-
function renderPreflightGroup(label,
|
|
22069
|
-
if (
|
|
22356
|
+
function renderPreflightGroup(label, paths2) {
|
|
22357
|
+
if (paths2.length === 0)
|
|
22070
22358
|
return [];
|
|
22071
|
-
return [`${label}:`, ...
|
|
22359
|
+
return [`${label}:`, ...paths2.map((path) => `- ${path}`)];
|
|
22072
22360
|
}
|
|
22073
22361
|
var MAX_SEED_ARTIFACT_LINES = 150;
|
|
22074
22362
|
function renderAnalystSeedSection(rootDir, concern) {
|
|
@@ -22172,8 +22460,8 @@ function renderAnalystSeedLines(graph) {
|
|
|
22172
22460
|
}
|
|
22173
22461
|
function listAnalystPreflightPaths(rootDir) {
|
|
22174
22462
|
const gitPaths = readGitTrackedPaths(rootDir);
|
|
22175
|
-
const
|
|
22176
|
-
return [...new Set(
|
|
22463
|
+
const paths2 = gitPaths.length > 0 ? gitPaths : readDirectoryPreflightPaths(rootDir);
|
|
22464
|
+
return [...new Set(paths2.map(normalizePath3))].filter((path) => path && !shouldSkipPreflightPath(path)).sort();
|
|
22177
22465
|
}
|
|
22178
22466
|
function readGitTrackedPaths(rootDir) {
|
|
22179
22467
|
try {
|
|
@@ -22187,9 +22475,9 @@ function readGitTrackedPaths(rootDir) {
|
|
|
22187
22475
|
}
|
|
22188
22476
|
}
|
|
22189
22477
|
function readDirectoryPreflightPaths(rootDir) {
|
|
22190
|
-
const
|
|
22478
|
+
const paths2 = [];
|
|
22191
22479
|
const stack = ["."];
|
|
22192
|
-
while (stack.length > 0 &&
|
|
22480
|
+
while (stack.length > 0 && paths2.length < 2000) {
|
|
22193
22481
|
const current = stack.pop() ?? ".";
|
|
22194
22482
|
const absolute = current === "." ? rootDir : join11(rootDir, current);
|
|
22195
22483
|
let entries;
|
|
@@ -22214,14 +22502,14 @@ function readDirectoryPreflightPaths(rootDir) {
|
|
|
22214
22502
|
if (stat.isDirectory()) {
|
|
22215
22503
|
stack.push(child);
|
|
22216
22504
|
} else {
|
|
22217
|
-
|
|
22505
|
+
paths2.push(child);
|
|
22218
22506
|
}
|
|
22219
22507
|
}
|
|
22220
22508
|
}
|
|
22221
|
-
return
|
|
22509
|
+
return paths2;
|
|
22222
22510
|
}
|
|
22223
22511
|
function shouldSkipPreflightPath(path) {
|
|
22224
|
-
const normalized =
|
|
22512
|
+
const normalized = normalizePath3(path);
|
|
22225
22513
|
if (!normalized || normalized.startsWith(".moda/"))
|
|
22226
22514
|
return true;
|
|
22227
22515
|
const parts = normalized.split("/");
|
|
@@ -22346,7 +22634,7 @@ function collectSnapshotInputs(rootDir, maxFiles, maxTextBytes) {
|
|
|
22346
22634
|
let inventoryFileCount = 0;
|
|
22347
22635
|
let inventoryTextBytes = 0;
|
|
22348
22636
|
function walk(current) {
|
|
22349
|
-
const path =
|
|
22637
|
+
const path = normalizePath3(relative9(rootDir, current)) || ".";
|
|
22350
22638
|
let stat;
|
|
22351
22639
|
try {
|
|
22352
22640
|
stat = lstatSync7(current);
|
|
@@ -22417,7 +22705,7 @@ function buildSourceSnapshot(rootDir) {
|
|
|
22417
22705
|
}
|
|
22418
22706
|
function buildCommandScanPlan(context, rootDir) {
|
|
22419
22707
|
const explicitPath = context.flags.path !== undefined;
|
|
22420
|
-
const rel2 =
|
|
22708
|
+
const rel2 = normalizePath3(relative9(context.cwd, rootDir)) || ".";
|
|
22421
22709
|
const scope = explicitPath && rel2 !== "." ? "narrow" : "broad";
|
|
22422
22710
|
const machineReadable = context.outputMode !== "human";
|
|
22423
22711
|
const approvalRequired = context.positional === "analyze" && scope === "broad" && !context.yes;
|
|
@@ -22502,7 +22790,7 @@ function writeHumanBlock(context, message) {
|
|
|
22502
22790
|
function buildHarnessReadPlan(rootDir, pathWasExplicit) {
|
|
22503
22791
|
return {
|
|
22504
22792
|
scope: pathWasExplicit ? "narrow" : "broad",
|
|
22505
|
-
rootPaths: [
|
|
22793
|
+
rootPaths: [normalizePath3(relative9(rootDir, rootDir)) || "."],
|
|
22506
22794
|
willRead: [
|
|
22507
22795
|
"package manifests",
|
|
22508
22796
|
"source files under the selected path",
|
|
@@ -22715,7 +23003,7 @@ function findFresherHarnessReports(rootDir) {
|
|
|
22715
23003
|
const candidate = lstatSync7(join11(child, HARNESS_REPORT_PATH));
|
|
22716
23004
|
if (candidate.isFile() && candidate.mtimeMs > rootMtimeMs) {
|
|
22717
23005
|
fresher.push({
|
|
22718
|
-
path:
|
|
23006
|
+
path: normalizePath3(relative9(rootDir, join11(child, HARNESS_REPORT_PATH))),
|
|
22719
23007
|
mtimeMs: candidate.mtimeMs
|
|
22720
23008
|
});
|
|
22721
23009
|
}
|
|
@@ -22727,8 +23015,8 @@ function findFresherHarnessReports(rootDir) {
|
|
|
22727
23015
|
return fresher.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
22728
23016
|
}
|
|
22729
23017
|
function warnFresherSubdirHarnessReports(context, rootDir, explicitReport) {
|
|
22730
|
-
const explicitReportPath = explicitReport && explicitReport !== "true" ?
|
|
22731
|
-
if (explicitReportPath && explicitReportPath !==
|
|
23018
|
+
const explicitReportPath = explicitReport && explicitReport !== "true" ? normalizePath3(relative9(rootDir, resolve9(rootDir, explicitReport))) : undefined;
|
|
23019
|
+
if (explicitReportPath && explicitReportPath !== normalizePath3(HARNESS_REPORT_PATH))
|
|
22732
23020
|
return;
|
|
22733
23021
|
let fresher;
|
|
22734
23022
|
try {
|
|
@@ -22739,7 +23027,7 @@ function warnFresherSubdirHarnessReports(context, rootDir, explicitReport) {
|
|
|
22739
23027
|
if (fresher.length === 0)
|
|
22740
23028
|
return;
|
|
22741
23029
|
const newest = fresher[0];
|
|
22742
|
-
const subdir =
|
|
23030
|
+
const subdir = normalizePath3(dirname8(dirname8(newest.path)));
|
|
22743
23031
|
const rootState = existsSync8(join11(rootDir, HARNESS_REPORT_PATH)) ? `older ${HARNESS_REPORT_PATH}` : `no ${HARNESS_REPORT_PATH}`;
|
|
22744
23032
|
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
23033
|
}
|
|
@@ -22934,7 +23222,7 @@ function inventoryFiles(rootDir, skipped, options = {}) {
|
|
|
22934
23222
|
const maxTextBytes = numericEnv("MODA_HARNESS_MAX_TEXT_BYTES", DEFAULT_MAX_INVENTORY_TEXT_BYTES);
|
|
22935
23223
|
let textBytes = 0;
|
|
22936
23224
|
function walk(current) {
|
|
22937
|
-
const rel2 =
|
|
23225
|
+
const rel2 = normalizePath3(relative9(rootReal, current)) || ".";
|
|
22938
23226
|
let stat;
|
|
22939
23227
|
try {
|
|
22940
23228
|
stat = lstatSync7(current);
|
|
@@ -23150,7 +23438,7 @@ function runtimeAgentFromAnnotation(annotation) {
|
|
|
23150
23438
|
kind: "runtime_agent",
|
|
23151
23439
|
purpose: first2(values.purpose) ?? first2(values.description),
|
|
23152
23440
|
familyId: first2(values.family),
|
|
23153
|
-
root:
|
|
23441
|
+
root: normalizePath3(first2(values.root) ?? dirname8(annotation.evidence.path)),
|
|
23154
23442
|
entrypointIds: values.entrypoint ?? [stableId("entry", annotation.evidence.path)],
|
|
23155
23443
|
channelAdapterIds: values.channel ?? [],
|
|
23156
23444
|
artifactIds: [...values.artifact ?? [], ...values.prompt ?? [], ...values.tool ?? []],
|
|
@@ -23386,7 +23674,7 @@ function inferRuntimeAgent(file, graph) {
|
|
|
23386
23674
|
name: titleFromId(file.path.replace(/\.(ts|tsx|js|mjs|py)$/i, "")),
|
|
23387
23675
|
kind: "runtime_agent",
|
|
23388
23676
|
purpose: inferAgentPurpose(file),
|
|
23389
|
-
root:
|
|
23677
|
+
root: normalizePath3(dirname8(file.path)),
|
|
23390
23678
|
entrypointIds: [entryId],
|
|
23391
23679
|
channelAdapterIds: channelIds,
|
|
23392
23680
|
artifactIds,
|
|
@@ -24285,7 +24573,7 @@ function contentHashForAnnotatedSource(sourcePath, annotation) {
|
|
|
24285
24573
|
function readSmallTextFileForHash(absPath, rootDir) {
|
|
24286
24574
|
if (!existsSync8(absPath))
|
|
24287
24575
|
return;
|
|
24288
|
-
const rel2 =
|
|
24576
|
+
const rel2 = normalizePath3(relative9(rootDir, absPath));
|
|
24289
24577
|
if (isSecretishPath(rel2))
|
|
24290
24578
|
return;
|
|
24291
24579
|
let stat;
|
|
@@ -24386,7 +24674,7 @@ function titleFromId(id) {
|
|
|
24386
24674
|
function promptNameFromPath(path) {
|
|
24387
24675
|
return titleFromId(basename6(path).replace(/\.(prompt\.)?(md|json|ya?ml)$/i, ""));
|
|
24388
24676
|
}
|
|
24389
|
-
function
|
|
24677
|
+
function normalizePath3(path) {
|
|
24390
24678
|
return path.split(sep5).join("/");
|
|
24391
24679
|
}
|
|
24392
24680
|
function hashText(text) {
|
|
@@ -27112,8 +27400,8 @@ function collectModels(result, ctx) {
|
|
|
27112
27400
|
const context = modelPathContext(result.rootDir);
|
|
27113
27401
|
const harnessPath = (path) => isHarnessModelPath(path, context);
|
|
27114
27402
|
for (const [id, entry] of byId) {
|
|
27115
|
-
const
|
|
27116
|
-
if (!
|
|
27403
|
+
const paths2 = [...entry.definitions.map((at) => at.path), ...entry.sites.map((site) => site.path)];
|
|
27404
|
+
if (!paths2.some(harnessPath))
|
|
27117
27405
|
byId.delete(id);
|
|
27118
27406
|
}
|
|
27119
27407
|
const kept = unresolved.filter((entry) => harnessPath(entry.path));
|
|
@@ -27430,7 +27718,7 @@ function enumerationRepository(ctx) {
|
|
|
27430
27718
|
};
|
|
27431
27719
|
walk(ctx.rootDir);
|
|
27432
27720
|
const workers = [];
|
|
27433
|
-
const
|
|
27721
|
+
const paths2 = new Set(files.map((file) => file.path));
|
|
27434
27722
|
const closure = (main) => {
|
|
27435
27723
|
const found = new Set, pending = [main];
|
|
27436
27724
|
for (let index = 0;index < pending.length; index++) {
|
|
@@ -27445,7 +27733,7 @@ function enumerationRepository(ctx) {
|
|
|
27445
27733
|
if (!ref.fileName.startsWith("."))
|
|
27446
27734
|
continue;
|
|
27447
27735
|
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) =>
|
|
27736
|
+
const target = [base, ...[".ts", ".tsx", ".js", ".mjs", "/index.ts", "/index.js"].map((suffix) => base + suffix)].find((candidate) => paths2.has(candidate));
|
|
27449
27737
|
if (target)
|
|
27450
27738
|
pending.push(target);
|
|
27451
27739
|
}
|
|
@@ -29046,7 +29334,7 @@ function runExtract(rootDir, options) {
|
|
|
29046
29334
|
return /\.svelte$/i.test(abs) ? svelteVirtualName(abs) : abs;
|
|
29047
29335
|
};
|
|
29048
29336
|
const lookup = (path) => repo?.owner.get(fileKey(path));
|
|
29049
|
-
const
|
|
29337
|
+
const sourceFile2 = (path) => lookup(path)?.program.getSourceFile(fileKey(path));
|
|
29050
29338
|
let files;
|
|
29051
29339
|
const ctx = {
|
|
29052
29340
|
rootDir,
|
|
@@ -29055,7 +29343,7 @@ function runExtract(rootDir, options) {
|
|
|
29055
29343
|
checkerFor: (path) => lookup(path)?.checker(),
|
|
29056
29344
|
sourceFiles: () => files ??= [...repo?.owner.entries() ?? []].filter(([file]) => !isTestPath(relPath(rootDir, file))).map(([file, entry]) => entry.program.getSourceFile(file)).filter((file) => Boolean(file)),
|
|
29057
29345
|
nodeAt: (ref) => {
|
|
29058
|
-
const source =
|
|
29346
|
+
const source = sourceFile2(ref.path);
|
|
29059
29347
|
return source ? nodeSpanning(source, ref.start, ref.end) : undefined;
|
|
29060
29348
|
}
|
|
29061
29349
|
};
|
|
@@ -30009,8 +30297,8 @@ function mergeEnumeratedComponents(artifacts, components) {
|
|
|
30009
30297
|
const candidates = extractedByName.get(item.name) ?? [];
|
|
30010
30298
|
if (candidates.length === 0)
|
|
30011
30299
|
return item.id.startsWith("tool:catalog:") ? `tool:${item.id}` : `tool:${item.name}`;
|
|
30012
|
-
const
|
|
30013
|
-
const target = candidates.find((candidate) => candidate.sourcePath &&
|
|
30300
|
+
const paths2 = new Set([item.sourcePath, ...item.evidence.map((entry) => entry.path)].filter(Boolean));
|
|
30301
|
+
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
30302
|
return `tool:${target.id}`;
|
|
30015
30303
|
};
|
|
30016
30304
|
for (const item of [...registry, ...artifacts, ...components.artifacts.filter((item2) => !registry.includes(item2))]) {
|