fullcourtdefense-cli 1.3.1 → 1.3.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.
- package/dist/api.d.ts +13 -0
- package/dist/api.js +4 -1
- package/dist/commands/configure.d.ts +3 -0
- package/dist/commands/configure.js +36 -4
- package/dist/commands/discover.d.ts +2 -0
- package/dist/commands/discover.js +218 -102
- package/dist/commands/discoverAgentFiles.d.ts +15 -0
- package/dist/commands/discoverAgentFiles.js +204 -0
- package/dist/commands/discoverBlastRadius.d.ts +30 -0
- package/dist/commands/discoverBlastRadius.js +139 -0
- package/dist/commands/discoverSecrets.d.ts +24 -0
- package/dist/commands/discoverSecrets.js +286 -0
- package/dist/commands/hook.js +9 -27
- package/dist/commands/installAll.d.ts +11 -0
- package/dist/commands/installAll.js +55 -0
- package/dist/commands/installCursorHook.js +16 -27
- package/dist/commands/mcpGateway.d.ts +23 -0
- package/dist/commands/mcpGateway.js +313 -67
- package/dist/config.d.ts +26 -0
- package/dist/config.js +92 -16
- package/dist/index.js +191 -120
- package/dist/version.json +3 -0
- package/package.json +1 -1
package/dist/config.js
CHANGED
|
@@ -33,11 +33,17 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getHomeConfigPath = getHomeConfigPath;
|
|
36
37
|
exports.loadConfig = loadConfig;
|
|
37
38
|
exports.getDefaultConfigPath = getDefaultConfigPath;
|
|
38
39
|
exports.saveShieldConfig = saveShieldConfig;
|
|
40
|
+
exports.resolveCliCredentials = resolveCliCredentials;
|
|
41
|
+
exports.isCliSetupComplete = isCliSetupComplete;
|
|
42
|
+
exports.requireCliSetup = requireCliSetup;
|
|
43
|
+
exports.saveSetupConfig = saveSetupConfig;
|
|
39
44
|
exports.resolveSystemPrompt = resolveSystemPrompt;
|
|
40
45
|
const fs = __importStar(require("fs"));
|
|
46
|
+
const os = __importStar(require("os"));
|
|
41
47
|
const path = __importStar(require("path"));
|
|
42
48
|
const CONFIG_FILENAMES = [
|
|
43
49
|
'.fullcourtdefense.yml',
|
|
@@ -120,27 +126,14 @@ function parseValue(s) {
|
|
|
120
126
|
return num;
|
|
121
127
|
return stripped;
|
|
122
128
|
}
|
|
123
|
-
function
|
|
124
|
-
|
|
125
|
-
if (configPath) {
|
|
126
|
-
filePath = path.resolve(configPath);
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
for (const name of CONFIG_FILENAMES) {
|
|
130
|
-
const candidate = path.resolve(process.cwd(), name);
|
|
131
|
-
if (fs.existsSync(candidate)) {
|
|
132
|
-
filePath = candidate;
|
|
133
|
-
break;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
if (!filePath || !fs.existsSync(filePath)) {
|
|
129
|
+
function readConfigFile(filePath) {
|
|
130
|
+
if (!fs.existsSync(filePath))
|
|
138
131
|
return {};
|
|
139
|
-
}
|
|
140
132
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
141
133
|
const raw = parseSimpleYaml(content);
|
|
142
134
|
return {
|
|
143
135
|
apiKey: raw.apiKey ? interpolateEnv(String(raw.apiKey)) : undefined,
|
|
136
|
+
organizationId: raw.organizationId ? interpolateEnv(String(raw.organizationId)) : undefined,
|
|
144
137
|
apiUrl: raw.apiUrl ? interpolateEnv(String(raw.apiUrl)) : undefined,
|
|
145
138
|
shieldId: raw.shieldId ? interpolateEnv(String(raw.shieldId)) : undefined,
|
|
146
139
|
shieldKey: raw.shieldKey ? interpolateEnv(String(raw.shieldKey)) : undefined,
|
|
@@ -159,11 +152,89 @@ function loadConfig(configPath) {
|
|
|
159
152
|
: undefined,
|
|
160
153
|
};
|
|
161
154
|
}
|
|
155
|
+
function mergeConfig(base, override) {
|
|
156
|
+
return {
|
|
157
|
+
...base,
|
|
158
|
+
...Object.fromEntries(Object.entries(override).filter(([, value]) => value !== undefined && value !== '')),
|
|
159
|
+
scan: override.scan ? { ...base.scan, ...override.scan } : base.scan,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function getHomeConfigPath() {
|
|
163
|
+
return path.join(os.homedir(), '.fullcourtdefense.yml');
|
|
164
|
+
}
|
|
165
|
+
function loadConfig(configPath) {
|
|
166
|
+
const homeConfig = readConfigFile(getHomeConfigPath());
|
|
167
|
+
let projectConfig = {};
|
|
168
|
+
if (configPath) {
|
|
169
|
+
projectConfig = readConfigFile(path.resolve(configPath));
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
for (const name of CONFIG_FILENAMES) {
|
|
173
|
+
const candidate = path.resolve(process.cwd(), name);
|
|
174
|
+
if (fs.existsSync(candidate)) {
|
|
175
|
+
projectConfig = readConfigFile(candidate);
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return mergeConfig(homeConfig, projectConfig);
|
|
181
|
+
}
|
|
162
182
|
function getDefaultConfigPath() {
|
|
163
183
|
return path.resolve(process.cwd(), '.fullcourtdefense.yml');
|
|
164
184
|
}
|
|
165
185
|
function saveShieldConfig(input) {
|
|
166
186
|
const target = getDefaultConfigPath();
|
|
187
|
+
return writeSetupConfig(target, input);
|
|
188
|
+
}
|
|
189
|
+
const DEFAULT_API_URL = 'https://api.fullcourtdefense.ai';
|
|
190
|
+
/** Merge saved ~/.fullcourtdefense.yml + env + optional CLI flag overrides. */
|
|
191
|
+
function resolveCliCredentials(config, overrides = {}) {
|
|
192
|
+
return {
|
|
193
|
+
apiKey: overrides.apiKey
|
|
194
|
+
|| config.apiKey
|
|
195
|
+
|| process.env.FULLCOURTDEFENSE_API_KEY
|
|
196
|
+
|| process.env.BOTGUARD_API_KEY,
|
|
197
|
+
organizationId: overrides.organizationId || config.organizationId,
|
|
198
|
+
apiUrl: (overrides.apiUrl
|
|
199
|
+
|| config.apiUrl
|
|
200
|
+
|| process.env.FULLCOURTDEFENSE_API_URL
|
|
201
|
+
|| process.env.FCD_API_URL
|
|
202
|
+
|| DEFAULT_API_URL).replace(/\/$/, ''),
|
|
203
|
+
shieldId: overrides.shieldId
|
|
204
|
+
|| config.shieldId
|
|
205
|
+
|| process.env.FCD_SHIELD_ID
|
|
206
|
+
|| process.env.FULLCOURTDEFENSE_SHIELD_ID
|
|
207
|
+
|| process.env.AGENTGUARD_SHIELD_ID,
|
|
208
|
+
shieldKey: overrides.shieldKey
|
|
209
|
+
|| config.shieldKey
|
|
210
|
+
|| process.env.FCD_SHIELD_KEY
|
|
211
|
+
|| process.env.FULLCOURTDEFENSE_SHIELD_KEY
|
|
212
|
+
|| process.env.AGENTGUARD_SHIELD_KEY,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
function isCliSetupComplete(config) {
|
|
216
|
+
const creds = resolveCliCredentials(config);
|
|
217
|
+
return Boolean(creds.shieldId && creds.apiKey && creds.organizationId);
|
|
218
|
+
}
|
|
219
|
+
/** Fail fast with a clear message when setup was not run. */
|
|
220
|
+
function requireCliSetup(config, overrides = {}, options = {}) {
|
|
221
|
+
const creds = resolveCliCredentials(config, overrides);
|
|
222
|
+
const requireApiKey = options.requireApiKey !== false;
|
|
223
|
+
const requireOrganizationId = options.requireOrganizationId !== false;
|
|
224
|
+
const requireShield = options.requireShield !== false;
|
|
225
|
+
const missing = [];
|
|
226
|
+
if (requireShield && !creds.shieldId)
|
|
227
|
+
missing.push('shieldId');
|
|
228
|
+
if (requireApiKey && !creds.apiKey)
|
|
229
|
+
missing.push('apiKey');
|
|
230
|
+
if (requireOrganizationId && !creds.organizationId)
|
|
231
|
+
missing.push('organizationId');
|
|
232
|
+
if (missing.length > 0) {
|
|
233
|
+
throw new Error(`Missing ${missing.join(', ')}. Run \`fullcourtdefense setup\` once — it saves org, API key, Shield ID, and Shield key to ~/.fullcourtdefense.yml so you never pass them again.`);
|
|
234
|
+
}
|
|
235
|
+
return creds;
|
|
236
|
+
}
|
|
237
|
+
function writeSetupConfig(target, input) {
|
|
167
238
|
const existing = fs.existsSync(target) ? fs.readFileSync(target, 'utf-8') : '';
|
|
168
239
|
const lines = existing ? existing.split(/\r?\n/) : [
|
|
169
240
|
'# FullCourtDefense CLI Configuration',
|
|
@@ -185,12 +256,17 @@ function saveShieldConfig(input) {
|
|
|
185
256
|
lines.push(next);
|
|
186
257
|
}
|
|
187
258
|
};
|
|
259
|
+
setTopLevel('apiKey', input.apiKey);
|
|
260
|
+
setTopLevel('organizationId', input.organizationId);
|
|
188
261
|
setTopLevel('shieldId', input.shieldId);
|
|
189
262
|
setTopLevel('shieldKey', input.shieldKey);
|
|
190
263
|
setTopLevel('apiUrl', input.apiUrl);
|
|
191
264
|
fs.writeFileSync(target, `${lines.filter((line, idx, arr) => !(line === '' && arr[idx - 1] === '')).join('\n').trim()}\n`, 'utf-8');
|
|
192
265
|
return target;
|
|
193
266
|
}
|
|
267
|
+
function saveSetupConfig(input, targetPath) {
|
|
268
|
+
return writeSetupConfig(targetPath || getHomeConfigPath(), input);
|
|
269
|
+
}
|
|
194
270
|
function resolveSystemPrompt(value) {
|
|
195
271
|
if (fs.existsSync(value)) {
|
|
196
272
|
return fs.readFileSync(value, 'utf-8').trim();
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
3
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
37
|
const config_1 = require("./config");
|
|
5
38
|
const scan_1 = require("./commands/scan");
|
|
@@ -11,7 +44,20 @@ const discover_1 = require("./commands/discover");
|
|
|
11
44
|
const hook_1 = require("./commands/hook");
|
|
12
45
|
const installCursorHook_1 = require("./commands/installCursorHook");
|
|
13
46
|
const mcpGateway_1 = require("./commands/mcpGateway");
|
|
14
|
-
const
|
|
47
|
+
const installAll_1 = require("./commands/installAll");
|
|
48
|
+
const fs = __importStar(require("fs"));
|
|
49
|
+
const path = __importStar(require("path"));
|
|
50
|
+
function readCliVersion() {
|
|
51
|
+
try {
|
|
52
|
+
const versionFile = path.join(__dirname, 'version.json');
|
|
53
|
+
const parsed = JSON.parse(fs.readFileSync(versionFile, 'utf8'));
|
|
54
|
+
return parsed.version || 'unknown';
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return 'unknown';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const VERSION = readCliVersion();
|
|
15
61
|
function parseArgs(argv) {
|
|
16
62
|
const flags = {};
|
|
17
63
|
let command = '';
|
|
@@ -63,29 +109,38 @@ function printHelp() {
|
|
|
63
109
|
\x1b[1mCommands:\x1b[0m
|
|
64
110
|
help Show this onboarding guide and command reference.
|
|
65
111
|
doctor First step. Checks outbound HTTPS access to FullCourtDefense.
|
|
66
|
-
configure Saves
|
|
112
|
+
configure Saves org API key, Organization ID, Shield ID, and Shield key to ~/.fullcourtdefense.yml.
|
|
113
|
+
After setup, other commands read credentials automatically — no --shield-id/--api-key needed.
|
|
114
|
+
setup Same as configure — validates credentials against the server before saving.
|
|
115
|
+
install-all One-click: MCP gateway in every AI client + Cursor hooks + optional upload.
|
|
116
|
+
install Alias for install-all.
|
|
67
117
|
scan Runs the scan. Use --local for inside-organization scans.
|
|
68
|
-
discover Finds MCP servers
|
|
69
|
-
|
|
70
|
-
Use --upload to add them to your AI Inventory. Use --deep for
|
|
71
|
-
live HTTP/SSE tools/list. Use --silent for fleet/MDM scripts.
|
|
118
|
+
discover Finds MCP servers, local secrets, agent rules/skills, and machine
|
|
119
|
+
blast radius on this laptop. Use --surface all --upload for AI Fleet.
|
|
72
120
|
install-cursor-hook
|
|
73
121
|
Installs a Cursor hook so every AI prompt + agent action
|
|
74
122
|
(shell, MCP) on this machine is scanned by your Shield.
|
|
75
123
|
uninstall-cursor-hook
|
|
76
124
|
Removes the FullCourtDefense Cursor hook entries.
|
|
77
125
|
install-mcp-gateway
|
|
78
|
-
|
|
79
|
-
clients (Cursor, Claude Code, Claude Desktop).
|
|
80
|
-
mcp-gateway
|
|
81
|
-
Runs a local MCP gateway that checks AgentGuard runtime/action
|
|
82
|
-
policies before forwarding tool calls to a real MCP server.
|
|
126
|
+
Install MCP gateway into selected clients (--clients all for every tool).
|
|
83
127
|
install-cursor-mcp-gateway
|
|
84
|
-
|
|
128
|
+
Cursor only — adds gateway to mcp.json.
|
|
85
129
|
install-claude-code-mcp-gateway
|
|
86
|
-
|
|
130
|
+
Claude Code only — uses claude mcp add or .mcp.json.
|
|
87
131
|
install-claude-desktop-mcp-gateway
|
|
88
|
-
|
|
132
|
+
Claude Desktop only.
|
|
133
|
+
install-codex-mcp-gateway
|
|
134
|
+
Codex only — writes ~/.codex/config.toml.
|
|
135
|
+
install-gemini-mcp-gateway
|
|
136
|
+
Gemini CLI only — writes settings.json mcpServers.
|
|
137
|
+
install-windsurf-mcp-gateway
|
|
138
|
+
Windsurf only.
|
|
139
|
+
install-vscode-mcp-gateway
|
|
140
|
+
VS Code only — .vscode/mcp.json or user settings.
|
|
141
|
+
mcp-gateway
|
|
142
|
+
Runs a local MCP gateway that checks AgentGuard runtime/action
|
|
143
|
+
policies before forwarding tool calls to a real MCP server.
|
|
89
144
|
hook Internal: invoked by Cursor per agent event (reads stdin JSON,
|
|
90
145
|
returns an allow/deny verdict). Not run by hand.
|
|
91
146
|
credits Shows hosted scan credits for CI/CD API-key scans.
|
|
@@ -99,17 +154,21 @@ function printHelp() {
|
|
|
99
154
|
fullcourtdefense doctor
|
|
100
155
|
This confirms the machine can reach https://api.fullcourtdefense.ai over HTTPS.
|
|
101
156
|
|
|
102
|
-
3. Save Shield credentials locally:
|
|
103
|
-
fullcourtdefense
|
|
104
|
-
|
|
157
|
+
3. Save org + Shield credentials locally (one time):
|
|
158
|
+
fullcourtdefense setup
|
|
159
|
+
Saves to ~/.fullcourtdefense.yml — install, discover --upload, scan, and hooks use it automatically.
|
|
160
|
+
|
|
161
|
+
4. One-click protect every AI client on this machine:
|
|
162
|
+
fullcourtdefense install-all --mcp-command npm --mcp-args "run mcp" --upload
|
|
163
|
+
Or install one client: fullcourtdefense install-cursor-mcp-gateway ...
|
|
105
164
|
|
|
106
|
-
|
|
165
|
+
5. Run a guided local scan:
|
|
107
166
|
fullcourtdefense scan --local
|
|
108
167
|
The CLI asks whether to scan endpoint, mcp, or rag.
|
|
109
168
|
To open the localhost web scan UI first:
|
|
110
169
|
fullcourtdefense scan --local --open-ui
|
|
111
170
|
|
|
112
|
-
|
|
171
|
+
6. Review results:
|
|
113
172
|
Use --format summary for CI, --format table for terminal view,
|
|
114
173
|
--format report for evidence, --format full-report for every row,
|
|
115
174
|
or --format json for raw output.
|
|
@@ -152,8 +211,8 @@ function printHelp() {
|
|
|
152
211
|
--mcp-args <args> MCP server args/path, for example ./server.js
|
|
153
212
|
--mcp-tool <tool> MCP tool to test, or all
|
|
154
213
|
--server-name <name> MCP gateway server name for client installers
|
|
155
|
-
--clients <list> Gateway
|
|
156
|
-
claude-
|
|
214
|
+
--clients <list> Gateway clients: all, auto, cursor, claude-code,
|
|
215
|
+
claude-desktop, codex, gemini-cli, windsurf, vscode
|
|
157
216
|
--developer-name <name> Runtime identity for user-scoped policies (auto-detected if omitted)
|
|
158
217
|
--agent-name <name> Runtime agent name (auto-generated from identity + client if omitted)
|
|
159
218
|
--scope <scope> Claude Code MCP scope: local, project, or user
|
|
@@ -178,7 +237,7 @@ function printHelp() {
|
|
|
178
237
|
--mode <sync|async> Hosted mode, or local mode: quick, full, targeted, deep
|
|
179
238
|
--categories <list> Comma-separated attack categories
|
|
180
239
|
--attack-count <n> Number of attacks to run
|
|
181
|
-
--
|
|
240
|
+
--surface <list> Discover surfaces: mcp, secrets, agent-files, posture, all
|
|
182
241
|
--fail-threshold <n> Exit code 1 if score below n (default: 0)
|
|
183
242
|
--format <fmt> Output: table, json, summary, report, full-report (default: table)
|
|
184
243
|
--open Open browser scan UI and saved local scan report
|
|
@@ -199,23 +258,27 @@ function printHelp() {
|
|
|
199
258
|
$ fullcourtdefense scan --local --type mcp --mcp-transport sse --mcp-url https://internal.company.com/sse --mcp-tool all --mode full
|
|
200
259
|
$ fullcourtdefense scan --local --type mcp --mcp-command node --mcp-args ./server.js --mcp-tool all --mode full --format report
|
|
201
260
|
$ fullcourtdefense discover
|
|
202
|
-
$ fullcourtdefense discover --upload
|
|
261
|
+
$ fullcourtdefense discover --surface all --upload
|
|
262
|
+
$ fullcourtdefense discover --surface secrets
|
|
263
|
+
$ fullcourtdefense discover --surface agent-files
|
|
203
264
|
$ fullcourtdefense discover --deep --upload --silent --user-email you@company.com
|
|
204
265
|
$ fullcourtdefense discover --type mcp --json
|
|
205
|
-
$ fullcourtdefense install-cursor-hook
|
|
266
|
+
$ fullcourtdefense install-cursor-hook
|
|
206
267
|
$ fullcourtdefense install-cursor-hook --shadow true # monitor only
|
|
207
268
|
$ fullcourtdefense install-cursor-hook --events prompt,shell,mcp,file
|
|
208
269
|
$ fullcourtdefense install-cursor-hook --project true # this repo only
|
|
209
270
|
$ fullcourtdefense uninstall-cursor-hook
|
|
210
|
-
$ fullcourtdefense install-mcp-gateway --clients auto --
|
|
211
|
-
$ fullcourtdefense install-mcp-gateway --clients all --
|
|
212
|
-
$ fullcourtdefense install-cursor-mcp-gateway --project true --
|
|
213
|
-
$ fullcourtdefense install-claude-code-mcp-gateway --scope local --
|
|
214
|
-
$ fullcourtdefense install-claude-code-mcp-gateway --scope project --
|
|
215
|
-
$ fullcourtdefense install-claude-desktop-mcp-gateway --
|
|
216
|
-
$ fullcourtdefense mcp-gateway --
|
|
217
|
-
$ fullcourtdefense
|
|
218
|
-
$ fullcourtdefense
|
|
271
|
+
$ fullcourtdefense install-mcp-gateway --clients auto --mcp-command npm --mcp-args "run mcp"
|
|
272
|
+
$ fullcourtdefense install-mcp-gateway --clients all --mcp-command npm --mcp-args "run mcp" --upload
|
|
273
|
+
$ fullcourtdefense install-cursor-mcp-gateway --project true --mcp-command npm --mcp-args "run mcp"
|
|
274
|
+
$ fullcourtdefense install-claude-code-mcp-gateway --scope local --mcp-command npm --mcp-args "run mcp"
|
|
275
|
+
$ fullcourtdefense install-claude-code-mcp-gateway --scope project --mcp-command npm --mcp-args "run mcp"
|
|
276
|
+
$ fullcourtdefense install-claude-desktop-mcp-gateway --mcp-command npm --mcp-args "run mcp"
|
|
277
|
+
$ fullcourtdefense mcp-gateway --mcp-command npm --mcp-args "run mcp"
|
|
278
|
+
$ fullcourtdefense setup
|
|
279
|
+
$ fullcourtdefense install-all --mcp-command npm --mcp-args "run mcp" --upload
|
|
280
|
+
$ fullcourtdefense install-mcp-gateway --clients cursor,codex --mcp-command npm --mcp-args "run mcp"
|
|
281
|
+
$ fullcourtdefense install-codex-mcp-gateway --mcp-command npm --mcp-args "run mcp"
|
|
219
282
|
$ fullcourtdefense scan --system-prompt ./prompts/system.md --fail-threshold 80
|
|
220
283
|
$ fullcourtdefense scan --config .fullcourtdefense.yml --format json
|
|
221
284
|
$ fullcourtdefense credits
|
|
@@ -226,6 +289,47 @@ function printHelp() {
|
|
|
226
289
|
}
|
|
227
290
|
async function main() {
|
|
228
291
|
const { command, flags } = parseArgs(process.argv.slice(2));
|
|
292
|
+
const buildInstallArgs = () => ({
|
|
293
|
+
clients: flags.clients,
|
|
294
|
+
cursorProject: flags['cursor-project'],
|
|
295
|
+
claudeCodeScope: flags['claude-code-scope'] || flags.scope,
|
|
296
|
+
serverName: flags['server-name'],
|
|
297
|
+
mcpCommand: flags['mcp-command'],
|
|
298
|
+
mcpArgs: flags['mcp-args'],
|
|
299
|
+
agentName: flags['agent-name'],
|
|
300
|
+
developerName: flags['developer-name'],
|
|
301
|
+
shieldId: flags['shield-id'],
|
|
302
|
+
shieldKey: flags['shield-key'],
|
|
303
|
+
apiUrl: flags['api-url'],
|
|
304
|
+
environment: flags.environment,
|
|
305
|
+
userObjective: flags['user-objective'],
|
|
306
|
+
authority: flags.authority,
|
|
307
|
+
approvalMode: flags['approval-mode'],
|
|
308
|
+
approvalTimeoutMs: flags['approval-timeout-ms'],
|
|
309
|
+
approvalPollMs: flags['approval-poll-ms'],
|
|
310
|
+
scanResponse: flags['scan-response'],
|
|
311
|
+
failClosed: flags['fail-closed'],
|
|
312
|
+
upload: flags.upload,
|
|
313
|
+
apiKey: flags['api-key'],
|
|
314
|
+
});
|
|
315
|
+
const buildGatewayArgs = () => ({
|
|
316
|
+
mcpCommand: flags['mcp-command'],
|
|
317
|
+
mcpArgs: flags['mcp-args'],
|
|
318
|
+
agentName: flags['agent-name'],
|
|
319
|
+
agentClient: flags['agent-client'],
|
|
320
|
+
developerName: flags['developer-name'],
|
|
321
|
+
shieldId: flags['shield-id'],
|
|
322
|
+
shieldKey: flags['shield-key'],
|
|
323
|
+
apiUrl: flags['api-url'],
|
|
324
|
+
environment: flags.environment,
|
|
325
|
+
userObjective: flags['user-objective'],
|
|
326
|
+
authority: flags.authority,
|
|
327
|
+
approvalMode: flags['approval-mode'],
|
|
328
|
+
approvalTimeoutMs: flags['approval-timeout-ms'],
|
|
329
|
+
approvalPollMs: flags['approval-poll-ms'],
|
|
330
|
+
scanResponse: flags['scan-response'],
|
|
331
|
+
failClosed: flags['fail-closed'],
|
|
332
|
+
});
|
|
229
333
|
if (flags.version || flags.v) {
|
|
230
334
|
console.log(VERSION);
|
|
231
335
|
return;
|
|
@@ -296,11 +400,15 @@ async function main() {
|
|
|
296
400
|
await (0, doctor_1.doctorCommand)(args, config);
|
|
297
401
|
break;
|
|
298
402
|
}
|
|
299
|
-
case 'configure':
|
|
403
|
+
case 'configure':
|
|
404
|
+
case 'setup': {
|
|
300
405
|
const args = {
|
|
406
|
+
apiKey: flags['api-key'],
|
|
407
|
+
organizationId: flags['organization-id'] || flags['org-id'],
|
|
301
408
|
shieldId: flags['shield-id'],
|
|
302
409
|
shieldKey: flags['shield-key'],
|
|
303
410
|
apiUrl: flags['api-url'],
|
|
411
|
+
skipValidate: flags['skip-validate'] === 'true',
|
|
304
412
|
};
|
|
305
413
|
await (0, configure_1.configureCommand)(args, config);
|
|
306
414
|
break;
|
|
@@ -316,6 +424,7 @@ async function main() {
|
|
|
316
424
|
case 'discover': {
|
|
317
425
|
const args = {
|
|
318
426
|
type: flags.type,
|
|
427
|
+
surface: flags.surface,
|
|
319
428
|
apiKey: flags['api-key'],
|
|
320
429
|
apiUrl: flags['api-url'],
|
|
321
430
|
json: flags.json,
|
|
@@ -364,123 +473,85 @@ async function main() {
|
|
|
364
473
|
break;
|
|
365
474
|
}
|
|
366
475
|
case 'mcp-gateway': {
|
|
476
|
+
await (0, mcpGateway_1.mcpGatewayCommand)(buildGatewayArgs(), config);
|
|
477
|
+
break;
|
|
478
|
+
}
|
|
479
|
+
case 'install-all':
|
|
480
|
+
case 'install': {
|
|
367
481
|
const args = {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
agentClient: flags['agent-client'],
|
|
372
|
-
developerName: flags['developer-name'],
|
|
373
|
-
shieldId: flags['shield-id'],
|
|
374
|
-
shieldKey: flags['shield-key'],
|
|
375
|
-
apiUrl: flags['api-url'],
|
|
376
|
-
environment: flags.environment,
|
|
377
|
-
userObjective: flags['user-objective'],
|
|
378
|
-
authority: flags.authority,
|
|
379
|
-
approvalMode: flags['approval-mode'],
|
|
380
|
-
approvalTimeoutMs: flags['approval-timeout-ms'],
|
|
381
|
-
approvalPollMs: flags['approval-poll-ms'],
|
|
382
|
-
scanResponse: flags['scan-response'],
|
|
383
|
-
failClosed: flags['fail-closed'],
|
|
482
|
+
...buildInstallArgs(),
|
|
483
|
+
hooks: flags.hooks,
|
|
484
|
+
discover: flags.discover,
|
|
384
485
|
};
|
|
385
|
-
await (0,
|
|
486
|
+
await (0, installAll_1.installAllCommand)(args, config);
|
|
386
487
|
break;
|
|
387
488
|
}
|
|
388
489
|
case 'install-mcp-gateway': {
|
|
389
|
-
|
|
390
|
-
clients: flags.clients,
|
|
391
|
-
cursorProject: flags['cursor-project'],
|
|
392
|
-
claudeCodeScope: flags['claude-code-scope'] || flags.scope,
|
|
393
|
-
serverName: flags['server-name'],
|
|
394
|
-
mcpCommand: flags['mcp-command'],
|
|
395
|
-
mcpArgs: flags['mcp-args'],
|
|
396
|
-
agentName: flags['agent-name'],
|
|
397
|
-
developerName: flags['developer-name'],
|
|
398
|
-
shieldId: flags['shield-id'],
|
|
399
|
-
shieldKey: flags['shield-key'],
|
|
400
|
-
apiUrl: flags['api-url'],
|
|
401
|
-
environment: flags.environment,
|
|
402
|
-
userObjective: flags['user-objective'],
|
|
403
|
-
authority: flags.authority,
|
|
404
|
-
approvalMode: flags['approval-mode'],
|
|
405
|
-
approvalTimeoutMs: flags['approval-timeout-ms'],
|
|
406
|
-
approvalPollMs: flags['approval-poll-ms'],
|
|
407
|
-
scanResponse: flags['scan-response'],
|
|
408
|
-
failClosed: flags['fail-closed'],
|
|
409
|
-
upload: flags.upload,
|
|
410
|
-
apiKey: flags['api-key'],
|
|
411
|
-
};
|
|
412
|
-
await (0, mcpGateway_1.installMcpGatewayCommand)(args, config);
|
|
490
|
+
await (0, mcpGateway_1.installMcpGatewayCommand)(buildInstallArgs(), config);
|
|
413
491
|
break;
|
|
414
492
|
}
|
|
415
493
|
case 'install-cursor-mcp-gateway': {
|
|
416
494
|
const args = {
|
|
495
|
+
...buildGatewayArgs(),
|
|
417
496
|
project: flags.project,
|
|
418
497
|
serverName: flags['server-name'],
|
|
419
|
-
mcpCommand: flags['mcp-command'],
|
|
420
|
-
mcpArgs: flags['mcp-args'],
|
|
421
|
-
agentName: flags['agent-name'],
|
|
422
|
-
developerName: flags['developer-name'],
|
|
423
|
-
shieldId: flags['shield-id'],
|
|
424
|
-
shieldKey: flags['shield-key'],
|
|
425
|
-
apiUrl: flags['api-url'],
|
|
426
|
-
environment: flags.environment,
|
|
427
|
-
userObjective: flags['user-objective'],
|
|
428
|
-
authority: flags.authority,
|
|
429
|
-
approvalMode: flags['approval-mode'],
|
|
430
|
-
approvalTimeoutMs: flags['approval-timeout-ms'],
|
|
431
|
-
approvalPollMs: flags['approval-poll-ms'],
|
|
432
|
-
scanResponse: flags['scan-response'],
|
|
433
|
-
failClosed: flags['fail-closed'],
|
|
434
498
|
};
|
|
435
499
|
await (0, mcpGateway_1.installCursorMcpGatewayCommand)(args, config);
|
|
436
500
|
break;
|
|
437
501
|
}
|
|
438
502
|
case 'install-claude-code-mcp-gateway': {
|
|
439
503
|
const args = {
|
|
504
|
+
...buildGatewayArgs(),
|
|
440
505
|
scope: flags.scope,
|
|
441
506
|
serverName: flags['server-name'],
|
|
442
|
-
mcpCommand: flags['mcp-command'],
|
|
443
|
-
mcpArgs: flags['mcp-args'],
|
|
444
|
-
agentName: flags['agent-name'],
|
|
445
|
-
developerName: flags['developer-name'],
|
|
446
|
-
shieldId: flags['shield-id'],
|
|
447
|
-
shieldKey: flags['shield-key'],
|
|
448
|
-
apiUrl: flags['api-url'],
|
|
449
|
-
environment: flags.environment,
|
|
450
|
-
userObjective: flags['user-objective'],
|
|
451
|
-
authority: flags.authority,
|
|
452
|
-
approvalMode: flags['approval-mode'],
|
|
453
|
-
approvalTimeoutMs: flags['approval-timeout-ms'],
|
|
454
|
-
approvalPollMs: flags['approval-poll-ms'],
|
|
455
|
-
scanResponse: flags['scan-response'],
|
|
456
|
-
failClosed: flags['fail-closed'],
|
|
457
507
|
};
|
|
458
508
|
await (0, mcpGateway_1.installClaudeCodeMcpGatewayCommand)(args, config);
|
|
459
509
|
break;
|
|
460
510
|
}
|
|
461
511
|
case 'install-claude-desktop-mcp-gateway': {
|
|
462
512
|
const args = {
|
|
513
|
+
...buildGatewayArgs(),
|
|
463
514
|
configPath: flags['config-path'],
|
|
464
515
|
serverName: flags['server-name'],
|
|
465
|
-
mcpCommand: flags['mcp-command'],
|
|
466
|
-
mcpArgs: flags['mcp-args'],
|
|
467
|
-
agentName: flags['agent-name'],
|
|
468
|
-
developerName: flags['developer-name'],
|
|
469
|
-
shieldId: flags['shield-id'],
|
|
470
|
-
shieldKey: flags['shield-key'],
|
|
471
|
-
apiUrl: flags['api-url'],
|
|
472
|
-
environment: flags.environment,
|
|
473
|
-
userObjective: flags['user-objective'],
|
|
474
|
-
authority: flags.authority,
|
|
475
|
-
approvalMode: flags['approval-mode'],
|
|
476
|
-
approvalTimeoutMs: flags['approval-timeout-ms'],
|
|
477
|
-
approvalPollMs: flags['approval-poll-ms'],
|
|
478
|
-
scanResponse: flags['scan-response'],
|
|
479
|
-
failClosed: flags['fail-closed'],
|
|
480
516
|
};
|
|
481
517
|
await (0, mcpGateway_1.installClaudeDesktopMcpGatewayCommand)(args, config);
|
|
482
518
|
break;
|
|
483
519
|
}
|
|
520
|
+
case 'install-codex-mcp-gateway': {
|
|
521
|
+
const args = {
|
|
522
|
+
...buildGatewayArgs(),
|
|
523
|
+
project: flags.project,
|
|
524
|
+
serverName: flags['server-name'],
|
|
525
|
+
};
|
|
526
|
+
await (0, mcpGateway_1.installCodexMcpGatewayCommand)(args, config);
|
|
527
|
+
break;
|
|
528
|
+
}
|
|
529
|
+
case 'install-gemini-mcp-gateway': {
|
|
530
|
+
const args = {
|
|
531
|
+
...buildGatewayArgs(),
|
|
532
|
+
project: flags.project,
|
|
533
|
+
serverName: flags['server-name'],
|
|
534
|
+
};
|
|
535
|
+
await (0, mcpGateway_1.installGeminiMcpGatewayCommand)(args, config);
|
|
536
|
+
break;
|
|
537
|
+
}
|
|
538
|
+
case 'install-windsurf-mcp-gateway': {
|
|
539
|
+
const args = {
|
|
540
|
+
...buildGatewayArgs(),
|
|
541
|
+
serverName: flags['server-name'],
|
|
542
|
+
};
|
|
543
|
+
await (0, mcpGateway_1.installWindsurfMcpGatewayCommand)(args, config);
|
|
544
|
+
break;
|
|
545
|
+
}
|
|
546
|
+
case 'install-vscode-mcp-gateway': {
|
|
547
|
+
const args = {
|
|
548
|
+
...buildGatewayArgs(),
|
|
549
|
+
project: flags.project,
|
|
550
|
+
serverName: flags['server-name'],
|
|
551
|
+
};
|
|
552
|
+
await (0, mcpGateway_1.installVscodeMcpGatewayCommand)(args, config);
|
|
553
|
+
break;
|
|
554
|
+
}
|
|
484
555
|
case 'init': {
|
|
485
556
|
await (0, init_1.initCommand)();
|
|
486
557
|
break;
|