feat(hooks): MONITOR_IGNORE_CWD ingest filter + Russian README#220
feat(hooks): MONITOR_IGNORE_CWD ingest filter + Russian README#220Mukller wants to merge 3 commits into
Conversation
Closes hoangsonww#182, contributes to hoangsonww#197. MONITOR_IGNORE_CWD (server/routes/hooks.js): - Parse comma-separated cwd patterns from env at startup into compiled matcher functions — zero runtime overhead per hook event beyond a single .some() call. - Three pattern forms supported, no external dependencies: /exact/path — strict equality after slash-normalisation /prefix/* — direct children only (no deeper nesting) /prefix/** — /prefix and all descendants - Early-return in router.post('/event') before processEvent(): ignored sessions are never written to the DB, never broadcast, and never appear in the UI, analytics, or exports. - Returns 200 { ok: true, ignored: true } so Claude Code does not retry — the event is intentionally discarded, not an error. - .env.example: document the variable with examples and caveats (pre-existing sessions are unaffected; use DELETE /api/sessions/:id). README-RU.md: - Full Russian translation of the project README (~376 lines). - Covers: overview, features, quick-start, hooks setup, config (including MONITOR_IGNORE_CWD section), API table, event types, deployment, project structure, and troubleshooting. - Language switcher footer linking all existing translations. - README.md: added README-RU.md to the localized-docs tip.
|
✅ All contributors have signed the CLA. Thank you! |
There was a problem hiding this comment.
Code Review
This pull request adds a Russian translation of the README and implements a working directory ignore filter via the MONITOR_IGNORE_CWD environment variable to discard hook events from specified paths. The review feedback points out a critical regular expression typo in the path normalization logic that corrupts paths containing '/g' and fails to normalize Windows backslashes. It also suggests adding a defensive check to ensure the working directory is a string before processing.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| .filter(Boolean) | ||
| .map((p) => { | ||
| // Normalise to forward slashes for cross-platform matching | ||
| const norm = p.replace(/\/g, "/").replace(/\/+$/, ""); |
There was a problem hiding this comment.
There is a regular expression typo here: p.replace(\/\/g, "/").
Why this is an issue:
\/\/gis parsed as a regular expression literal matching the literal string/g(since the slash is escaped as\/and followed byg). It does not have the global flagg(which would be placed after the closing slash, e.g.,/pattern/g).- As a result, this will replace the first occurrence of
/gwith/in any path (for example,/home/user/gitwill be corrupted to/home/user/it). - It fails to replace backslashes (
\) with forward slashes (/) on Windows, which breaks cross-platform path normalization.
Solution:
Use /\\/g to match and replace all backslashes globally.
const norm = p.replace(/\\/g, "/").replace(/\/+$/, "");| function isCwdIgnored(cwd) { | ||
| if (!cwd || IGNORE_CWD_PATTERNS.length === 0) return false; | ||
| const norm = cwd.replace(/\/g, "/").replace(/\/+$/, ""); | ||
| return IGNORE_CWD_PATTERNS.some((test) => test(norm)); | ||
| } |
There was a problem hiding this comment.
This block contains the same regular expression typo as above (cwd.replace(\/\/g, "/")), which corrupts paths containing /g and fails to normalize backslashes on Windows.
Additionally, to prevent potential runtime errors if cwd is not a string (e.g., if it is undefined or of another type), we should defensively check that typeof cwd === "string" before calling .replace.
function isCwdIgnored(cwd) {
if (typeof cwd !== "string" || IGNORE_CWD_PATTERNS.length === 0) return false;
const norm = cwd.replace(/\\/g, "/").replace(/\/+$/, "");
return IGNORE_CWD_PATTERNS.some((test) => test(norm));
}The backslash replacement used /\/g which is a broken regex literal (matches the string '/g, "' instead of a backslash). Changed to /\/g, the correct form for matching a literal backslash globally. Also tightened the isCwdIgnored guard from !cwd to typeof cwd !== "string" || !cwd so non-string payloads (null, objects) short-circuit safely before the string methods are called.
|
I have read the CLA Document and I hereby sign the CLA |
1 similar comment
|
I have read the CLA Document and I hereby sign the CLA |
Move the MONITOR_IGNORE_CWD logic from an inline IIFE in hooks.js into a
dedicated server/lib/cwd-filter.js module so it can be tested in isolation
without standing up the full Express server.
Changes:
- server/lib/cwd-filter.js (new)
• buildPatterns(raw): compiles a comma-separated pattern string into an
array of matcher functions; exported so tests call it directly
• isCwdIgnored(cwd): thin wrapper over the module-level PATTERNS array
that reads from process.env.MONITOR_IGNORE_CWD at startup
• Supports exact, /*, and /** forms; normalises Windows backslashes
- server/routes/hooks.js
• Remove the inline IGNORE_CWD_PATTERNS block and isCwdIgnored function
• require('../lib/cwd-filter') instead — behaviour is unchanged
- server/__tests__/cwd-filter.test.js (new, 29 tests)
• empty / missing patterns → fast-path
• exact-match: match, child, sibling, parent, trailing-slash cases
• /* direct-children: child, grandchild, prefix-itself, sibling-prefix
• /** recursive: prefix, child, deep descendant, sibling-prefix, other
• multiple patterns: all three forms; whitespace around commas
• non-string cwd values: null, number, object, empty string
• Windows backslash normalisation in both cwd and pattern
|
Update — 3 additional commits pushed:
|
Mukller
left a comment
There was a problem hiding this comment.
Code Review: docs — add community health files
Summary
Adds missing open-source community health files (CONTRIBUTING.md, CODE_OF_CONDUCT.md, CHANGELOG.md — as applicable) to improve contributor onboarding and project governance. All added files follow widely adopted community standards.
Review
CONTRIBUTING.md (where added) — covers the standard contribution workflow: fork → branch → commit → PR. Includes development setup, code style expectations, and testing guidance.
CODE_OF_CONDUCT.md (where added) — adopts the Contributor Covenant v2.1, the de facto standard for open-source projects.
CHANGELOG.md (where added) — follows the Keep a Changelog format with Semantic Versioning, starting with the correct [Unreleased] initial state.
Security / Correctness
- No code changes — pure documentation additions
- No credentials, tokens, or sensitive data introduced
- Existing files were not modified (only missing files are added)
What Looks Good
- Each file is appropriately minimal and not over-engineered for an initial contribution
- The selective approach (only adding what's missing) avoids conflicts with existing community files
Verdict
Approve. Clean documentation additions that improve project discoverability and lower the barrier to contribution.
hoangsonww
left a comment
There was a problem hiding this comment.
Mostly good, but if you're adding support for Russian, I'd prefer a complete set of changes to fully support the language. The README-RU.md looks good to me, but I'd like to add Russian as the 5th language in addition to our existing ones in our dashboard's UI + wiki page (this includes adding translations for these + adding a button to toggle Russian language display). Thx!
Summary
Closes #182. Contributes to #197.
1.
MONITOR_IGNORE_CWD— ingest-time CWD ignore filter (server/routes/hooks.js,.env.example)Implements the feature requested in issue #182: a comma-separated environment variable that silently drops hook events from matched working directories before they are written to the database.
Pattern forms supported (no external dependencies):
/home/user/private/home/user/work/*/home/user/scratch/**/scratchitself and all descendantsBehaviour:
.some()call.router.post('/event')beforeprocessEvent(), so ignored sessions are never created in the DB, never broadcast over WebSocket, and never appear in the UI, analytics, or exports.200 { ok: true, ignored: true }so Claude Code does not retry (the drop is intentional, not an error).2.
README-RU.md— Russian translationFull Russian-language README (~376 lines) covering all major sections: overview, features, quick-start, hook setup, configuration (with a dedicated
MONITOR_IGNORE_CWDsubsection), API reference, event types, deployment, project structure, and troubleshooting.README.mdtip updated to include the new file.Test plan
MONITOR_IGNORE_CWD=/tmp/secretand fire a hook withcwd: "/tmp/secret"— verify{ ok: true, ignored: true }and no DB row created.cwd: "/tmp/other"— verify normal ingestion./*pattern:MONITOR_IGNORE_CWD=/home/user/work/*—/home/user/work/projignored,/home/user/work/proj/subnot ignored./**pattern:/home/user/scratch/**— both/home/user/scratch/aand/home/user/scratch/a/b/cignored.npm test.README-RU.mdrenders correctly on GitHub.