Skip to content
gledachPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

snare

A hook that was not there yesterday.

Reads the hook files a coding agent runs at startup, and the editor tasks that run when a folder opens. The first run records that set and says so. Later runs print nothing when it matches. A new hook, a removed hook, or an edited command prints and exits 1.

Zero runtime dependencies. No account, no build step. Everything stays on your machine. It does not delete a hook.

git clone https://github.com/gledach/snare.git && cd snare
node bin/snare.mjs check

That works on a fresh clone with Node 22 and nothing else. There is no npm install.

Why

A coding agent will run a command from its settings the next time it starts. An editor will run a task when it opens a folder. A package, a pull request, or a plugin can write that command, and the session looks normal afterwards. snare keeps the last set it saw, so the change is the thing that speaks.

Commands

The command is gledach-snare. npm link in this clone puts that name on your PATH. Nothing named snare is installed: that name is an npm package. The package name is gledach-snare.

node bin/snare.mjs is the same program and needs no link.

gledach-snare check                  # quiet when the set matches
gledach-snare check D:\work\repo     # also read that folder
gledach-snare accept                 # remember the current set
gledach-snare list                   # print the current set
gledach-snare report                 # print data/latest.json
gledach-snare doctor

check with no folder reads your user settings and the current directory. Extra folders are arguments, or SNARE_ROOTS using your platform's path separator. It reads each folder you name. It does not open child folders, so a hook under node_modules is missed unless you pass that folder.

list and accept take the same folder arguments as check.

The first check writes data/baseline.json and data/latest.json, and prints the count. A match prints nothing and exits 0. latest.json is still refreshed, so report shows the current set. A difference prints ADDED, REMOVED, or CHANGED and exits 1. The baseline stays until accept.

accept updates the baseline. It does not edit, disable, or delete a hook.

Exit 2 means the command was not recognized, or data/baseline.json is corrupt. A corrupt baseline is left in place. accept replaces it.

What it reads

Claude Code settings.json and settings.local.json, for the user and for each folder you pass. Every hook event is recorded. SessionStart, Setup, and InstructionsLoaded are marked start. A hook on any other event is still a change, and the line says when it would run. The same files contribute statusLine.command and the helper commands apiKeyHelper, awsAuthRefresh, awsCredentialExport, and otelHeadersHelper.

CLAUDE_CONFIG_DIR replaces the user Claude folder. On Windows, the two managed settings paths are read when they exist: C:\Program Files\ClaudeCode\managed-settings.json and C:\ProgramData\ClaudeCode\managed-settings.json.

Codex hooks.json, config.toml, and a profile file named *.config.toml in the Codex home folder. Project copies of those files are read from each folder you pass. commandWindows and command_windows are the Windows command. CODEX_HOME replaces the user Codex folder. notify is marked auto because it runs at the end of a turn. features.codex_hooks is recorded when the file sets it.

Cursor hooks.json for the user and for each folder. sessionStart and workspaceOpen are marked start.

VS Code and Cursor tasks whose runOptions.runOn is folderOpen, plus tasks those entries depend on. The Windows command is windows.command. Paths are the user tasks.json, one level of profiles, Code - Insiders, a workspace .vscode/tasks.json, and a .code-workspace file sitting in a folder you passed. The files may contain comments.

The comparison hashes the command, its arguments, the Windows override, a url, and a prompt. data/ keeps the hash and a shortened redacted line. It does not keep the raw command. On Windows the printed line prefers commandWindows when the hook has one. Editing either command is a change.

SNARE_HOME and SNARE_APPDATA point the user folders somewhere else. SNARE_DATA moves data/. Tests use those.

What it cannot see

  • A hook written and removed between two runs.
  • Plugin hooks in a cache, and hooks declared on a skill or a subagent. They run when that plugin or skill is enabled. snare does not walk those trees.
  • An MCP server command. Those processes start with the client too. Claude keeps them in a user file that also holds account data, so this tool does not open that file.
  • A PowerShell profile, a startup entry, a service, or a scheduled task.
  • Whether the hook will actually run. disableAllHooks: true is recorded, and the hooks beside it are still listed. A folderOpen task can be blocked by workspace trust or by task.allowAutomaticTasks. A Codex hook can sit in the file and still not run: some builds want codex_hooks on, some skip a hook until it is trusted, and older Windows builds did not run hooks. snare reports the file either way.
  • A timeout-only edit. The command is the same, so the run stays quiet.
  • A binary replaced on disk when the command string is unchanged.
  • Cursor can run Claude SessionStart hooks it imported. Those Claude files are already in the baseline.
  • Anything outside the user locations above and the folders you named.

data/ is gitignored. Redaction covers sk-ant-, sk-, github_pat_, ghp_, glpat-, AKIA, xox, and Bearer. It is not a secret scanner. The hash still changes when a redacted value changes. The printed line stops at 160 characters.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages