fullcourtdefense-cli 1.1.13 → 1.1.15

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.
@@ -44,6 +44,7 @@ const SECRET_KEY = /key|token|secret|password|credential|api[_-]?key/i;
44
44
  function candidateConfigPaths(cwd, extra) {
45
45
  const home = os.homedir();
46
46
  const appData = process.env.APPDATA || path.join(home, 'AppData', 'Roaming');
47
+ const localAppData = process.env.LOCALAPPDATA || path.join(home, 'AppData', 'Local');
47
48
  const xdg = process.env.XDG_CONFIG_HOME || path.join(home, '.config');
48
49
  const list = [
49
50
  // Cursor
@@ -64,6 +65,22 @@ function candidateConfigPaths(cwd, extra) {
64
65
  { path: path.join(cwd, '.mcp.json'), source: 'Repo (.mcp.json)' },
65
66
  { path: path.join(cwd, 'mcp.json'), source: 'Repo (mcp.json)' },
66
67
  ];
68
+ if (process.platform === 'win32') {
69
+ const packagesDir = path.join(localAppData, 'Packages');
70
+ try {
71
+ for (const packageName of fs.readdirSync(packagesDir)) {
72
+ if (!/^Claude_/i.test(packageName))
73
+ continue;
74
+ list.push({
75
+ path: path.join(packagesDir, packageName, 'LocalCache', 'Roaming', 'Claude', 'claude_desktop_config.json'),
76
+ source: 'Claude Desktop (win MSIX)',
77
+ });
78
+ }
79
+ }
80
+ catch {
81
+ // Missing Packages directory is normal on non-Store installs.
82
+ }
83
+ }
67
84
  if (extra)
68
85
  list.push({ path: path.resolve(extra), source: 'Custom path' });
69
86
  return list;
@@ -29,7 +29,14 @@ export interface InstallClaudeDesktopMcpGatewayArgs extends McpGatewayArgs {
29
29
  configPath?: string;
30
30
  serverName?: string;
31
31
  }
32
+ export interface InstallMcpGatewayArgs extends McpGatewayArgs {
33
+ clients?: string;
34
+ cursorProject?: string;
35
+ claudeCodeScope?: string;
36
+ serverName?: string;
37
+ }
32
38
  export declare function mcpGatewayCommand(args: McpGatewayArgs, config: BotGuardConfig): Promise<void>;
33
39
  export declare function installCursorMcpGatewayCommand(args: InstallCursorMcpGatewayArgs, config: BotGuardConfig): Promise<void>;
40
+ export declare function installMcpGatewayCommand(args: InstallMcpGatewayArgs, config: BotGuardConfig): Promise<void>;
34
41
  export declare function installClaudeCodeMcpGatewayCommand(args: InstallClaudeCodeMcpGatewayArgs, config: BotGuardConfig): Promise<void>;
35
42
  export declare function installClaudeDesktopMcpGatewayCommand(args: InstallClaudeDesktopMcpGatewayArgs, config: BotGuardConfig): Promise<void>;
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.mcpGatewayCommand = mcpGatewayCommand;
37
37
  exports.installCursorMcpGatewayCommand = installCursorMcpGatewayCommand;
38
+ exports.installMcpGatewayCommand = installMcpGatewayCommand;
38
39
  exports.installClaudeCodeMcpGatewayCommand = installClaudeCodeMcpGatewayCommand;
39
40
  exports.installClaudeDesktopMcpGatewayCommand = installClaudeDesktopMcpGatewayCommand;
40
41
  const fs = __importStar(require("fs"));
@@ -80,24 +81,27 @@ function normalizeAgentClient(value, fallback) {
80
81
  return value;
81
82
  return fallback;
82
83
  }
84
+ /**
85
+ * Detect which agent client spawned this gateway process at runtime.
86
+ *
87
+ * Claude Code sets `CLAUDECODE=1` and `CLAUDE_CODE_SESSION_ID` in every stdio
88
+ * MCP subprocess it starts, so a gateway launched by Claude Code can self-label
89
+ * even when it was installed with no explicit `--agent-client`. Cursor and
90
+ * Claude Desktop don't expose a runtime marker, so they fall through to the
91
+ * install-time default baked into the MCP config.
92
+ */
93
+ function detectRuntimeAgentClient() {
94
+ if (process.env.CLAUDECODE === '1' || process.env.CLAUDE_CODE_SESSION_ID)
95
+ return 'claude-code';
96
+ return undefined;
97
+ }
98
+ /** Claude Code passes the session id to spawned MCP servers for correlation. */
99
+ function runtimeSessionId() {
100
+ return firstNonEmpty(process.env.CLAUDE_CODE_SESSION_ID, process.env.FCD_SESSION_ID);
101
+ }
83
102
  function firstNonEmpty(...values) {
84
103
  return values.map(value => value?.trim()).find(Boolean);
85
104
  }
86
- function commandOutput(command, args) {
87
- try {
88
- const result = (0, child_process_1.spawnSync)(command, args, {
89
- encoding: 'utf8',
90
- shell: process.platform === 'win32',
91
- stdio: ['ignore', 'pipe', 'ignore'],
92
- });
93
- if (result.status !== 0)
94
- return undefined;
95
- return result.stdout?.trim() || undefined;
96
- }
97
- catch {
98
- return undefined;
99
- }
100
- }
101
105
  function safeIdentityPart(value) {
102
106
  return value
103
107
  .trim()
@@ -106,8 +110,18 @@ function safeIdentityPart(value) {
106
110
  .replace(/^-+|-+$/g, '')
107
111
  .toLowerCase() || 'local-user';
108
112
  }
113
+ /**
114
+ * Resolve the developer identity for runtime attribution.
115
+ *
116
+ * Same behavior for Cursor, Claude Code, and Claude Desktop: prefer an explicit
117
+ * name (flag or env var IT can set per machine), otherwise fall back to
118
+ * `username@hostname` — exactly like the Cursor hook. We intentionally do NOT
119
+ * guess from git email / npm whoami: neither Cursor nor Claude exposes the
120
+ * account email, so the machine-scoped login is the one stable, predictable,
121
+ * collision-free identity.
122
+ */
109
123
  function detectedDeveloperName(args) {
110
- return firstNonEmpty(args.developerName, process.env.FCD_DEVELOPER_NAME, process.env.FULLCOURTDEFENSE_DEVELOPER_NAME, process.env.AGENTGUARD_DEVELOPER_NAME, process.env.USER_EMAIL, commandOutput('git', ['config', '--get', 'user.email']), commandOutput('npm', ['whoami']), safeUserName()) || 'unknown';
124
+ return firstNonEmpty(args.developerName, process.env.FCD_DEVELOPER_NAME, process.env.FULLCOURTDEFENSE_DEVELOPER_NAME, process.env.AGENTGUARD_DEVELOPER_NAME, machineScopedUser()) || 'unknown';
111
125
  }
112
126
  function defaultAgentName(agentClient, developerName, defaults) {
113
127
  if (defaults.agentName)
@@ -120,7 +134,7 @@ function resolveGatewayConfig(args, config, defaults = {}) {
120
134
  const shieldId = args.shieldId || process.env.FCD_SHIELD_ID || process.env.FULLCOURTDEFENSE_SHIELD_ID || process.env.AGENTGUARD_SHIELD_ID || config.shieldId || home.shieldId;
121
135
  if (!shieldId)
122
136
  throw new Error('Missing Shield ID. Pass --shield-id or run fullcourtdefense configure.');
123
- const agentClient = normalizeAgentClient(args.agentClient || process.env.FCD_AGENT_CLIENT, defaults.agentClient || 'cursor');
137
+ const agentClient = normalizeAgentClient(args.agentClient || process.env.FCD_AGENT_CLIENT || detectRuntimeAgentClient(), defaults.agentClient || 'cursor');
124
138
  const developerName = detectedDeveloperName(args);
125
139
  return {
126
140
  shieldId,
@@ -140,15 +154,17 @@ function resolveGatewayConfig(args, config, defaults = {}) {
140
154
  };
141
155
  }
142
156
  function machineMetadata(developerName, agentClient = 'cursor') {
157
+ const sessionId = runtimeSessionId();
143
158
  return {
144
- developerName: developerName || safeUserName(),
159
+ developerName: developerName || machineScopedUser(),
145
160
  machineName: os.hostname(),
146
161
  os: `${os.platform()} ${os.release()}`,
147
162
  username: safeUserName(),
148
163
  ipAddress: firstPrivateIp(),
149
164
  cwd: process.cwd(),
150
- workspacePath: process.env.WORKSPACE_PATH || process.cwd(),
165
+ workspacePath: process.env.WORKSPACE_PATH || process.env.CLAUDE_PROJECT_DIR || process.cwd(),
151
166
  agentClient,
167
+ ...(sessionId ? { sessionId } : {}),
152
168
  gateway: 'agentguard-mcp-gateway',
153
169
  };
154
170
  }
@@ -170,6 +186,25 @@ function safeUserName() {
170
186
  return 'unknown';
171
187
  }
172
188
  }
189
+ /**
190
+ * Machine-scoped identity: `username@hostname` (e.g. `boazl@BOAZ-PC`).
191
+ *
192
+ * Bare OS usernames collide across machines (every laptop has an `admin` /
193
+ * `user`), which breaks per-person attribution and fails SOC 2 CC6.1
194
+ * non-repudiation. Pairing the login with the hostname makes the identity
195
+ * unique per device with zero config, and matches the Cursor hook's format.
196
+ * For verified corporate identity, set `FCD_DEVELOPER_NAME` (e.g. via MDM/IdP).
197
+ */
198
+ function machineScopedUser() {
199
+ const user = safeUserName();
200
+ try {
201
+ const host = os.hostname();
202
+ return host ? `${user}@${host}` : user;
203
+ }
204
+ catch {
205
+ return user;
206
+ }
207
+ }
173
208
  function summarizeToolArgs(args, developerName, agentClient = 'cursor') {
174
209
  const out = { ...machineMetadata(developerName, agentClient) };
175
210
  for (const [key, value] of Object.entries(args || {})) {
@@ -629,6 +664,16 @@ function writeMcpServerConfig(file, serverName, nodeExe, commandArgs) {
629
664
  fs.mkdirSync(path.dirname(file), { recursive: true });
630
665
  fs.writeFileSync(file, `${JSON.stringify(json, null, 2)}\n`, 'utf8');
631
666
  }
667
+ function dedupePaths(candidates) {
668
+ const seen = new Set();
669
+ return candidates.filter(candidate => {
670
+ const key = path.resolve(candidate.file).toLowerCase();
671
+ if (seen.has(key))
672
+ return false;
673
+ seen.add(key);
674
+ return true;
675
+ });
676
+ }
632
677
  function claudeDesktopMcpPath() {
633
678
  const home = os.homedir();
634
679
  if (process.platform === 'win32') {
@@ -641,11 +686,128 @@ function claudeDesktopMcpPath() {
641
686
  const xdg = process.env.XDG_CONFIG_HOME || path.join(home, '.config');
642
687
  return path.join(xdg, 'Claude', 'claude_desktop_config.json');
643
688
  }
689
+ function claudeDesktopMsixCandidates() {
690
+ if (process.platform !== 'win32')
691
+ return [];
692
+ const localAppData = process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local');
693
+ const packagesDir = path.join(localAppData, 'Packages');
694
+ let packageNames = [];
695
+ try {
696
+ packageNames = fs.readdirSync(packagesDir)
697
+ .filter(name => /^Claude_/i.test(name));
698
+ }
699
+ catch {
700
+ return [];
701
+ }
702
+ return packageNames.map(name => {
703
+ const file = path.join(packagesDir, name, 'LocalCache', 'Roaming', 'Claude', 'claude_desktop_config.json');
704
+ return {
705
+ file,
706
+ source: 'Claude Desktop (Microsoft Store/MSIX)',
707
+ exists: fs.existsSync(file),
708
+ };
709
+ });
710
+ }
711
+ function claudeDesktopMcpCandidates() {
712
+ const documented = claudeDesktopMcpPath();
713
+ const normal = {
714
+ file: documented,
715
+ source: process.platform === 'win32'
716
+ ? 'Claude Desktop (Windows documented AppData)'
717
+ : process.platform === 'darwin'
718
+ ? 'Claude Desktop (macOS)'
719
+ : 'Claude Desktop (Linux/XDG)',
720
+ exists: fs.existsSync(documented),
721
+ };
722
+ // Store/MSIX Claude Desktop reads a virtualized AppData path. Prefer it when present.
723
+ return dedupePaths([
724
+ ...claudeDesktopMsixCandidates(),
725
+ normal,
726
+ ]);
727
+ }
728
+ function claudeDesktopInstallTargets(configPath) {
729
+ if (configPath) {
730
+ const file = path.resolve(configPath);
731
+ return [{ file, source: 'Claude Desktop (custom config path)', exists: fs.existsSync(file) }];
732
+ }
733
+ const candidates = claudeDesktopMcpCandidates();
734
+ const existing = candidates.filter(candidate => candidate.exists);
735
+ if (existing.length > 0)
736
+ return existing;
737
+ const msix = candidates.find(candidate => candidate.source.includes('MSIX'));
738
+ return [msix || candidates[candidates.length - 1] || {
739
+ file: claudeDesktopMcpPath(),
740
+ source: 'Claude Desktop',
741
+ exists: false,
742
+ }];
743
+ }
644
744
  function normalizeClaudeCodeScope(scope) {
645
745
  if (scope === 'project' || scope === 'user' || scope === 'local')
646
746
  return scope;
647
747
  return 'local';
648
748
  }
749
+ function parseClientList(value) {
750
+ const raw = (value || 'auto').trim().toLowerCase();
751
+ if (!raw || raw === 'auto')
752
+ return 'auto';
753
+ const aliases = {
754
+ cursor: 'cursor',
755
+ 'claude-code': 'claude-code',
756
+ claude_code: 'claude-code',
757
+ code: 'claude-code',
758
+ 'claude-desktop': 'claude-desktop',
759
+ claude_desktop: 'claude-desktop',
760
+ desktop: 'claude-desktop',
761
+ };
762
+ const requested = raw === 'all'
763
+ ? ['cursor', 'claude-code', 'claude-desktop']
764
+ : raw.split(',').map(part => part.trim()).filter(Boolean);
765
+ const clients = requested.map(client => aliases[client]);
766
+ const unknown = requested.filter((_, index) => !clients[index]);
767
+ if (unknown.length > 0)
768
+ throw new Error(`Unknown client(s): ${unknown.join(', ')}. Use auto, all, cursor, claude-code, claude-desktop.`);
769
+ return Array.from(new Set(clients));
770
+ }
771
+ function commandAvailable(command) {
772
+ const result = (0, child_process_1.spawnSync)(process.platform === 'win32' ? 'where' : 'command', process.platform === 'win32' ? [command] : ['-v', command], {
773
+ stdio: 'ignore',
774
+ shell: process.platform !== 'win32',
775
+ });
776
+ return result.status === 0;
777
+ }
778
+ function detectInstallClients(cursorProject) {
779
+ const clients = [];
780
+ const cursorGlobal = path.join(os.homedir(), '.cursor');
781
+ const cursorProjectDir = path.join(process.cwd(), '.cursor');
782
+ if (fs.existsSync(cursorGlobal) || fs.existsSync(cursorProjectDir) || cursorProject)
783
+ clients.push('cursor');
784
+ if (commandAvailable('claude'))
785
+ clients.push('claude-code');
786
+ if (claudeDesktopMcpCandidates().some(candidate => candidate.exists) || fs.existsSync(path.dirname(claudeDesktopMcpPath()))) {
787
+ clients.push('claude-desktop');
788
+ }
789
+ return clients;
790
+ }
791
+ function clientInstallArgs(args) {
792
+ return {
793
+ mcpCommand: args.mcpCommand,
794
+ mcpArgs: args.mcpArgs,
795
+ agentName: args.agentName,
796
+ agentClient: args.agentClient,
797
+ developerName: args.developerName,
798
+ shieldId: args.shieldId,
799
+ shieldKey: args.shieldKey,
800
+ apiUrl: args.apiUrl,
801
+ environment: args.environment,
802
+ userObjective: args.userObjective,
803
+ authority: args.authority,
804
+ approvalMode: args.approvalMode,
805
+ approvalTimeoutMs: args.approvalTimeoutMs,
806
+ approvalPollMs: args.approvalPollMs,
807
+ scanResponse: args.scanResponse,
808
+ failClosed: args.failClosed,
809
+ };
810
+ }
649
811
  async function installCursorMcpGatewayCommand(args, config) {
650
812
  const gatewayConfig = resolveGatewayConfig(args, config, {
651
813
  agentClient: 'cursor',
@@ -668,6 +830,45 @@ async function installCursorMcpGatewayCommand(args, config) {
668
830
  console.log(`Downstream: ${downstreamCommand} ${downstreamArgs.join(' ')}`);
669
831
  console.log('Restart Cursor or reload MCP servers to use the protected tools.');
670
832
  }
833
+ async function installMcpGatewayCommand(args, config) {
834
+ const cursorProject = args.cursorProject === 'true';
835
+ const selection = parseClientList(args.clients);
836
+ const clients = selection === 'auto' ? detectInstallClients(cursorProject) : selection;
837
+ if (clients.length === 0) {
838
+ throw new Error('No supported MCP clients detected. Re-run with --clients all or a comma list such as cursor,claude-desktop.');
839
+ }
840
+ const baseArgs = clientInstallArgs(args);
841
+ const successes = [];
842
+ const failures = [];
843
+ for (const client of clients) {
844
+ try {
845
+ if (client === 'cursor') {
846
+ await installCursorMcpGatewayCommand({ ...baseArgs, project: String(cursorProject), serverName: args.serverName }, config);
847
+ }
848
+ else if (client === 'claude-code') {
849
+ await installClaudeCodeMcpGatewayCommand({ ...baseArgs, scope: args.claudeCodeScope, serverName: args.serverName }, config);
850
+ }
851
+ else {
852
+ await installClaudeDesktopMcpGatewayCommand({ ...baseArgs, serverName: args.serverName }, config);
853
+ }
854
+ successes.push(client);
855
+ }
856
+ catch (error) {
857
+ failures.push(`${client}: ${error instanceof Error ? error.message : String(error)}`);
858
+ }
859
+ }
860
+ console.log('');
861
+ console.log('AgentGuard one-install summary:');
862
+ console.log(`Installed: ${successes.length > 0 ? successes.join(', ') : 'none'}`);
863
+ if (failures.length > 0) {
864
+ console.log('Failed:');
865
+ for (const failure of failures)
866
+ console.log(`- ${failure}`);
867
+ }
868
+ console.log(`Runtime identity: ${detectedDeveloperName(args)}`);
869
+ console.log('Restart/reload each client to use the protected tools.');
870
+ console.log('Smoke test prompt: "Use lookup_customer to look up customer C-1001."');
871
+ }
671
872
  async function installClaudeCodeMcpGatewayCommand(args, config) {
672
873
  const gatewayConfig = resolveGatewayConfig(args, config, {
673
874
  agentClient: 'claude-code',
@@ -719,7 +920,7 @@ async function installClaudeDesktopMcpGatewayCommand(args, config) {
719
920
  agentNamePrefix: 'claude-desktop',
720
921
  userObjective: 'Developer requested this action from Claude Desktop.',
721
922
  });
722
- const file = args.configPath ? path.resolve(args.configPath) : claudeDesktopMcpPath();
923
+ const targets = claudeDesktopInstallTargets(args.configPath);
723
924
  const nodeExe = process.execPath;
724
925
  const serverName = args.serverName || MANAGED_SERVER_NAME;
725
926
  const downstreamCommand = args.mcpCommand || process.env.FCD_MCP_COMMAND;
@@ -727,9 +928,13 @@ async function installClaudeDesktopMcpGatewayCommand(args, config) {
727
928
  throw new Error('Pass --mcp-command for the real MCP server you want to protect.');
728
929
  const downstreamArgs = parseArgsList(args.mcpArgs || process.env.FCD_MCP_ARGS);
729
930
  const commandArgs = buildGatewayCommandArgs(gatewayConfig, downstreamCommand, downstreamArgs);
730
- writeMcpServerConfig(file, serverName, nodeExe, commandArgs);
931
+ for (const target of targets) {
932
+ writeMcpServerConfig(target.file, serverName, nodeExe, commandArgs);
933
+ }
731
934
  console.log('AgentGuard MCP Gateway installed for Claude Desktop.');
732
- console.log(`Config: ${file}`);
935
+ for (const target of targets) {
936
+ console.log(`Config: ${target.file} (${target.source})`);
937
+ }
733
938
  console.log(`Server: ${serverName}`);
734
939
  console.log(`Downstream: ${downstreamCommand} ${downstreamArgs.join(' ')}`);
735
940
  console.log('Restart Claude Desktop to load the protected tools.');
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ const discover_1 = require("./commands/discover");
11
11
  const hook_1 = require("./commands/hook");
12
12
  const installCursorHook_1 = require("./commands/installCursorHook");
13
13
  const mcpGateway_1 = require("./commands/mcpGateway");
14
- const VERSION = '1.1.13';
14
+ const VERSION = '1.1.15';
15
15
  function parseArgs(argv) {
16
16
  const flags = {};
17
17
  let command = '';
@@ -73,6 +73,9 @@ function printHelp() {
73
73
  (shell, MCP) on this machine is scanned by your Shield.
74
74
  uninstall-cursor-hook
75
75
  Removes the FullCourtDefense Cursor hook entries.
76
+ install-mcp-gateway
77
+ One command to install the AgentGuard MCP Gateway into detected
78
+ clients (Cursor, Claude Code, Claude Desktop).
76
79
  mcp-gateway
77
80
  Runs a local MCP gateway that checks AgentGuard runtime/action
78
81
  policies before forwarding tool calls to a real MCP server.
@@ -148,9 +151,13 @@ function printHelp() {
148
151
  --mcp-args <args> MCP server args/path, for example ./server.js
149
152
  --mcp-tool <tool> MCP tool to test, or all
150
153
  --server-name <name> MCP gateway server name for client installers
154
+ --clients <list> Gateway install clients: auto, all, cursor,
155
+ claude-code, claude-desktop
151
156
  --developer-name <name> Runtime identity for user-scoped policies (auto-detected if omitted)
152
157
  --agent-name <name> Runtime agent name (auto-generated from identity + client if omitted)
153
158
  --scope <scope> Claude Code MCP scope: local, project, or user
159
+ --claude-code-scope <s> Claude Code scope for install-mcp-gateway
160
+ --cursor-project <bool> Cursor project config for install-mcp-gateway
154
161
  --config-path <path> Claude Desktop config override path
155
162
  --mcp-auth-type <type> HTTP MCP auth: none, bearer, basic, api-key
156
163
  --mcp-token <token> HTTP MCP bearer token
@@ -198,6 +205,8 @@ function printHelp() {
198
205
  $ fullcourtdefense install-cursor-hook --events prompt,shell,mcp,file
199
206
  $ fullcourtdefense install-cursor-hook --project true # this repo only
200
207
  $ fullcourtdefense uninstall-cursor-hook
208
+ $ fullcourtdefense install-mcp-gateway --clients auto --shield-id <id> --shield-key <key> --mcp-command npm --mcp-args "run mcp"
209
+ $ fullcourtdefense install-mcp-gateway --clients all --mcp-command node --mcp-args ./server.js
201
210
  $ fullcourtdefense install-cursor-mcp-gateway --project true --shield-id <id> --shield-key <key> --mcp-command npm --mcp-args "run mcp"
202
211
  $ fullcourtdefense install-claude-code-mcp-gateway --scope local --shield-id <id> --shield-key <key> --mcp-command npm --mcp-args "run mcp"
203
212
  $ fullcourtdefense install-claude-code-mcp-gateway --scope project --shield-id <id> --mcp-command npm --mcp-args "run mcp"
@@ -368,6 +377,31 @@ async function main() {
368
377
  await (0, mcpGateway_1.mcpGatewayCommand)(args, config);
369
378
  break;
370
379
  }
380
+ case 'install-mcp-gateway': {
381
+ const args = {
382
+ clients: flags.clients,
383
+ cursorProject: flags['cursor-project'],
384
+ claudeCodeScope: flags['claude-code-scope'] || flags.scope,
385
+ serverName: flags['server-name'],
386
+ mcpCommand: flags['mcp-command'],
387
+ mcpArgs: flags['mcp-args'],
388
+ agentName: flags['agent-name'],
389
+ developerName: flags['developer-name'],
390
+ shieldId: flags['shield-id'],
391
+ shieldKey: flags['shield-key'],
392
+ apiUrl: flags['api-url'],
393
+ environment: flags.environment,
394
+ userObjective: flags['user-objective'],
395
+ authority: flags.authority,
396
+ approvalMode: flags['approval-mode'],
397
+ approvalTimeoutMs: flags['approval-timeout-ms'],
398
+ approvalPollMs: flags['approval-poll-ms'],
399
+ scanResponse: flags['scan-response'],
400
+ failClosed: flags['fail-closed'],
401
+ };
402
+ await (0, mcpGateway_1.installMcpGatewayCommand)(args, config);
403
+ break;
404
+ }
371
405
  case 'install-cursor-mcp-gateway': {
372
406
  const args = {
373
407
  project: flags.project,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fullcourtdefense-cli",
3
- "version": "1.1.13",
3
+ "version": "1.1.15",
4
4
  "description": "Full Court Defense CLI — security scanning for AI agents from your terminal",
5
5
  "main": "dist/index.js",
6
6
  "bin": {