mirror of
https://github.com/affaan-m/ECC.git
synced 2026-09-03 06:34:16 +08:00
fix(hooks,lib): fix hook detection and parsing edge cases (#2405)
* fix(hooks,lib): fix hook detection and parsing edge cases
- auto-tmux-dev: dev\b -> dev(?![\w-]) so one-shot dev-build/dev-docs scripts
are not detached into tmux; align command shapes (yarn run dev, bun dev) with
pre-bash-dev-server-block.js DEV_PATTERN.
- pre-bash-commit-quality: skip obvious non-secret placeholders (env refs,
${...}, <...>, whitelisted tokens) in the api-key rule without suppressing
real high-entropy secrets; make -m message extraction quote- and
escaped-quote-aware so `-m "fix: \"x\""` / apostrophes are not truncated.
- pre-compact: annotate the CURRENT worktree's session (match **Worktree:** /
legacy **Project:**) instead of the newest *-session.tmp across all projects,
layered onto the LLM-summary flow from #2388; a present-but-blank Worktree
header is treated as non-legacy (no foreign project fallback).
- shell-substitution: stop double-appending a trailing backslash in an
unterminated backtick span.
- utils readStdinJson: on overflow, settle and resolve {} immediately (clear
timer + listeners) instead of waiting for end/timeout and parsing a partial
prefix; surface the overflow on stderr.
Regression tests added/extended (new tests/hooks/pre-compact.test.js).
Addresses review feedback on #2405. The earlier block-no-verify change was
dropped: its message-value skip on merge/cherry-pick/am/rebase would let
`git rebase -m --no-verify` bypass the hook (rebase's -m is the boolean
--merge), a false-negative worse than the contrived false-positive it fixed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(ci): align hook fixtures and drain oversized stdin
---------
Co-authored-by: djpjronline-netizen <276112803+djpjronline-netizen@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: haelyra <49814733+haelyra@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
6be87a56ae
commit
837acaf20b
@@ -284,6 +284,7 @@ async function readStdinJson(options = {}) {
|
||||
return new Promise((resolve) => {
|
||||
let data = '';
|
||||
let settled = false;
|
||||
let overflowed = false;
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
if (!settled) {
|
||||
@@ -293,7 +294,12 @@ async function readStdinJson(options = {}) {
|
||||
process.stdin.removeAllListeners('end');
|
||||
process.stdin.removeAllListeners('error');
|
||||
if (process.stdin.unref) process.stdin.unref();
|
||||
// Resolve with whatever we have so far rather than hanging
|
||||
// Oversized input is always rejected. Otherwise, resolve with whatever
|
||||
// arrived before the timeout rather than hanging.
|
||||
if (overflowed) {
|
||||
resolve({});
|
||||
return;
|
||||
}
|
||||
try {
|
||||
resolve(data.trim() ? JSON.parse(data) : {});
|
||||
} catch {
|
||||
@@ -304,15 +310,34 @@ async function readStdinJson(options = {}) {
|
||||
|
||||
process.stdin.setEncoding('utf8');
|
||||
process.stdin.on('data', chunk => {
|
||||
if (data.length < maxSize) {
|
||||
data += chunk;
|
||||
if (settled) return;
|
||||
if (overflowed) return;
|
||||
// Mark oversized input as rejected and discard the buffered prefix.
|
||||
// Continue consuming the stream without retaining later chunks so a
|
||||
// finite parent can finish writing without EPIPE. Resolution happens at
|
||||
// EOF or the existing timeout, which also bounds never-closing writers.
|
||||
if (data.length + chunk.length > maxSize) {
|
||||
overflowed = true;
|
||||
data = '';
|
||||
process.stderr.write(
|
||||
`[readStdinJson] stdin exceeded ${maxSize} bytes; input truncated and treated as empty\n`
|
||||
);
|
||||
return;
|
||||
}
|
||||
data += chunk;
|
||||
});
|
||||
|
||||
process.stdin.on('end', () => {
|
||||
if (settled) return;
|
||||
if (settled) {
|
||||
clearTimeout(timer);
|
||||
return;
|
||||
}
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
if (overflowed) {
|
||||
resolve({});
|
||||
return;
|
||||
}
|
||||
try {
|
||||
resolve(data.trim() ? JSON.parse(data) : {});
|
||||
} catch {
|
||||
@@ -323,7 +348,10 @@ async function readStdinJson(options = {}) {
|
||||
});
|
||||
|
||||
process.stdin.on('error', () => {
|
||||
if (settled) return;
|
||||
if (settled) {
|
||||
clearTimeout(timer);
|
||||
return;
|
||||
}
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
// Resolve with empty object so hooks don't crash on stdin errors
|
||||
|
||||
Reference in New Issue
Block a user