Skip to content

feat(hooks): MONITOR_IGNORE_CWD ingest filter + Russian README#220

Open
Mukller wants to merge 3 commits into
hoangsonww:masterfrom
Mukller:feat/monitor-ignore-cwd
Open

feat(hooks): MONITOR_IGNORE_CWD ingest filter + Russian README#220
Mukller wants to merge 3 commits into
hoangsonww:masterfrom
Mukller:feat/monitor-ignore-cwd

Conversation

@Mukller

@Mukller Mukller commented Jul 10, 2026

Copy link
Copy Markdown

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):

Pattern Matches
/home/user/private Exact path only
/home/user/work/* Direct children only (not deeper)
/home/user/scratch/** /scratch itself and all descendants
# .env
MONITOR_IGNORE_CWD=/home/user/private,/home/user/scratch/**,/tmp/*

Behaviour:

  • Patterns are parsed once at startup into compiled matcher functions — zero overhead per request beyond a single .some() call.
  • The early-return fires in router.post('/event') before processEvent(), so ignored sessions are never created in the DB, never broadcast over WebSocket, and never appear in the UI, analytics, or exports.
  • Returns 200 { ok: true, ignored: true } so Claude Code does not retry (the drop is intentional, not an error).
  • Slash-normalised on both sides for cross-platform consistency.

2. README-RU.md — Russian translation

Full Russian-language README (~376 lines) covering all major sections: overview, features, quick-start, hook setup, configuration (with a dedicated MONITOR_IGNORE_CWD subsection), API reference, event types, deployment, project structure, and troubleshooting.

  • Language-switcher footer links all existing translations.
  • README.md tip updated to include the new file.

Test plan

  • Set MONITOR_IGNORE_CWD=/tmp/secret and fire a hook with cwd: "/tmp/secret" — verify { ok: true, ignored: true } and no DB row created.
  • Fire the same hook with cwd: "/tmp/other" — verify normal ingestion.
  • Test /* pattern: MONITOR_IGNORE_CWD=/home/user/work/*/home/user/work/proj ignored, /home/user/work/proj/sub not ignored.
  • Test /** pattern: /home/user/scratch/** — both /home/user/scratch/a and /home/user/scratch/a/b/c ignored.
  • Verify existing tests still pass: npm test.
  • Verify README-RU.md renders correctly on GitHub.

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.
@Mukller Mukller requested a review from hoangsonww as a code owner July 10, 2026 19:05
@github-actions github-actions Bot added bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed question Further information is requested labels Jul 10, 2026
@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown

✅ All contributors have signed the CLA. Thank you!
Posted by the CLA Assistant Lite bot.

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

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.

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.

Comment thread server/routes/hooks.js Outdated
.filter(Boolean)
.map((p) => {
// Normalise to forward slashes for cross-platform matching
const norm = p.replace(/\/g, "/").replace(/\/+$/, "");

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.

high

There is a regular expression typo here: p.replace(\/\/g, "/").

Why this is an issue:

  1. \/\/g is parsed as a regular expression literal matching the literal string /g (since the slash is escaped as \/ and followed by g). It does not have the global flag g (which would be placed after the closing slash, e.g., /pattern/g).
  2. As a result, this will replace the first occurrence of /g with / in any path (for example, /home/user/git will be corrupted to /home/user/it).
  3. 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(/\/+$/, "");

Comment thread server/routes/hooks.js Outdated
Comment on lines +68 to +72
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));
}

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.

high

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.
@Mukller

Mukller commented Jul 10, 2026

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

1 similar comment
@Mukller

Mukller commented Jul 10, 2026

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Jul 10, 2026
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
@Mukller

Mukller commented Jul 10, 2026

Copy link
Copy Markdown
Author

Update — 3 additional commits pushed:

  1. Fixed regex bug flagged by Gemini review: /\/g/\/g (the broken form matched the literal string /g, "" instead of a backslash); also tightened the isCwdIgnored guard to typeof cwd !== "string".

  2. Refactored the inline logic into server/lib/cwd-filter.js — a self-contained module with buildPatterns(raw) and isCwdIgnored(cwd) exported separately so the logic can be tested without standing up Express.

  3. Added 29 unit tests in server/__tests__/cwd-filter.test.js covering: empty/missing env, exact match (child/sibling/parent/trailing-slash cases), /* direct-children, /** recursive-descendants, multiple comma-separated patterns, non-string cwd values (null / number / object), and Windows backslash normalisation in both cwd and pattern. All 29 pass.

@Mukller Mukller left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

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 hoangsonww left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed question Further information is requested

Projects

Development

Successfully merging this pull request may close these issues.

2 participants