fix: finish hook fallback and canonical session follow-ups

This commit is contained in:
Affaan Mustafa
2026-03-25 03:44:03 -04:00
parent 7b510c886e
commit 9c5ca92e6e
9 changed files with 108 additions and 28 deletions

View File

@@ -66,6 +66,16 @@ function emitHookResult(raw, output) {
return 0;
}
function writeLegacySpawnOutput(raw, result) {
const stdout = typeof result.stdout === 'string' ? result.stdout : '';
if (stdout) {
process.stdout.write(stdout);
return;
}
process.stdout.write(raw);
}
function getPluginRoot() {
if (process.env.CLAUDE_PLUGIN_ROOT && process.env.CLAUDE_PLUGIN_ROOT.trim()) {
return process.env.CLAUDE_PLUGIN_ROOT;
@@ -135,7 +145,7 @@ async function main() {
}
// Legacy path: spawn a child Node process for hooks without run() export
const result = spawnSync('node', [scriptPath], {
const result = spawnSync(process.execPath, [scriptPath], {
input: raw,
encoding: 'utf8',
env: {
@@ -147,11 +157,20 @@ async function main() {
timeout: 30000
});
if (result.stdout) process.stdout.write(result.stdout);
writeLegacySpawnOutput(raw, result);
if (result.stderr) process.stderr.write(result.stderr);
const code = Number.isInteger(result.status) ? result.status : 0;
process.exit(code);
if (result.error || result.signal || result.status === null) {
const failureDetail = result.error
? result.error.message
: result.signal
? `terminated by signal ${result.signal}`
: 'missing exit status';
writeStderr(`[Hook] legacy hook execution failed for ${hookId}: ${failureDetail}`);
process.exit(1);
}
process.exit(Number.isInteger(result.status) ? result.status : 0);
}
main().catch(err => {

View File

@@ -22,6 +22,36 @@ const {
const { getPackageManager, getSelectionPrompt } = require('../lib/package-manager');
const { listAliases } = require('../lib/session-aliases');
const { detectProjectType } = require('../lib/project-detect');
const path = require('path');
function dedupeRecentSessions(searchDirs) {
const recentSessionsByName = new Map();
for (const [dirIndex, dir] of searchDirs.entries()) {
const matches = findFiles(dir, '*-session.tmp', { maxAge: 7 });
for (const match of matches) {
const basename = path.basename(match.path);
const current = {
...match,
basename,
dirIndex,
};
const existing = recentSessionsByName.get(basename);
if (
!existing
|| current.mtime > existing.mtime
|| (current.mtime === existing.mtime && current.dirIndex < existing.dirIndex)
) {
recentSessionsByName.set(basename, current);
}
}
}
return Array.from(recentSessionsByName.values())
.sort((left, right) => right.mtime - left.mtime || left.dirIndex - right.dirIndex);
}
async function main() {
const sessionsDir = getSessionsDir();
@@ -33,9 +63,7 @@ async function main() {
ensureDir(learnedDir);
// Check for recent session files (last 7 days)
const recentSessions = getSessionSearchDirs()
.flatMap(dir => findFiles(dir, '*-session.tmp', { maxAge: 7 }))
.sort((a, b) => b.mtime - a.mtime);
const recentSessions = dedupeRecentSessions(getSessionSearchDirs());
if (recentSessions.length > 0) {
const latest = recentSessions[0];