fullcourtdefense-cli 1.21.0 → 1.21.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.
@@ -593,10 +593,18 @@ async function hookCommand(args, config) {
593
593
  decision.agent_message = agentMsg;
594
594
  }
595
595
  dbg({ phase: 'verdict', event, format: hookFormat, blocked, decision });
596
+ if (hookFormat === 'claude' && event === 'prompt' && blocked) {
597
+ // Claude Desktop/Code variants do not all honor the structured
598
+ // UserPromptSubmit decision consistently. Exit 2 is the documented hard
599
+ // block contract: stderr is shown as the rejection reason and the prompt
600
+ // is not sent to the model.
601
+ process.stderr.write(userMsg || agentMsg || 'Blocked by FullCourtDefense.');
602
+ process.exit(2);
603
+ }
596
604
  process.stdout.write(JSON.stringify(decision));
597
- // ALWAYS exit 0 so the client uses our JSON verdict. Exit 2 is interpreted as
598
- // `permission: "deny"`, which beforeSubmitPrompt ignores (it uses `continue`),
599
- // so exiting 2 would silently let blocked prompts through.
605
+ // Cursor must exit 0 so it consumes the JSON verdict. In particular,
606
+ // beforeSubmitPrompt ignores an exit-2 permission denial and uses
607
+ // `{ continue: false }`.
600
608
  process.exit(0);
601
609
  };
602
610
  // Claude-format lifecycle events with no pre-execution surface (PostToolUse,
package/dist/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "1.21.0"
2
+ "version": "1.21.2"
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fullcourtdefense-cli",
3
- "version": "1.21.0",
3
+ "version": "1.21.2",
4
4
  "description": "Full Court Defense CLI — security scanning for AI agents from your terminal",
5
5
  "main": "dist/index.js",
6
6
  "bin": {