From f9d7557a06aaa8a90832e33058cee98bd152c205 Mon Sep 17 00:00:00 2001 From: Joey Maffiola <7maffiolajoey@gmail.com> Date: Mon, 24 Aug 2026 02:55:55 +0000 Subject: [PATCH 1/2] feat: ship a Claude Code plugin marketplace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds .claude-plugin/marketplace.json and .claude-plugin/plugin.json so this repo can be installed as a proper Claude Code plugin via `/plugin marketplace add 1Password/agent-hooks` + `/plugin install 1password@agent-hooks`, instead of only the copy-paste install.sh bundle. Adds hooks/hooks.json using ${CLAUDE_PLUGIN_ROOT} for the hook command path, which Claude Code resolves to an absolute path reliably for plugin-scoped hooks. This sidesteps the two problems described in #34: the vendored install.sh bundle has no update mechanism, and its generated .claude/settings.json uses a path relative to the project root that breaks with a "No such file or directory" hook error when Claude Code runs hooks from a non-root working directory. Verified: `claude plugin validate .` and `claude plugin validate ./.claude-plugin/plugin.json` both pass (including --strict); a manual simulation invoking bin/run-hook.sh via an absolute CLAUDE_PLUGIN_ROOT-style path from an unrelated cwd exits 0 with no path-resolution error, confirming the fix for the reported bug. Documents the new install flow in README.md as the recommended path for Claude Code, alongside (not replacing) the existing `install.sh --agent claude-code` flow for other agents and for users who prefer a vendored copy. - Added: .claude-plugin/marketplace.json, .claude-plugin/plugin.json, hooks/hooks.json - Modified: README.md (Available Hooks table + new "Claude Code plugin (recommended)" section) - Out of scope (left untouched): adapters/claude-code.sh, .claude/settings.json template logic — overlaps with #28, being worked concurrently - Tested: JSON syntax validated; `claude plugin validate` clean with --strict; manual run-hook.sh path-resolution simulation from a non-root cwd Closes #34 --- .claude-plugin/marketplace.json | 22 ++++++++++++++++++++++ .claude-plugin/plugin.json | 20 ++++++++++++++++++++ README.md | 19 ++++++++++++++++++- hooks/hooks.json | 15 +++++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 .claude-plugin/marketplace.json create mode 100644 .claude-plugin/plugin.json create mode 100644 hooks/hooks.json 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..17ea1b8 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, and replaces 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" + } + ] + } + ] + } +} From 81c7dda6cc1771000c910cb1c3aef7046737b851 Mon Sep 17 00:00:00 2001 From: Joey Maffiola <7maffiolajoey@gmail.com> Date: Mon, 24 Aug 2026 02:56:41 +0000 Subject: [PATCH 2/2] docs: soften wording in Claude Code plugin README section "Replaces" read as contradicting the next paragraph, which says the install.sh bundle flow still works and is unaffected. Reworded to "in place of" to make clear the plugin is the recommended path without implying the bundle option is being removed. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 17ea1b8..09e842a 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Use the `--agent` value when running the install script: ## 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, and replaces the copy-paste bundle described in [Installation](#installation) below for that agent: +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