Back to catalogue
WorkflowWorktreeRemove
Clean up artifacts on worktree removal
Runs cleanup tasks when a worktree is removed: stops any Docker Compose services declared in the worktree and removes node_modules to reclaim disk space. Prevents orphaned containers and disk bloat after isolation: worktree subagent sessions.
Use cases
- Stop Docker Compose services started inside an isolated worktree
- Reclaim disk space by removing node_modules after worktree cleanup
- Prevent orphaned containers when parallel subagents each run their own stack
Providers & tags
Claude Code
#worktree#docker#cleanup#node_modules#disk-space
settings.json fragment
{
"hooks": {
"WorktreeRemove": [
{
"hooks": [
{
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/worktree-remove-cleanup.mjs",
"type": "command"
}
]
}
]
}
}Script · .claude/hooks/worktree-remove-cleanup.mjs
#!/usr/bin/env node
// Nettoie un worktree supprimé : docker compose down + node_modules (WorktreeRemove)
import { readFileSync, existsSync, rmSync } from 'fs';
import { execSync } from 'child_process';
import { join } from 'path';
import { fileURLToPath } from 'url';
function defaultExec(cmd) {
execSync(cmd, { timeout: 30_000 });
}
export function run(input, { exec = defaultExec, exists = existsSync, rm = rmSync } = {}) {
const p = input.worktree_path;
if (!p) return null;
const actions = [];
try {
if (exists(join(p, 'docker-compose.yml')) || exists(join(p, 'docker-compose.yaml'))) {
exec(`docker compose -f ${p}/docker-compose.yml down --remove-orphans 2>&1`);
actions.push('docker-down');
}
} catch { /* ignore */ }
try {
const nm = join(p, 'node_modules');
if (exists(nm)) {
rm(nm, { recursive: true, force: true });
actions.push('rm-node-modules');
}
} catch { /* ignore */ }
return { actions };
}
/* v8 ignore next 4 */
if (process.argv[1] === fileURLToPath(import.meta.url)) {
const input = JSON.parse(readFileSync(0, 'utf8'));
run(input);
}