fullcourtdefense-cli 1.5.1 → 1.5.2

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.
@@ -61,6 +61,7 @@ export declare function installMcpGatewayCommand(args: InstallMcpGatewayArgs, co
61
61
  export interface ProtectAllArgs extends McpGatewayArgs {
62
62
  dryRun?: string;
63
63
  config?: string;
64
+ clients?: string;
64
65
  }
65
66
  export declare function protectAllCommand(args: ProtectAllArgs, config: BotGuardConfig): Promise<void>;
66
67
  export declare function unprotectAllCommand(args: ProtectAllArgs, config: BotGuardConfig): Promise<void>;
@@ -942,6 +942,24 @@ async function installMcpGatewayCommand(args, config) {
942
942
  console.log('Add --upload to refresh AI Fleet after install.');
943
943
  }
944
944
  }
945
+ /** Map a high-level client to the discovery clientKey(s) its config files use. */
946
+ const AGENT_TO_CLIENT_KEYS = {
947
+ cursor: ['cursor'],
948
+ 'claude-code': ['claude_code'],
949
+ 'claude-desktop': ['claude_desktop'],
950
+ codex: ['codex'],
951
+ 'gemini-cli': ['gemini_cli'],
952
+ windsurf: ['windsurf'],
953
+ vscode: ['vscode'],
954
+ };
955
+ /** Resolve the optional --clients filter into a set of clientKeys, or undefined for "all". */
956
+ function resolveProtectClientKeys(clients) {
957
+ const raw = (clients || '').trim().toLowerCase();
958
+ if (!raw || raw === 'auto' || raw === 'all')
959
+ return undefined; // no filter — process every client
960
+ const selection = parseClientList(clients);
961
+ return new Set(selection.flatMap(client => AGENT_TO_CLIENT_KEYS[client] || []));
962
+ }
945
963
  const CLIENT_KEY_TO_AGENT = {
946
964
  cursor: 'cursor',
947
965
  claude_code: 'claude-code',
@@ -1218,24 +1236,29 @@ function transformCodexToml(file, mode, gatewayConfig, dryRun) {
1218
1236
  }
1219
1237
  return stats;
1220
1238
  }
