d48cda4081
CI / Test (ubuntu-latest, Node 18.x, bun) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, npm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, pnpm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, yarn) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 20.x, bun) (push) Failing after 17m13s
CI / Test (ubuntu-latest, Node 20.x, npm) (push) Failing after 18m42s
CI / Test (ubuntu-latest, Node 20.x, pnpm) (push) Failing after 15m0s
CI / Test (ubuntu-latest, Node 20.x, yarn) (push) Failing after 49m44s
CI / Test (ubuntu-latest, Node 22.x, bun) (push) Failing after 51m55s
CI / Test (ubuntu-latest, Node 22.x, pnpm) (push) Failing after 21m57s
CI / Test (ubuntu-latest, Node 22.x, npm) (push) Failing after 37m39s
CI / Test (ubuntu-latest, Node 22.x, yarn) (push) Failing after 34m7s
CI / Validate Components (push) Failing after 37m15s
CI / Python Tests (push) Failing after 10m1s
CI / Security Scan (push) Failing after 10m1s
CI / Lint (push) Failing after 17m12s
CI / Coverage (push) Failing after 20m19s
CI / Test (macos-latest, Node 18.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, yarn) (push) Has been cancelled
79 lines
2.3 KiB
JavaScript
79 lines
2.3 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* PostToolUse Hook: Accumulate edited JS/TS file paths for batch processing
|
|
*
|
|
* Cross-platform (Windows, macOS, Linux)
|
|
*
|
|
* Records each edited JS/TS path to a session-scoped temp file (one path per
|
|
* line). stop-format-typecheck.js reads this list at Stop time and runs format
|
|
* + typecheck once across all edited files, eliminating per-edit latency.
|
|
*
|
|
* appendFileSync is used so concurrent hook processes write atomically
|
|
* without overwriting each other. Deduplication is deferred to the Stop hook.
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
const crypto = require('crypto');
|
|
const fs = require('fs');
|
|
const os = require('os');
|
|
const path = require('path');
|
|
|
|
const MAX_STDIN = 1024 * 1024;
|
|
|
|
function getAccumFile() {
|
|
const raw =
|
|
process.env.CLAUDE_SESSION_ID ||
|
|
crypto.createHash('sha1').update(process.cwd()).digest('hex').slice(0, 12);
|
|
// Strip path separators and traversal sequences so the value is safe to embed
|
|
// directly in a filename regardless of what CLAUDE_SESSION_ID contains.
|
|
const sessionId = raw.replace(/[^a-zA-Z0-9_-]/g, '_').slice(0, 64);
|
|
return path.join(os.tmpdir(), `ecc-edited-${sessionId}.txt`);
|
|
}
|
|
|
|
/**
|
|
* @param {string} rawInput - Raw JSON string from stdin
|
|
* @returns {string} The original input (pass-through)
|
|
*/
|
|
const JS_TS_EXT = /\.(ts|tsx|js|jsx)$/;
|
|
|
|
function appendPath(filePath) {
|
|
if (filePath && JS_TS_EXT.test(filePath)) {
|
|
fs.appendFileSync(getAccumFile(), filePath + '\n', 'utf8');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {string} rawInput - Raw JSON string from stdin
|
|
* @returns {string} The original input (pass-through)
|
|
*/
|
|
function run(rawInput) {
|
|
try {
|
|
const input = JSON.parse(rawInput);
|
|
// Edit / Write: single file_path
|
|
appendPath(input.tool_input?.file_path);
|
|
// MultiEdit: array of edits, each with its own file_path
|
|
const edits = input.tool_input?.edits;
|
|
if (Array.isArray(edits)) {
|
|
for (const edit of edits) appendPath(edit?.file_path);
|
|
}
|
|
} catch {
|
|
// Invalid input — pass through
|
|
}
|
|
return rawInput;
|
|
}
|
|
|
|
if (require.main === module) {
|
|
let data = '';
|
|
process.stdin.setEncoding('utf8');
|
|
process.stdin.on('data', chunk => {
|
|
if (data.length < MAX_STDIN) data += chunk.substring(0, MAX_STDIN - data.length);
|
|
});
|
|
process.stdin.on('end', () => {
|
|
process.stdout.write(run(data));
|
|
process.exit(0);
|
|
});
|
|
}
|
|
|
|
module.exports = { run };
|