agentinit 1.5.0 → 1.7.0

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +93 -10
  3. package/dist/agentinit-1.7.0.tgz +0 -0
  4. package/dist/agents/DroidAgent.d.ts +52 -0
  5. package/dist/agents/DroidAgent.d.ts.map +1 -0
  6. package/dist/agents/DroidAgent.js +228 -0
  7. package/dist/agents/DroidAgent.js.map +1 -0
  8. package/dist/cli.js +501 -48
  9. package/dist/commands/apply.d.ts.map +1 -1
  10. package/dist/commands/apply.js +2 -2
  11. package/dist/commands/apply.js.map +1 -1
  12. package/dist/commands/verifyMcp.d.ts.map +1 -1
  13. package/dist/commands/verifyMcp.js +26 -4
  14. package/dist/commands/verifyMcp.js.map +1 -1
  15. package/dist/constants/index.d.ts +1 -1
  16. package/dist/constants/index.d.ts.map +1 -1
  17. package/dist/constants/index.js +1 -1
  18. package/dist/constants/index.js.map +1 -1
  19. package/dist/constants/mcp.d.ts +1 -0
  20. package/dist/constants/mcp.d.ts.map +1 -1
  21. package/dist/constants/mcp.js +2 -0
  22. package/dist/constants/mcp.js.map +1 -1
  23. package/dist/core/agentManager.d.ts.map +1 -1
  24. package/dist/core/agentManager.js +3 -1
  25. package/dist/core/agentManager.js.map +1 -1
  26. package/dist/core/mcpClient.d.ts +124 -6
  27. package/dist/core/mcpClient.d.ts.map +1 -1
  28. package/dist/core/mcpClient.js +385 -39
  29. package/dist/core/mcpClient.js.map +1 -1
  30. package/dist/lib/utils/index.d.ts +3 -1
  31. package/dist/lib/utils/index.d.ts.map +1 -1
  32. package/dist/lib/utils/index.js +4 -1
  33. package/dist/lib/utils/index.js.map +1 -1
  34. package/dist/types/index.d.ts +10 -1
  35. package/dist/types/index.d.ts.map +1 -1
  36. package/dist/types/jsonSchema.d.ts +31 -0
  37. package/dist/types/jsonSchema.d.ts.map +1 -0
  38. package/dist/types/jsonSchema.js +6 -0
  39. package/dist/types/jsonSchema.js.map +1 -0
  40. package/dist/utils/packageVersion.d.ts +105 -0
  41. package/dist/utils/packageVersion.d.ts.map +1 -0
  42. package/dist/utils/packageVersion.js +219 -0
  43. package/dist/utils/packageVersion.js.map +1 -0
  44. package/package.json +1 -1
  45. package/dist/agentinit-1.5.0.tgz +0 -0
