ad8ac7970d
* fix: distinguish connection errors from collection-not-found in ChromaSync Previously, ensureCollection() caught ALL errors from chroma_get_collection_info and assumed they meant "collection doesn't exist". This caused connection errors like "Not connected" to trigger unnecessary collection creation attempts. Now connection-related errors are re-thrown immediately instead of being misinterpreted as missing collections. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: improve error handling for Chroma connection and collection creation * fix: remove dead last_user_message from summarize flow The last_user_message field was extracted from transcripts but never used. In Claude Code transcripts, "user" type messages are mostly tool_results, not actual user input. The user's original request is already stored in user_prompts table. This removes the false warning "Missing last_user_message when queueing summary" which was complaining about missing data that didn't exist and wasn't needed. Changes: - summary-hook: Only extract last_assistant_message - SessionRoutes: Remove last_user_message from request body handling - SessionManager.queueSummarize: Remove lastUserMessage parameter - PendingMessage interface: Remove last_user_message field - SDKSession interface: Remove last_user_message field - All agents: Remove last_user_message from buildSummaryPrompt calls 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * build artifacts for plugin * Enhance error handling across multiple services - Improved logging in `BranchManager.ts` to capture recovery checkout failures. - Updated `PaginationHelper.ts` to log when file paths are plain strings instead of valid JSON. - Enhanced error logging in `SDKAgent.ts` for Claude executable detection failures. - Added logging for plain string handling in `SearchManager.ts` for files read and edited. - Improved logging in `paths.ts` for git root detection failures. - Enhanced JSON parsing error handling in `timeline-formatting.ts` with previews of failed inputs. - Updated `transcript-parser.ts` to log summary of parse errors after processing transcript lines. - Established a baseline for error handling practices in `error-handling-baseline.txt`. - Documented error handling anti-pattern rules in `CLAUDE.md` to prevent silent failures and improve code quality. * Add error handling anti-pattern detection script and guidelines - Introduced `detect-error-handling-antipatterns.ts` to identify common error handling issues in TypeScript code. - Created comprehensive documentation in `CLAUDE.md` outlining forbidden patterns, allowed patterns, and critical path protection rules. - Implemented checks for empty catch blocks, logging practices, and try-catch block sizes to prevent silent failures and improve debugging. - Established a reporting mechanism to summarize detected anti-patterns with severity levels. * feat: add console filter bar and log line parsing with filtering capabilities - Introduced a console filter bar with options to filter logs by level and component. - Implemented parsing of log lines to extract structured data including timestamp, level, component, and correlation ID. - Added functionality to toggle individual and all levels/components for filtering. - Enhanced log line rendering with color coding based on log level and special message types. - Improved responsiveness of the filter bar for smaller screens. --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
88 lines
2.8 KiB
TypeScript
88 lines
2.8 KiB
TypeScript
/**
|
|
* Summary Hook - Stop
|
|
*
|
|
* Pure HTTP client - sends data to worker, worker handles all database operations
|
|
* including privacy checks. This allows the hook to run under any runtime
|
|
* (Node.js or Bun) since it has no native module dependencies.
|
|
*
|
|
* Transcript parsing stays in the hook because only the hook has access to
|
|
* the transcript file path.
|
|
*/
|
|
|
|
import { stdin } from 'process';
|
|
import { STANDARD_HOOK_RESPONSE } from './hook-response.js';
|
|
import { logger } from '../utils/logger.js';
|
|
import { ensureWorkerRunning, getWorkerPort } from '../shared/worker-utils.js';
|
|
import { HOOK_TIMEOUTS } from '../shared/hook-constants.js';
|
|
import { extractLastMessage } from '../shared/transcript-parser.js';
|
|
|
|
export interface StopInput {
|
|
session_id: string;
|
|
cwd: string;
|
|
transcript_path: string;
|
|
}
|
|
|
|
/**
|
|
* Summary Hook Main Logic - Fire-and-forget HTTP client
|
|
*/
|
|
async function summaryHook(input?: StopInput): Promise<void> {
|
|
// Ensure worker is running before any other logic
|
|
await ensureWorkerRunning();
|
|
|
|
if (!input) {
|
|
throw new Error('summaryHook requires input');
|
|
}
|
|
|
|
const { session_id } = input;
|
|
|
|
const port = getWorkerPort();
|
|
|
|
// Validate required fields before processing
|
|
if (!input.transcript_path) {
|
|
throw new Error(`Missing transcript_path in Stop hook input for session ${session_id}`);
|
|
}
|
|
|
|
// Extract last assistant message from transcript (the work Claude did)
|
|
// Note: "user" messages in transcripts are mostly tool_results, not actual user input.
|
|
// The user's original request is already stored in user_prompts table.
|
|
const lastAssistantMessage = extractLastMessage(input.transcript_path, 'assistant', true);
|
|
|
|
logger.dataIn('HOOK', 'Stop: Requesting summary', {
|
|
workerPort: port,
|
|
hasLastAssistantMessage: !!lastAssistantMessage
|
|
});
|
|
|
|
// Send to worker - worker handles privacy check and database operations
|
|
const response = await fetch(`http://127.0.0.1:${port}/api/sessions/summarize`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
contentSessionId: session_id,
|
|
last_assistant_message: lastAssistantMessage
|
|
})
|
|
// Note: Removed signal to avoid Windows Bun cleanup issue (libuv assertion)
|
|
});
|
|
|
|
if (!response.ok) {
|
|
console.log(STANDARD_HOOK_RESPONSE);
|
|
throw new Error(`Summary generation failed: ${response.status}`);
|
|
}
|
|
|
|
logger.debug('HOOK', 'Summary request sent successfully');
|
|
|
|
console.log(STANDARD_HOOK_RESPONSE);
|
|
}
|
|
|
|
// Entry Point
|
|
let input = '';
|
|
stdin.on('data', (chunk) => input += chunk);
|
|
stdin.on('end', async () => {
|
|
let parsed: StopInput | undefined;
|
|
try {
|
|
parsed = input ? JSON.parse(input) : undefined;
|
|
} catch (error) {
|
|
throw new Error(`Failed to parse hook input: ${error instanceof Error ? error.message : String(error)}`);
|
|
}
|
|
await summaryHook(parsed);
|
|
});
|