1221
- function protectAllTargetFiles(extra) {
1239
+ function protectAllTargetFiles(extra, allowedClientKeys) {
1222
1240
  const cwd = process.cwd();
1223
1241
  const seen = new Set();
1242
+ const allow = (clientKey) => !allowedClientKeys || allowedClientKeys.has(clientKey);
1224
1243
  const files = [];
1225
1244
  for (const candidate of (0, discoverPaths_1.candidateConfigPaths)(cwd, extra)) {
1226
1245
  const key = path.resolve(candidate.path).toLowerCase();
1227
1246
  if (seen.has(key))
1228
1247
  continue;
1248
+ if (!allow(candidate.clientKey))
1249
+ continue;
1229
1250
  if (!fs.existsSync(candidate.path))
1230
1251
  continue;
1231
1252
  seen.add(key);
1232
1253
  files.push(candidate);
1233
1254
  }
1234
- for (const target of (0, discoverPaths_1.claudeDesktopInstallTargets)()) {
1235
- const key = path.resolve(target.file).toLowerCase();
1236
- if (target.exists && !seen.has(key)) {
1237
- seen.add(key);
1238
- files.push({ path: target.file, source: target.source, clientKey: 'claude_desktop' });
1255
+ if (allow('claude_desktop')) {
1256
+ for (const target of (0, discoverPaths_1.claudeDesktopInstallTargets)()) {
1257
+ const key = path.resolve(target.file).toLowerCase();
1258
+ if (target.exists && !seen.has(key)) {
1259
+ seen.add(key);
1260
+ files.push({ path: target.file, source: target.source, clientKey: 'claude_desktop' });
1261
+ }
1239
1262
  }
1240
1263
  }
1241
1264
  return files;
@@ -1244,11 +1267,14 @@ async function protectAllCommand(args, config) {
1244
1267
  (0, config_1.requireCliSetup)(config, { shieldId: args.shieldId, shieldKey: args.shieldKey, apiUrl: args.apiUrl }, { requireOrganizationId: false });
1245
1268
  const gatewayConfig = resolveGatewayConfig(args, config);
1246
1269
  const dryRun = args.dryRun === 'true';
1247
- const files = protectAllTargetFiles(args.config);
1270
+ const allowedClientKeys = resolveProtectClientKeys(args.clients);
1271
+ const files = protectAllTargetFiles(args.config, allowedClientKeys);
1248
1272
  console.log('\n\x1b[1m\x1b[36mFullCourtDefense — protect every MCP server in every client\x1b[0m');
1249
1273
  console.log(`\x1b[2mRuntime identity: ${gatewayConfig.developerName} | Shield: ${gatewayConfig.shieldId}${dryRun ? ' | DRY RUN' : ''}\x1b[0m\n`);
1250
1274
  if (files.length === 0) {
1251
- console.log('No MCP client config files found on this machine. Configure an MCP server in any client, then re-run.');
1275
+ console.log(allowedClientKeys
1276
+ ? 'No matching client config files found for the requested --clients. Try without --clients, or pick a client that is installed.'
1277
+ : 'No MCP client config files found on this machine. Configure an MCP server in any client, then re-run.');
1252
1278
  return;
1253
1279
  }
1254
1280
  let totalWrapped = 0;
@@ -1285,7 +1311,8 @@ async function protectAllCommand(args, config) {
1285
1311
  }
1286
1312
  async function unprotectAllCommand(args, config) {
1287
1313
  const dryRun = args.dryRun === 'true';
1288
- const files = protectAllTargetFiles(args.config);
1314
+ const allowedClientKeys = resolveProtectClientKeys(args.clients);
1315
+ const files = protectAllTargetFiles(args.config, allowedClientKeys);
1289
1316
  let gatewayConfig;
1290
1317
  try {
1291
1318
  gatewayConfig = resolveGatewayConfig(args, config);
package/dist/index.js CHANGED
@@ -128,8 +128,11 @@ function printHelp() {
128
128
  (Cursor, Claude Code/Desktop, Codex, Gemini, Windsurf, VS Code)
129
129
  and wrap each through the Shield proxy — no --mcp-command needed.
130
130
  Enforces your org Action Policies on every tool. --dry-run to preview.
131
+ Per-tool: --clients cursor (or claude-code, claude-desktop, codex,
132
+ gemini-cli, windsurf, vscode; comma-separated). Default: all tools.
131
133
  unprotect-all
132
134
  Reverse protect-all: restore every server to its original command.
135
+ Also supports --clients to target one tool, and --dry-run.
133
136
  install-mcp-gateway
134
137
  Install MCP gateway into selected clients (--clients all for every tool).
135
138
  install-cursor-mcp-gateway
@@ -511,6 +514,7 @@ async function main() {
511
514
  ...buildGatewayArgs(),
512
515
  dryRun: flags['dry-run'],
513
516
  config: flags.config,
517
+ clients: flags.clients,
514
518
  };
515
519
  await (0, mcpGateway_1.protectAllCommand)(args, config);
516
520
  break;
@@ -521,6 +525,7 @@ async function main() {
521
525
  ...buildGatewayArgs(),
522
526
  dryRun: flags['dry-run'],
523
527
  config: flags.config,
528
+ clients: flags.clients,
524
529
  };
525
530
  await (0, mcpGateway_1.unprotectAllCommand)(args, config);
526
531
  break;
package/dist/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "1.5.1"
2
+ "version": "1.5.2"
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fullcourtdefense-cli",
3
- "version": "1.5.1",
3
+ "version": "1.5.2",
4
4
  "description": "Full Court Defense CLI — security scanning for AI agents from your terminal",
5
5
  "main": "dist/index.js",
6
6
  "bin": {