Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions .claude/hooks/check-new-deps/index.mts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
// 0 = allow (no new deps, all clean, or non-dep file)
// 2 = block (malware detected by Socket.dev)

import path from 'node:path'
import { fileURLToPath } from 'node:url'

import {
parseNpmSpecifier,
stringify,
Expand All @@ -32,6 +35,12 @@ import {
import { SocketSdk } from '@socketsecurity/sdk'
import type { MalwareCheckPackage } from '@socketsecurity/sdk'

// Hook runs standalone with only @socketsecurity/* deps, so this
// one-liner lives here instead of importing a shared helper.
function errorMessage(error: unknown): string {
return error instanceof Error ? error.message : String(error)
}

const logger = getDefaultLogger()

// Per-request timeout (ms) to avoid blocking the hook on slow responses.
Expand Down Expand Up @@ -273,7 +282,7 @@ const extractors: Record<string, Extractor> = {

// --- main (only when executed directly, not imported) ---

if (import.meta.filename === process.argv[1]) {
if (fileURLToPath(import.meta.url) === path.resolve(process.argv[1])) {
// Read the full JSON blob from stdin (piped by Claude Code).
let input = ''
for await (const chunk of process.stdin) input += chunk
Expand Down Expand Up @@ -402,10 +411,7 @@ async function checkDepsBatch(
}
} catch (e) {
// Network failure — log and allow all deps through.
logger.warn(
`Socket: network error`
+ ` (${(e as Error).message}), allowing all`
)
logger.warn(`Socket: network error (${errorMessage(e)}), allowing all`)
}

return blocked
Expand Down
25 changes: 25 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,31 @@
- Identify users by git credentials (commit author, GitHub account). Use their actual name, never "the user".
- Use "you/your" when speaking directly; use their name when discussing their work.

## PARALLEL CLAUDE SESSIONS - WORKTREE REQUIRED

**This repo may have multiple Claude sessions running concurrently against the same checkout, against parallel git worktrees, or against sibling clones.** Several common git operations are hostile to that and silently destroy or hijack the other session's work.

- **FORBIDDEN in the primary checkout** (the one another Claude may be editing):
- `git stash` — shared stash store; another session can `pop` yours.
- `git add -A` / `git add .` — sweeps files belonging to other sessions.
- `git checkout <branch>` / `git switch <branch>` — yanks the working tree out from under another session.
- `git reset --hard` against a non-HEAD ref — discards another session's commits.
- **REQUIRED for branch work**: spawn a worktree instead of switching branches in place. Each worktree has its own HEAD, so branch operations inside it are safe.

```bash
# From the primary checkout — does NOT touch the working tree here.
git worktree add -b <task-branch> ../<repo>-<task> main
cd ../<repo>-<task>
# edit, commit, push from here; the primary checkout is untouched.
cd -
git worktree remove ../<repo>-<task>
```

- **REQUIRED for staging**: surgical `git add <specific-file> [<file>…]` with explicit paths. Never `-A` / `.`.
- **If you need a quick WIP save**: commit on a new branch from inside a worktree, not a stash.

The umbrella rule: never run a git command that mutates state belonging to a path other than the file you just edited.

## PRE-ACTION PROTOCOL

**MANDATORY**: Review CLAUDE.md before any action. No exceptions.
Expand Down