Gate hooks to Salesforce projects only - #13
Conversation
guardrails.py (PreToolUse:Bash) and agent-validator.py (PostToolUse:Write|Edit) now check for Salesforce project markers (sfdx-project.json, force-app/, aiAuthoringBundles/) in cwd or an ancestor and exit immediately if none are found. Previously, when the plugin was installed globally, the PreToolUse hook ran on every Bash command in every session — including projects with no Salesforce relevance — before the is_sf_context() text-regex gate. This change makes the hooks complete no-ops outside Salesforce projects, so they do not observe tool I/O in unrelated work. Behavior inside Salesforce projects is unchanged.
|
Thanks for the contribution! Before we can merge this, we need @tobinsouth to sign the Salesforce Inc. Contributor License Agreement. |
|
CLA done as an individual contributor |
|
Thanks for the change — the gate is correctly placed (before any stdin/tool-input is read), the markers match the heuristic already documented in Two requests before merging: 1. Add unit tests
2. Consolidate
|
Summary
Adds a project-relevance gate to both lifecycle hooks so they exit immediately when the working directory is not a Salesforce project.
Why
When this plugin is installed globally (which is the typical install mode for Claude Code plugins), the
PreToolUse:Bashhook (guardrails.py) currently runs on every Bash command in every session — including projects with no Salesforce relevance. The existingis_sf_context(command)check is a text-regex gate on the command string, applied after the hook has already read the tool input.This means the plugin observes Bash tool I/O in unrelated Node/Python/Rust/etc. projects. The hook is local-only (no network, no logging), so there's no data exfiltration — but it's still broader than the plugin's stated scope, and the install description doesn't disclose it.
The same applies to
agent-validator.py(PostToolUse:Write|Edit), though that one is already effectively gated by the.agentfile-extension check.Change
Both hook scripts now call
is_salesforce_project()at the top ofmain(), which walks up from cwd looking for any of:sfdx-project.jsonforce-app/aiAuthoringBundles/If none are found, the hook returns
allowimmediately without reading stdin. These are the same markersCLAUDE.mdalready documents as the project-detection heuristic.Behavior inside Salesforce projects is unchanged.
Verified