Six hooks to check before you trust a repository.
Opening a folder, installing dependencies, attaching a coding agent, or launching a devcontainer can activate configuration-defined commands. Here is a short checklist for finding the known entry points before you decide what to trust.
Start with the scope, not a security score
Repository configuration can describe what a development tool may run later. Seeing a command in a file is not proof that it executed, that the author is malicious, or that the project is compromised. Triggers depend on individual package-manager, editor, trust and agent settings.
Review an unfamiliar checkout from a separate trusted terminal before installing its packages, opening it as a trusted editor workspace, or starting a coding agent. Even cloning is not a sandbox: your local Git configuration and environment may affect Git operations.
1. Package-manager lifecycle scripts
Look in package.json, especially the scripts keys preinstall, install, postinstall, prepare and prepack. Some package-manager operations can invoke these automatically. A normal lifecycle command is not inherently suspicious; check the script and the programs it calls.
{
"scripts": {
"postinstall": "node scripts/verify-setup.js"
}
}
This is an inert illustration. Do not execute it to inspect it. ClonePeek models these npm surfaces and follows one statically identifiable hop into literal local .sh references, but it does not analyze arbitrary JavaScript imports or recursive script execution.
2. VS Code automatic folder-open tasks
Inspect .vscode/tasks.json for tasks that declare runOptions.runOn: folderOpen. Whether a task runs when the folder is opened depends on workspace trust and automatic-task settings. Read the command, task arguments and referenced files before accepting the workspace.
{
"version": "2.0.0",
"tasks": [{
"label": "Example setup task",
"type": "shell",
"command": "echo review-me",
"runOptions": {"runOn": "folderOpen"}
}]
}
The echo value is deliberately harmless; this snippet exists to demonstrate the configuration shape, not to perform a setup.
3. Devcontainer lifecycle
Review .devcontainer/devcontainer.json for initializeCommand, onCreateCommand, postCreateCommand, postStartCommand and postAttachCommand. Those correspond to different phases of creating, starting and attaching to a development environment. Devcontainer features can also introduce build-time setup. An isolated container is not a blanket guarantee of safety when it has mounts, credentials or network access.
4. Claude Code command hooks
Look at project files such as .claude/settings.json and .claude/settings.local.json. Command hooks can be attached to events such as SessionStart or PostToolUse. Activation depends on the agent and its configuration. Treat instructions, tools and automatic commands from a new project as untrusted until reviewed.
5. Cursor workspace and agent hooks
Look for .cursor/hooks.json, including event definitions such as workspaceOpen and afterFileEdit. Read what will be invoked, when, and by which process. A passive review tool should never trigger the hook merely to discover its output.
6. Local MCP process launch configuration
Review the local MCP configuration your agent or editor may consume, particularly each mcpServers entry with a command, args, environment variables and filesystem references. These are process-launch instructions, not necessarily running servers. They may take effect only when the client enables or approves them.
Run a passive review in a trusted terminal
I maintain ClonePeek, a small MIT-licensed Python CLI and GitHub Action for enumerating the modeled entry points above. The scan reads bounded configuration files and does not run the target repository's scripts. Downloading/installing the scanner itself uses a network connection; the scan itself operates offline.
uvx --from git+https://github.com/harshitethic/clonepeek@v0.5.1 clonepeek /path/to/repo
For an inert demonstration, use the bundled agent-hooks fixture. Review the trigger, source path and line, example evidence, and suggested review advice for each finding. None of the example commands needs to run.
You can also start with this non-blocking PR workflow:
name: Review execution hooks
on: [pull_request]
permissions:
contents: read
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: harshitethic/clonepeek@v0.5.1
with:
path: .
fail-on: none
The Action integration guide explains thresholds, baselines, JSON/SARIF and changed-file mode.
What a clean result does not mean
- No scanner can promise a safe repository. ClonePeek deliberately omits dynamic references, many language/build execution paths and other unsupported tools.
- Severity means review urgency. Common, benign setup tasks can still receive high heuristic severity, while obfuscated or unsupported paths can be missed.
- Baseline does not equal approval. A finding marked known is still an execution-capable surface; it merely matched your stored fingerprint.
- Scan reports can contain sensitive content. Redaction is best effort. Review and sanitize source excerpts before posting an artifact or CI comment publicly.
- Git operations deserve a boundary review too. ClonePeek's Git fsmonitor case study documents a prior bug where a passive-looking diff invoked a configured helper. This was fixed with regression tests; it is not a sandbox guarantee.
Help improve the checklist
Have a harmless repository hook that is missing or misclassified? A tiny inert reproduction and clear expected trigger help more than generic praise. The public threat model lists blind spots, and the labeled synthetic evaluation is explicitly not independent real-world accuracy evidence.
Contribute an inert field test ↗ Get the stable release ↗ Explore ClonePeek ↗