diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json new file mode 100644 index 0000000..613b906 --- /dev/null +++ b/.claude-plugin/marketplace.json @@ -0,0 +1,22 @@ +{ + "name": "agent-hooks", + "owner": { + "name": "1Password", + "url": "https://github.com/1Password" + }, + "description": "1Password agent hooks for AI coding agents (Claude Code, Cursor, GitHub Copilot, Windsurf).", + "plugins": [ + { + "name": "1password", + "source": "./", + "description": "Validates 1Password Environments mounted .env files before Claude Code runs Bash commands.", + "version": "1.0.0", + "author": { + "name": "1Password", + "url": "https://github.com/1Password" + }, + "license": "MIT", + "homepage": "https://github.com/1Password/agent-hooks" + } + ] +} diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..c773e87 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,20 @@ +{ + "name": "1password", + "displayName": "1Password Agent Hooks", + "version": "1.0.0", + "description": "Validates 1Password Environments mounted .env files before Claude Code runs Bash commands.", + "author": { + "name": "1Password", + "url": "https://github.com/1Password" + }, + "homepage": "https://github.com/1Password/agent-hooks", + "repository": "https://github.com/1Password/agent-hooks", + "license": "MIT", + "keywords": [ + "1password", + "secrets", + "environments", + "hooks", + "validation" + ] +} diff --git a/README.md b/README.md index 517189c..09e842a 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,24 @@ Use the `--agent` value when running the install script: | Hook | Installation | |------|--------------| -| [`1password-validate-mounted-env-files`](./hooks/1password-validate-mounted-env-files/README.md) — validates mounted `.env` files from 1Password Environments | | +| [`1password-validate-mounted-env-files`](./hooks/1password-validate-mounted-env-files/README.md) — validates mounted `.env` files from 1Password Environments | | + +## Claude Code plugin (recommended) + +Claude Code users can install the `1password-validate-mounted-env-files` hook as a proper [Claude Code plugin](https://code.claude.com/docs/en/plugins), distributed from this repo's [`.claude-plugin/marketplace.json`](.claude-plugin/marketplace.json). This is the recommended way to install for Claude Code, in place of the copy-paste bundle described in [Installation](#installation) below for that agent: + +``` +/plugin marketplace add 1Password/agent-hooks +/plugin install 1password@agent-hooks +``` + +Why this is better than the `install.sh --agent claude-code` bundle: + +- **Auto-updates.** The bundle approach vendors a static copy of `bin/`, `lib/`, `adapters/`, and `hooks/` into your project's `.claude/` directory with no update mechanism — fixes and new hooks never reach you unless you manually re-run `install.sh`. The plugin is managed by Claude Code's plugin system and updates when you run `/plugin marketplace update` (or automatically, depending on your settings). +- **Reliable path resolution.** The bundle's generated `.claude/settings.json` entry uses a path relative to the project root, which breaks with a "No such file or directory" hook error when Claude Code executes hooks from a non-root working directory. The plugin's [`hooks/hooks.json`](hooks/hooks.json) uses `${CLAUDE_PLUGIN_ROOT}`, which Claude Code resolves to an absolute path reliably regardless of the session's current working directory. +- **No per-project vendoring.** Nothing is copied into your repo's `.claude/` directory, so there's nothing to commit or drift. + +If you'd rather not use the plugin system (e.g. to pin an exact vendored copy, or your Claude Code version doesn't support plugins), the `install.sh --agent claude-code` flow in [Installation](#installation) below still works and is unaffected by this option. ## Installation diff --git a/hooks/hooks.json b/hooks/hooks.json new file mode 100644 index 0000000..172816e --- /dev/null +++ b/hooks/hooks.json @@ -0,0 +1,15 @@ +{ + "hooks": { + "PreToolUse": [ + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "command": "\"${CLAUDE_PLUGIN_ROOT}\"/bin/run-hook.sh 1password-validate-mounted-env-files" + } + ] + } + ] + } +}