Skip to content

feat(plugin): add Claude Code plugin#282

Merged
peaktwilight merged 1 commit intomainfrom
feat/280-claude-plugin
May 1, 2026
Merged

feat(plugin): add Claude Code plugin#282
peaktwilight merged 1 commit intomainfrom
feat/280-claude-plugin

Conversation

@peaktwilight
Copy link
Copy Markdown
Collaborator

@peaktwilight peaktwilight commented May 1, 2026

Summary

  • Add a Claude Code plugin manifest, hook configuration, and secure-coding preamble for foxguard.
  • Auto-scan files after Claude Write/Edit/MultiEdit tool use and surface medium+ findings back to Claude.
  • Add namespaced /foxguard:* skills for setup, scan, diff scan, PQ audit, secrets, triage, and secure-coding guidance.

Verification

  • jq empty plugins/claude-code/.claude-plugin/plugin.json && jq empty plugins/claude-code/hooks/hooks.json
  • bash -n plugins/claude-code/scripts/scan-edited-file.sh
  • printf '%s' '{"tool_input":{"file_path":"Cargo.toml"}}' | PATH="$(pwd)/target/debug:$PATH" plugins/claude-code/scripts/scan-edited-file.sh

Closes #280

Summary by CodeRabbit

  • New Features

    • Added Claude Code plugin for automated security scanning of edited files during write/edit operations
    • Integrated security analysis capabilities including full scans, diff scans, secrets detection, and post-quantum cryptography auditing
    • Added on-demand commands for setup verification, repository scanning, and interactive triage
  • Documentation

    • Added comprehensive plugin documentation with secure coding guidelines and best practices
    • Included secure defaults configuration defining mandatory security practices for code development

Adds plugins/claude-code/ — a Claude Code plugin that integrates foxguard
into the Claude Code workflow.

What it does:
- PostToolUse hook auto-scans every Write/Edit/MultiEdit/NotebookEdit
  with `foxguard --format json --severity medium`. Findings are surfaced
  to Claude on stderr (exit 2) so the model self-corrects before bad
  patterns land. Clean files, missing binary, or unreadable inputs stay
  silent (exit 0) — the hook never blocks Claude on its own machinery.
- SessionStart hook seeds each session with foxguard's secure-coding
  defaults (command exec, SQL, path traversal, SSRF, secrets, randomness,
  crypto, deserialization).
- Slash commands: /foxguard:setup, scan, diff-scan, pq-audit, secrets,
  triage. Each is a SKILL.md with disable-model-invocation so the user
  drives them.
- Model-invokable `secure-coding` skill provides remediation guidance
  Claude can pull in proactively when touching security-sensitive code.

The hook resolves foxguard from PATH first, then falls back to
`npx --yes foxguard`. Severity threshold is tunable via
FOXGUARD_HOOK_SEVERITY (default: medium).

Tested against bad files (exit 2 with findings), clean files (exit 0),
missing files, empty input, and a severity override — all behave as
expected.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

📝 Walkthrough

Walkthrough

This PR introduces a complete Claude Code plugin for foxguard that enables automatic security scanning as Claude writes and edits code. It includes PostToolUse hooks for auto-scanning files, SessionStart hooks for security defaults, and seven skill-based slash commands for setup, full/diff scanning, post-quantum auditing, secret scanning, and remediation guidance.

Changes

Cohort / File(s) Summary
Plugin Manifest & Configuration
plugins/claude-code/.claude-plugin/plugin.json, plugins/claude-code/hooks/hooks.json
Defines plugin identity (foxguard), version (0.1.0), ownership, and licenses; registers PostToolUse hook to scan edited files and SessionStart hook to inject secure-defaults preamble.
Core Documentation & Defaults
plugins/claude-code/README.md, plugins/claude-code/scripts/secure-defaults.txt
Comprehensive README documenting installation (binary/homebrew/npm/cargo), plugin loading, configuration via environment variables, and operational notes; secure-defaults text file specifying mandatory practices for shell/SQL/path/SSRF/crypto/randomness/deserialization.
Scan Execution & Parsing
plugins/claude-code/scripts/scan-edited-file.sh
Bash script that consumes hook input from stdin, resolves edited file path, invokes foxguard in JSON mode with configurable severity threshold, parses results with jq, emits compact stderr report of findings, and exits with status 2 if issues found (status 0 otherwise to avoid blocking).
Skills & Slash Commands
plugins/claude-code/skills/setup/SKILL.md, plugins/claude-code/skills/scan/SKILL.md, plugins/claude-code/skills/diff-scan/SKILL.md, plugins/claude-code/skills/pq-audit/SKILL.md, plugins/claude-code/skills/secrets/SKILL.md, plugins/claude-code/skills/secure-coding/SKILL.md, plugins/claude-code/skills/triage/SKILL.md
Seven skill documentation files defining user-facing workflows for setup verification, full repo scanning with grouped results, branch-relative diff scanning, post-quantum cryptography auditing with deprecation timeline guidance, secrets scanning with remediation categorization, secure-coding practices across eight vulnerability categories, and interactive TUI-based triage guidance.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A scanner hops into Claude's den,
Fox guards the code again and again,
Secure by default, each hook runs deep,
Finding the flaws while Claude's asleep! 🦊✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(plugin): add Claude Code plugin' is clear, concise, and directly summarizes the main change—adding a Claude Code plugin for foxguard integration.
Linked Issues check ✅ Passed The PR implements all core requirements from issue #280: PostToolUse hook for auto-scanning Write/Edit actions, SessionStart hook with secure-coding defaults, slash commands (/setup, /scan, /diff-scan, /pq-audit, /secrets, /triage), and model-invocable skills for remediation guidance.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the Claude Code plugin as specified in issue #280; no unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/280-claude-plugin

