@mcpc-tech/cli 0.1.51 → 0.1.53

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/app.cjs CHANGED
@@ -506,7 +506,7 @@ var require_cross_spawn = __commonJS({
506
506
  var cp = require("child_process");
507
507
  var parse2 = require_parse();
508
508
  var enoent = require_enoent();
509
- function spawn2(command, args, options) {
509
+ function spawn3(command, args, options) {
510
510
  const parsed = parse2(command, args, options);
511
511
  const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
512
512
  enoent.hookChildProcess(spawned, parsed);
@@ -518,8 +518,8 @@ var require_cross_spawn = __commonJS({
518
518
  result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
519
519
  return result;
520
520
  }
521
- module2.exports = spawn2;
522
- module2.exports.spawn = spawn2;
521
+ module2.exports = spawn3;
522
+ module2.exports.spawn = spawn3;
523
523
  module2.exports.sync = spawnSync;
524
524
  module2.exports._parse = parse2;
525
525
  module2.exports._enoent = enoent;
@@ -9807,6 +9807,7 @@ var ComposableMCPServer = class extends Server {
9807
9807
  toolManager;
9808
9808
  logger = createLogger("mcpc.compose");
9809
9809
  fileLoaders = /* @__PURE__ */ new Map();
9810
+ pluginsDisposed = false;
9810
9811
  // Legacy property for backward compatibility
9811
9812
  get toolNameMapping() {
9812
9813
  return this.toolManager.getToolNameMapping();
@@ -10282,11 +10283,21 @@ var ComposableMCPServer = class extends Server {
10282
10283
  async disposePlugins() {
10283
10284
  await this.pluginManager.dispose();
10284
10285
  }
10286
+ /**
10287
+ * Dispose plugins only once to avoid duplicated cleanup in chained handlers.
10288
+ */
10289
+ async disposePluginsOnce() {
10290
+ if (this.pluginsDisposed) {
10291
+ return;
10292
+ }
10293
+ this.pluginsDisposed = true;
10294
+ await this.disposePlugins();
10295
+ }
10285
10296
  /**
10286
10297
  * Close the server and ensure all plugins are disposed
10287
10298
  */
10288
10299
  async close() {
10289
- await this.disposePlugins();
10300
+ await this.disposePluginsOnce();
10290
10301
  await super.close();
10291
10302
  }
10292
10303
  async compose(name, description, depsConfig = {
@@ -10391,16 +10402,20 @@ var ComposableMCPServer = class extends Server {
10391
10402
  server: this,
10392
10403
  toolNames: Object.keys(allTools)
10393
10404
  });
10405
+ const previousOnClose = this.onclose;
10394
10406
  this.onclose = async () => {
10395
10407
  await cleanupClients();
10396
- await this.disposePlugins();
10408
+ await this.disposePluginsOnce();
10397
10409
  await this.logger.info(`[${name}] Event: closed - cleaned up dependent clients and plugins`);
10410
+ previousOnClose?.();
10398
10411
  };
10412
+ const previousOnError = this.onerror;
10399
10413
  this.onerror = async (error) => {
10400
10414
  await this.logger.error(`[${name}] Event: error - ${error?.stack ?? String(error)}`);
10401
10415
  await cleanupClients();
10402
- await this.disposePlugins();
10416
+ await this.disposePluginsOnce();
10403
10417
  await this.logger.info(`[${name}] Action: cleaned up dependent clients and plugins`);
10418
+ previousOnError?.(error);
10404
10419
  };
10405
10420
  const toolNameToDetailList = Object.entries(allTools);
10406
10421
  const publicToolNames = this.getPublicToolNames();
@@ -11052,6 +11067,152 @@ Skill path: ${meta.basePath}
11052
11067
  };
11053
11068
  }
11054
11069
 
11070
+ // __mcpc__cli_latest/node_modules/@jsr/mcpc__core/src/plugins/bash.js
11071
+ var import_node_child_process = require("node:child_process");
11072
+ var import_node_process7 = __toESM(require("node:process"), 1);
11073
+ var DEFAULT_MAX_BYTES = 1e5;
11074
+ var DEFAULT_MAX_LINES = 2e3;
11075
+ var DEFAULT_TIMEOUT_MS = 6e4;
11076
+ function truncateOutput(stdout, stderr, maxBytes = DEFAULT_MAX_BYTES, maxLines = DEFAULT_MAX_LINES) {
11077
+ const fullOutput = (stderr ? `STDERR:
11078
+ ${stderr}
11079
+
11080
+ STDOUT:
11081
+ ` : "") + stdout;
11082
+ const lines = fullOutput.split("\n");
11083
+ if (lines.length > maxLines) {
11084
+ const truncatedLines = lines.slice(-maxLines);
11085
+ return {
11086
+ output: `[OUTPUT TRUNCATED] Showing last ${maxLines} lines of ${lines.length} total
11087
+
11088
+ ` + truncatedLines.join("\n"),
11089
+ truncated: true
11090
+ };
11091
+ }
11092
+ if (fullOutput.length > maxBytes) {
11093
+ const truncatedBytes = fullOutput.slice(-maxBytes);
11094
+ return {
11095
+ output: `[OUTPUT TRUNCATED] Showing last ${maxBytes} bytes of ${fullOutput.length} total
11096
+
11097
+ ` + truncatedBytes,
11098
+ truncated: true
11099
+ };
11100
+ }
11101
+ return {
11102
+ output: fullOutput,
11103
+ truncated: false
11104
+ };
11105
+ }
11106
+ function executeBash(command, cwd2, timeoutMs) {
11107
+ return new Promise((resolve5) => {
11108
+ const stdout = [];
11109
+ const stderr = [];
11110
+ const proc = (0, import_node_child_process.spawn)("bash", [
11111
+ "-c",
11112
+ command
11113
+ ], {
11114
+ cwd: cwd2,
11115
+ stdio: [
11116
+ "ignore",
11117
+ "pipe",
11118
+ "pipe"
11119
+ ]
11120
+ });
11121
+ proc.stdout?.on("data", (data) => {
11122
+ stdout.push(data.toString());
11123
+ });
11124
+ proc.stderr?.on("data", (data) => {
11125
+ stderr.push(data.toString());
11126
+ });
11127
+ proc.on("close", (code) => {
11128
+ resolve5({
11129
+ stdout: stdout.join(""),
11130
+ stderr: stderr.join(""),
11131
+ exitCode: code
11132
+ });
11133
+ });
11134
+ proc.on("error", (err) => {
11135
+ resolve5({
11136
+ stdout: "",
11137
+ stderr: err.message,
11138
+ exitCode: null
11139
+ });
11140
+ });
11141
+ setTimeout(() => {
11142
+ proc.kill("SIGTERM");
11143
+ resolve5({
11144
+ stdout: stdout.join(""),
11145
+ stderr: stderr.join("") + "\n\n[TIMEOUT] Command execution timed out",
11146
+ exitCode: null
11147
+ });
11148
+ }, timeoutMs);
11149
+ });
11150
+ }
11151
+ function createBashPlugin(options = {}) {
11152
+ const { maxBytes, maxLines, timeoutMs } = {
11153
+ maxBytes: DEFAULT_MAX_BYTES,
11154
+ maxLines: DEFAULT_MAX_LINES,
11155
+ timeoutMs: DEFAULT_TIMEOUT_MS,
11156
+ ...options
11157
+ };
11158
+ let serverRef = null;
11159
+ return {
11160
+ name: "plugin-bash",
11161
+ version: "1.0.0",
11162
+ // Store server reference for tool registration
11163
+ configureServer: (server) => {
11164
+ serverRef = server;
11165
+ },
11166
+ // Register bash tool with agent name prefix
11167
+ composeStart: (context2) => {
11168
+ if (!serverRef) return;
11169
+ const agentName = context2.serverName;
11170
+ const toolName = `${agentName}__bash`;
11171
+ serverRef.tool(toolName, "Execute a bash command and return its output.\n\nUse this for:\n- Running shell commands\n- Executing scripts\n- System operations\n\nNote: Output is truncated if too large.", {
11172
+ type: "object",
11173
+ properties: {
11174
+ command: {
11175
+ type: "string",
11176
+ description: "The bash command to execute"
11177
+ },
11178
+ cwd: {
11179
+ type: "string",
11180
+ description: "Optional: Working directory for the command (defaults to current directory)"
11181
+ }
11182
+ },
11183
+ required: [
11184
+ "command"
11185
+ ]
11186
+ }, async (args) => {
11187
+ const cwd2 = args.cwd || import_node_process7.default.cwd();
11188
+ const result = await executeBash(args.command, cwd2, timeoutMs);
11189
+ const { output, truncated } = truncateOutput(result.stdout, result.stderr, maxBytes, maxLines);
11190
+ let finalOutput = output;
11191
+ if (result.exitCode !== null && result.exitCode !== 0) {
11192
+ finalOutput = `[EXIT CODE: ${result.exitCode}]
11193
+ ` + finalOutput;
11194
+ }
11195
+ if (truncated) {
11196
+ finalOutput += `
11197
+
11198
+ [Note: Output was truncated]`;
11199
+ }
11200
+ return {
11201
+ content: [
11202
+ {
11203
+ type: "text",
11204
+ text: finalOutput
11205
+ }
11206
+ ],
11207
+ isError: result.exitCode !== null && result.exitCode !== 0
11208
+ };
11209
+ }, {
11210
+ internal: true
11211
+ });
11212
+ }
11213
+ };
11214
+ }
11215
+
11055
11216
  // __mcpc__cli_latest/node_modules/@mcpc/cli/src/defaults.js
11056
11217
  var import_plugin_code_execution = require("@mcpc-tech/plugin-code-execution");
11057
11218
 
@@ -13031,10 +13192,10 @@ function parse(content, options = {}) {
13031
13192
  }
13032
13193
 
13033
13194
  // __mcpc__cli_latest/node_modules/@jsr/mcpc__plugin-markdown-loader/src/markdown-loader.js
13034
- var import_node_process7 = __toESM(require("node:process"), 1);
13195
+ var import_node_process8 = __toESM(require("node:process"), 1);
13035
13196
  function replaceEnvVars(str2) {
13036
13197
  return str2.replace(/\$([A-Za-z_][A-Za-z0-9_]*)(?!\s*\()/g, (match, varName) => {
13037
- const value = import_node_process7.default.env[varName];
13198
+ const value = import_node_process8.default.env[varName];
13038
13199
  if (value !== void 0) {
13039
13200
  return value;
13040
13201
  }
@@ -13133,17 +13294,18 @@ var defaultPlugin = markdownLoaderPlugin();
13133
13294
 
13134
13295
  // __mcpc__cli_latest/node_modules/@mcpc/cli/src/defaults.js
13135
13296
  var import_node_path5 = require("node:path");
13136
- var import_node_process8 = __toESM(require("node:process"), 1);
13297
+ var import_node_process9 = __toESM(require("node:process"), 1);
13137
13298
  var DEFAULT_SKILLS_PATHS = [
13138
13299
  ".agent/skills"
13139
13300
  ];
13140
13301
  function getGlobalPlugins(skillsPaths) {
13141
- const resolvedPaths = skillsPaths.map((p2) => (0, import_node_path5.resolve)(import_node_process8.default.cwd(), p2));
13302
+ const resolvedPaths = skillsPaths.map((p2) => (0, import_node_path5.resolve)(import_node_process9.default.cwd(), p2));
13142
13303
  return [
13143
13304
  markdownLoaderPlugin(),
13144
13305
  createSkillsPlugin({
13145
13306
  paths: resolvedPaths
13146
- })
13307
+ }),
13308
+ createBashPlugin()
13147
13309
  ];
13148
13310
  }
13149
13311
  function getDefaultAgents() {
@@ -13449,15 +13611,17 @@ var Response2 = class _Response {
13449
13611
  this.#init = init;
13450
13612
  }
13451
13613
  if (typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) {
13452
- headers ||= init?.headers || { "content-type": "text/plain; charset=UTF-8" };
13453
- this[cacheKey] = [init?.status || 200, body, headers];
13614
+ ;
13615
+ this[cacheKey] = [init?.status || 200, body, headers || init?.headers];
13454
13616
  }
13455
13617
  }
13456
13618
  get headers() {
13457
13619
  const cache = this[cacheKey];
13458
13620
  if (cache) {
13459
13621
  if (!(cache[2] instanceof Headers)) {
13460
- cache[2] = new Headers(cache[2]);
13622
+ cache[2] = new Headers(
13623
+ cache[2] || { "content-type": "text/plain; charset=UTF-8" }
13624
+ );
13461
13625
  }
13462
13626
  return cache[2];
13463
13627
  }
@@ -13582,15 +13746,32 @@ var flushHeaders = (outgoing) => {
13582
13746
  };
13583
13747
  var responseViaCache = async (res, outgoing) => {
13584
13748
  let [status, body, header] = res[cacheKey];
13585
- if (header instanceof Headers) {
13749
+ let hasContentLength = false;
13750
+ if (!header) {
13751
+ header = { "content-type": "text/plain; charset=UTF-8" };
13752
+ } else if (header instanceof Headers) {
13753
+ hasContentLength = header.has("content-length");
13586
13754
  header = buildOutgoingHttpHeaders(header);
13755
+ } else if (Array.isArray(header)) {
13756
+ const headerObj = new Headers(header);
13757
+ hasContentLength = headerObj.has("content-length");
13758
+ header = buildOutgoingHttpHeaders(headerObj);
13759
+ } else {
13760
+ for (const key in header) {
13761
+ if (key.length === 14 && key.toLowerCase() === "content-length") {
13762
+ hasContentLength = true;
13763
+ break;
13764
+ }
13765
+ }
13587
13766
  }
13588
- if (typeof body === "string") {
13589
- header["Content-Length"] = Buffer.byteLength(body);
13590
- } else if (body instanceof Uint8Array) {
13591
- header["Content-Length"] = body.byteLength;
13592
- } else if (body instanceof Blob) {
13593
- header["Content-Length"] = body.size;
13767
+ if (!hasContentLength) {
13768
+ if (typeof body === "string") {
13769
+ header["Content-Length"] = Buffer.byteLength(body);
13770
+ } else if (body instanceof Uint8Array) {
13771
+ header["Content-Length"] = body.byteLength;
13772
+ } else if (body instanceof Blob) {
13773
+ header["Content-Length"] = body.size;
13774
+ }
13594
13775
  }
13595
13776
  outgoing.writeHead(status, header);
13596
13777
  if (typeof body === "string" || body instanceof Uint8Array) {
@@ -14743,8 +14924,8 @@ function parseArgs(args, options) {
14743
14924
  var import_promises4 = require("node:fs/promises");
14744
14925
  var import_node_os3 = require("node:os");
14745
14926
  var import_node_path6 = require("node:path");
14746
- var import_node_process9 = __toESM(require("node:process"), 1);
14747
- var CLI_VERSION = "0.1.51";
14927
+ var import_node_process10 = __toESM(require("node:process"), 1);
14928
+ var CLI_VERSION = "0.1.53";
14748
14929
  function extractServerName(command, commandArgs) {
14749
14930
  for (const arg of commandArgs) {
14750
14931
  if (!arg.startsWith("-")) {
@@ -14804,7 +14985,7 @@ async function saveUserConfig(config, newAgentName) {
14804
14985
  async function createWrapConfig(args) {
14805
14986
  if (!args.mcpServers || args.mcpServers.length === 0) {
14806
14987
  console.error("Error: --wrap/--add requires at least one MCP server\nExample: mcpc --wrap --mcp-stdio 'npx -y @wonderwhy-er/desktop-commander'\nMultiple: mcpc --add --mcp-stdio 'npx -y server1' --mcp-http 'https://api.example.com'");
14807
- import_node_process9.default.exit(1);
14988
+ import_node_process10.default.exit(1);
14808
14989
  }
14809
14990
  const mcpServers = {};
14810
14991
  const serverNames = [];
@@ -14927,7 +15108,7 @@ function parseMcpServer(cmdString, transportType) {
14927
15108
  };
14928
15109
  }
14929
15110
  function parseCLIArgs() {
14930
- const args = parseArgs(import_node_process9.default.argv.slice(2), {
15111
+ const args = parseArgs(import_node_process10.default.argv.slice(2), {
14931
15112
  boolean: [
14932
15113
  "help",
14933
15114
  "version",
@@ -15016,15 +15197,15 @@ async function loadConfig() {
15016
15197
  const args = parseCLIArgs();
15017
15198
  if (args.version) {
15018
15199
  printVersion();
15019
- import_node_process9.default.exit(0);
15200
+ import_node_process10.default.exit(0);
15020
15201
  }
15021
15202
  if (args.help) {
15022
15203
  printHelp();
15023
- import_node_process9.default.exit(0);
15204
+ import_node_process10.default.exit(0);
15024
15205
  }
15025
15206
  if (args.cwd) {
15026
- const targetCwd = (0, import_node_path6.resolve)(import_node_process9.default.cwd(), args.cwd);
15027
- import_node_process9.default.chdir(targetCwd);
15207
+ const targetCwd = (0, import_node_path6.resolve)(import_node_process10.default.cwd(), args.cwd);
15208
+ import_node_process10.default.chdir(targetCwd);
15028
15209
  console.error(`Changed working directory to: ${targetCwd}`);
15029
15210
  }
15030
15211
  const mergeSkills = (config) => {
@@ -15036,7 +15217,7 @@ async function loadConfig() {
15036
15217
  ...args,
15037
15218
  saveConfig: true
15038
15219
  });
15039
- import_node_process9.default.exit(0);
15220
+ import_node_process10.default.exit(0);
15040
15221
  }
15041
15222
  if (args.wrap) {
15042
15223
  return mergeSkills(await createWrapConfig({
@@ -15053,16 +15234,16 @@ async function loadConfig() {
15053
15234
  throw error;
15054
15235
  }
15055
15236
  }
15056
- if (import_node_process9.default.env.MCPC_CONFIG) {
15237
+ if (import_node_process10.default.env.MCPC_CONFIG) {
15057
15238
  try {
15058
- const parsed = JSON.parse(import_node_process9.default.env.MCPC_CONFIG);
15239
+ const parsed = JSON.parse(import_node_process10.default.env.MCPC_CONFIG);
15059
15240
  return mergeSkills(applyModeOverride(normalizeConfig(parsed), args.mode));
15060
15241
  } catch (error) {
15061
15242
  console.error("Failed to parse MCPC_CONFIG environment variable:", error);
15062
15243
  throw error;
15063
15244
  }
15064
15245
  }
15065
- const configUrl = args.configUrl || import_node_process9.default.env.MCPC_CONFIG_URL;
15246
+ const configUrl = args.configUrl || import_node_process10.default.env.MCPC_CONFIG_URL;
15066
15247
  if (configUrl) {
15067
15248
  try {
15068
15249
  const headers = {
@@ -15083,7 +15264,7 @@ async function loadConfig() {
15083
15264
  throw error;
15084
15265
  }
15085
15266
  }
15086
- const configFile = args.configFile || import_node_process9.default.env.MCPC_CONFIG_FILE;
15267
+ const configFile = args.configFile || import_node_process10.default.env.MCPC_CONFIG_FILE;
15087
15268
  if (configFile) {
15088
15269
  try {
15089
15270
  const config = await loadConfigFromFile(configFile);
@@ -15108,7 +15289,7 @@ async function loadConfig() {
15108
15289
  throw error;
15109
15290
  }
15110
15291
  }
15111
- const defaultJsonConfigPath = (0, import_node_path6.resolve)(import_node_process9.default.cwd(), "mcpc.config.json");
15292
+ const defaultJsonConfigPath = (0, import_node_path6.resolve)(import_node_process10.default.cwd(), "mcpc.config.json");
15112
15293
  try {
15113
15294
  const config = await loadConfigFromFile(defaultJsonConfigPath);
15114
15295
  return mergeSkills(applyModeOverride(config, args.mode));
@@ -15123,7 +15304,7 @@ async function loadConfig() {
15123
15304
  }
15124
15305
  function replaceEnvVars2(str2) {
15125
15306
  return str2.replace(/\$([A-Z_][A-Z0-9_]*)/g, (_match, varName) => {
15126
- return import_node_process9.default.env[varName] || "";
15307
+ return import_node_process10.default.env[varName] || "";
15127
15308
  });
15128
15309
  }
15129
15310
  function isMarkdownFile2(path) {
@@ -15167,7 +15348,7 @@ function applyModeOverride(config, mode) {
15167
15348
  agent.options.mode = mode;
15168
15349
  if (mode === "ai_acp" && !agent.options.acpSettings) {
15169
15350
  agent.options.acpSettings = {
15170
- command: "claude-code-acp",
15351
+ command: "claude-agent-acp",
15171
15352
  args: [],
15172
15353
  session: {}
15173
15354
  };