fullcourtdefense-cli 1.6.9 → 1.6.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.
- package/dist/commands/hook.js +43 -1
- package/dist/commands/installAll.js +4 -2
- package/dist/commands/installCursorHook.js +3 -1
- package/dist/commands/mcpGateway.js +6 -3
- package/dist/commands/restartNotice.d.ts +1 -0
- package/dist/commands/restartNotice.js +9 -0
- package/dist/version.json +1 -1
- package/package.json +1 -1
package/dist/commands/hook.js
CHANGED
|
@@ -104,6 +104,30 @@ function inferEvent(explicit, payload) {
|
|
|
104
104
|
return 'unknown';
|
|
105
105
|
}
|
|
106
106
|
const str = (v) => (typeof v === 'string' ? v : '');
|
|
107
|
+
function collectPromptStrings(value, out = [], depth = 0) {
|
|
108
|
+
if (depth > 5 || value === null || value === undefined)
|
|
109
|
+
return out;
|
|
110
|
+
if (typeof value === 'string') {
|
|
111
|
+
if (value.trim())
|
|
112
|
+
out.push(value);
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
if (Array.isArray(value)) {
|
|
116
|
+
for (const item of value.slice(-10))
|
|
117
|
+
collectPromptStrings(item, out, depth + 1);
|
|
118
|
+
return out;
|
|
119
|
+
}
|
|
120
|
+
if (typeof value === 'object') {
|
|
121
|
+
const obj = value;
|
|
122
|
+
for (const key of ['text', 'content', 'message', 'value', 'input', 'prompt']) {
|
|
123
|
+
collectPromptStrings(obj[key], out, depth + 1);
|
|
124
|
+
}
|
|
125
|
+
for (const key of ['messages', 'parts', 'items']) {
|
|
126
|
+
collectPromptStrings(obj[key], out, depth + 1);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
107
131
|
/** Pull the meaningful text to scan out of a Cursor PROMPT hook payload. */
|
|
108
132
|
function extractPromptText(p) {
|
|
109
133
|
const direct = str(p.prompt) || str(p.text) || str(p.message) || str(p.content);
|
|
@@ -114,12 +138,29 @@ function extractPromptText(p) {
|
|
|
114
138
|
const t = str(promptObj.text) || str(promptObj.content);
|
|
115
139
|
if (t)
|
|
116
140
|
return t;
|
|
141
|
+
const nestedPrompt = collectPromptStrings(promptObj);
|
|
142
|
+
if (nestedPrompt.length)
|
|
143
|
+
return nestedPrompt.join('\n');
|
|
117
144
|
}
|
|
118
145
|
const messages = p.messages;
|
|
119
146
|
if (Array.isArray(messages) && messages.length) {
|
|
120
147
|
const last = messages[messages.length - 1];
|
|
121
|
-
|
|
148
|
+
const fromLast = str(last?.content) || str(last?.text);
|
|
149
|
+
if (fromLast)
|
|
150
|
+
return fromLast;
|
|
151
|
+
const nestedMessages = collectPromptStrings(last);
|
|
152
|
+
if (nestedMessages.length)
|
|
153
|
+
return nestedMessages.join('\n');
|
|
122
154
|
}
|
|
155
|
+
const nestedTopLevel = collectPromptStrings({
|
|
156
|
+
text: p.text,
|
|
157
|
+
message: p.message,
|
|
158
|
+
content: p.content,
|
|
159
|
+
input: p.input,
|
|
160
|
+
prompt: p.prompt,
|
|
161
|
+
});
|
|
162
|
+
if (nestedTopLevel.length)
|
|
163
|
+
return nestedTopLevel.join('\n');
|
|
123
164
|
return '';
|
|
124
165
|
}
|
|
125
166
|
/**
|
|
@@ -356,6 +397,7 @@ async function hookCommand(args, config) {
|
|
|
356
397
|
// --- Shield text analysis for prompts (developer chat) ---
|
|
357
398
|
if (event === 'prompt') {
|
|
358
399
|
const text = extractPromptText(payload).trim();
|
|
400
|
+
dbg({ phase: 'prompt_text', textLen: text.length, textPreview: text.slice(0, 300) });
|
|
359
401
|
if (!text)
|
|
360
402
|
respond(false);
|
|
361
403
|
const localBlock = (0, deterministicGuard_1.scanDeterministicPrompt)(text);
|
|
@@ -6,6 +6,7 @@ const discover_1 = require("./discover");
|
|
|
6
6
|
const installCursorHook_1 = require("./installCursorHook");
|
|
7
7
|
const mcpGateway_1 = require("./mcpGateway");
|
|
8
8
|
const autoProtect_1 = require("./autoProtect");
|
|
9
|
+
const restartNotice_1 = require("./restartNotice");
|
|
9
10
|
/**
|
|
10
11
|
* One-click install: discover/wrap every existing MCP server, install Cursor
|
|
11
12
|
* hooks for built-in Cursor actions, optional self-heal and fleet upload.
|
|
@@ -32,7 +33,7 @@ async function installAllCommand(args, config) {
|
|
|
32
33
|
shieldKey: creds.shieldKey,
|
|
33
34
|
apiUrl: creds.apiUrl,
|
|
34
35
|
project: args.cursorProject,
|
|
35
|
-
events: 'shell,mcp',
|
|
36
|
+
events: 'prompt,shell,mcp',
|
|
36
37
|
failClosed: 'true',
|
|
37
38
|
};
|
|
38
39
|
try {
|
|
@@ -61,5 +62,6 @@ async function installAllCommand(args, config) {
|
|
|
61
62
|
};
|
|
62
63
|
await (0, discover_1.discoverCommand)(discoverArgs, config);
|
|
63
64
|
}
|
|
64
|
-
console.log('\n\x1b[32mDone.\x1b[0m
|
|
65
|
+
console.log('\n\x1b[32mDone.\x1b[0m Run \x1b[1mfullcourtdefense protect-all --dry-run true\x1b[0m to verify gateways.');
|
|
66
|
+
(0, restartNotice_1.printRestartNotice)();
|
|
65
67
|
}
|
|
@@ -39,6 +39,7 @@ const fs = __importStar(require("fs"));
|
|
|
39
39
|
const os = __importStar(require("os"));
|
|
40
40
|
const path = __importStar(require("path"));
|
|
41
41
|
const config_1 = require("../config");
|
|
42
|
+
const restartNotice_1 = require("./restartNotice");
|
|
42
43
|
const COLOR = {
|
|
43
44
|
reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
|
|
44
45
|
red: '\x1b[31m', yellow: '\x1b[33m', green: '\x1b[32m', cyan: '\x1b[36m', gray: '\x1b[90m',
|
|
@@ -168,7 +169,8 @@ async function installCursorHookCommand(args, config) {
|
|
|
168
169
|
console.log(`${COLOR.yellow}No Shield ID set.${COLOR.reset} Run ${COLOR.bold}fullcourtdefense setup${COLOR.reset} first, then re-run install.`);
|
|
169
170
|
}
|
|
170
171
|
console.log('');
|
|
171
|
-
|
|
172
|
+
(0, restartNotice_1.printRestartNotice)('Cursor');
|
|
173
|
+
console.log(`${COLOR.gray}Verify in Cursor → Settings → Hooks after restart.${COLOR.reset}`);
|
|
172
174
|
console.log(`${COLOR.gray}Remove with:${COLOR.reset} fullcourtdefense uninstall-cursor-hook${projectScope ? ' --project true' : ''}`);
|
|
173
175
|
}
|
|
174
176
|
async function uninstallCursorHookCommand(args) {
|
|
@@ -53,6 +53,7 @@ const config_1 = require("../config");
|
|
|
53
53
|
const discoverPaths_1 = require("./discoverPaths");
|
|
54
54
|
const discover_1 = require("./discover");
|
|
55
55
|
const deterministicGuard_1 = require("./deterministicGuard");
|
|
56
|
+
const restartNotice_1 = require("./restartNotice");
|
|
56
57
|
const DEFAULT_API_URL = 'https://api.fullcourtdefense.ai';
|
|
57
58
|
const MANAGED_SERVER_NAME = 'agentguard-gateway';
|
|
58
59
|
const INSTALL_GATEWAY_ARGS = { includeShieldKey: false };
|
|
@@ -936,7 +937,7 @@ async function installMcpGatewayCommand(args, config) {
|
|
|
936
937
|
console.log(` - ${failure}`);
|
|
937
938
|
}
|
|
938
939
|
console.log(` Runtime identity: ${detectedDeveloperName(args)}`);
|
|
939
|
-
|
|
940
|
+
(0, restartNotice_1.printRestartNotice)(clients.map(c => CLIENT_LABELS[c]).join(', '));
|
|
940
941
|
if (args.upload === 'true') {
|
|
941
942
|
console.log('\nUploading desktop inventory to AI Fleet…');
|
|
942
943
|
const creds = (0, config_1.resolveCliCredentials)(config, { apiKey: args.apiKey, apiUrl: args.apiUrl });
|
|
@@ -1334,8 +1335,10 @@ async function protectAllCommand(args, config) {
|
|
|
1334
1335
|
console.log('\x1b[1mSummary\x1b[0m');
|
|
1335
1336
|
console.log(` ${dryRun ? 'would update' : 'updated'}: ${totalWrapped} already protected: ${totalManaged} no servers: ${totalEmpty} skipped remote: ${totalRemote}`);
|
|
1336
1337
|
console.log(` Each protected server enforces your org Action Policies (allow / block / wait-for-human-approval) on its tool calls.`);
|
|
1337
|
-
if (!dryRun && totalWrapped > 0)
|
|
1338
|
-
console.log(' Backups saved next to each edited file (*.fcd-backup-*).
|
|
1338
|
+
if (!dryRun && totalWrapped > 0) {
|
|
1339
|
+
console.log(' Backups saved next to each edited file (*.fcd-backup-*).');
|
|
1340
|
+
(0, restartNotice_1.printRestartNotice)(allowedClientKeys ? [...allowedClientKeys].join(', ') : undefined);
|
|
1341
|
+
}
|
|
1339
1342
|
console.log(' Reverse anytime with: \x1b[1mfullcourtdefense unprotect-all\x1b[0m');
|
|
1340
1343
|
}
|
|
1341
1344
|
async function unprotectAllCommand(args, config) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function printRestartNotice(clients?: string): void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.printRestartNotice = printRestartNotice;
|
|
4
|
+
function printRestartNotice(clients = 'Cursor, Claude, Codex, VS Code, Windsurf, Gemini') {
|
|
5
|
+
console.log('');
|
|
6
|
+
console.log('\x1b[33m\x1b[1mACTION REQUIRED: restart your AI clients\x1b[0m');
|
|
7
|
+
console.log(`\x1b[33mRestart/reload ${clients} so they load the protected MCP gateway and hooks.\x1b[0m`);
|
|
8
|
+
console.log('\x1b[2mAlready-running MCP servers may keep using old unprotected processes until the client restarts.\x1b[0m');
|
|
9
|
+
}
|
package/dist/version.json
CHANGED