* Remove legacy codex compatiblity scripts/shims.
Codex supports claude plugins so this shouldn't be necessary.
Add a script to test the plugin loadablility in both claude and codex
* fix: resolve code review findings for PR #173
Review findings addressed (4 reviewers: pr-review-toolkit agents,
Codex gpt-5.3-codex, direct diff review):
P2 fixed:
- Bump versions for the 5 substantively changed plugins in both
plugin.json and marketplace.json (gh-cli 1.5.0 new skill,
claude-in-chrome-troubleshooting 1.1.0 skill rename,
modern-python 1.5.1 / skill-improver 1.0.3 hooks change,
zeroize-audit 0.1.1 MCP config relocation) so clients pick up
the changes
- README Codex install: replace unpasteable /plugins slash-command
block with verified CLI syntax (codex plugin marketplace add)
- check_claude_loadability: parse_json_output now fails fast with
command context on empty CLI output instead of returning None
- check_codex_loadability: surface skipped RPC error messages in
timeout failures instead of a bare TimeoutError
P3 fixed:
- Both checkers: error out when marketplace.json lists no plugins
instead of passing vacuously
Dismissed:
- @latest CLI installs in validate.yml: deliberate; the check
validates against the clients users actually run
- select.select portability: CI-only script on ubuntu-latest
- Divergent mcpServers validation between checkers: intentional;
the Codex checker enforces the repo's .mcp.json convention
Verified: ruff, prek, validate_plugin_metadata.py, and both
loadability checks pass end-to-end (39 plugins, 74 skills, 2 MCP
servers load in Claude Code and Codex)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Dan Guido <dan@trailofbits.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* ci: add python-tests job to run plugin Python test suites
Discovers test_*.py / *_test.py files under plugins/ and executes
each one as a script. Matches the style of the existing bats job.
Works today for:
- plugins/constant-time-analysis/ct_analyzer/tests/test_analyzer.py
- plugins/let-fate-decide/.../scripts/test_draw_cards.py
Both test files already exist in the repo but no CI job invoked them.
As a result, PR #125 (which broke let-fate-decide by removing
`import os` while leaving `os.path` calls in draw()) merged with
green CI even though the existing `test_draw_*` / `test_cli_*`
tests would have caught it.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ci(python-tests): install aarch64 cross toolchain for constant-time-analysis
TestCrossArchitecture.test_cross_compile_arm64 invokes clang with
--target=aarch64-unknown-linux-gnu, which needs the aarch64 libc
headers. Without them clang fails with:
fatal error: 'bits/libc-header-start.h' file not found
Install gcc-aarch64-linux-gnu + libc6-dev-arm64-cross so clang can
find the cross headers. Also install clang explicitly since the
runner may not have it preinstalled.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ci: clarify python-tests workflow comments
Resolves code review findings on PR #147 (comment accuracy only —
no behavior change):
- Rewrite the toolchain dependencies comment. The previous wording
("aarch64 cross gcc pulls in libc6-dev-arm64-cross") implied a
transitive dependency, but `--no-install-recommends` suppresses
Recommends, so libc6-dev-arm64-cross is installed only because it
is listed explicitly. New comment names what each package supplies.
- Document why `set -uo pipefail` deliberately omits -e (the loop
collects per-file failures and exits with a combined code).
Reviewers (codex + gemini + pr-review-toolkit agents) flagged 13
findings total; 11 were dismissed (false positives, design choices
matching the bats job, or speculative). Quality pipeline (actionlint,
zizmor, shellcheck, pre-commit, plugin validators, both Python test
suites) all pass locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Dan Guido <dan@trailofbits.com>
* Add Codex-native skill installation support
* Document Codex install commands in README
* Enforce Codex skill mappings in CI
* Fix review issues in Codex skill support
- Fix ruff line-length violations in validate_codex_skills.py
- Rewrite gh-cli SKILL.md description to third-person voice
- Fix misleading error messages: describe actual symlink fix
instead of referencing the user-local installer script
- Add early check for missing .codex/skills/ directory
- Distinguish dangling symlinks from mismatched symlinks
- Add defensive ValueError handling in rel()
- Add PLUGINS_DIR existence guard
- Add install count and zero-install warning to installer
- Add SOURCE_DIR existence check to installer
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Dan Guido <dan@trailofbits.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ci: enforce pre-commit formatting hooks in CI
check-yaml, check-json, end-of-file-fixer, and trailing-whitespace
only ran locally via pre-commit. Contributors who skip pre-commit
can introduce formatting drift (see #97). Add a CI job using
pre-commit/action to enforce these four hooks on every PR.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ci: consolidate lint jobs into single pre-commit pass
Run all pre-commit hooks (ruff, shellcheck, shfmt, check-yaml,
check-json, end-of-file-fixer, trailing-whitespace) in one job
instead of separate CI jobs per tool. Fixes the extra_args error
where pre-commit run only accepts one hook ID positionally.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style: fix trailing whitespace and EOF in semgrep-rule-creator
Pre-commit hooks caught two files missed by the earlier formatting
PR: trailing blank line in quick-reference.md and trailing
whitespace plus missing final newline in workflow.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* better ci validations, fix marketplace error
* fix lints
* fix lint script
* fix lint script2
* fix ruff errors
* fix abs path regex
* fix shellcheck lint
* fix: resolve code review findings for PR #85
- Remove dead CHANGED_FILES code path (unreachable in CI)
- Add version and description consistency checks between plugin.json
and marketplace.json
- Eliminate duplicate plugin.json reads via parse_plugin_json()
- Fix bats test discovery for filenames with spaces (print0/xargs -0)
- Sync marketplace.json with plugin.json for 5 pre-existing mismatches
(second-opinion version, ask-questions/burpsuite/fix-review/insecure-defaults descriptions)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: gh-cli bats tests fail when gh is in /usr/bin
The _no_gh test helpers used PATH=/usr/bin:/bin to exclude gh, but
on Ubuntu CI runners gh is installed at /usr/bin/gh. Fix by creating
a temp directory with symlinks to only jq and bash.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: improve plugin descriptions for better skill triggering
- ask-questions-if-underspecified: restore trigger context ("asking
questions") while keeping invocation constraint
- burpsuite-project-parser: drop filler "directly from the command
line", use outcome-oriented "for security analysis"
- insecure-defaults: restore specific scenarios (hardcoded credentials,
fallback secrets, weak auth defaults) for better matching
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Dan Guido <dan@trailofbits.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Add devcontainer-setup plugin for Claude Code development environments
Creates pre-configured devcontainers with Claude Code and language-specific
tooling. Supports Python, Node/TypeScript, Rust, and Go projects with
automatic detection and configuration.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add plugin to marketplace list
* Fix the post install command
* Fix YARN installation
* Install fzf from GitHub and add plugin marketplaces
- Install fzf from GitHub releases instead of apt (Ubuntu 24.04's apt
version lacks shell integration)
- Add Claude plugin marketplace setup for anthropics/skills and
trailofbits/skills in post_install.py
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix linting issues in devcontainer-setup plugin
- Use contextlib.suppress instead of try-except-pass (SIM105)
- Fix case statement indentation in install.sh for shfmt
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Exclude /home/vscode from hardcoded path check
Standard devcontainer user path should not be flagged as a
personal hardcoded path.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Sync devcontainer-setup with upstream claude-code-devcontainer
Sync resources with https://github.com/trailofbits/claude-code-devcontainer:
- Add Python 3.13 via uv and Node 22 via fnm to base Dockerfile
- Add ast-grep for AST-based code search
- Include network isolation tools (iptables, ipset) by default
- Add Tailscale feature for secure networking
- Add NPM security settings (ignore-scripts, 24-hour release delay)
- Add init: true and updateRemoteUserUID: true to devcontainer.json
- Expand .zshrc with fnm integration, fzf config, and more aliases
- Update post_install.py to print to stderr and add ghostty terminal features
- Integrate delta config into .gitconfig.local
- Move marketplace plugin installation from post_install.py to Dockerfile
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Sync devcontainer-setup resources with upstream
Align with https://github.com/trailofbits/claude-code-devcontainer:
- Move PATH env before Claude install
- Remove -p fzf from Oh My Zsh, download fzf shell integration separately
- Add FZF_VERSION arg for shell integration download
- Use uv run --no-project for post_install.py
- Add fzf sourcing to .zshrc
- Add symlink resolution and update command to install.sh
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Address PR review comments and sync with upstream devcontainer
DarkaMaul's review comments:
- Restore SHA256 hash on base image for reproducibility
- Sort apt packages alphabetically within category groups
- Install fzf from GitHub releases (v0.67.0) instead of old apt package
- Remove Tailscale feature (not generic enough for template)
Upstream sync (3 new commits from claude-code-devcontainer):
- Add bubblewrap and socat for Claude Code sandboxing
- Add exec, upgrade, and mount commands to devc CLI
- Mount .devcontainer/ read-only to prevent container escape on rebuild
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Harden devcontainer templates from multi-agent review findings
- Pin uv to 0.10.0 with SHA256 digest (supply chain security)
- Add SYS_ADMIN capability guard to install.sh (prevents defeating
read-only .devcontainer mount)
- Fix mount filter to use target paths instead of source prefixes
(was broken when PROJECT_SLUG was substituted)
- Fix temp file leak in extract_mounts_to_file
- Remove claude-yolo alias (unsafe pattern for a template)
- Remove dead POWERLEVEL9K_DISABLE_GITSTATUS and NODE_OPTIONS configs
- Remove unnecessary terminal profile definitions
- Default timezone to UTC instead of America/New_York
- Remove stale Tailscale reference from SKILL.md
- Fix line length violations throughout install.sh
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Restore claude-yolo alias and POWERLEVEL9K_DISABLE_GITSTATUS
The claude-yolo alias is intentional for devcontainer use.
POWERLEVEL9K_DISABLE_GITSTATUS is needed because zsh-in-docker
installs Powerlevel10k, whose gitstatus can be slow in large repos.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Restore NODE_OPTIONS, terminal profiles, and re-clone URL
NODE_OPTIONS 4GB heap is intentional for Claude Code in containers.
Terminal profiles are useful in VS Code dropdown. Re-clone message
needs the full URL to be actionable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Dan Guido <dan@trailofbits.com>
* Add BATS test suite for intercept-legacy-python hook
- Add 64 tests covering all code paths: early exits, allow cases
(uv run, diagnostics, search tools), deny cases (python/pip
execution, uv pip, piped commands, compound commands)
- Add test_helper.bash with run_hook, assert_allow, assert_deny,
and assert_suggestion_contains helpers
- Add bats job to CI workflow
- Fix hook to properly detect python execution in piped commands
like `python script.py | grep foo` and `find . | xargs python`
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix CI failures in hook test suite
- Suppress jq stderr in run_hook_no_uv to avoid "Broken pipe" error
when hook script exits early due to missing uv
- Fix shfmt formatting: remove trailing backslash, single space before
inline comments
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* ci: add lint enforcement with ruff, shellcheck, and shfmt
Add pre-commit hooks (prek) and GitHub Actions CI to enforce Python and
shell linting across the repository.
- Add root pyproject.toml with ruff configuration (line-length=100, py311)
- Add .pre-commit-config.yaml with ruff, shellcheck, shfmt, and standard hooks
- Add .github/workflows/lint.yml with SHA-pinned actions
- Update .github/dependabot.yml with root pip ecosystem entry
- Fix existing lint violations:
- Auto-fix imports and formatting with ruff
- Fix duplicate dict key in ct_analyzer (contentequals -> arrays.contentequals)
- Add noqa comment for required sys.path manipulation in extract_pdf.py
- Format shell scripts with shfmt (case statement indentation)
- Add per-file-ignores for ct_analyzer's long opcode tables and style patterns
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use 2-space indentation for shell scripts
Change shfmt configuration from 4-space to 2-space indentation
to match CLAUDE.md standards.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>