@farming-labs/docs 0.2.63 → 0.2.64
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/cli/index.mjs
CHANGED
|
@@ -180,7 +180,7 @@ async function main() {
|
|
|
180
180
|
printAgentsGenerateHelp();
|
|
181
181
|
process.exit(1);
|
|
182
182
|
} else if (parsedCommand.command === "doctor") {
|
|
183
|
-
const { parseDoctorArgs, printDoctorHelp, runDoctor } = await import("../doctor-
|
|
183
|
+
const { parseDoctorArgs, printDoctorHelp, runDoctor } = await import("../doctor-DtGYZ41i.mjs");
|
|
184
184
|
const doctorOptions = parseDoctorArgs(args.slice(1));
|
|
185
185
|
if (doctorOptions.help) {
|
|
186
186
|
printDoctorHelp();
|
|
@@ -188,7 +188,7 @@ async function main() {
|
|
|
188
188
|
}
|
|
189
189
|
await runDoctor(doctorOptions);
|
|
190
190
|
} else if (parsedCommand.command === "review") {
|
|
191
|
-
const { parseReviewArgs, printReviewHelp, runReview } = await import("../review-
|
|
191
|
+
const { parseReviewArgs, printReviewHelp, runReview } = await import("../review-CLoHTywU.mjs");
|
|
192
192
|
const reviewOptions = parseReviewArgs(args.slice(1));
|
|
193
193
|
if (reviewOptions.help) {
|
|
194
194
|
printReviewHelp();
|
|
@@ -13,7 +13,7 @@ import "./agent-skills-server-DraIb6FV.mjs";
|
|
|
13
13
|
import "./server.mjs";
|
|
14
14
|
import { _ as resolveDocsContentDir, d as readNavTitle, g as resolveDocsConfigPath, h as readTopLevelStringProperty, l as readBooleanProperty, r as extractTopLevelConfigObject, s as loadDocsConfigModuleResultWithProjectEnv, t as extractNestedObjectLiteral } from "./config-Wcdj-D0a.mjs";
|
|
15
15
|
import { t as detectFramework } from "./utils-DpiIioYb.mjs";
|
|
16
|
-
import { i as createAgentUsefulnessPagesFromMcp, n as analyzeAgentSurfaceDrift, r as analyzeAgentUsefulness, t as resolveGoldenEvaluationInput } from "./golden-evaluations-
|
|
16
|
+
import { i as createAgentUsefulnessPagesFromMcp, n as analyzeAgentSurfaceDrift, r as analyzeAgentUsefulness, t as resolveGoldenEvaluationInput } from "./golden-evaluations-Dj-9Eo3v.mjs";
|
|
17
17
|
import { existsSync, lstatSync, readFileSync, readdirSync } from "node:fs";
|
|
18
18
|
import path from "node:path";
|
|
19
19
|
import { LATEST_PROTOCOL_VERSION } from "@modelcontextprotocol/sdk/types.js";
|
|
@@ -210,6 +210,94 @@ const PACKAGE_MANAGER_OPTIONS_WITH_VALUES = new Set([
|
|
|
210
210
|
"-F",
|
|
211
211
|
"-w"
|
|
212
212
|
]);
|
|
213
|
+
const CURL_OPTIONS_WITH_VALUES = new Set([
|
|
214
|
+
"--cacert",
|
|
215
|
+
"--cert",
|
|
216
|
+
"--connect-timeout",
|
|
217
|
+
"--data",
|
|
218
|
+
"--data-ascii",
|
|
219
|
+
"--data-binary",
|
|
220
|
+
"--data-raw",
|
|
221
|
+
"--data-urlencode",
|
|
222
|
+
"--form",
|
|
223
|
+
"--header",
|
|
224
|
+
"--json",
|
|
225
|
+
"--key",
|
|
226
|
+
"--max-time",
|
|
227
|
+
"--output",
|
|
228
|
+
"--request",
|
|
229
|
+
"--resolve",
|
|
230
|
+
"--retry",
|
|
231
|
+
"--retry-delay",
|
|
232
|
+
"--url",
|
|
233
|
+
"--user",
|
|
234
|
+
"--user-agent"
|
|
235
|
+
]);
|
|
236
|
+
const CURL_OPTIONS_WITHOUT_VALUES = new Set([
|
|
237
|
+
"--compressed",
|
|
238
|
+
"--fail",
|
|
239
|
+
"--fail-with-body",
|
|
240
|
+
"--head",
|
|
241
|
+
"--include",
|
|
242
|
+
"--insecure",
|
|
243
|
+
"--location",
|
|
244
|
+
"--show-error",
|
|
245
|
+
"--silent",
|
|
246
|
+
"--verbose"
|
|
247
|
+
]);
|
|
248
|
+
const CURL_SHORT_OPTIONS_WITH_VALUES = new Set([
|
|
249
|
+
"A",
|
|
250
|
+
"d",
|
|
251
|
+
"F",
|
|
252
|
+
"H",
|
|
253
|
+
"o",
|
|
254
|
+
"u",
|
|
255
|
+
"X"
|
|
256
|
+
]);
|
|
257
|
+
const CURL_SHORT_OPTIONS_WITHOUT_VALUES = new Set([
|
|
258
|
+
"f",
|
|
259
|
+
"I",
|
|
260
|
+
"i",
|
|
261
|
+
"k",
|
|
262
|
+
"L",
|
|
263
|
+
"s",
|
|
264
|
+
"S",
|
|
265
|
+
"v"
|
|
266
|
+
]);
|
|
267
|
+
const TEST_UNARY_OPERATORS = new Set([
|
|
268
|
+
"-b",
|
|
269
|
+
"-c",
|
|
270
|
+
"-d",
|
|
271
|
+
"-e",
|
|
272
|
+
"-f",
|
|
273
|
+
"-g",
|
|
274
|
+
"-h",
|
|
275
|
+
"-L",
|
|
276
|
+
"-n",
|
|
277
|
+
"-p",
|
|
278
|
+
"-r",
|
|
279
|
+
"-S",
|
|
280
|
+
"-s",
|
|
281
|
+
"-t",
|
|
282
|
+
"-u",
|
|
283
|
+
"-w",
|
|
284
|
+
"-x",
|
|
285
|
+
"-z"
|
|
286
|
+
]);
|
|
287
|
+
const TEST_BINARY_OPERATORS = new Set([
|
|
288
|
+
"=",
|
|
289
|
+
"==",
|
|
290
|
+
"!=",
|
|
291
|
+
"-ef",
|
|
292
|
+
"-eq",
|
|
293
|
+
"-ge",
|
|
294
|
+
"-gt",
|
|
295
|
+
"-le",
|
|
296
|
+
"-lt",
|
|
297
|
+
"-ne",
|
|
298
|
+
"-nt",
|
|
299
|
+
"-ot"
|
|
300
|
+
]);
|
|
213
301
|
function isAgentContextVisible(scopes) {
|
|
214
302
|
return scopes.every((scope) => scope.only === void 0 || scope.only === "agent");
|
|
215
303
|
}
|
|
@@ -274,7 +362,8 @@ function analyzeAgentUsefulness(options) {
|
|
|
274
362
|
const rootDir = path.resolve(options.rootDir);
|
|
275
363
|
const packageManager = options.packageManager ?? detectPackageManager(rootDir);
|
|
276
364
|
const knownDocsCommands = new Set([...DEFAULT_DOCS_COMMANDS, ...options.knownDocsCommands ?? []]);
|
|
277
|
-
const
|
|
365
|
+
const workspaceRoot = findEnclosingWorkspaceRoot(rootDir);
|
|
366
|
+
const packageManifests = readProjectPackageManifests(workspaceRoot);
|
|
278
367
|
const pages = options.pages.map((page) => analyzePage(page));
|
|
279
368
|
const findings = [];
|
|
280
369
|
const unhealthyCommandKeys = /* @__PURE__ */ new Set();
|
|
@@ -345,7 +434,8 @@ function analyzeAgentUsefulness(options) {
|
|
|
345
434
|
rootDir,
|
|
346
435
|
packageManager,
|
|
347
436
|
knownDocsCommands,
|
|
348
|
-
packageManifests
|
|
437
|
+
packageManifests,
|
|
438
|
+
workspaceRoot
|
|
349
439
|
});
|
|
350
440
|
if (commandAnalysis.status === "unhealthy") unhealthyCommandKeys.add(commandKey);
|
|
351
441
|
if (commandAnalysis.status === "unverified") unverifiedCommandKeys.add(commandKey);
|
|
@@ -620,6 +710,14 @@ function analyzeCommand(options) {
|
|
|
620
710
|
}));
|
|
621
711
|
return commandAnalysis(findings);
|
|
622
712
|
}
|
|
713
|
+
if (hasUnsupportedShellControlSyntax(executableCommand)) {
|
|
714
|
+
findings.push(commandFinding(options, {
|
|
715
|
+
code: "command-unverified",
|
|
716
|
+
severity: "suggestion",
|
|
717
|
+
message: "Compound commands, redirections, and shell expansions are not executed or inferred; this command is unverified."
|
|
718
|
+
}));
|
|
719
|
+
return commandAnalysis(findings);
|
|
720
|
+
}
|
|
623
721
|
const tokens = tokenizeShellCommand(executableCommand);
|
|
624
722
|
const commandPackageManager = readCommandPackageManager(tokens);
|
|
625
723
|
const expectedPackageManager = options.command.packageManagerHint ?? (options.command.source === "contract" ? options.packageManager : void 0);
|
|
@@ -629,7 +727,7 @@ function analyzeCommand(options) {
|
|
|
629
727
|
message: `Command uses ${commandPackageManager}, but ${expectedPackageManager} is expected for this project or code block.`
|
|
630
728
|
}));
|
|
631
729
|
const workspaceSelection = readWorkspaceSelection(tokens, commandPackageManager);
|
|
632
|
-
const workspaceResolution = resolveWorkspaceSelection(workspaceSelection, options.packageManifests, options.rootDir);
|
|
730
|
+
const workspaceResolution = resolveWorkspaceSelection(workspaceSelection, options.packageManifests, options.rootDir, options.workspaceRoot);
|
|
633
731
|
if (workspaceResolution.status === "unresolved") {
|
|
634
732
|
const selectors = workspaceSelection.selectors.length ? workspaceSelection.selectors.join(", ") : "all workspaces";
|
|
635
733
|
findings.push(commandFinding(options, {
|
|
@@ -660,7 +758,7 @@ function analyzeCommand(options) {
|
|
|
660
758
|
severity: "error",
|
|
661
759
|
message: `Command references an unknown docs CLI command: docs ${docsCommand}`
|
|
662
760
|
}));
|
|
663
|
-
if (isStaticallyKnownPackageManagerCommand(tokens) || isVersionProbe(tokens)) verificationEstablished = true;
|
|
761
|
+
if (isStaticallyKnownPackageManagerCommand(tokens) || isVersionProbe(tokens) || isStaticallyValidCurlCommand(tokens) || isStaticallyValidShellBuiltin(tokens, resolvedCwd, options.rootDir) || isStaticallyValidAgentToolCommand(tokens)) verificationEstablished = true;
|
|
664
762
|
if (!verificationEstablished && findings.length === 0) findings.push(commandFinding(options, {
|
|
665
763
|
code: "command-unverified",
|
|
666
764
|
severity: "suggestion",
|
|
@@ -894,9 +992,74 @@ function detectPackageManager(rootDir) {
|
|
|
894
992
|
const declared = typeof packageJson?.packageManager === "string" ? packageJson.packageManager : "";
|
|
895
993
|
return /^(npm|pnpm|yarn|bun)@/.exec(declared)?.[1];
|
|
896
994
|
}
|
|
995
|
+
function findEnclosingWorkspaceRoot(startDir) {
|
|
996
|
+
const repositoryBoundary = findNearestGitBoundary(startDir);
|
|
997
|
+
let current = startDir;
|
|
998
|
+
let traversed = 0;
|
|
999
|
+
while (true) {
|
|
1000
|
+
if (existsSync(path.join(current, "pnpm-workspace.yaml")) || existsSync(path.join(current, "pnpm-workspace.yml"))) return current;
|
|
1001
|
+
const workspaces = readJsonFile(path.join(current, "package.json"))?.workspaces;
|
|
1002
|
+
if (Array.isArray(workspaces) || workspaces !== null && typeof workspaces === "object" && !Array.isArray(workspaces)) return current;
|
|
1003
|
+
if (current === repositoryBoundary || !repositoryBoundary && traversed >= 12) return startDir;
|
|
1004
|
+
const parent = path.dirname(current);
|
|
1005
|
+
if (parent === current) return startDir;
|
|
1006
|
+
current = parent;
|
|
1007
|
+
traversed += 1;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
function findNearestGitBoundary(startDir) {
|
|
1011
|
+
let current = startDir;
|
|
1012
|
+
while (true) {
|
|
1013
|
+
if (existsSync(path.join(current, ".git"))) return current;
|
|
1014
|
+
const parent = path.dirname(current);
|
|
1015
|
+
if (parent === current) return void 0;
|
|
1016
|
+
current = parent;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
897
1019
|
function normalizeShellCommand(command) {
|
|
898
1020
|
return command.trim().replace(/^\$\s*/, "");
|
|
899
1021
|
}
|
|
1022
|
+
function hasUnsupportedShellControlSyntax(command) {
|
|
1023
|
+
let quote;
|
|
1024
|
+
let escaped = false;
|
|
1025
|
+
for (let index = 0; index < command.length; index += 1) {
|
|
1026
|
+
const character = command[index] ?? "";
|
|
1027
|
+
if (escaped) {
|
|
1028
|
+
escaped = false;
|
|
1029
|
+
continue;
|
|
1030
|
+
}
|
|
1031
|
+
if (character === "\\") {
|
|
1032
|
+
escaped = true;
|
|
1033
|
+
continue;
|
|
1034
|
+
}
|
|
1035
|
+
if (quote) {
|
|
1036
|
+
if (character === quote) quote = void 0;
|
|
1037
|
+
continue;
|
|
1038
|
+
}
|
|
1039
|
+
if (character === "'" || character === "\"") {
|
|
1040
|
+
quote = character;
|
|
1041
|
+
continue;
|
|
1042
|
+
}
|
|
1043
|
+
if (character === "<") {
|
|
1044
|
+
const placeholder = /^<[A-Za-z0-9._-]+>/.exec(command.slice(index))?.[0];
|
|
1045
|
+
if (placeholder) {
|
|
1046
|
+
index += placeholder.length - 1;
|
|
1047
|
+
continue;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
if ([
|
|
1051
|
+
"&",
|
|
1052
|
+
"|",
|
|
1053
|
+
";",
|
|
1054
|
+
"<",
|
|
1055
|
+
">",
|
|
1056
|
+
"`",
|
|
1057
|
+
"\n",
|
|
1058
|
+
"\r"
|
|
1059
|
+
].includes(character) || character === "$" && command[index + 1] === "(") return true;
|
|
1060
|
+
}
|
|
1061
|
+
return Boolean(quote || escaped);
|
|
1062
|
+
}
|
|
900
1063
|
function tokenizeShellCommand(command) {
|
|
901
1064
|
return command.match(/"[^"]*"|'[^']*'|[^\s]+/g)?.map(stripShellQuotes) ?? [];
|
|
902
1065
|
}
|
|
@@ -1071,7 +1234,126 @@ function isVersionProbe(tokens) {
|
|
|
1071
1234
|
"yarn"
|
|
1072
1235
|
].includes(tokens[0] ?? "") && ["--version", "-v"].includes(tokens[1] ?? "");
|
|
1073
1236
|
}
|
|
1074
|
-
function
|
|
1237
|
+
function isStaticallyValidCurlCommand(tokens) {
|
|
1238
|
+
if (tokens[0] !== "curl") return false;
|
|
1239
|
+
let urls = 0;
|
|
1240
|
+
let parseOptions = true;
|
|
1241
|
+
for (let index = 1; index < tokens.length; index += 1) {
|
|
1242
|
+
const token = tokens[index] ?? "";
|
|
1243
|
+
if (parseOptions && token === "--") {
|
|
1244
|
+
parseOptions = false;
|
|
1245
|
+
continue;
|
|
1246
|
+
}
|
|
1247
|
+
if (parseOptions && token.startsWith("--")) {
|
|
1248
|
+
const equalsIndex = token.indexOf("=");
|
|
1249
|
+
const option = equalsIndex >= 0 ? token.slice(0, equalsIndex) : token;
|
|
1250
|
+
const inlineValue = equalsIndex >= 0 ? token.slice(equalsIndex + 1) : void 0;
|
|
1251
|
+
if (CURL_OPTIONS_WITHOUT_VALUES.has(option)) {
|
|
1252
|
+
if (inlineValue !== void 0) return false;
|
|
1253
|
+
continue;
|
|
1254
|
+
}
|
|
1255
|
+
if (!CURL_OPTIONS_WITH_VALUES.has(option)) return false;
|
|
1256
|
+
const value = inlineValue ?? tokens[index + 1];
|
|
1257
|
+
if (!value || !inlineValue && value.startsWith("-")) return false;
|
|
1258
|
+
if (inlineValue === void 0) index += 1;
|
|
1259
|
+
if (!isValidCurlOptionValue(option, value)) return false;
|
|
1260
|
+
if (option === "--url") urls += 1;
|
|
1261
|
+
continue;
|
|
1262
|
+
}
|
|
1263
|
+
if (parseOptions && token.startsWith("-") && token !== "-") {
|
|
1264
|
+
const shortOptions = token.slice(1);
|
|
1265
|
+
if (!shortOptions) return false;
|
|
1266
|
+
let consumed = false;
|
|
1267
|
+
for (let offset = 0; offset < shortOptions.length; offset += 1) {
|
|
1268
|
+
const option = shortOptions[offset] ?? "";
|
|
1269
|
+
if (CURL_SHORT_OPTIONS_WITHOUT_VALUES.has(option)) continue;
|
|
1270
|
+
if (!CURL_SHORT_OPTIONS_WITH_VALUES.has(option)) return false;
|
|
1271
|
+
const inlineValue = shortOptions.slice(offset + 1);
|
|
1272
|
+
const value = inlineValue || tokens[index + 1];
|
|
1273
|
+
if (!value || !inlineValue && value.startsWith("-")) return false;
|
|
1274
|
+
if (!inlineValue) index += 1;
|
|
1275
|
+
if (!isValidCurlOptionValue(`-${option}`, value)) return false;
|
|
1276
|
+
consumed = true;
|
|
1277
|
+
break;
|
|
1278
|
+
}
|
|
1279
|
+
if (consumed || [...shortOptions].every((item) => CURL_SHORT_OPTIONS_WITHOUT_VALUES.has(item))) continue;
|
|
1280
|
+
return false;
|
|
1281
|
+
}
|
|
1282
|
+
if (!isHttpUrl(token)) return false;
|
|
1283
|
+
urls += 1;
|
|
1284
|
+
}
|
|
1285
|
+
return urls > 0;
|
|
1286
|
+
}
|
|
1287
|
+
function isValidCurlOptionValue(option, value) {
|
|
1288
|
+
if (option === "--url") return isHttpUrl(value);
|
|
1289
|
+
if (option === "--request" || option === "-X") return /^[A-Z]+$/i.test(value);
|
|
1290
|
+
if (option === "--header" || option === "-H") return /^[^:\s][^:]*:\s*.*$/.test(value);
|
|
1291
|
+
if (option === "--connect-timeout" || option === "--max-time") return /^\d+(?:\.\d+)?$/.test(value);
|
|
1292
|
+
if (option === "--retry" || option === "--retry-delay") return /^\d+$/.test(value);
|
|
1293
|
+
return value.length > 0;
|
|
1294
|
+
}
|
|
1295
|
+
function isHttpUrl(value) {
|
|
1296
|
+
try {
|
|
1297
|
+
const url = new URL(value);
|
|
1298
|
+
return (url.protocol === "http:" || url.protocol === "https:") && Boolean(url.hostname);
|
|
1299
|
+
} catch {
|
|
1300
|
+
return false;
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
function isStaticallyValidShellBuiltin(tokens, cwd, rootDir) {
|
|
1304
|
+
const command = tokens[0];
|
|
1305
|
+
const args = tokens.slice(1);
|
|
1306
|
+
if (command === "echo") return true;
|
|
1307
|
+
if (command === "printf") return args.length > 0;
|
|
1308
|
+
if (command === "pwd") return args.every((argument) => argument === "-L" || argument === "-P");
|
|
1309
|
+
if (command === "export" || command === "unset") {
|
|
1310
|
+
if (args.length === 0) return false;
|
|
1311
|
+
return args.every((argument) => command === "export" ? /^[A-Za-z_][A-Za-z0-9_]*(?:=.*)?$/.test(argument) : /^[A-Za-z_][A-Za-z0-9_]*$/.test(argument));
|
|
1312
|
+
}
|
|
1313
|
+
if (command === "test") return isValidTestExpression(args);
|
|
1314
|
+
if (command === "[") return args.at(-1) === "]" && isValidTestExpression(args.slice(0, -1));
|
|
1315
|
+
if (command !== "cd" || args.length !== 1) return false;
|
|
1316
|
+
const target = args[0] ?? "";
|
|
1317
|
+
if (!target || target === "-" || path.isAbsolute(target) || /[$*?[\]{}]/.test(target)) return false;
|
|
1318
|
+
return isPathInside(rootDir, path.resolve(cwd, target));
|
|
1319
|
+
}
|
|
1320
|
+
function isValidTestExpression(args) {
|
|
1321
|
+
if (args[0] === "!") return args.length > 1 && isValidTestExpression(args.slice(1));
|
|
1322
|
+
if (args.length === 1) return true;
|
|
1323
|
+
if (args.length === 2) return TEST_UNARY_OPERATORS.has(args[0] ?? "");
|
|
1324
|
+
return args.length === 3 && TEST_BINARY_OPERATORS.has(args[1] ?? "");
|
|
1325
|
+
}
|
|
1326
|
+
function isStaticallyValidAgentToolCommand(tokens) {
|
|
1327
|
+
return isStaticallyValidSkillsCommand(tokens) || isStaticallyValidClaudeMcpCommand(tokens);
|
|
1328
|
+
}
|
|
1329
|
+
function isStaticallyValidSkillsCommand(tokens) {
|
|
1330
|
+
const invocation = unwrapDownloadRunner(tokens);
|
|
1331
|
+
if (!invocation || !/^skills(?:@(?:latest|\d+(?:\.\d+){0,2}))?$/.test(invocation[0] ?? "")) return false;
|
|
1332
|
+
if (invocation.length !== 3 || invocation[1] !== "add") return false;
|
|
1333
|
+
const source = invocation[2] ?? "";
|
|
1334
|
+
if (/^https:\/\/(?:www\.)?github\.com\/[^/\s]+\/[^/\s]+(?:\.git)?(?:#[^\s]+)?$/.test(source)) return true;
|
|
1335
|
+
return /^@?[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+(?:#[A-Za-z0-9._/-]+)?$/.test(source);
|
|
1336
|
+
}
|
|
1337
|
+
function unwrapDownloadRunner(tokens) {
|
|
1338
|
+
const runner = tokens[0];
|
|
1339
|
+
if (runner === "skills") return tokens;
|
|
1340
|
+
if (runner === "npx" || runner === "pnpx" || runner === "bunx") return tokens.slice(1);
|
|
1341
|
+
if (runner === "npm" && tokens[1] === "exec" && tokens[2] === "--") return tokens.slice(3);
|
|
1342
|
+
if ((runner === "pnpm" || runner === "yarn" || runner === "bun") && ["dlx", "x"].includes(tokens[1] ?? "")) return tokens.slice(2);
|
|
1343
|
+
}
|
|
1344
|
+
function isStaticallyValidClaudeMcpCommand(tokens) {
|
|
1345
|
+
if (tokens.length !== 5 || tokens[0] !== "claude" || tokens[1] !== "mcp" || tokens[2] !== "add-json" || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(tokens[3] ?? "")) return false;
|
|
1346
|
+
try {
|
|
1347
|
+
const config = JSON.parse(tokens[4] ?? "");
|
|
1348
|
+
if (!config || typeof config !== "object" || Array.isArray(config)) return false;
|
|
1349
|
+
if (config.type === "http" || config.type === "sse") return typeof config.url === "string" && isHttpUrl(config.url);
|
|
1350
|
+
if (config.type !== "stdio" || typeof config.command !== "string" || !config.command.trim()) return false;
|
|
1351
|
+
return config.args === void 0 || Array.isArray(config.args) && config.args.every((argument) => typeof argument === "string");
|
|
1352
|
+
} catch {
|
|
1353
|
+
return false;
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
function resolveWorkspaceSelection(selection, manifests, rootDir, workspaceRoot) {
|
|
1075
1357
|
if (!selection.requested) return {
|
|
1076
1358
|
status: "none",
|
|
1077
1359
|
manifests: []
|
|
@@ -1092,8 +1374,8 @@ function resolveWorkspaceSelection(selection, manifests, rootDir) {
|
|
|
1092
1374
|
resolved.push(namedManifest);
|
|
1093
1375
|
continue;
|
|
1094
1376
|
}
|
|
1095
|
-
const
|
|
1096
|
-
const pathManifest = [...manifests.values()].find((manifest) => path.resolve(manifest.directory)
|
|
1377
|
+
const selectorPaths = Array.from(new Set([path.resolve(rootDir, selector), path.resolve(workspaceRoot, selector)]));
|
|
1378
|
+
const pathManifest = [...manifests.values()].find((manifest) => selectorPaths.includes(path.resolve(manifest.directory)));
|
|
1097
1379
|
if (!pathManifest) return {
|
|
1098
1380
|
status: "unresolved",
|
|
1099
1381
|
manifests: []
|
|
@@ -7,7 +7,7 @@ import { createFilesystemDocsMcpSource, getDocsConfigSchema, resolveDocsMcpConfi
|
|
|
7
7
|
import "./code-blocks-DnNVNK2M.mjs";
|
|
8
8
|
import { _ as resolveDocsContentDir, g as resolveDocsConfigPath, h as readTopLevelStringProperty, s as loadDocsConfigModuleResultWithProjectEnv } from "./config-Wcdj-D0a.mjs";
|
|
9
9
|
import { t as detectFramework } from "./utils-DpiIioYb.mjs";
|
|
10
|
-
import { a as extractAgentBlocks, i as createAgentUsefulnessPagesFromMcp, n as analyzeAgentSurfaceDrift, r as analyzeAgentUsefulness, t as resolveGoldenEvaluationInput } from "./golden-evaluations-
|
|
10
|
+
import { a as extractAgentBlocks, i as createAgentUsefulnessPagesFromMcp, n as analyzeAgentSurfaceDrift, r as analyzeAgentUsefulness, t as resolveGoldenEvaluationInput } from "./golden-evaluations-Dj-9Eo3v.mjs";
|
|
11
11
|
import matter from "gray-matter";
|
|
12
12
|
import { existsSync, lstatSync, readFileSync, readdirSync } from "node:fs";
|
|
13
13
|
import path from "node:path";
|