fullcourtdefense-cli 1.6.8 → 1.6.10

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.
@@ -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
- return str(last?.content) || str(last?.text);
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);
@@ -137,7 +137,7 @@ async function installCursorHookCommand(args, config) {
137
137
  const { hookKey, flag, failClosedDefault, timeoutSec } = EVENT_MAP[e];
138
138
  const failClosed = e === 'prompt' ? false : (args.failClosed !== undefined ? args.failClosed === 'true' : failClosedDefault);
139
139
  const entry = {
140
- command: buildHookCommand(flag, { shadow: e === 'prompt' ? true : shadow, failClosed }),
140
+ command: buildHookCommand(flag, { shadow, failClosed }),
141
141
  timeout: timeoutSec,
142
142
  };
143
143
  if (failClosed)
package/dist/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "1.6.8"
2
+ "version": "1.6.10"
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fullcourtdefense-cli",
3
- "version": "1.6.8",
3
+ "version": "1.6.10",
4
4
  "description": "Full Court Defense CLI — security scanning for AI agents from your terminal",
5
5
  "main": "dist/index.js",
6
6
  "bin": {