Module: ReactOnRails::AgentGuardrails
- Defined in:
- lib/react_on_rails/agent_guardrails.rb
Overview
Installs (and idempotently updates) the RSC "agent guardrail" assets into a host app:
a Claude Code skill and an advisory PostToolUse hook that steer AI agents away from the
React Server Components API footguns (unauthenticated payload route, trusting props, exposing
the Node renderer, leaking secrets). Invoked by rake react_on_rails:install_rsc_agent_guardrails
and by the RSC generator.
Defined Under Namespace
Classes: Installer
Constant Summary collapse
- Error =
Class.new(StandardError)
- TEMPLATES_DIR =
File.("agent_guardrails/templates", __dir__)
- FILES =
source template (under TEMPLATES_DIR) => destination path relative to the app root
{ "rsc_app_safety_skill.md" => ".claude/skills/rsc-app-safety/SKILL.md", "rsc_app_safety_check.rb" => ".claude/hooks/rsc-app-safety-check.rb" }.freeze
- HOOK_COMMAND =
"ruby"- HOOK_ARGS =
["${CLAUDE_PROJECT_DIR}/.claude/hooks/rsc-app-safety-check.rb"].freeze
- LEGACY_HOOK_COMMAND =
"${CLAUDE_PROJECT_DIR}/.claude/hooks/rsc-app-safety-check.sh"- LEGACY_HOOK_REL =
".claude/hooks/rsc-app-safety-check.sh"- HOOK_REL =
".claude/hooks/rsc-app-safety-check.rb"- HOOK_MATCHER =
"Edit|Write"- SETTINGS_REL =
".claude/settings.json"
Class Method Summary collapse
-
.default_destination_root(explicit = nil) ⇒ Object
Where guardrails get installed when no explicit destination is given.
-
.install(destination_root, skip_existing: false) ⇒ Object
Copies the guardrail files and registers the advisory hook.
- .new_installer(destination_root, skip_existing: false) ⇒ Object
Class Method Details
.default_destination_root(explicit = nil) ⇒ Object
Where guardrails get installed when no explicit destination is given. Prefers the Rails
application root so the task installs into the app's .claude/ even when rake is invoked
from a subdirectory; falls back to the working directory outside a Rails app.
45 46 47 48 49 50 51 |
# File 'lib/react_on_rails/agent_guardrails.rb', line 45 def self.default_destination_root(explicit = nil) explicit = explicit.to_s return explicit unless explicit.empty? rails_root = defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : nil rails_root ? rails_root.to_s : Dir.pwd end |
.install(destination_root, skip_existing: false) ⇒ Object
Copies the guardrail files and registers the advisory hook. Idempotent: re-running only writes what changed. Returns an array of human-readable action strings.
34 35 36 |
# File 'lib/react_on_rails/agent_guardrails.rb', line 34 def self.install(destination_root, skip_existing: false) new_installer(destination_root, skip_existing:).install end |