Skip to content

feat: add copilot hooks and prometheus configuration#1794

Merged
shunkakinoki merged 1 commit into
mainfrom
feature/copilot-hooks-and-prometheus
May 17, 2026
Merged

feat: add copilot hooks and prometheus configuration#1794
shunkakinoki merged 1 commit into
mainfrom
feature/copilot-hooks-and-prometheus

Conversation

@shunkakinoki
Copy link
Copy Markdown
Owner

@shunkakinoki shunkakinoki commented May 17, 2026

Summary

This PR adds new copilot hooks and configures prometheus monitoring.

Changes

  • Add rtk-rewrite.sh and security.sh hooks to copilot
  • Add prometheus program configuration to home-manager
  • Update sync scripts for codex-security and rtk-rewrite

Testing

Manual verification of hook scripts and prometheus configuration.


Summary by cubic

Adds Copilot hooks for RTK auto-rewrite and shell command safety, and adds Prometheus tooling via Home Manager. Keeps Claude, Codex, and Copilot hooks in sync.

  • New Features

    • Copilot RTK auto-rewrite hook: config/copilot/hooks/rtk-rewrite.sh uses rtk rewrite (supports allow/ask/deny; audit via RTK_HOOK_AUDIT=1).
    • Copilot security hook: config/copilot/hooks/security.sh blocks risky commands (e.g., sudo, force-push, rm -rf) with exit code 2.
    • Prometheus tooling in Home Manager: prometheus, prometheus-alertmanager, prom2json.
    • Sync scripts mirror hooks to Copilot: scripts/sync-rtk-rewrite.sh, scripts/sync-codex-security.sh.
  • Dependencies

    • Updated packages (@anthropic-ai/claude-code, @github/copilot, @ccusage/*, turbo, vite, oxlint, openclaw, etc.) and refreshed bun.lock and flake.lock.

Written for commit 753840c. Summary will update on new commits. Review in cubic

Add rtk-rewrite and security hooks for copilot, and configure prometheus monitoring.

Changes:
- Add rtk-rewrite.sh and security.sh hooks to copilot
- Add prometheus program configuration
- Update sync scripts for codex-security and rtk-rewrite
@indent
Copy link
Copy Markdown
Contributor

indent Bot commented May 17, 2026

PR Summary

Decouples the Copilot CLI from sharing Codex's hook files directly: adds local byte-identical copies of rtk-rewrite.sh and security.sh under config/copilot/hooks/, repoints config/copilot/default.nix to source from there, and extends scripts/sync-{codex-security,rtk-rewrite}.sh to mirror the codex versions into the new location so they stay in lockstep. Also adds a new home-manager/programs/prometheus module (prom2json, prometheus, prometheus-alertmanager), registered alphabetically in home-manager/programs/default.nix, plus routine package.json / bun.lock / flake.lock dependency bumps.

  • Added config/copilot/hooks/rtk-rewrite.sh and config/copilot/hooks/security.sh (copies of the codex hooks).
  • Switched config/copilot/default.nix sources from ../codex/hooks/... to ./hooks/....
  • Updated scripts/sync-rtk-rewrite.sh to also cp to config/copilot/hooks/rtk-rewrite.sh.
  • Updated scripts/sync-codex-security.sh to mirror the regenerated codex security hook to config/copilot/hooks/security.sh.
  • Added home-manager/programs/prometheus/default.nix and wired it into home-manager/programs/default.nix.
  • Bumped a number of unrelated dependencies in package.json, bun.lock, and flake.lock.

Issues

3 potential issues found:

  • In scripts/sync-codex-security.sh, the new cp "$CODEX_SECURITY" "$COPILOT_SECURITY" mirror step has no [[ -f ]] / mkdir -p guard like the codex path does, so if config/copilot/hooks/ is ever absent the codex file gets updated but the copilot copy silently lags behind. Add a mkdir -p "$(dirname "$COPILOT_SECURITY")" (or an existence check that errors loudly) before the cp for parity with the rest of the script. → Autofix
  • Copilot hooks are now physical copies of the codex hooks instead of sourcing them directly, so they will silently drift if scripts/sync-{codex-security,rtk-rewrite}.sh aren't run after a codex hook edit; only those two hooks are mirrored, so any future codex hook (e.g. atuin-history.sh, notify.sh, pushover.sh) won't propagate at all. Consider keeping source = ../codex/hooks/...; in config/copilot/default.nix or moving the shared hooks under config/shared/hooks/ to make drift impossible by construction. → Autofix
  • This PR bundles ~25 unrelated dependency version bumps in package.json / bun.lock / flake.lock (claude-code, ccusage, copilot CLI, droid, openclaw, typescript-native preview, etc.) with the copilot-hooks-and-prometheus change, which makes it harder to revert either side independently. Consider splitting routine dep bumps into their own commit/PR going forward. → Autofix

CI Checks

Waiting for CI checks...


⚡ Autofix All Issues

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 17, 2026

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 55d05d55-3432-481d-90ac-310cb2fb1a0b

📥 Commits

Reviewing files that changed from the base of the PR and between 538e7e4 and 753840c.

⛔ Files ignored due to path filters (2)
  • bun.lock is excluded by !**/*.lock
  • flake.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • config/copilot/default.nix
  • config/copilot/hooks/rtk-rewrite.sh
  • config/copilot/hooks/security.sh
  • home-manager/programs/default.nix
  • home-manager/programs/prometheus/default.nix
  • package.json
  • scripts/sync-codex-security.sh
  • scripts/sync-rtk-rewrite.sh

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.


📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Copilot integration now includes command rewriting and security hooks for enhanced protection.
    • Prometheus monitoring tools and alerting components are now available.
  • Chores

    • Updated multiple dependencies to latest versions.
    • Enhanced hook synchronization across system components.

Walkthrough

This PR extends Claude Code integration to Copilot by implementing RTK-based command rewriting and security filtering hooks, wires them via Nix, adds Prometheus monitoring packages to Home Manager, and updates project dependencies.

Changes

Copilot Hook System

Layer / File(s) Summary
RTK rewrite hook setup
config/copilot/default.nix, config/copilot/hooks/rtk-rewrite.sh
Copilot hook sources now reference local ./hooks/ paths. The rtk-rewrite.sh hook intercepts PreToolUse commands, rewrites them via rtk rewrite, and uses exit codes (0=allow, 1=pass-through, 2=skip for deny, 3=ask) to control Claude Code's permission model, with optional audit logging to ~/.local/share/rtk/hook-audit.log.
Security hook implementation
config/copilot/hooks/security.sh
New security hook reads shell commands from hook input, checks them against a hardcoded deny-list of dangerous patterns (chmod 777, destructive filesystem ops, sudo, forced git push), and exits with code 2 to block matching commands.
Hook synchronization scripts
scripts/sync-codex-security.sh, scripts/sync-rtk-rewrite.sh
Synchronization scripts now copy both RTK rewrite and security hooks from upstream sources into config/copilot/hooks/, keeping Copilot's hook behavior in sync with Claude Code and Codex.

Prometheus Module & Tooling

Layer / File(s) Summary
Prometheus Home Manager module
home-manager/programs/default.nix, home-manager/programs/prometheus/default.nix
New Prometheus module installs prom2json, prometheus, and prometheus-alertmanager packages. The module is imported and included in the home programs composition.
Dependency version updates
package.json
Dependencies updated across @ccusage/* packages, @anthropic-ai/claude-code, @oh-my-pi/pi-*, @pulumi/pulumi, @sourcegraph/amp, @traces-sh/traces, and tooling packages including oxlint, turbo, vite, and xcodebuildmcp.

Possibly related PRs

  • shunkakinoki/dotfiles#1789: Implements the same RTK rewrite exit-code-based control flow and command rewriting logic in Claude Code and Codex hooks that this PR mirrors to Copilot.

Suggested labels

enhancement

Poem

🐰 A copilot joins the flock,
RTK rewrite on the clock,
Security hooks block the bad,
Prometheus charts we're glad,
Dependencies fresh—this PR's rad!


🎯 3 (Moderate) | ⏱️ ~25 minutes

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/copilot-hooks-and-prometheus

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@shunkakinoki shunkakinoki merged commit f540871 into main May 17, 2026
25 of 31 checks passed
@shunkakinoki shunkakinoki deleted the feature/copilot-hooks-and-prometheus branch May 17, 2026 13:03

home.file.".copilot/hooks/rtk-rewrite.sh" = {
source = ../codex/hooks/rtk-rewrite.sh;
source = ./hooks/rtk-rewrite.sh;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hook duplication invites drift. Before this PR, source = ../codex/hooks/rtk-rewrite.sh; made the codex and copilot hooks literally the same file, so they could never diverge. Pointing at ./hooks/rtk-rewrite.sh (and ./hooks/security.sh below) introduces a second copy that must be kept in sync via scripts/sync-{rtk-rewrite,codex-security}.sh. A few practical consequences:

  • Manual edits to config/codex/hooks/security.sh (e.g. ad-hoc deny-pattern tweaks) silently won't reach copilot until someone remembers to run scripts/sync-codex-security.sh.
  • Only rtk-rewrite.sh and security.sh are mirrored. Other codex hooks (atuin-history.sh, notify.sh, pushover.sh) won't be reachable from copilot at all if/when they're added to its config.
  • The previous Nix-level sharing was zero-maintenance.

If the intent is to let copilot's hooks evolve independently from codex, that's fine — otherwise consider either reverting the source paths to ../codex/hooks/... or moving the shared hooks under config/shared/hooks/ and pointing both config/codex/default.nix and config/copilot/default.nix at that single location.

chmod +x "$CODEX_SECURITY"

# Mirror to copilot hooks so codex + copilot stay identical.
cp "$CODEX_SECURITY" "$COPILOT_SECURITY"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the codex path is guarded at the top ([[ -f $CODEX_SECURITY ]] || ...), but this new mirror step has no equivalent protection — if config/copilot/hooks/ is missing for any reason, the codex hook has already been mutated by mv above and this cp then fails partway through, leaving the two hooks out of sync. A mkdir -p "$(dirname "$COPILOT_SECURITY")" here (or an existence check up top) would keep behavior consistent with the rest of the script.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces Copilot-specific hooks for command rewriting and security filtering, including synchronization scripts to maintain parity with Codex. It also adds Prometheus packages to the Home Manager configuration and updates various project dependencies. Feedback focused on improving the robustness of the new shell scripts by using printf instead of echo for arbitrary strings, ensuring the rewrite hook fails open on invalid JSON input, and optimizing jq usage for better performance.

set -euo pipefail

INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The script is currently fail-closed on invalid JSON input. If INPUT is not valid JSON, jq will exit with an error, and because set -e is active, the script will terminate with exit code 1. Following the pattern for execution scripts in this repo, it is safer to handle parsing errors gracefully and fail-open (allowing the command) as seen in security.sh. Additionally, using printf is safer than echo for arbitrary strings.

Suggested change
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
CMD=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null) || CMD=""
References
  1. Do not use set -e in execution scripts that must handle failures gracefully to avoid blocking the process.

Comment on lines +82 to +83
ORIGINAL_INPUT=$(echo "$INPUT" | jq -c '.tool_input')
UPDATED_INPUT=$(echo "$ORIGINAL_INPUT" | jq --arg cmd "$REWRITTEN" '.command = $cmd')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

These two jq calls can be combined into a single invocation for better performance and to avoid unnecessary intermediate variables.

Suggested change
ORIGINAL_INPUT=$(echo "$INPUT" | jq -c '.tool_input')
UPDATED_INPUT=$(echo "$ORIGINAL_INPUT" | jq --arg cmd "$REWRITTEN" '.command = $cmd')
UPDATED_INPUT=$(printf '%s' "$INPUT" | jq -c --arg cmd "$REWRITTEN" '.tool_input | .command = $cmd')

)

# Split command at logical operators
IFS=$'\n' read -r -d '' -a segments < <(echo "$command" | sed -E 's/[;&|]+/\n/g' && printf '\0') || true
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

Using echo "$command" is unsafe if the command string starts with a hyphen (e.g., -n), as echo will interpret it as an option. Use printf to safely handle arbitrary command strings. Additionally, to robustly parse command output, use a unique delimiter and read with a matching IFS as per repository standards.

Suggested change
IFS=$'\n' read -r -d '' -a segments < <(echo "$command" | sed -E 's/[;&|]+/\n/g' && printf '\0') || true
IFS=$'\n' read -r -d '' -a segments < <(printf '%s\n' "$command" | sed -E 's/[;&|]+/\n/g' && printf '\0') || true
References
  1. To robustly parse command output in shell scripts, use a unique delimiter (e.g., tab) and read with a matching IFS.

IFS=$'\n' read -r -d '' -a segments < <(echo "$command" | sed -E 's/[;&|]+/\n/g' && printf '\0') || true

for segment in "${segments[@]}"; do
segment=$(echo "$segment" | xargs 2>/dev/null) || continue
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

Using echo "$segment" is unsafe if the segment starts with a hyphen. Use printf instead.

Suggested change
segment=$(echo "$segment" | xargs 2>/dev/null) || continue
segment=$(printf '%s' "$segment" | xargs 2>/dev/null) || continue

shunkakinoki added a commit that referenced this pull request May 17, 2026
…1795)

* fix: add Copilot toolArgs/modifiedArgs support to rtk-rewrite hook

Tests added in #1788 check that rtk-rewrite.sh reads Copilot-format input
(.toolArgs as object or stringified JSON) and emits .modifiedArgs output,
but the hook itself was never updated, so the Shell workflow has been
failing on every push to main. #1794 then added two new copilot hook
files without updating the coverage list, adding a 5th failure.

- Read CMD from .tool_input.command OR .toolArgs.command (object) OR
  .toolArgs | fromjson | .command (string).
- Emit modifiedArgs alongside hookSpecificOutput when input used toolArgs,
  preserving original fields (e.g. timeout).
- Mirror to claude/codex/copilot copies (sync_rtk_rewrite_spec.sh enforces
  byte equality between claude and codex).
- Add config/copilot/hooks/{rtk-rewrite,security}.sh to coverage_spec.sh.

Note: scripts/sync-rtk-rewrite.sh fetches from upstream and overwrites all
three local copies — next sync will wipe this fix. Documented inline.

* fix(hooks): tolerant fromjson, exclude copilot from shfmt, preserve sync

Entire-Checkpoint: 9d826b214b88

* refactor(sync): drop patch file, make sync drift-check-only

Entire-Checkpoint: 8c976510b69a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant