4df9f61347
* fix: stop generating empty CLAUDE.md files - Return empty string instead of "No recent activity" when no observations exist - Skip writing CLAUDE.md files when formatted content is empty - Remove redundant "auto-generated by claude-mem" HTML comment - Clean up 98 existing empty CLAUDE.md files across the codebase - Update tests to expect empty string for empty input Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * build assets * refactor: implement in-process worker architecture for hooks Replaces spawn-based worker startup with in-process architecture: - Hook processes now become the worker when port 37777 is free - Eliminates Windows spawn issues (NO SPAWN rule) - SessionStart chains: smart-install && stop && context Key changes: - worker-service.ts: hook case starts WorkerService in-process - hook-command.ts: skipExit option prevents process.exit() when hosting worker - hooks.json: single chained command replaces separate start/hook commands - worker-utils.ts: ensureWorkerRunning() returns boolean, doesn't block - handlers: graceful fallback when worker unavailable All 761 tests pass. Manual verification confirms hook stays alive as worker. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * context * a * MAESTRO: Mark PR #722 test verification task complete All 797 tests passed (3 skipped, 0 failed) after merge conflict resolution. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * MAESTRO: Mark PR #722 build verification task complete * MAESTRO: Mark PR #722 code review task complete Code review verified: - worker-service.ts hook case starts WorkerService in-process - hook-command.ts has skipExit option - hooks.json uses single chained command - worker-utils.ts ensureWorkerRunning() returns boolean Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * MAESTRO: Mark PR #722 conflict resolution push task complete Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
55 lines
1.8 KiB
TypeScript
55 lines
1.8 KiB
TypeScript
/**
|
|
* Context Handler - SessionStart
|
|
*
|
|
* Extracted from context-hook.ts - calls worker to generate context.
|
|
* Returns context as hookSpecificOutput for Claude Code to inject.
|
|
*/
|
|
|
|
import type { EventHandler, NormalizedHookInput, HookResult } from '../types.js';
|
|
import { ensureWorkerRunning, getWorkerPort } from '../../shared/worker-utils.js';
|
|
import { getProjectContext } from '../../utils/project-name.js';
|
|
import { HOOK_EXIT_CODES } from '../../shared/hook-constants.js';
|
|
|
|
export const contextHandler: EventHandler = {
|
|
async execute(input: NormalizedHookInput): Promise<HookResult> {
|
|
// Ensure worker is running before any other logic
|
|
const workerReady = await ensureWorkerRunning();
|
|
if (!workerReady) {
|
|
// Worker not available - return empty context gracefully
|
|
return {
|
|
hookSpecificOutput: {
|
|
hookEventName: 'SessionStart',
|
|
additionalContext: ''
|
|
},
|
|
exitCode: HOOK_EXIT_CODES.SUCCESS
|
|
};
|
|
}
|
|
|
|
const cwd = input.cwd ?? process.cwd();
|
|
const context = getProjectContext(cwd);
|
|
const port = getWorkerPort();
|
|
|
|
// Pass all projects (parent + worktree if applicable) for unified timeline
|
|
const projectsParam = context.allProjects.join(',');
|
|
const url = `http://127.0.0.1:${port}/api/context/inject?projects=${encodeURIComponent(projectsParam)}`;
|
|
|
|
// Note: Removed AbortSignal.timeout due to Windows Bun cleanup issue (libuv assertion)
|
|
// Worker service has its own timeouts, so client-side timeout is redundant
|
|
const response = await fetch(url);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`Context generation failed: ${response.status}`);
|
|
}
|
|
|
|
const result = await response.text();
|
|
const additionalContext = result.trim();
|
|
|
|
return {
|
|
hookSpecificOutput: {
|
|
hookEventName: 'SessionStart',
|
|
additionalContext
|
|
}
|
|
};
|
|
}
|
|
};
|