feat(hooks): add Factory Droid integration#1
Open
krimvp wants to merge 4 commits into
Open
Conversation
Register RTK with Factory Droid so shell commands the agent runs are transparently rewritten to their token-saving `rtk` equivalents. - `rtk init --agent droid`: install a native PreToolUse hook into ~/.factory/settings.json (matcher "Execute"); supports global (-g) and project scope, the FACTORY_HOME override, idempotent install with backup + atomic write, and a clean uninstall round-trip. - `rtk hook droid`: process Droid's PreToolUse payload (BOM strip, stdin cap, JSON-parse fallback), mirroring the existing provider hooks. - Deny verdict steps aside (no output) so Droid's native deny handling fires, matching Claude/Cursor/Copilot and the PermissionVerdict::Deny contract. - Rewrites are auto-allowed: Droid only applies a hook's updatedInput when the decision is "allow", so we mirror run_cursor to avoid silently dropping the rewrite (and its savings) on the default verdict.
Droid 0.140.0 applies a PreToolUse hook's updatedInput regardless of the permission decision (verified empirically + via binary decompile), so the forced permissionDecision:"allow" was unnecessary. Worse, Droid resolves the decision as the first hook result carrying one (no deny-over-allow priority), so an unconditional allow could suppress another PreToolUse hook's deny/ask and bypass Droid's native prompt. Now omit permissionDecision by default and only assert allow on an explicit allow rule, mirroring process_claude_payload. The rewrite still lands via Droid's decision-independent "updated input result" path. Updated the inaccurate comment and the test that required allow.
Adopt the decide_from_verdict/HookDecision flow introduced on develop so the Droid handler gains the same safety behavior as Claude/Cursor/Copilot: commands with substitution or file redirects now Defer (no rewrite) instead of being rewritten, and deny/allow/ask mapping is shared instead of reimplemented. Also removes an unwrap() in the response builder. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Vp4p5YroP2cfFvThhQE4Rv
Adversarial verification against Droid v0.164.0 (shipped code + docs) found two broken assumptions in the original integration: - Droid's canonical hooks file is hooks.json (root event map, no wrapper); the hooks key of settings.json is only a fallback that hooks.json shadows per event key. Droid's own /hooks UI writes hooks.json, so an RTK entry in settings.json silently dies as soon as the user adds any PreToolUse hook there. Install now targets the file whose PreToolUse array Droid actually reads (live hooks.json > live settings.json fallback > create canonical hooks.json), migrates stale copies, and uninstall sweeps root hooks.json, legacy hooks/hooks.json, and settings.json. - The config-home env var is FACTORY_HOME_OVERRIDE (replaces $HOME, with .factory appended), not FACTORY_HOME pointing at the config dir. Also corrects the 'legacy Bash matcher' comment (Droid never had a Bash tool; the acceptance is purely defensive) and records that the omit-permissionDecision rewrite path is confirmed in v0.164.0: decisions resolve as find(first result with a decision) and updatedInput applies via a separate path even when no decision is set. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Vp4p5YroP2cfFvThhQE4Rv
5106c44 to
77d9ee4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Register RTK with Factory Droid so shell commands the agent runs are
transparently rewritten to their token-saving
rtkequivalents.rtk init --agent droid: install a native PreToolUse hook into~/.factory/settings.json (matcher "Execute"); supports global (-g) and
project scope, the FACTORY_HOME override, idempotent install with backup +
atomic write, and a clean uninstall round-trip.
rtk hook droid: process Droid's PreToolUse payload (BOM strip, stdin cap,JSON-parse fallback), mirroring the existing provider hooks.
matching Claude/Cursor/Copilot and the PermissionVerdict::Deny contract.
decision is "allow", so we mirror run_cursor to avoid silently dropping the
rewrite (and its savings) on the default verdict.