package/dist/cli.js CHANGED
@@ -19950,27 +19950,27 @@ var require_windows = __commonJS((exports, module) => {
19950
19950
  return checkPathExt(path, options2);
19951
19951
  };
19952
19952
  var isexe = function(path, options2, cb) {
19953
- fs14.stat(path, function(er, stat) {
19953
+ fs15.stat(path, function(er, stat) {
19954
19954
  cb(er, er ? false : checkStat(stat, path, options2));
19955
19955
  });
19956
19956
  };
19957
19957
  var sync = function(path, options2) {
19958
- return checkStat(fs14.statSync(path), path, options2);
19958
+ return checkStat(fs15.statSync(path), path, options2);
19959
19959
  };
19960
19960
  module.exports = isexe;
19961
19961
  isexe.sync = sync;
19962
- var fs14 = __require("fs");
19962
+ var fs15 = __require("fs");
19963
19963
  });
19964
19964
 
19965
19965
  // node_modules/isexe/mode.js
19966
19966
  var require_mode = __commonJS((exports, module) => {
19967
19967
  var isexe = function(path, options2, cb) {
19968
- fs14.stat(path, function(er, stat) {
19968
+ fs15.stat(path, function(er, stat) {
19969
19969
  cb(er, er ? false : checkStat(stat, options2));
19970
19970
  });
19971
19971
  };
19972
19972
  var sync = function(path, options2) {
19973
- return checkStat(fs14.statSync(path), options2);
19973
+ return checkStat(fs15.statSync(path), options2);
19974
19974
  };
19975
19975
  var checkStat = function(stat, options2) {
19976
19976
  return stat.isFile() && checkMode(stat, options2);
@@ -19990,7 +19990,7 @@ var require_mode = __commonJS((exports, module) => {
19990
19990
  };
19991
19991
  module.exports = isexe;
19992
19992
  isexe.sync = sync;
19993
- var fs14 = __require("fs");
19993
+ var fs15 = __require("fs");
19994
19994
  });
19995
19995
 
19996
19996
  // node_modules/isexe/index.js
@@ -20035,7 +20035,7 @@ var require_isexe = __commonJS((exports, module) => {
20035
20035
  }
20036
20036
  }
20037
20037
  };
20038
- var fs14 = __require("fs");
20038
+ var fs15 = __require("fs");
20039
20039
  var core;
20040
20040
  if (process.platform === "win32" || global.TESTING_WINDOWS) {
20041
20041
  core = require_windows();
@@ -20242,14 +20242,14 @@ var require_readShebang = __commonJS((exports, module) => {
20242
20242
  const buffer = Buffer.alloc(size);
20243
20243
  let fd;
20244
20244
  try {
20245
- fd = fs14.openSync(command, "r");
20246
- fs14.readSync(fd, buffer, 0, size, 0);
20247
- fs14.closeSync(fd);
20245
+ fd = fs15.openSync(command, "r");
20246
+ fs15.readSync(fd, buffer, 0, size, 0);
20247
+ fs15.closeSync(fd);
20248
20248
  } catch (e) {
20249
20249
  }
20250
20250
  return shebangCommand(buffer.toString());
20251
20251
  };
20252
- var fs14 = __require("fs");
20252
+ var fs15 = __require("fs");
20253
20253
  var shebangCommand = require_shebang_command();
20254
20254
  module.exports = readShebang;
20255
20255
  });
@@ -23001,6 +23001,7 @@ var getPackageVersion = function() {
23001
23001
  }
23002
23002
  };
23003
23003
  var DEFAULT_CONNECTION_TIMEOUT_MS = 30000;
23004
+ var MAX_RESOURCE_CONTENT_SIZE = 10 * 1024 * 1024;
23004
23005
  var MCP_VERIFIER_CONFIG = {
23005
23006
  name: "agentinit-verifier",
23006
23007
  version: getPackageVersion()
@@ -24862,6 +24863,179 @@ class CursorAgent extends Agent {
24862
24863
  }
24863
24864
  }
24864
24865
 
24866
+ // dist/agents/DroidAgent.js
24867
+ class DroidAgent extends Agent {
24868
+ constructor() {
24869
+ const definition = {
24870
+ id: "droid",
24871
+ name: "Droid (Factory)",
24872
+ url: "https://factory.ai",
24873
+ capabilities: {
24874
+ mcp: {
24875
+ stdio: true,
24876
+ http: false,
24877
+ sse: false
24878
+ },
24879
+ rules: true,
24880
+ hooks: false,
24881
+ commands: false,
24882
+ subagents: false,
24883
+ statusline: false
24884
+ },
24885
+ configFiles: [
24886
+ {
24887
+ path: "AGENTS.md",
24888
+ purpose: "rules",
24889
+ format: "markdown",
24890
+ type: "file",
24891
+ optional: true,
24892
+ description: "Agent instructions and rules in markdown format"
24893
+ }
24894
+ ],
24895
+ nativeConfigPath: ".factory/mcp.json",
24896
+ globalConfigPath: "~/.factory/mcp.json"
24897
+ };
24898
+ super(definition);
24899
+ }
24900
+ async applyMCPConfig(projectPath, servers) {
24901
+ await this.applyGlobalMCPConfig(servers);
24902
+ }
24903
+ async applyGlobalMCPConfig(servers) {
24904
+ const globalPath = this.getGlobalMcpPath();
24905
+ if (!globalPath) {
24906
+ throw new Error(`Droid global configuration path could not be determined`);
24907
+ }
24908
+ await ensureDirectoryExists(globalPath);
24909
+ const existingContent = await readFileIfExists(globalPath);
24910
+ let existingConfig = { mcpServers: {} };
24911
+ if (existingContent) {
24912
+ try {
24913
+ existingConfig = JSON.parse(existingContent);
24914
+ if (!existingConfig.mcpServers) {
24915
+ existingConfig.mcpServers = {};
24916
+ }
24917
+ } catch (error) {
24918
+ console.warn("Warning: Existing ~/.factory/mcp.json is invalid, creating new configuration");
24919
+ existingConfig = { mcpServers: {} };
24920
+ }
24921
+ }
24922
+ for (const server of servers) {
24923
+ const droidServer = {
24924
+ type: "stdio"
24925
+ };
24926
+ if (server.command) {
24927
+ droidServer.command = server.command;
24928
+ }
24929
+ if (server.args && server.args.length > 0) {
24930
+ droidServer.args = server.args;
24931
+ }
24932
+ if (server.env && Object.keys(server.env).length > 0) {
24933
+ droidServer.env = server.env;
24934
+ }
24935
+ droidServer.disabled = false;
24936
+ existingConfig.mcpServers[server.name] = droidServer;
24937
+ }
24938
+ const configJson = JSON.stringify(existingConfig, null, 2);
24939
+ await writeFile(globalPath, configJson);
24940
+ }
24941
+ filterMCPServers(servers) {
24942
+ return servers.filter((server) => server.type === "stdio");
24943
+ }
24944
+ transformMCPServers(servers) {
24945
+ return servers;
24946
+ }
24947
+ async applyRulesConfig(configPath, rules, existingContent) {
24948
+ const rulesSection = this.generateRulesContent(rules.sections);
24949
+ let content = existingContent;
24950
+ if (content && !content.endsWith("\n")) {
24951
+ content += "\n";
24952
+ }
24953
+ if (content) {
24954
+ content += "\n";
24955
+ }
24956
+ content += rulesSection;
24957
+ return content.trim() + "\n";
24958
+ }
24959
+ extractExistingRules(content) {
24960
+ const ruleLines = content.split("\n").filter((line) => line.trim().startsWith("- "));
24961
+ return ruleLines.map((line) => line.replace(/^- /, "").trim()).filter((rule) => rule.length > 0);
24962
+ }
24963
+ extractExistingSections(content) {
24964
+ const lines = content.split("\n");
24965
+ const sections = [];
24966
+ let currentSection = null;
24967
+ for (const line of lines) {
24968
+ const trimmed = line.trim();
24969
+ if (trimmed.startsWith("## ") && trimmed.includes(" ")) {
24970
+ if (currentSection) {
24971
+ sections.push(currentSection);
24972
+ }
24973
+ const sectionName = trimmed.replace(/^##\s*/, "");
24974
+ currentSection = {
24975
+ templateId: sectionName.toLowerCase().replace(/\s+/g, "_"),
24976
+ templateName: sectionName,
24977
+ rules: []
24978
+ };
24979
+ } else if (currentSection && trimmed.startsWith("- ")) {
24980
+ const rule = trimmed.replace(/^- /, "");
24981
+ currentSection.rules.push(rule);
24982
+ }
24983
+ }
24984
+ if (currentSection) {
24985
+ sections.push(currentSection);
24986
+ }
24987
+ return sections;
24988
+ }
24989
+ generateRulesContent(sections) {
24990
+ let content = "";
24991
+ if (sections && sections.length > 0) {
24992
+ for (const ruleSection of sections) {
24993
+ content += `## ${ruleSection.templateName}\n\n`;
24994
+ for (const rule of ruleSection.rules) {
24995
+ content += `- ${rule}\n`;
24996
+ }
24997
+ content += "\n";
24998
+ }
24999
+ }
25000
+ return content;
25001
+ }
25002
+ async getMCPServers(projectPath) {
25003
+ const globalPath = this.getGlobalMcpPath();
25004
+ if (!globalPath) {
25005
+ return [];
25006
+ }
25007
+ const configContent = await readFileIfExists(globalPath);
25008
+ if (!configContent) {
25009
+ return [];
25010
+ }
25011
+ try {
25012
+ const config = JSON.parse(configContent);
25013
+ const servers = [];
25014
+ if (config.mcpServers) {
25015
+ for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
25016
+ const server = {
25017
+ name,
25018
+ type: "stdio"
25019
+ };
25020
+ if (serverConfig.command) {
25021
+ server.command = serverConfig.command;
25022
+ }
25023
+ if (serverConfig.args) {
25024
+ server.args = serverConfig.args;
25025
+ }
25026
+ if (serverConfig.env) {
25027
+ server.env = serverConfig.env;
25028
+ }
25029
+ servers.push(server);
25030
+ }
25031
+ }
25032
+ return servers;
25033
+ } catch (error) {
25034
+ return [];
25035
+ }
25036
+ }
25037
+ }
25038
+
24865
25039
  // dist/core/agentManager.js
24866
25040
  class AgentManager {
24867
25041
  agents = [];
@@ -24874,7 +25048,8 @@ class AgentManager {
24874
25048
  new ClaudeDesktopAgent,
24875
25049
  new CodexCliAgent,
24876
25050
  new GeminiCliAgent,
24877
- new CursorAgent
25051
+ new CursorAgent,
25052
+ new DroidAgent
24878
25053
  ];
24879
25054
  }
24880
25055
  getAllAgents() {
@@ -32263,6 +32438,96 @@ class SSEClientTransport {
32263
32438
  }
32264
32439
  }
32265
32440
 
32441
+ // dist/utils/packageVersion.js
32442
+ function extractExplicitVersion(packageSpec) {
32443
+ const versionMatch = packageSpec.match(/@([\d]+\.[\d]+\.[\d]+(?:[-+].+)?$)/);
32444
+ if (versionMatch && versionMatch[1]) {
32445
+ logger.debug(`[extractExplicitVersion] Found explicit version: ${versionMatch[1]} in "${packageSpec}"`);
32446
+ return versionMatch[1];
32447
+ }
32448
+ return null;
32449
+ }
32450
+ function extractPackageName(packageSpec) {
32451
+ return packageSpec.replace(/@[\d]+\.[\d]+\.[\d]+(?:[-+].+)?$/, "").replace(/@latest$/, "").replace(/@next$/, "").replace(/@canary$/, "");
32452
+ }
32453
+ function extractPackageFromCommand(command, args) {
32454
+ if (!command || !args || args.length === 0) {
32455
+ return null;
32456
+ }
32457
+ const packageManagers = ["npx", "bunx", "pnpm", "yarn"];
32458
+ if (!packageManagers.includes(command)) {
32459
+ logger.debug(`[extractPackageFromCommand] Not a package manager command: ${command}`);
32460
+ return null;
32461
+ }
32462
+ for (const arg of args) {
32463
+ if (arg.startsWith("-")) {
32464
+ continue;
32465
+ }
32466
+ if (arg === "dlx" || arg === "exec") {
32467
+ continue;
32468
+ }
32469
+ const packagePattern = /^(@[a-z0-9-]+\/)?[a-z0-9_-]+(@[\w.-]+)?$/i;
32470
+ if (packagePattern.test(arg)) {
32471
+ logger.debug(`[extractPackageFromCommand] Found package: ${arg}`);
32472
+ return arg;
32473
+ }
32474
+ }
32475
+ logger.debug(`[extractPackageFromCommand] No package found in args: ${args.join(" ")}`);
32476
+ return null;
32477
+ }
32478
+ async function fetchLatestVersion(packageSpec, options2 = {}) {
32479
+ const { timeout = 5000, useCache = true } = options2;
32480
+ const explicitVersion = extractExplicitVersion(packageSpec);
32481
+ if (explicitVersion) {
32482
+ return explicitVersion;
32483
+ }
32484
+ const cleanPackageName = extractPackageName(packageSpec);
32485
+ if (useCache) {
32486
+ const cached = versionCache.get(cleanPackageName);
32487
+ if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {
32488
+ logger.debug(`[fetchLatestVersion] Cache hit for: ${cleanPackageName} -> ${cached.version}`);
32489
+ return cached.version;
32490
+ }
32491
+ }
32492
+ try {
32493
+ logger.debug(`[fetchLatestVersion] Fetching from npm registry: ${cleanPackageName}`);
32494
+ const controller = new AbortController;
32495
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
32496
+ const url = `https://registry.npmjs.org/${cleanPackageName}/latest`;
32497
+ const response = await fetch(url, {
32498
+ headers: { Accept: "application/json" },
32499
+ signal: controller.signal
32500
+ });
32501
+ clearTimeout(timeoutId);
32502
+ if (!response.ok) {
32503
+ logger.debug(`[fetchLatestVersion] npm registry returned ${response.status} for ${cleanPackageName}`);
32504
+ return null;
32505
+ }
32506
+ const data = await response.json();
32507
+ if (!data.version) {
32508
+ logger.debug(`[fetchLatestVersion] No version field in response for ${cleanPackageName}`);
32509
+ return null;
32510
+ }
32511
+ versionCache.set(cleanPackageName, {
32512
+ version: data.version,
32513
+ timestamp: Date.now()
32514
+ });
32515
+ logger.debug(`[fetchLatestVersion] Success: ${cleanPackageName}@${data.version}`);
32516
+ return data.version;
32517
+ } catch (error) {
32518
+ if (error instanceof Error) {
32519
+ if (error.name === "AbortError") {
32520
+ logger.debug(`[fetchLatestVersion] Timeout fetching version for ${cleanPackageName}`);
32521
+ } else {
32522
+ logger.debug(`[fetchLatestVersion] Error fetching version: ${error.message}`);
32523
+ }
32524
+ }
32525
+ return null;
32526
+ }
32527
+ }
32528
+ var versionCache = new Map;
32529
+ var CACHE_TTL_MS = 5 * 60 * 1000;
32530
+
32266
32531
  // dist/core/mcpClient.js
32267
32532
  class MCPVerificationError extends Error {
32268
32533
  serverName;
@@ -32285,6 +32550,83 @@ class MCPVerifier {
32285
32550
  return yellow(tokenCount.toString());
32286
32551
  return red(tokenCount.toString());
32287
32552
  }
32553
+ hasValidInputSchema(tool) {
32554
+ return tool.inputSchema !== undefined && typeof tool.inputSchema === "object" && Object.keys(tool.inputSchema.properties || {}).length > 0;
32555
+ }
32556
+ formatType(schema) {
32557
+ const type = schema.type || "any";
32558
+ return Array.isArray(type) ? type.join(" | ") : type;
32559
+ }
32560
+ formatNumberRange(schema) {
32561
+ const min = schema.minimum !== undefined ? schema.minimum : "-\u221E";
32562
+ const max = schema.maximum !== undefined ? schema.maximum : "\u221E";
32563
+ return `(${min}-${max})`;
32564
+ }
32565
+ formatStringLength(schema) {
32566
+ const minLen = schema.minLength !== undefined ? schema.minLength : 0;
32567
+ const maxLen = schema.maxLength !== undefined ? schema.maxLength : "\u221E";
32568
+ return `length: ${minLen}-${maxLen}`;
32569
+ }
32570
+ formatArrayConstraints(schema) {
32571
+ const constraints = [];
32572
+ if (schema.items) {
32573
+ const itemType = schema.items.type;
32574
+ const itemTypeStr = itemType ? Array.isArray(itemType) ? itemType.join(" | ") : itemType : "any";
32575
+ constraints.push(`items: ${itemTypeStr}`);
32576
+ if (schema.minItems !== undefined || schema.maxItems !== undefined) {
32577
+ const minItems = schema.minItems !== undefined ? schema.minItems : 0;
32578
+ const maxItems = schema.maxItems !== undefined ? schema.maxItems : "\u221E";
32579
+ constraints.push(`(${minItems}-${maxItems} items)`);
32580
+ }
32581
+ }
32582
+ return constraints;
32583
+ }
32584
+ formatConstraints(schema, typeInfo) {
32585
+ const constraints = [];
32586
+ if (schema.enum && Array.isArray(schema.enum)) {
32587
+ constraints.push(`[${schema.enum.join(", ")}]`);
32588
+ }
32589
+ if (schema.minimum !== undefined || schema.maximum !== undefined) {
32590
+ constraints.push(this.formatNumberRange(schema));
32591
+ }
32592
+ if (schema.default !== undefined) {
32593
+ constraints.push(`default: ${JSON.stringify(schema.default)}`);
32594
+ }
32595
+ if (schema.minLength !== undefined || schema.maxLength !== undefined) {
32596
+ constraints.push(this.formatStringLength(schema));
32597
+ }
32598
+ if (schema.pattern) {
32599
+ constraints.push(`pattern: ${schema.pattern}`);
32600
+ }
32601
+ const isArray = Array.isArray(schema.type) ? schema.type.includes("array") : schema.type === "array";
32602
+ if (isArray) {
32603
+ constraints.push(...this.formatArrayConstraints(schema));
32604
+ }
32605
+ return constraints;
32606
+ }
32607
+ formatParameter(name, schema, isRequired) {
32608
+ const parts = [];
32609
+ const typeInfo = this.formatType(schema);
32610
+ parts.push(`${name} (${isRequired ? "required" : "optional"})`);
32611
+ parts.push(typeInfo);
32612
+ if (schema.description) {
32613
+ parts.push(schema.description);
32614
+ }
32615
+ const constraints = this.formatConstraints(schema, typeInfo);
32616
+ if (constraints.length > 0) {
32617
+ parts.push(constraints.join(", "));
32618
+ }
32619
+ return ` \u2022 ${parts.join(" - ")}`;
32620
+ }
32621
+ formatToolParameters(tool) {
32622
+ if (!this.hasValidInputSchema(tool)) {
32623
+ return [];
32624
+ }
32625
+ const schema = tool.inputSchema;
32626
+ const properties = schema.properties || {};
32627
+ const required = schema.required || [];
32628
+ return Object.entries(properties).map(([name, prop]) => this.formatParameter(name, prop, required.includes(name)));
32629
+ }
32288
32630
  calculateToolTokens(tools, serverName) {
32289
32631
  const toolTokenCounts = new Map;
32290
32632
  let totalToolTokens = 0;
@@ -32316,19 +32658,19 @@ class MCPVerifier {
32316
32658
  };
32317
32659
  const functionDefinition = JSON.stringify(toolForCounting);
32318
32660
  const claudeToolRepresentation = `<function>${functionDefinition}</function>`;
32319
- const tokenCount = countTokens(claudeToolRepresentation) * 5;
32661
+ const tokenCount = countTokens(claudeToolRepresentation) * 9;
32320
32662
  toolTokenCounts.set(tool.name, tokenCount);
32321
32663
  totalToolTokens += tokenCount;
32322
32664
  } catch (error) {
32323
- console.warn(`Failed to count tokens for tool ${tool.name}:`, error);
32665
+ logger.error(`Failed to count tokens for tool ${tool.name}: ${error instanceof Error ? error.message : String(error)}`);
32324
32666
  toolTokenCounts.set(tool.name, 0);
32325
32667
  }
32326
32668
  }
32327
32669
  return { toolTokenCounts, totalToolTokens };
32328
32670
  }
32329
- async verifyServer(server, timeout) {
32671
+ async verifyServer(server, options2) {
32330
32672
  const startTime = Date.now();
32331
- const timeoutMs = timeout || this.defaultTimeout;
32673
+ const timeoutMs = options2?.timeout || this.defaultTimeout;
32332
32674
  const abortController = new AbortController;
32333
32675
  let client2 = null;
32334
32676
  let transport = null;
@@ -32356,7 +32698,7 @@ class MCPVerifier {
32356
32698
  clearTimeout(timeoutId);
32357
32699
  });
32358
32700
  });
32359
- const connectPromise = this.connectAndVerify(client2, transport, server, abortController.signal);
32701
+ const connectPromise = this.connectAndVerify(client2, transport, server, abortController.signal, options2);
32360
32702
  const capabilities = await Promise.race([connectPromise, timeoutPromise]);
32361
32703
  const connectionTime = Date.now() - startTime;
32362
32704
  return {
@@ -32388,8 +32730,8 @@ class MCPVerifier {
32388
32730
  }
32389
32731
  }
32390
32732
  }
