fullcourtdefense-cli 1.3.1 → 1.3.3
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 +21 -2
- package/dist/commands/configure.d.ts +3 -0
- package/dist/commands/configure.js +56 -11
- 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/commands/hook.js
CHANGED
|
@@ -37,7 +37,7 @@ exports.hookCommand = hookCommand;
|
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
38
|
const os = __importStar(require("os"));
|
|
39
39
|
const path = __importStar(require("path"));
|
|
40
|
-
const
|
|
40
|
+
const config_1 = require("../config");
|
|
41
41
|
const DEBUG_LOG = path.join(os.homedir(), '.fullcourtdefense-hook.log');
|
|
42
42
|
/** Append a diagnostic line so we can see exactly what Cursor invoked + the verdict. */
|
|
43
43
|
function dbg(obj) {
|
|
@@ -78,27 +78,6 @@ function readStdin() {
|
|
|
78
78
|
setTimeout(finish, 2000).unref?.();
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
|
-
/** Load ~/.fullcourtdefense.yml (machine-wide creds) as a fallback to project config. */
|
|
82
|
-
function loadHomeShield() {
|
|
83
|
-
try {
|
|
84
|
-
const candidates = ['.fullcourtdefense.yml', '.fullcourtdefense.yaml'];
|
|
85
|
-
for (const name of candidates) {
|
|
86
|
-
const p = path.join(os.homedir(), name);
|
|
87
|
-
if (!fs.existsSync(p))
|
|
88
|
-
continue;
|
|
89
|
-
const text = fs.readFileSync(p, 'utf8');
|
|
90
|
-
const pick = (key) => {
|
|
91
|
-
const m = text.match(new RegExp(`^\\s*${key}\\s*:\\s*(.+)\\s*$`, 'm'));
|
|
92
|
-
if (!m)
|
|
93
|
-
return undefined;
|
|
94
|
-
return m[1].replace(/^["']|["']$/g, '').trim() || undefined;
|
|
95
|
-
};
|
|
96
|
-
return { shieldId: pick('shieldId'), shieldKey: pick('shieldKey'), apiUrl: pick('apiUrl') };
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
catch { /* ignore */ }
|
|
100
|
-
return {};
|
|
101
|
-
}
|
|
102
81
|
function inferEvent(explicit, payload) {
|
|
103
82
|
const e = (explicit || '').toLowerCase();
|
|
104
83
|
if (e) {
|
|
@@ -234,11 +213,14 @@ async function hookCommand(args, config) {
|
|
|
234
213
|
const shadow = args.shadow === 'true';
|
|
235
214
|
const failClosed = args.failClosed === 'true';
|
|
236
215
|
const timeoutMs = Number(args.timeout) > 0 ? Number(args.timeout) : 8000;
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
216
|
+
const creds = (0, config_1.resolveCliCredentials)(config, {
|
|
217
|
+
shieldId: args.shieldId,
|
|
218
|
+
shieldKey: args.shieldKey,
|
|
219
|
+
apiUrl: args.apiUrl,
|
|
220
|
+
});
|
|
221
|
+
const shieldId = creds.shieldId;
|
|
222
|
+
const shieldKey = creds.shieldKey;
|
|
223
|
+
const apiUrl = creds.apiUrl;
|
|
242
224
|
let raw = '';
|
|
243
225
|
let stdinErr = '';
|
|
244
226
|
const isTTY = !!process.stdin.isTTY;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BotGuardConfig } from '../config';
|
|
2
|
+
import { InstallMcpGatewayArgs } from './mcpGateway';
|
|
3
|
+
export interface InstallAllArgs extends InstallMcpGatewayArgs {
|
|
4
|
+
hooks?: string;
|
|
5
|
+
discover?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* One-click install: MCP gateway into every supported AI client, optional Cursor hooks,
|
|
9
|
+
* optional fleet upload. Use per-client commands when you only need one tool.
|
|
10
|
+
*/
|
|
11
|
+
export declare function installAllCommand(args: InstallAllArgs, config: BotGuardConfig): Promise<void>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.installAllCommand = installAllCommand;
|
|
4
|
+
const config_1 = require("../config");
|
|
5
|
+
const discover_1 = require("./discover");
|
|
6
|
+
const installCursorHook_1 = require("./installCursorHook");
|
|
7
|
+
const mcpGateway_1 = require("./mcpGateway");
|
|
8
|
+
/**
|
|
9
|
+
* One-click install: MCP gateway into every supported AI client, optional Cursor hooks,
|
|
10
|
+
* optional fleet upload. Use per-client commands when you only need one tool.
|
|
11
|
+
*/
|
|
12
|
+
async function installAllCommand(args, config) {
|
|
13
|
+
const creds = (0, config_1.requireCliSetup)(config, {
|
|
14
|
+
apiKey: args.apiKey,
|
|
15
|
+
shieldId: args.shieldId,
|
|
16
|
+
shieldKey: args.shieldKey,
|
|
17
|
+
apiUrl: args.apiUrl,
|
|
18
|
+
}, { requireOrganizationId: false });
|
|
19
|
+
const gatewayArgs = {
|
|
20
|
+
...args,
|
|
21
|
+
...creds,
|
|
22
|
+
clients: args.clients || 'all',
|
|
23
|
+
};
|
|
24
|
+
console.log('\n\x1b[1m\x1b[36mFullCourtDefense — install all AI clients\x1b[0m');
|
|
25
|
+
console.log('\x1b[2mGateway + optional Cursor hooks + optional fleet upload\x1b[0m\n');
|
|
26
|
+
await (0, mcpGateway_1.installMcpGatewayCommand)(gatewayArgs, config);
|
|
27
|
+
if (args.hooks !== 'false') {
|
|
28
|
+
console.log('\n\x1b[1mInstalling Cursor runtime hooks…\x1b[0m');
|
|
29
|
+
const hookArgs = {
|
|
30
|
+
shieldId: creds.shieldId,
|
|
31
|
+
shieldKey: creds.shieldKey,
|
|
32
|
+
apiUrl: creds.apiUrl,
|
|
33
|
+
project: args.cursorProject,
|
|
34
|
+
};
|
|
35
|
+
try {
|
|
36
|
+
await (0, installCursorHook_1.installCursorHookCommand)(hookArgs, config);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
console.log(`Cursor hooks skipped: ${error instanceof Error ? error.message : String(error)}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (args.discover === 'true' || args.upload === 'true') {
|
|
43
|
+
console.log('\n\x1b[1mUploading desktop posture to AI Fleet…\x1b[0m');
|
|
44
|
+
const discoverArgs = {
|
|
45
|
+
surface: 'all',
|
|
46
|
+
upload: 'true',
|
|
47
|
+
apiKey: creds.apiKey,
|
|
48
|
+
apiUrl: creds.apiUrl,
|
|
49
|
+
userEmail: args.developerName,
|
|
50
|
+
silent: args.upload === 'true' && args.discover !== 'true' ? 'true' : undefined,
|
|
51
|
+
};
|
|
52
|
+
await (0, discover_1.discoverCommand)(discoverArgs, config);
|
|
53
|
+
}
|
|
54
|
+
console.log('\n\x1b[32mDone.\x1b[0m Restart each AI client you use, then run \x1b[1mfullcourtdefense discover --surface all\x1b[0m to verify.');
|
|
55
|
+
}
|
|
@@ -38,6 +38,7 @@ exports.uninstallCursorHookCommand = uninstallCursorHookCommand;
|
|
|
38
38
|
const fs = __importStar(require("fs"));
|
|
39
39
|
const os = __importStar(require("os"));
|
|
40
40
|
const path = __importStar(require("path"));
|
|
41
|
+
const config_1 = require("../config");
|
|
41
42
|
const COLOR = {
|
|
42
43
|
reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
|
|
43
44
|
red: '\x1b[31m', yellow: '\x1b[33m', green: '\x1b[32m', cyan: '\x1b[36m', gray: '\x1b[90m',
|
|
@@ -90,28 +91,15 @@ function isManaged(entry) {
|
|
|
90
91
|
return typeof entry?.command === 'string'
|
|
91
92
|
&& (entry.command.includes(MANAGED_MARKER) || entry.command.includes(MANAGED_TAG));
|
|
92
93
|
}
|
|
93
|
-
/**
|
|
94
|
-
function
|
|
94
|
+
/** Ensure Shield creds are in ~/.fullcourtdefense.yml for runtime hooks (no-op if already saved via setup). */
|
|
95
|
+
function ensureHomeShield(input) {
|
|
95
96
|
if (!input.shieldId && !input.shieldKey && !input.apiUrl)
|
|
96
97
|
return undefined;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return;
|
|
103
|
-
const idx = lines.findIndex((l) => new RegExp(`^\\s*${key}\\s*:`).test(l));
|
|
104
|
-
const next = `${key}: ${value}`;
|
|
105
|
-
if (idx >= 0)
|
|
106
|
-
lines[idx] = next;
|
|
107
|
-
else
|
|
108
|
-
lines.push(next);
|
|
109
|
-
};
|
|
110
|
-
setKey('shieldId', input.shieldId);
|
|
111
|
-
setKey('shieldKey', input.shieldKey);
|
|
112
|
-
setKey('apiUrl', input.apiUrl);
|
|
113
|
-
fs.writeFileSync(target, lines.filter((l, i, a) => !(l === '' && a[i - 1] === '')).join('\n').trim() + '\n', 'utf8');
|
|
114
|
-
return target;
|
|
98
|
+
return (0, config_1.saveSetupConfig)({
|
|
99
|
+
shieldId: input.shieldId,
|
|
100
|
+
shieldKey: input.shieldKey,
|
|
101
|
+
apiUrl: input.apiUrl,
|
|
102
|
+
});
|
|
115
103
|
}
|
|
116
104
|
async function installCursorHookCommand(args, config) {
|
|
117
105
|
const projectScope = args.project === 'true';
|
|
@@ -124,11 +112,12 @@ async function installCursorHookCommand(args, config) {
|
|
|
124
112
|
console.error(`${COLOR.red}No valid events. Choose from: ${Object.keys(EVENT_MAP).join(', ')}${COLOR.reset}`);
|
|
125
113
|
process.exit(1);
|
|
126
114
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
115
|
+
const creds = (0, config_1.resolveCliCredentials)(config, {
|
|
116
|
+
shieldId: args.shieldId,
|
|
117
|
+
shieldKey: args.shieldKey,
|
|
118
|
+
apiUrl: args.apiUrl,
|
|
119
|
+
});
|
|
120
|
+
const credFile = ensureHomeShield(creds);
|
|
132
121
|
const json = readHooksJson(file);
|
|
133
122
|
for (const e of events) {
|
|
134
123
|
const { hookKey, flag, failClosedDefault } = EVENT_MAP[e];
|
|
@@ -155,9 +144,9 @@ async function installCursorHookCommand(args, config) {
|
|
|
155
144
|
console.log(`${COLOR.yellow}Mode: SHADOW (monitor only — nothing is blocked).${COLOR.reset}`);
|
|
156
145
|
if (credFile)
|
|
157
146
|
console.log(`${COLOR.gray}Creds:${COLOR.reset} ${credFile}`);
|
|
158
|
-
if (!shieldId) {
|
|
147
|
+
if (!creds.shieldId) {
|
|
159
148
|
console.log('');
|
|
160
|
-
console.log(`${COLOR.yellow}No Shield ID set.${COLOR.reset} Run ${COLOR.bold}fullcourtdefense
|
|
149
|
+
console.log(`${COLOR.yellow}No Shield ID set.${COLOR.reset} Run ${COLOR.bold}fullcourtdefense setup${COLOR.reset} first, then re-run install.`);
|
|
161
150
|
}
|
|
162
151
|
console.log('');
|
|
163
152
|
console.log(`${COLOR.gray}Restart Cursor (or it will hot-reload hooks.json). Verify in Cursor → Settings → Hooks.${COLOR.reset}`);
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { BotGuardConfig } from '../config';
|
|
2
|
+
type AgentClient = 'cursor' | 'claude-code' | 'claude-desktop' | 'codex' | 'gemini-cli' | 'windsurf' | 'vscode';
|
|
3
|
+
export type GatewayClient = AgentClient;
|
|
4
|
+
export declare const ALL_GATEWAY_CLIENTS: GatewayClient[];
|
|
2
5
|
export interface McpGatewayArgs {
|
|
3
6
|
mcpCommand?: string;
|
|
4
7
|
mcpArgs?: string;
|
|
@@ -29,6 +32,21 @@ export interface InstallClaudeDesktopMcpGatewayArgs extends McpGatewayArgs {
|
|
|
29
32
|
configPath?: string;
|
|
30
33
|
serverName?: string;
|
|
31
34
|
}
|
|
35
|
+
export interface InstallVscodeMcpGatewayArgs extends McpGatewayArgs {
|
|
36
|
+
project?: string;
|
|
37
|
+
serverName?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface InstallCodexMcpGatewayArgs extends McpGatewayArgs {
|
|
40
|
+
project?: string;
|
|
41
|
+
serverName?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface InstallGeminiMcpGatewayArgs extends McpGatewayArgs {
|
|
44
|
+
project?: string;
|
|
45
|
+
serverName?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface InstallWindsurfMcpGatewayArgs extends McpGatewayArgs {
|
|
48
|
+
serverName?: string;
|
|
49
|
+
}
|
|
32
50
|
export interface InstallMcpGatewayArgs extends McpGatewayArgs {
|
|
33
51
|
clients?: string;
|
|
34
52
|
cursorProject?: string;
|
|
@@ -42,3 +60,8 @@ export declare function installCursorMcpGatewayCommand(args: InstallCursorMcpGat
|
|
|
42
60
|
export declare function installMcpGatewayCommand(args: InstallMcpGatewayArgs, config: BotGuardConfig): Promise<void>;
|
|
43
61
|
export declare function installClaudeCodeMcpGatewayCommand(args: InstallClaudeCodeMcpGatewayArgs, config: BotGuardConfig): Promise<void>;
|
|
44
62
|
export declare function installClaudeDesktopMcpGatewayCommand(args: InstallClaudeDesktopMcpGatewayArgs, config: BotGuardConfig): Promise<void>;
|
|
63
|
+
export declare function installCodexMcpGatewayCommand(args: InstallCodexMcpGatewayArgs, config: BotGuardConfig): Promise<void>;
|
|
64
|
+
export declare function installGeminiMcpGatewayCommand(args: InstallGeminiMcpGatewayArgs, config: BotGuardConfig): Promise<void>;
|
|
65
|
+
export declare function installWindsurfMcpGatewayCommand(args: InstallWindsurfMcpGatewayArgs, config: BotGuardConfig): Promise<void>;
|
|
66
|
+
export declare function installVscodeMcpGatewayCommand(args: InstallVscodeMcpGatewayArgs, config: BotGuardConfig): Promise<void>;
|
|
67
|
+
export {};
|