fullcourtdefense-cli 1.14.9 → 1.14.11

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.
@@ -739,7 +739,8 @@ function printPostureReport(posture, silent) {
739
739
  async function discoverCommand(args, config) {
740
740
  const surfaces = parseSurfaces(args);
741
741
  const silent = args.silent === 'true';
742
- const deep = args.deep === 'true';
742
+ const uploadRequested = args.upload === 'true';
743
+ const deep = args.deep === 'false' ? false : (args.deep === 'true' || uploadRequested);
743
744
  if (args.unschedule === 'true') {
744
745
  (0, discoverSchedule_1.uninstallDailyDiscoverSchedule)();
745
746
  if (!silent)
@@ -757,7 +758,7 @@ async function discoverCommand(args, config) {
757
758
  });
758
759
  if (!silent) {
759
760
  const when = args.schedule === 'logon' ? 'at logon' : `daily at ${String(Number.isFinite(hour) ? hour : 9).padStart(2, '0')}:00`;
760
- console.log(`Desktop discovery scheduled ${when} (runs discover --surface ${surface} --upload --silent${args.userEmail ? ` --user-email ${args.userEmail}` : ''}).`);
761
+ console.log(`Desktop discovery scheduled ${when} (runs discover --surface ${surface} --upload --deep --silent${args.userEmail ? ` --user-email ${args.userEmail}` : ''}).`);
761
762
  console.log('Uses login Shield credentials or an explicit org API key.');
762
763
  }
763
764
  return;
@@ -837,7 +838,7 @@ async function discoverCommand(args, config) {
837
838
  },
838
839
  };
839
840
  async function maybeUpload() {
840
- if (args.upload !== 'true')
841
+ if (!uploadRequested)
841
842
  return;
842
843
  const creds = (0, config_1.resolveCliCredentials)(config, { apiKey: args.apiKey, apiUrl: args.apiUrl });
843
844
  // Either an org API key OR an enrolled Shield key (from `login`) is enough.
@@ -851,7 +852,7 @@ async function discoverCommand(args, config) {
851
852
  await upload(found, host, clientCoverage, creds.apiUrl, { apiKey: creds.apiKey, shieldId: creds.shieldId, shieldKey: creds.shieldKey, preferApiKey: !!args.apiKey }, args.connectorName, uploadExtras);
852
853
  }
853
854
  if (silent) {
854
- if (args.upload === 'true') {
855
+ if (uploadRequested) {
855
856
  const creds = (0, config_1.resolveCliCredentials)(config, { apiKey: args.apiKey, apiUrl: args.apiUrl });
856
857
  if (!creds.apiKey && !(creds.shieldId && creds.shieldKey))
857
858
  process.exit(1);
@@ -903,14 +904,14 @@ async function discoverCommand(args, config) {
903
904
  printAgentFilesReport(agentFiles, silent);
904
905
  if (posture)
905
906
  printPostureReport(posture, silent);
906
- if (args.upload === 'true') {
907
+ if (uploadRequested) {
907
908
  console.log('');
908
909
  await maybeUpload();
909
910
  }
910
911
  else {
911
912
  console.log(`${COLOR.gray}Run with --upload to push results into AI Fleet.${COLOR.reset}`);
912
913
  if (runMcp && !deep)
913
- console.log(`${COLOR.gray}Add --deep to live-probe HTTP/SSE MCP servers.${COLOR.reset}`);
914
+ console.log(`${COLOR.gray}Add --deep to live-probe HTTP/SSE/stdio MCP servers.${COLOR.reset}`);
914
915
  if (!surfaces.has('secrets'))
915
916
  console.log(`${COLOR.gray}Add --surface secrets for .env / credential store scan (local-only).${COLOR.reset}`);
916
917
  if (surfaces.size < 4)
@@ -49,7 +49,7 @@ function discoverCommandLine(userEmail, surface) {
49
49
  const node = process.execPath;
50
50
  const script = path.resolve(process.argv[1] || path.join(__dirname, '..', 'index.js'));
51
51
  const q = (value) => (/\s/.test(value) ? `"${value}"` : value);
52
- const parts = [q(node), q(script), 'discover', '--upload', '--silent'];
52
+ const parts = [q(node), q(script), 'discover', '--upload', '--deep', '--silent'];
53
53
  if (surface)
54
54
  parts.push('--surface', q(surface));
55
55
  if (userEmail)
@@ -967,7 +967,7 @@ function clientInstallArgs(args) {
967
967
  };
968
968
  }
969
969
  async function installCursorMcpGatewayCommand(args, config) {
970
- const gatewayConfig = resolveGatewayConfig(args, config, {
970
+ const baseGatewayConfig = resolveGatewayConfig(args, config, {
971
971
  agentClient: 'cursor',
972
972
  agentNamePrefix: 'cursor',
973
973
  userObjective: 'Developer requested this action from Cursor.',
@@ -976,6 +976,7 @@ async function installCursorMcpGatewayCommand(args, config) {
976
976
  const file = cursorMcpPath(projectScope);
977
977
  const nodeExe = process.execPath;
978
978
  const serverName = args.serverName || MANAGED_SERVER_NAME;
979
+ const gatewayConfig = applyPerServerAgentName(baseGatewayConfig, args, serverName);
979
980
  const downstreamCommand = args.mcpCommand || process.env.FCD_MCP_COMMAND;
980
981
  if (!downstreamCommand)
981
982
  throw new Error('Pass --mcp-command for the real MCP server you want to protect.');
@@ -1141,6 +1142,24 @@ function backupFile(file) {
1141
1142
  function perServerAgentName(developerName, _agentClient, serverName) {
1142
1143
  return `${safeIdentityPart(developerName)}-${safeIdentityPart(serverName)}`;
1143
1144
  }
1145
+ /**
1146
+ * Per-server installs (`install-*-mcp-gateway --server-name foo`) must report the SAME
1147
+ * runtime-agnostic agent identity that protect-all/auto-protect produce (`<developer>-<server>`).
1148
+ * Otherwise the gateway reports a generic `<developer>-<client>` name and a dashboard policy
1149
+ * targeting the MCP server (agentName contains <server>) silently never matches — the exact
1150
+ * bug where a block policy on `patria-bank-finance` did not fire because the Claude Desktop
1151
+ * entry reported `boazl-claude-desktop`. An explicit --agent-name / FCD_AGENT_NAME still wins.
1152
+ */
1153
+ function applyPerServerAgentName(gatewayConfig, args, serverName) {
1154
+ if (args.agentName || process.env.FCD_AGENT_NAME)
1155
+ return gatewayConfig;
1156
+ if (!serverName || serverName === MANAGED_SERVER_NAME)
1157
+ return gatewayConfig;
1158
+ return {
1159
+ ...gatewayConfig,
1160
+ agentName: perServerAgentName(gatewayConfig.developerName, gatewayConfig.agentClient, serverName),
1161
+ };
1162
+ }
1144
1163
  function wrapJsonConfigFile(file, gatewayConfig, agentClient, dryRun) {
1145
1164
  const stats = newWrapStats();
1146
1165
  let json;
@@ -1495,7 +1514,7 @@ async function unprotectAllCommand(args, config) {
1495
1514
  console.log(`\n${dryRun ? 'Would restore' : 'Restored'} ${total} server(s) to their original commands. Restart each client.`);
1496
1515
  }
1497
1516
  async function installClaudeCodeMcpGatewayCommand(args, config) {
1498
- const gatewayConfig = resolveGatewayConfig(args, config, {
1517
+ const baseGatewayConfig = resolveGatewayConfig(args, config, {
1499
1518
  agentClient: 'claude-code',
1500
1519
  agentNamePrefix: 'claude-code',
1501
1520
  userObjective: 'Developer requested this action from Claude Code.',
@@ -1503,6 +1522,7 @@ async function installClaudeCodeMcpGatewayCommand(args, config) {
1503
1522
  const scope = normalizeClaudeCodeScope(args.scope);
1504
1523
  const nodeExe = process.execPath;
1505
1524
  const serverName = args.serverName || MANAGED_SERVER_NAME;
1525
+ const gatewayConfig = applyPerServerAgentName(baseGatewayConfig, args, serverName);
1506
1526
  const downstreamCommand = args.mcpCommand || process.env.FCD_MCP_COMMAND;
1507
1527
  if (!downstreamCommand)
1508
1528
  throw new Error('Pass --mcp-command for the real MCP server you want to protect.');
@@ -1555,7 +1575,7 @@ async function installClaudeCodeMcpGatewayCommand(args, config) {
1555
1575
  throw new Error('Claude Code CLI was not available. Install Claude Code or rerun with --scope project to write .mcp.json directly.');
1556
1576
  }
1557
1577
  async function installClaudeDesktopMcpGatewayCommand(args, config) {
1558
- const gatewayConfig = resolveGatewayConfig(args, config, {
1578
+ const baseGatewayConfig = resolveGatewayConfig(args, config, {
1559
1579
  agentClient: 'claude-desktop',
1560
1580
  agentNamePrefix: 'claude-desktop',
1561
1581
  userObjective: 'Developer requested this action from Claude Desktop.',
@@ -1563,6 +1583,7 @@ async function installClaudeDesktopMcpGatewayCommand(args, config) {
1563
1583
  const targets = (0, discoverPaths_1.claudeDesktopInstallTargets)(args.configPath);
1564
1584
  const nodeExe = process.execPath;
1565
1585
  const serverName = args.serverName || MANAGED_SERVER_NAME;
1586
+ const gatewayConfig = applyPerServerAgentName(baseGatewayConfig, args, serverName);
1566
1587
  const downstreamCommand = args.mcpCommand || process.env.FCD_MCP_COMMAND;
1567
1588
  if (!downstreamCommand)
1568
1589
  throw new Error('Pass --mcp-command for the real MCP server you want to protect.');
@@ -1580,7 +1601,7 @@ async function installClaudeDesktopMcpGatewayCommand(args, config) {
1580
1601
  console.log('Restart Claude Desktop to load the protected tools.');
1581
1602
  }
1582
1603
  async function installCodexMcpGatewayCommand(args, config) {
1583
- const gatewayConfig = resolveGatewayConfig(args, config, {
1604
+ const baseGatewayConfig = resolveGatewayConfig(args, config, {
1584
1605
  agentClient: 'codex',
1585
1606
  agentNamePrefix: 'codex',
1586
1607
  userObjective: 'Developer requested this action from Codex.',
@@ -1589,6 +1610,7 @@ async function installCodexMcpGatewayCommand(args, config) {
1589
1610
  const file = codexConfigPath(projectScope);
1590
1611
  const nodeExe = process.execPath;
1591
1612
  const serverName = args.serverName || MANAGED_SERVER_NAME;
1613
+ const gatewayConfig = applyPerServerAgentName(baseGatewayConfig, args, serverName);
1592
1614
  const downstreamCommand = args.mcpCommand || process.env.FCD_MCP_COMMAND;
1593
1615
  if (!downstreamCommand)
1594
1616
  throw new Error('Pass --mcp-command for the real MCP server you want to protect.');
@@ -1601,7 +1623,7 @@ async function installCodexMcpGatewayCommand(args, config) {
1601
1623
  console.log('Restart Codex or reload MCP servers. Project config requires a trusted project.');
1602
1624
  }
1603
1625
  async function installGeminiMcpGatewayCommand(args, config) {
1604
- const gatewayConfig = resolveGatewayConfig(args, config, {
1626
+ const baseGatewayConfig = resolveGatewayConfig(args, config, {
1605
1627
  agentClient: 'gemini-cli',
1606
1628
  agentNamePrefix: 'gemini',
1607
1629
  userObjective: 'Developer requested this action from Gemini CLI.',
@@ -1610,6 +1632,7 @@ async function installGeminiMcpGatewayCommand(args, config) {
1610
1632
  const file = geminiSettingsPath(projectScope);
1611
1633
  const nodeExe = process.execPath;
1612
1634
  const serverName = args.serverName || MANAGED_SERVER_NAME;
1635
+ const gatewayConfig = applyPerServerAgentName(baseGatewayConfig, args, serverName);
1613
1636
  const downstreamCommand = args.mcpCommand || process.env.FCD_MCP_COMMAND;
1614
1637
  if (!downstreamCommand)
1615
1638
  throw new Error('Pass --mcp-command for the real MCP server you want to protect.');
@@ -1622,7 +1645,7 @@ async function installGeminiMcpGatewayCommand(args, config) {
1622
1645
  console.log('Restart Gemini CLI to load the protected tools.');
1623
1646
  }
1624
1647
  async function installWindsurfMcpGatewayCommand(args, config) {
1625
- const gatewayConfig = resolveGatewayConfig(args, config, {
1648
+ const baseGatewayConfig = resolveGatewayConfig(args, config, {
1626
1649
  agentClient: 'windsurf',
1627
1650
  agentNamePrefix: 'windsurf',
1628
1651
  userObjective: 'Developer requested this action from Windsurf.',
@@ -1630,6 +1653,7 @@ async function installWindsurfMcpGatewayCommand(args, config) {
1630
1653
  const file = windsurfConfigPath();
1631
1654
  const nodeExe = process.execPath;
1632
1655
  const serverName = args.serverName || MANAGED_SERVER_NAME;
1656
+ const gatewayConfig = applyPerServerAgentName(baseGatewayConfig, args, serverName);
1633
1657
  const downstreamCommand = args.mcpCommand || process.env.FCD_MCP_COMMAND;
1634
1658
  if (!downstreamCommand)
1635
1659
  throw new Error('Pass --mcp-command for the real MCP server you want to protect.');
@@ -1642,7 +1666,7 @@ async function installWindsurfMcpGatewayCommand(args, config) {
1642
1666
  console.log('Restart Windsurf to load the protected tools.');
1643
1667
  }
1644
1668
  async function installVscodeMcpGatewayCommand(args, config) {
1645
- const gatewayConfig = resolveGatewayConfig(args, config, {
1669
+ const baseGatewayConfig = resolveGatewayConfig(args, config, {
1646
1670
  agentClient: 'vscode',
1647
1671
  agentNamePrefix: 'vscode',
1648
1672
  userObjective: 'Developer requested this action from VS Code.',
@@ -1650,6 +1674,7 @@ async function installVscodeMcpGatewayCommand(args, config) {
1650
1674
  const projectScope = args.project !== 'false';
1651
1675
  const nodeExe = process.execPath;
1652
1676
  const serverName = args.serverName || MANAGED_SERVER_NAME;
1677
+ const gatewayConfig = applyPerServerAgentName(baseGatewayConfig, args, serverName);
1653
1678
  const downstreamCommand = args.mcpCommand || process.env.FCD_MCP_COMMAND;
1654
1679
  if (!downstreamCommand)
1655
1680
  throw new Error('Pass --mcp-command for the real MCP server you want to protect.');
package/dist/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "1.14.9"
2
+ "version": "1.14.11"
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fullcourtdefense-cli",
3
- "version": "1.14.9",
3
+ "version": "1.14.11",
4
4
  "description": "Full Court Defense CLI — security scanning for AI agents from your terminal",
5
5
  "main": "dist/index.js",
6
6
  "bin": {