perf(guardrails, eol-normalizer, typos-format): about 440 ms of hooks per Edit/Write across three node-to-bash hops
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 30/100
- Issue type
- Refactor
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- javascript, shell
- Domain
- devtools, performance
Research direction
Start with the three hooks.json files (plugins/guardrails, plugins/eol-normalizer, plugins/typos-format) and the shared hooks/exec-bash.mjs launcher that each one invokes through node. Read how exec-bash.mjs resolves the Git Bash path on Windows before changing any registration. Done means the combined PostToolUse runner runs EOL then typos in one bash process, the existing eol-normalizer and typos-format tests pass, and a CRLF file written by Write ends LF-only. Confirm the design with a maintainer first, since the issue asks to keep the PreToolUse guards synchronous.
Written by the indexing model from the issue text.
Description
Related: #4390 (guardrails Edit/Write process counts), #4391 and #3751 (closed formatter fan-out), #4373 (umbrella).
Problem
Each Edit/Write pays about 440 ms of hook time across three plugins, each starting its own node process that then starts bash:
- guardrails PreToolUse (
secret-pattern-detection.sh,hardcoded-path-check.sh,block-windows-drive-tmp.shviarun-guards.sh): about 220 ms, before the edit. - eol-normalizer PostToolUse: about 205 ms.
- typos-format PostToolUse: about 205 ms.
The two PostToolUse hooks run in parallel with each other, so the wall-clock after an edit is about the slower of the two, but both add process load and both are node-to-bash hops.
Measured
Method: direct timing on the windows lane (melo-desk-001): canned Edit payload on a copy of a repo README in the session scratchpad, date +%s%N around node exec-bash.mjs <script>, stdin from the payload, 3 runs, latest cached versions.
| hook | runs (ms) |
|---|---|
| guardrails PreToolUse Edit trio (guardrails 0.48.1) | 218 / 222 / 221 |
| eol-normalizer 0.9.11 | 204 / 205 / 203 |
| typos-format 0.9.12 | 206 / 206 / 203 |
bare node -e 0 |
52 |
Context: #4390 measured the guardrails Edit/Write guards at 25 to 87 processes per fire; OTEL in #4373 shows PostToolUse:Edit p50 850 ms, p95 4,249 ms (n=4,081, 7 days).
Where
plugins/guardrails/hooks/hooks.json:18-35(PreToolUse, matcherWrite|Edit|NotebookEdit,node hooks/exec-bash.mjs hooks/run-guards.sh secret-pattern-detection.sh hardcoded-path-check.sh block-windows-drive-tmp.sh)plugins/eol-normalizer/hooks/hooks.json:17-35(PostToolUseWrite|Edit,node hooks/exec-bash.mjs --run-if-unset-or-true EOL_NORMALIZER_ENABLED hooks/eol-normalizer.sh)plugins/typos-format/hooks/hooks.json:4-22(PostToolUseWrite|Edit|NotebookEdit,node hooks/exec-bash.mjs --run-if-unset-or-true TYPOS_FORMAT_ENABLED hooks/typos-format.sh)
Example command line: node ${CLAUDE_PLUGIN_ROOT}/hooks/exec-bash.mjs --run-if-unset-or-true TYPOS_FORMAT_ENABLED ${CLAUDE_PLUGIN_ROOT}/hooks/typos-format.sh
Proposed fix
One combined PostToolUse runner for the file-normalizing family (eol-normalizer, typos-format, and the other formatter plugins that match Write|Edit), registered once, running its steps in order in a single bash process (EOL first, then typos, so the second sees normalized bytes), with no node-to-bash hop: register bash with the resolved Git Bash path directly, as exec-bash.mjs resolves it today (#3686/#3708 explain why bare bash cannot be used on Windows).
Keep the secrets/path guards in PreToolUse as blocking hooks: they can deny the edit, and an async hook cannot ("response fields like decision, permissionDecision, and continue have no effect", https://code.claude.com/docs/en/hooks#run-hooks-in-the-background). Only the report-only PostToolUse rows (typos-format reports; #4677 is the earlier decision) may go "async": true. The EOL normalizer rewrites the file, so it must stay synchronous or the model's next Edit races it.
Basis: measured node start-up share (52 of about 205 ms) and bash start-up 29 ms (above); async limits at the URL above; if narrowing at https://code.claude.com/docs/en/hooks#common-fields (already used in guardrails for .md/.sh).
Expected saving
About 150 to 250 ms of CPU per Edit/Write removed (two node processes and two bash starts become one bash), and one fewer process tree for Defender-style scanners to inspect. At 581 Edit fires per day (#4390) that is 1.5 to 2.5 CPU-minutes per day; the wall-clock gain is smaller because the two rows already run in parallel.
Verify after the fix
- Re-run the three timing commands; the combined runner should land near 100 ms.
/harness-ops:observability latencyPostToolUse:Edit p50/p95 before and after, 7 days each.- Existing eol-normalizer and typos-format tests pass against the runner; a CRLF file written by Write ends LF-only, and a typo is still reported once.
- Dominant language
- Shell
- Stars
- 22
- Forks
- 2
- Avg merge
- 5h 18m
- Merged PRs (30d)
- 869
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from melodic-software/claude-code-plugins
-
good first issue needs-triage priority: low
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
melodic-software/claude-code-plugins#6699 · 1 comment ·
Maintainers usually reply within 1 day
-
good first issue needs-triage priority: medium
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
melodic-software/claude-code-plugins#6631 · 1 comment ·
Maintainers usually reply within 1 day
-
needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
melodic-software/claude-code-plugins#6547 ·
Maintainers usually reply within 1 day
-
needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
melodic-software/claude-code-plugins#6535 ·
Maintainers usually reply within 1 day
-
test_comment_census.py: SccArgv flag-shaped-filename test errors on Windows (#!/bin/sh scc shim)Opengood first issue needs-triage priority: low
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
melodic-software/claude-code-plugins#6532 · 1 comment ·
Maintainers usually reply within 1 day
All issues in melodic-software/claude-code-plugins
Similar issues
-
command: monitor command: update info: steamcmd reproducible: always severity: medium type: bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
GameServerManagers/LinuxGSM#4997 ·
Maintainers usually reply within 1 day
-
area:space-accuracy good first issue track:data
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
Sara-Managed-Projects/space-radar#886 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
zerocracy/judges-action#2733 ·
Maintainers usually reply within 8 days
-
[Nginx] Warning: duplicate extension "wasm" in nextcloud.confPossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 1/5 Under an hour Newbie friendliness 74/100
YunoHost-Apps/nextcloud_ynh#916 ·
Maintainers usually reply within 1 day
-
dependencies feature github_actions good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
wemake-services/wemake-django-template#3149 ·
Maintainers usually reply within 1 day