Review rate limit: 9/10 reviews remaining, refill in 6 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
plugins/claude-code/skills/setup/SKILL.md (1)

10-14: ⚡ Quick win

Avoid “curl | sh” without verification guidance.

Line 10 uses curl -fsSL https://foxguard.dev/install.sh | sh. Even with “do NOT install without confirmation”, this still encourages an insecure-by-default installation pattern. Consider updating the step to: download the script to a file, verify a published checksum/signature (or explicitly instruct users to inspect the script before executing), then run it.

Suggested doc wording
- - **Prebuilt binary (fastest)**: `curl -fsSL https://foxguard.dev/install.sh | sh`
+ - **Prebuilt binary (fastest)**: Download the installer script, verify it (checksum/signature if provided by foxguard), then run it (e.g., `sh install.sh`).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/claude-code/skills/setup/SKILL.md` around lines 10 - 14, Replace the
insecure "curl -fsSL https://foxguard.dev/install.sh | sh" install suggestion
with explicit download-and-verify guidance: instruct users to curl or wget the
install script to a local file (e.g., download the install.sh), verify its
published checksum or signature (or inspect the script manually), and only then
run it (sh ./install.sh) after verification and explicit consent; update the
SKILL.md install bullet that currently contains the piped curl command to this
safer sequence and mention verifying signed checksums or manual inspection as
the required step before execution.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugins/claude-code/README.md`:
- Around line 64-73: The fenced code block under "How the auto-scan looks" in
README.md is missing a language specifier which triggers markdownlint MD040;
update the opening triple-backtick to include a language (for example change ```
to ```text) so the block is recognized as text, leaving the block contents
unchanged; locate the fenced block in the "How the auto-scan looks" example and
modify its opening delimiter accordingly.
- Around line 79-95: The README's layout directory tree code block uses a bare
triple-backtick which triggers markdownlint MD040; update the fenced code block
around the "plugins/claude-code/" tree (the Layout directory tree block) to
include a language identifier (e.g., change ``` to ```text) so the block is
fenced with a language and MD040 is resolved.
- Around line 54-57: The markdown table defining configuration (the row for
FOXGUARD_HOOK_SEVERITY) is malformed and triggers MD056 because the
header/separator doesn't unambiguously define three columns; open the table near
the FOXGUARD_HOOK_SEVERITY row and fix the header and separator to have exactly
three columns (e.g., a single header row with three cells and a matching
separator like `| :-- | :-- | :-- |`), and remove any accidental extra `|`
characters inside cells so the FOXGUARD_HOOK_SEVERITY row and its header align
to three columns.

In `@plugins/claude-code/scripts/scan-edited-file.sh`:
- Line 30: The scanner is invoked as "${fg[@]}" --format json --severity
"$min_severity" "$file_path" which can misinterpret filenames beginning with '-'
as options; update the invocation that constructs findings to insert a
standalone "--" before the positional path (i.e., call "${fg[@]}" --format json
--severity "$min_severity" -- "$file_path") so the scanner treats file_path as a
filename; ensure you update the line that assigns findings and keep existing
quoting and the fallback "|| true".