32391
- async verifyServers(servers, timeout) {
32392
- const results = await Promise.allSettled(servers.map((server) => this.verifyServer(server, timeout)));
32733
+ async verifyServers(servers, options2) {
32734
+ const results = await Promise.allSettled(servers.map((server) => this.verifyServer(server, options2)));
32393
32735
  return results.map((result, index) => {
32394
32736
  if (result.status === "fulfilled") {
32395
32737
  return result.value;
@@ -32440,17 +32782,39 @@ class MCPVerifier {
32440
32782
  throw new MCPVerificationError(`Unsupported server type: ${server.type}`, server.name);
32441
32783
  }
32442
32784
  }
32443
- async connectAndVerify(client2, transport, server, abortSignal) {
32785
+ async connectAndVerify(client2, transport, server, abortSignal, options2) {
32444
32786
  try {
32445
32787
  if (abortSignal?.aborted) {
32446
32788
  throw new Error("Operation aborted");
32447
32789
  }
32448
32790
  await client2.connect(transport);
32791
+ const serverVersion = client2.getServerVersion();
32792
+ logger.debug(`[Version Detection] MCP protocol returned: ${JSON.stringify(serverVersion)}`);
32449
32793
  const serverInfo = {
32450
- name: server.name,
32451
- version: "unknown",
32794
+ name: serverVersion?.name || server.name,
32795
+ version: serverVersion?.version || "unknown",
32452
32796
  protocolVersion: "unknown"
32453
32797
  };
32798
+ if (serverInfo.version === "unknown" && server.type === MCPServerType.STDIO) {
32799
+ logger.debug(`[Version Detection] Version unknown, attempting npm registry fallback for STDIO server`);
32800
+ const packageSpec = extractPackageFromCommand(server.command, server.args);
32801
+ if (packageSpec) {
32802
+ logger.debug(`[Version Detection] Extracted package: ${packageSpec}`);
32803
+ try {
32804
+ const registryVersion = await fetchLatestVersion(packageSpec, { timeout: 3000 });
32805
+ if (registryVersion) {
32806
+ serverInfo.version = registryVersion;
32807
+ logger.debug(`[Version Detection] npm registry returned: ${registryVersion}`);
32808
+ } else {
32809
+ logger.debug(`[Version Detection] npm registry returned no version for: ${packageSpec}`);
32810
+ }
32811
+ } catch (error) {
32812
+ logger.debug(`[Version Detection] npm registry lookup failed: ${error instanceof Error ? error.message : "Unknown error"}`);
32813
+ }
32814
+ } else {
32815
+ logger.debug(`[Version Detection] Could not extract package name from command: ${server.command} ${server.args?.join(" ")}`);
32816
+ }
32817
+ }
32454
32818
  if (abortSignal?.aborted) {
32455
32819
  throw new Error("Operation aborted");
32456
32820
  }
@@ -32473,7 +32837,7 @@ class MCPVerifier {
32473
32837
  const resources = [];
32474
32838
  try {
32475
32839
  const resourcesResponse = await client2.listResources();
32476
- resources.push(...resourcesResponse.resources.map((resource) => {
32840
+ const resourcePromises = resourcesResponse.resources.map(async (resource) => {
32477
32841
  const mcpResource = { uri: resource.uri };
32478
32842
  if (resource.name !== undefined)
32479
32843
  mcpResource.name = resource.name;
@@ -32481,8 +32845,34 @@ class MCPVerifier {
32481
32845
  mcpResource.description = resource.description;
32482
32846
  if (resource.mimeType !== undefined)
32483
32847
  mcpResource.mimeType = resource.mimeType;
32848
+ if (options2?.includeResourceContents) {
32849
+ try {
32850
+ const resourceData = await client2.readResource({ uri: resource.uri });
32851
+ if (resourceData.contents && resourceData.contents.length > 0) {
32852
+ const content = resourceData.contents[0];
32853
+ if (content && "text" in content && typeof content.text === "string") {
32854
+ const contentSize = Buffer.byteLength(content.text, "utf8");
32855
+ if (contentSize > MAX_RESOURCE_CONTENT_SIZE) {
32856
+ logger.debug(`Resource content too large for ${resource.uri}: ${contentSize} bytes (max: ${MAX_RESOURCE_CONTENT_SIZE})`);
32857
+ } else {
32858
+ mcpResource.contents = content.text;
32859
+ }
32860
+ } else if (content && "blob" in content && typeof content.blob === "string") {
32861
+ const blobBuffer = Buffer.from(content.blob, "base64");
32862
+ if (blobBuffer.length > MAX_RESOURCE_CONTENT_SIZE) {
32863
+ logger.debug(`Resource content too large for ${resource.uri}: ${blobBuffer.length} bytes (max: ${MAX_RESOURCE_CONTENT_SIZE})`);
32864
+ } else {
32865
+ mcpResource.contents = new Uint8Array(blobBuffer);
32866
+ }
32867
+ }
32868
+ }
32869
+ } catch (resourceError) {
32870
+ logger.debug(`Failed to fetch resource content for ${resource.uri}: ${resourceError instanceof Error ? resourceError.message : "Unknown error"}`);
32871
+ }
32872
+ }
32484
32873
  return mcpResource;
32485
- }));
32874
+ });
32875
+ resources.push(...await Promise.all(resourcePromises));
32486
32876
  } catch (error) {
32487
32877
  }
32488
32878
  if (abortSignal?.aborted) {
@@ -32491,7 +32881,7 @@ class MCPVerifier {
32491
32881
  const prompts2 = [];
32492
32882
  try {
32493
32883
  const promptsResponse = await client2.listPrompts();
32494
- prompts2.push(...promptsResponse.prompts.map((prompt) => {
32884
+ const promptPromises = promptsResponse.prompts.map(async (prompt) => {
32495
32885
  const mcpPrompt = { name: prompt.name };
32496
32886
  if (prompt.description !== undefined)
32497
32887
  mcpPrompt.description = prompt.description;
@@ -32505,19 +32895,40 @@ class MCPVerifier {
32505
32895
  return mcpArg;
32506
32896
  });
32507
32897
  }
32898
+ if (options2?.includePromptDetails) {
32899
+ try {
32900
+ const promptData = await client2.getPrompt({ name: prompt.name, arguments: {} });
32901
+ if (promptData.messages && promptData.messages.length > 0) {
32902
+ mcpPrompt.template = promptData.messages.map((msg) => {
32903
+ if (typeof msg.content === "string")
32904
+ return msg.content;
32905
+ if (typeof msg.content === "object" && "text" in msg.content)
32906
+ return msg.content.text;
32907
+ return JSON.stringify(msg.content);
32908
+ }).join("\n\n");
32909
+ }
32910
+ } catch (promptError) {
32911
+ logger.debug(`Failed to fetch prompt template for ${prompt.name}: ${promptError instanceof Error ? promptError.message : "Unknown error"}`);
32912
+ }
32913
+ }
32508
32914
  return mcpPrompt;
32509
- }));
32915
+ });
32916
+ prompts2.push(...await Promise.all(promptPromises));
32510
32917
  } catch (error) {
32511
32918
  }
32512
- const { toolTokenCounts, totalToolTokens } = this.calculateToolTokens(tools, server.name);
32513
- return {
32919
+ const shouldIncludeTokenCounts = options2?.includeTokenCounts !== false;
32920
+ const tokenData = shouldIncludeTokenCounts ? this.calculateToolTokens(tools, server.name) : undefined;
32921
+ const capabilities = {
32514
32922
  tools,
32515
32923
  resources,
32516
32924
  prompts: prompts2,
32517
- serverInfo,
32518
- toolTokenCounts,
32519
- totalToolTokens
32925
+ serverInfo
32520
32926
  };
32927
+ if (tokenData) {
32928
+ capabilities.toolTokenCounts = tokenData.toolTokenCounts;
32929
+ capabilities.totalToolTokens = tokenData.totalToolTokens;
32930
+ }
32931
+ return capabilities;
32521
32932
  } finally {
32522
32933
  try {
32523
32934
  await client2.close();
@@ -32543,20 +32954,42 @@ class MCPVerifier {
32543
32954
  const tokenCount = capabilities.toolTokenCounts?.get(tool.name) || 0;
32544
32955
  const tokenDisplay = tokenCount > 0 ? ` (${tokenCount} tokens)` : "";
32545
32956
  output.push(` \u2022 ${tool.name}${tokenDisplay}${tool.description ? ` - ${tool.description}` : ""}`);
32957
+ const parameters = this.formatToolParameters(tool);
32958
+ if (parameters.length > 0) {
32959
+ parameters.forEach((param) => output.push(param));
32960
+ }
32546
32961
  });
32547
32962
  }
32548
- if (isDebugMode && capabilities.resources.length > 0) {
32549
- output.push(` \n Resources (${capabilities.resources.length}):`);
32550
- capabilities.resources.forEach((resource) => {
32551
- const resourceName = resource.name || resource.uri.split("/").pop() || resource.uri;
32552
- output.push(` \u2022 ${resourceName}${resource.description ? ` - ${resource.description}` : ""}`);
32553
- });
32963
+ if (capabilities.resources.length > 0) {
32964
+ const hasContents = capabilities.resources.some((r) => r.contents !== undefined);
32965
+ if (isDebugMode || hasContents) {
32966
+ output.push(` \n Resources (${capabilities.resources.length}):`);
32967
+ capabilities.resources.forEach((resource) => {
32968
+ const resourceName = resource.name || resource.uri.split("/").pop() || resource.uri;
32969
+ output.push(` \u2022 ${resourceName}${resource.description ? ` - ${resource.description}` : ""}`);
32970
+ if (resource.contents) {
32971
+ const contentStr = typeof resource.contents === "string" ? resource.contents : `<binary data: ${resource.contents.length} bytes>`;
32972
+ const preview = contentStr.length > 100 ? contentStr.slice(0, 100) + "..." : contentStr;
32973
+ output.push(` Content: ${preview}`);
32974
+ }
32975
+ });
32976
+ }
32554
32977
  }
32555
- if (isDebugMode && capabilities.prompts.length > 0) {
32556
- output.push(` \n Prompts (${capabilities.prompts.length}):`);
32557
- capabilities.prompts.forEach((prompt) => {
32558
- output.push(` \u2022 ${prompt.name}${prompt.description ? ` - ${prompt.description}` : ""}`);
32559
- });
32978
+ if (capabilities.prompts.length > 0) {
32979
+ const hasTemplates = capabilities.prompts.some((p) => p.template !== undefined);
32980
+ if (isDebugMode || hasTemplates) {
32981
+ output.push(` \n Prompts (${capabilities.prompts.length}):`);
32982
+ capabilities.prompts.forEach((prompt) => {
32983
+ output.push(` \u2022 ${prompt.name}${prompt.description ? ` - ${prompt.description}` : ""}`);
32984
+ if (prompt.template) {
32985
+ const preview = prompt.template.length > 100 ? prompt.template.slice(0, 100) + "..." : prompt.template;
32986
+ output.push(` Template: ${preview}`);
32987
+ }
32988
+ if (prompt.arguments && prompt.arguments.length > 0) {
32989
+ output.push(` Arguments: ${prompt.arguments.map((a) => `${a.name}${a.required ? "*" : ""}`).join(", ")}`);
32990
+ }
32991
+ });
32992
+ }
32560
32993
  }
32561
32994
  if (capabilities.tools.length === 0 && capabilities.resources.length === 0 && capabilities.prompts.length === 0) {
32562
32995
  output.push(` \u26A0\uFE0F No tools, resources, or prompts available`);
@@ -32839,8 +33272,8 @@ async function applyCommand(args) {
32839
33272
  logger.info("");
32840
33273
  const verifySpinner = ora(`Verifying ${mcpParsed.servers.length} MCP server(s)...`).start();
32841
33274
  try {
32842
- const verifier = new MCPVerifier(timeout);
32843
- const verificationResults = await verifier.verifyServers(mcpParsed.servers, timeout);
33275
+ const verifier = new MCPVerifier;
33276
+ const verificationResults = await verifier.verifyServers(mcpParsed.servers, timeout ? { timeout } : undefined);
32844
33277
  const successCount = verificationResults.filter((r) => r.status === "success").length;
32845
33278
  const errorCount = verificationResults.filter((r) => r.status === "error").length;
32846
33279
  const timeoutCount = verificationResults.filter((r) => r.status === "timeout").length;
@@ -33001,6 +33434,9 @@ async function verifyMcpCommand(args) {
33001
33434
  const timeoutArg = timeoutIndex >= 0 && timeoutIndex + 1 < args.length ? args[timeoutIndex + 1] : null;
33002
33435
  const parsedTimeout = timeoutArg ? parseInt(timeoutArg, 10) : NaN;
33003
33436
  const timeout = timeoutArg && Number.isFinite(parsedTimeout) && parsedTimeout > 0 ? parsedTimeout : undefined;
33437
+ const includeResources = args.includes("--include-resources");
33438
+ const includePrompts = args.includes("--include-prompts");
33439
+ const noTokens = args.includes("--no-tokens");
33004
33440
  const hasMcpArgs = args.some((arg) => arg.startsWith("--mcp-"));
33005
33441
  if (mcpName && hasAll) {
33006
33442
  logger.error("Cannot use --mcp-name and --all together. Choose one option.");
@@ -33014,9 +33450,9 @@ async function verifyMcpCommand(args) {
33014
33450
  logger.info("Usage: agentinit verify_mcp [options]");
33015
33451
  logger.info("");
33016
33452
  logger.info("Verify existing configurations:");
33017
- logger.info(" --mcp-name <name> Verify specific MCP server by name");
33018
- logger.info(" --all Verify all configured MCP servers");
33019
- logger.info(` --timeout <ms> Connection timeout in milliseconds (default: ${DEFAULT_CONNECTION_TIMEOUT_MS})`);
33453
+ logger.info(" --mcp-name <name> Verify specific MCP server by name");
33454
+ logger.info(" --all Verify all configured MCP servers");
33455
+ logger.info(` --timeout <ms> Connection timeout in milliseconds (default: ${DEFAULT_CONNECTION_TIMEOUT_MS})`);
33020
33456
  logger.info("");
33021
33457
  logger.info("Verify direct MCP configuration:");
33022
33458
  logger.info(" --mcp-stdio <name> <command> Verify STDIO MCP server");
@@ -33026,6 +33462,11 @@ async function verifyMcpCommand(args) {
33026
33462
  logger.info(" --env <env_vars> Environment variables for server");
33027
33463
  logger.info(" --auth <token> Authentication token for HTTP/SSE");
33028
33464
  logger.info("");
33465
+ logger.info("Advanced options:");
33466
+ logger.info(" --include-resources Fetch actual resource contents (may be slow)");
33467
+ logger.info(" --include-prompts Fetch prompt templates");
33468
+ logger.info(" --no-tokens Skip token counting");
33469
+ logger.info("");
33029
33470
  logger.info("Examples:");
33030
33471
  logger.info(" # Verify existing configurations");
33031
33472
  logger.info(" agentinit verify_mcp --all");
@@ -33034,6 +33475,9 @@ async function verifyMcpCommand(args) {
33034
33475
  logger.info(" # Verify direct configuration");
33035
33476
  logger.info(' agentinit verify_mcp --mcp-stdio everything "npx -y @modelcontextprotocol/server-everything"');
33036
33477
  logger.info(' agentinit verify_mcp --mcp-http github "https://api.github.com/mcp" --auth "Bearer token"');
33478
+ logger.info("");
33479
+ logger.info(" # Fetch resource contents and prompt templates");
33480
+ logger.info(" agentinit verify_mcp --all --include-resources --include-prompts");
33037
33481
  return;
33038
33482
  }
33039
33483
  let spinner;
@@ -33110,7 +33554,16 @@ async function verifyMcpCommand(args) {
33110
33554
  }
33111
33555
  }
33112
33556
  const verifier = new MCPVerifier(timeout);
33113
- const results = await verifier.verifyServers(serversToVerify, timeout);
33557
+ const options2 = {};
33558
+ if (timeout)
33559
+ options2.timeout = timeout;
33560
+ if (includeResources)
33561
+ options2.includeResourceContents = true;
33562
+ if (includePrompts)
33563
+ options2.includePromptDetails = true;
33564
+ if (noTokens)
33565
+ options2.includeTokenCounts = false;
33566
+ const results = await verifier.verifyServers(serversToVerify, Object.keys(options2).length > 0 ? options2 : undefined);
33114
33567
  const successCount = results.filter((r) => r.status === "success").length;
33115
33568
  const errorCount = results.filter((r) => r.status === "error").length;
33116
33569
  const timeoutCount = results.filter((r) => r.status === "timeout").length;