feat(remote): install custom CLI hooks on SSH remote hosts (#192)#204
Merged
Conversation
Remote install only handled the five built-in CLIs (claude/codex/codebuddy/ traecli/opencode) plus hermes; user-defined custom CLIs were never pushed to the remote, so a custom CLI running on the remote host got no hooks. Serialize the custom CLI configs into the remote install script and write their hooks alongside the built-ins via a new install_custom(). Limited to the claude/nested JSON-hook formats: their stdin carries hook_event_name, so the remote hook (codeisland-remote-hook.py) handles them with no --event flag. Cursor-style "flat" (needs --event) and the non-JSON formats (traecli/copilot/ kimi/kiroAgent/cline) are skipped remotely; they still work locally. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GeorgeDong32
pushed a commit
to GeorgeDong32/CodeIsland
that referenced
this pull request
May 31, 2026
… (wxtsky#204) Remote install only handled the five built-in CLIs (claude/codex/codebuddy/ traecli/opencode) plus hermes; user-defined custom CLIs were never pushed to the remote, so a custom CLI running on the remote host got no hooks. Serialize the custom CLI configs into the remote install script and write their hooks alongside the built-ins via a new install_custom(). Limited to the claude/nested JSON-hook formats: their stdin carries hook_event_name, so the remote hook (codeisland-remote-hook.py) handles them with no --event flag. Cursor-style "flat" (needs --event) and the non-JSON formats (traecli/copilot/ kimi/kiroAgent/cline) are skipped remotely; they still work locally. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Fixes #192.
Remote install previously only configured the five built-in CLIs (claude / codex / codebuddy / traecli / opencode) plus hermes. User-defined custom CLIs were never pushed to the remote host, so a custom CLI running over SSH got no hooks installed.
What changed
configureRemoteHooksScriptnow takes the custom CLI list (defaults toConfigInstaller.customCLIs()), serializes it into the remote Python install script, and a newinstall_custom()writes their hooks alongside the built-ins.command_for(source)(so events route throughcodeisland-remote-hook.pywith the rightCODEISLAND_SOURCE) andremove_our_hooksfor clean reinstalls.Scope (deliberate)
Limited to the claude and nested JSON-hook formats — their stdin carries
hook_event_name, so the remote hook handles them without a--eventflag. These cover the Claude-fork / Codex-style CLIs that realistically run on a remote dev box.Skipped remotely (still work locally): flat (Cursor-style, needs
--eventthe remote hook can't supply), and the non-JSON formats (traecli YAML / copilot / kimi TOML / kiroAgent / cline).Tests
install_custom()emitted + the whole script still compiles as Python (assertPythonCompiles); flat format is skipped (empty list); empty input iscustom_clis = [].swift test— 344 passing.Note: the remote SSH link can't be exercised in CI, so this is verified via the generated-script tests + Python compile; real end-to-end on a remote host welcome.
🤖 Generated with Claude Code