In `@plugins/claude-code/skills/secure-coding/SKILL.md`:
- Line 11: The inline code span on Line 11 is malformed because nested backticks
break Markdown rendering around the Node example; update the text to avoid
nested backticks by using a single backtick for the surrounding inline code and
escaping or reformatting the inner example (e.g., use execFile("git", ["log",
branch"]) instead of backticked exec(`git log ${branch}`) or present the inner
command in a code span block), targeting the phrase that references execFile and
exec with the git log ${branch} example so the Markdown renders correctly.

---

Nitpick comments:
In `@plugins/claude-code/skills/setup/SKILL.md`:
- Around line 10-14: Replace the insecure "curl -fsSL
https://foxguard.dev/install.sh | sh" install suggestion with explicit
download-and-verify guidance: instruct users to curl or wget the install script
to a local file (e.g., download the install.sh), verify its published checksum
or signature (or inspect the script manually), and only then run it (sh
./install.sh) after verification and explicit consent; update the SKILL.md
install bullet that currently contains the piped curl command to this safer
sequence and mention verifying signed checksums or manual inspection as the
required step before execution.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bbb1bd68-9515-4b57-ae5c-bdf71bda486d

📥 Commits

Reviewing files that changed from the base of the PR and between 61c7230 and c600704.

📒 Files selected for processing (12)
  • plugins/claude-code/.claude-plugin/plugin.json
  • plugins/claude-code/README.md
  • plugins/claude-code/hooks/hooks.json
  • plugins/claude-code/scripts/scan-edited-file.sh
  • plugins/claude-code/scripts/secure-defaults.txt
  • plugins/claude-code/skills/diff-scan/SKILL.md
  • plugins/claude-code/skills/pq-audit/SKILL.md
  • plugins/claude-code/skills/scan/SKILL.md
  • plugins/claude-code/skills/secrets/SKILL.md
  • plugins/claude-code/skills/secure-coding/SKILL.md
  • plugins/claude-code/skills/setup/SKILL.md
  • plugins/claude-code/skills/triage/SKILL.md

Comment on lines +54 to +57
| Var | Default | Purpose |
| :-- | :-- | :-- |
| `FOXGUARD_HOOK_SEVERITY` | `medium` | Minimum severity for the auto-scan. One of `low|medium|high|critical`. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix markdownlint MD056: table column count.

Your configuration table around lines 54-57 is triggering markdownlint-cli2 MD056 (“Expected: 3; Actual: 6”). Adjust the table to unambiguously define 3 columns in the header/separator, and avoid any accidental extra | characters.

Example normalization
-| Var | Default | Purpose |
-| :-- | :-- | :-- |
+| Var | Default | Purpose |
+| --- | --- | --- |
 | `FOXGUARD_HOOK_SEVERITY` | `medium` | Minimum severity for the auto-scan. One of `low|medium|high|critical`. |
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| Var | Default | Purpose |
| :-- | :-- | :-- |
| `FOXGUARD_HOOK_SEVERITY` | `medium` | Minimum severity for the auto-scan. One of `low|medium|high|critical`. |
| Var | Default | Purpose |
| --- | --- | --- |
| `FOXGUARD_HOOK_SEVERITY` | `medium` | Minimum severity for the auto-scan. One of `low\|medium\|high\|critical`. |
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 56-56: Table column count
Expected: 3; Actual: 6; Too many cells, extra data will be missing

(MD056, table-column-count)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/claude-code/README.md` around lines 54 - 57, The markdown table
defining configuration (the row for FOXGUARD_HOOK_SEVERITY) is malformed and
triggers MD056 because the header/separator doesn't unambiguously define three
columns; open the table near the FOXGUARD_HOOK_SEVERITY row and fix the header
and separator to have exactly three columns (e.g., a single header row with
three cells and a matching separator like `| :-- | :-- | :-- |`), and remove any
accidental extra `|` characters inside cells so the FOXGUARD_HOOK_SEVERITY row
and its header align to three columns.

Comment on lines +64 to +73
```
foxguard found 1 issue(s) in src/auth.py (severity >= medium):

[CRITICAL] py/no-command-injection at line 42
os.system() called with dynamic argument — risk of command injection
CWE-78
> os.system("ls " + user_input)

Fix these before continuing. Run `/foxguard:scan` for the full repo or `/foxguard:triage` for the interactive TUI.
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix markdownlint MD040: add a fenced-code language.

The example block under “How the auto-scan looks” starts with a bare triple-backtick (line 64 per hint). Specify a language (e.g. text) to satisfy MD040.

Suggested change
-```
+```text
 foxguard found 1 issue(s) in src/auth.py (severity >= medium):
 ...
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 64-64: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/claude-code/README.md` around lines 64 - 73, The fenced code block
under "How the auto-scan looks" in README.md is missing a language specifier
which triggers markdownlint MD040; update the opening triple-backtick to include
a language (for example change ``` to ```text) so the block is recognized as
text, leaving the block contents unchanged; locate the fenced block in the "How
the auto-scan looks" example and modify its opening delimiter accordingly.

Comment on lines +79 to +95
```
plugins/claude-code/
├── .claude-plugin/plugin.json # manifest
├── hooks/hooks.json # PostToolUse + SessionStart
├── scripts/
│ ├── scan-edited-file.sh # the PostToolUse scanner
│ └── secure-defaults.txt # SessionStart preamble
├── skills/
│ ├── setup/SKILL.md # /foxguard:setup
│ ├── scan/SKILL.md # /foxguard:scan
│ ├── diff-scan/SKILL.md # /foxguard:diff-scan
│ ├── pq-audit/SKILL.md # /foxguard:pq-audit
│ ├── secrets/SKILL.md # /foxguard:secrets
│ ├── triage/SKILL.md # /foxguard:triage
│ └── secure-coding/SKILL.md # model-invoked remediation guidance
└── README.md
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix markdownlint MD040: add a fenced-code language.

The “Layout” directory tree block also uses a bare triple-backtick (line 79 per hint). Add a language identifier like text to clear MD040.

Suggested change
-```
+```text
 plugins/claude-code/
 ├── .claude-plugin/plugin.json     # manifest
 ...
</details>

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.22.1)</summary>

[warning] 79-79: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @plugins/claude-code/README.md around lines 79 - 95, The README's layout
directory tree code block uses a bare triple-backtick which triggers
markdownlint MD040; update the fenced code block around the
"plugins/claude-code/" tree (the Layout directory tree block) to include a
language identifier (e.g., change totext) so the block is fenced with a
language and MD040 is resolved.


</details>

<!-- fingerprinting:phantom:triton:puma:05f3783a-a64c-4a50-b1f4-3b1690357be0 -->

<!-- d98c2f50 -->

<!-- This is an auto-generated comment by CodeRabbit -->


min_severity="${FOXGUARD_HOOK_SEVERITY:-medium}"

findings=$("${fg[@]}" --format json --severity "$min_severity" "$file_path" 2>/dev/null) || true
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Prevent option-style filename bypass in scanner invocation

On Line 30, "$file_path" is passed as a positional argument without --. If the edited filename starts with -, the scanner may parse it as a flag instead of a path.

Suggested fix
-findings=$("${fg[@]}" --format json --severity "$min_severity" "$file_path" 2>/dev/null) || true
+findings=$("${fg[@]}" --format json --severity "$min_severity" -- "$file_path" 2>/dev/null) || true
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
findings=$("${fg[@]}" --format json --severity "$min_severity" "$file_path" 2>/dev/null) || true
findings=$("${fg[@]}" --format json --severity "$min_severity" -- "$file_path" 2>/dev/null) || true
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/claude-code/scripts/scan-edited-file.sh` at line 30, The scanner is
invoked as "${fg[@]}" --format json --severity "$min_severity" "$file_path"
which can misinterpret filenames beginning with '-' as options; update the
invocation that constructs findings to insert a standalone "--" before the
positional path (i.e., call "${fg[@]}" --format json --severity "$min_severity"
-- "$file_path") so the scanner treats file_path as a filename; ensure you
update the line that assigns findings and keep existing quoting and the fallback
"|| true".


- Never pass concatenated strings to a shell. Use argument lists.
- Python: `subprocess.run(["git", "log", branch], check=True)` — never `subprocess.run(f"git log {branch}", shell=True)`.
- Node: `execFile("git", ["log", branch])` — never `exec(`git log ${branch}`)`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix malformed inline code span in Node example

On Line 11, nested backticks break Markdown rendering for the exec example.

Suggested fix
-  - Node: `execFile("git", ["log", branch])` — never `exec(`git log ${branch}`)`.
+  - Node: `execFile("git", ["log", branch])` — never `exec("git log " + branch)` (or template-string shell commands).
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- Node: `execFile("git", ["log", branch])` — never `exec(`git log ${branch}`)`.
- Node: `execFile("git", ["log", branch])` — never `exec("git log " + branch)` (or template-string shell commands).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/claude-code/skills/secure-coding/SKILL.md` at line 11, The inline
code span on Line 11 is malformed because nested backticks break Markdown
rendering around the Node example; update the text to avoid nested backticks by
using a single backtick for the surrounding inline code and escaping or
reformatting the inner example (e.g., use execFile("git", ["log", branch"])
instead of backticked exec(`git log ${branch}`) or present the inner command in
a code span block), targeting the phrase that references execFile and exec with
the git log ${branch} example so the Markdown renders correctly.

@peaktwilight peaktwilight merged commit 85a63ee into main May 1, 2026
17 checks passed
@peaktwilight peaktwilight deleted the feat/280-claude-plugin branch May 1, 2026 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Claude Code plugin for foxguard

1 participant