Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions Releases/v2.5/.claude/hooks/AgentOutputCapture.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ async function delay(ms: number): Promise<void> {
}

async function findTaskResult(transcriptPath: string, maxAttempts: number = 2): Promise<{ result: string | null, agentType: string | null, description: string | null, toolInput: any | null }> {
console.error(`📂 Looking for Task result in transcript: ${transcriptPath}`);
// Looking for Task result in transcript

// If the provided transcript path doesn't exist, try to find the most recent agent transcript
let actualTranscriptPath = transcriptPath;
Expand All @@ -101,7 +101,7 @@ async function findTaskResult(transcriptPath: string, maxAttempts: number = 2):
}

if (!existsSync(actualTranscriptPath)) {
console.error(`❌ Transcript file doesn't exist: ${actualTranscriptPath} (attempt ${attempt + 1}/${maxAttempts})`);
// Transcript file doesn't exist yet

// Try to find agent transcript in the same directory
const dir = require('path').dirname(transcriptPath);
Expand All @@ -114,7 +114,7 @@ async function findTaskResult(transcriptPath: string, maxAttempts: number = 2):

if (files.length > 0) {
actualTranscriptPath = join(dir, files[0].name);
console.error(`🔄 Found recent agent transcript: ${actualTranscriptPath}`);
// Found recent agent transcript
}
}

Expand All @@ -138,7 +138,7 @@ async function findTaskResult(transcriptPath: string, maxAttempts: number = 2):
if (content.type === 'tool_use' && content.name === 'Task') {
const toolInput = content.input;
const description = toolInput?.description || null;
console.error(`✅ Found Task invocation with subagent: ${toolInput?.subagent_type}, description: ${description}`);
// Found Task invocation
// Found a Task invocation, now look for its result
// The result should be in a subsequent user message
for (let j = i + 1; j < lines.length; j++) {
Expand All @@ -158,7 +158,7 @@ async function findTaskResult(transcriptPath: string, maxAttempts: number = 2):
.map((item: any) => item.text)
.join('\n');
} else {
console.error('❌ Unexpected tool_result content type');
// Unexpected tool_result content type
continue;
}

Expand Down Expand Up @@ -190,9 +190,7 @@ async function findTaskResult(transcriptPath: string, maxAttempts: number = 2):
}

function extractCompletionMessage(taskOutput: string): { message: string | null, agentType: string | null } {
console.error('🔍 DEBUG - Extracting from task output, length:', taskOutput.length);
console.error('🔍 DEBUG - First 200 chars:', taskOutput.substring(0, 200));
console.error('🔍 DEBUG - Last 200 chars:', taskOutput.substring(taskOutput.length - 200));
// Debug extraction from task output

// Look for the COMPLETED section in the agent's output
// Priority: 1) New 🗣️ format, 2) Legacy [AGENT:type] format
Expand Down Expand Up @@ -246,7 +244,7 @@ function extractCompletionMessage(taskOutput: string): { message: string | null,
? message // Just the message for greetings/questions/status
: `${agentName} completed ${message}`; // Prepend "completed" for tasks

console.error(`✅ FOUND AGENT MATCH: [${agentType}] ${fullMessage}`);
// Found agent match

// Return agent type and message
return { message: fullMessage, agentType };
Expand Down Expand Up @@ -306,7 +304,7 @@ async function main() {
function debug(msg: string) {
const timestamp = new Date().toISOString();
appendFileSync(debugLog, `[${timestamp}] ${msg}\n`);
console.error(msg);
// No stderr output - write to debug log file only
}

debug('🔍 SubagentStop hook started');
Expand Down Expand Up @@ -396,7 +394,7 @@ async function main() {
try {
await captureAgentOutput(finalAgentType, completionMessage, taskOutput, transcriptPath);
} catch (e) {
console.error('Failed to capture agent output:', e);
// Failed to capture agent output - non-critical
}

// Send push notification for background agents
Expand Down Expand Up @@ -539,4 +537,4 @@ ${taskOutput}
console.log(`📝 UOCS: Captured agent output to ${category}/${yearMonth}/${filename}`);
}

main().catch(console.error);
main().catch(() => { /* silent fail */ });
15 changes: 7 additions & 8 deletions Releases/v2.5/.claude/hooks/AutoWorkCreation.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ status: "ACTIVE"
`;
writeFileSync(join(sessionPath, 'META.yaml'), meta, 'utf-8');

console.error(`[AutoWork] Created session: ${sessionPath}`);
// Created session directory
return sessionPath;
}

Expand Down Expand Up @@ -227,7 +227,7 @@ _Important observations during execution..._
} catch { /* ignore if doesn't exist */ }
symlinkSync(taskDirName, currentLink);

console.error(`[AutoWork] Created task: ${taskPath}`);
// Created task directory
return taskDirName;
}

Expand Down Expand Up @@ -263,7 +263,7 @@ async function classifyPrompt(prompt: string, hasExistingSession: boolean): Prom
};
}
} catch (err) {
console.error(`[AutoWork] Classification failed: ${err}`);
// Classification failed - using fallback
}

// Fallback
Expand Down Expand Up @@ -295,7 +295,7 @@ async function main() {

// Skip task creation for pure conversational
if (classification.type === 'conversational' && !classification.is_new_topic) {
console.error('[AutoWork] Conversational continuation, no new task');
// Conversational continuation, no new task
process.exit(0);
}

Expand All @@ -322,7 +322,7 @@ async function main() {
};
writeCurrentWork(currentWork);

console.error(`[AutoWork] New session with task: ${taskDirName}`);
// New session with task created
} else if (classification.is_new_topic) {
// Existing session, new topic: create new task
const sessionPath = join(WORK_DIR, currentWork!.session_dir);
Expand All @@ -341,15 +341,14 @@ async function main() {
currentWork!.task_count = newTaskNumber;
writeCurrentWork(currentWork!);

console.error(`[AutoWork] New task in session: ${taskDirName}`);
// New task in session
} else {
// Continuation of current task - no new task needed
console.error(`[AutoWork] Continuing task: ${currentWork!.current_task}`);
}

process.exit(0);
} catch (err) {
console.error(`[AutoWork] Error: ${err}`);
// AutoWork error - non-blocking
process.exit(0);
}
}
Expand Down
2 changes: 1 addition & 1 deletion Releases/v2.5/.claude/hooks/CheckVersion.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ async function main() {
]);

if (currentVersion !== 'unknown' && latestVersion !== 'unknown' && currentVersion !== latestVersion) {
console.error(`💡 Update available: CC ${currentVersion} → ${latestVersion}`);
// Update available - not surfaced to stderr to avoid false hook errors
}

process.exit(0);
Expand Down
20 changes: 10 additions & 10 deletions Releases/v2.5/.claude/hooks/ExplicitRatingCapture.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ function writeRating(entry: RatingEntry): void {
const jsonLine = JSON.stringify(entry) + '\n';
appendFileSync(ratingsFile, jsonLine, 'utf-8');

console.error(`[ExplicitRatingCapture] Wrote rating ${entry.rating} to ${ratingsFile}`);
// Wrote rating to ratings file
}

/**
Expand Down Expand Up @@ -231,24 +231,24 @@ ${comment ? `**${getPrincipalName()}'s feedback:** ${comment}` : ''}
`;

writeFileSync(filepath, content, 'utf-8');
console.error(`[ExplicitRatingCapture] Captured low rating learning to ${filepath}`);
// Captured low rating learning
}

async function main() {
try {
console.error('[ExplicitRatingCapture] Hook started');
// ExplicitRatingCapture hook started
const input = await readStdinWithTimeout();
const data: HookInput = JSON.parse(input);
const prompt = data.prompt || '';

const result = parseRating(prompt);

if (!result) {
console.error('[ExplicitRatingCapture] Not a rating, exiting');
// Not a rating, exiting
process.exit(0);
}

console.error(`[ExplicitRatingCapture] Detected rating: ${result.rating}${result.comment ? ` - ${result.comment}` : ''}`);
// Detected explicit rating

const entry: RatingEntry = {
timestamp: getISOTimestamp(),
Expand All @@ -269,7 +269,7 @@ async function main() {
stdout: 'ignore',
stderr: 'ignore'
});
console.error('[ExplicitRatingCapture] Triggered TrendingAnalysis update');
// Triggered TrendingAnalysis update
}

if (result.rating < 6) {
Expand All @@ -286,17 +286,17 @@ async function main() {
detailedContext: responseContext,
sessionId: data.session_id,
});
console.error(`[ExplicitRatingCapture] Created full failure capture for rating ${result.rating}`);
// Created full failure capture
} catch (err) {
console.error(`[ExplicitRatingCapture] Error creating failure capture: ${err}`);
// Error creating failure capture - non-critical
}
}
}

console.error('[ExplicitRatingCapture] Done');
// ExplicitRatingCapture done
process.exit(0);
} catch (err) {
console.error(`[ExplicitRatingCapture] Error: ${err}`);
// ExplicitRatingCapture error - non-blocking
process.exit(0);
}
}
Expand Down
30 changes: 15 additions & 15 deletions Releases/v2.5/.claude/hooks/ImplicitSentimentCapture.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ async function analyzeSentiment(prompt: string, context: string): Promise<Sentim
});

if (!result.success || !result.parsed) {
console.error(`[ImplicitSentimentCapture] Inference failed: ${result.error}`);
// Inference failed
return null;
}

Expand All @@ -290,7 +290,7 @@ function writeImplicitRating(entry: ImplicitRatingEntry): void {
}

appendFileSync(ratingsFile, JSON.stringify(entry) + '\n', 'utf-8');
console.error(`[ImplicitSentimentCapture] Wrote implicit rating ${entry.rating} to ${ratingsFile}`);
// Wrote implicit rating to ratings file
}

/**
Expand Down Expand Up @@ -388,25 +388,25 @@ This response triggered a ${rating}/10 implicit rating based on detected user se
`;

writeFileSync(filepath, content, 'utf-8');
console.error(`[ImplicitSentimentCapture] Captured low rating learning to ${filepath}`);
// Captured low rating learning
}

async function main() {
try {
console.error('[ImplicitSentimentCapture] Hook started');
// ImplicitSentimentCapture hook started
const input = await readStdinWithTimeout();
const data: HookInput = JSON.parse(input);
// The payload uses 'prompt' (Claude Code) - user_prompt is legacy
const prompt = data.prompt || data.user_prompt || '';

// Skip if explicit rating (let ExplicitRatingCapture handle)
if (isExplicitRating(prompt)) {
console.error('[ImplicitSentimentCapture] Explicit rating detected, deferring to ExplicitRatingCapture');
// Explicit rating detected, deferring to ExplicitRatingCapture
process.exit(0);
}

if (prompt.length < MIN_PROMPT_LENGTH) {
console.error('[ImplicitSentimentCapture] Prompt too short, exiting');
// Prompt too short, exiting
process.exit(0);
}

Expand All @@ -420,22 +420,22 @@ async function main() {
const sentiment = await Promise.race([analysisPromise, timeoutPromise]);

if (!sentiment) {
console.error('[ImplicitSentimentCapture] Analysis failed or timed out');
// Analysis failed or timed out
process.exit(0);
}

// Neutral sentiment gets rating 5 (baseline for feature requests)
if (sentiment.rating === null) {
sentiment.rating = 5;
console.error('[ImplicitSentimentCapture] Neutral sentiment, assigning baseline rating 5');
// Neutral sentiment, assigning baseline rating 5
}

if (sentiment.confidence < MIN_CONFIDENCE) {
console.error(`[ImplicitSentimentCapture] Low confidence (${sentiment.confidence}), not logging`);
// Low confidence, not logging
process.exit(0);
}

console.error(`[ImplicitSentimentCapture] Detected: ${sentiment.rating}/10 - ${sentiment.summary}`);
// Detected sentiment rating

const entry: ImplicitRatingEntry = {
timestamp: getISOTimestamp(),
Expand All @@ -456,7 +456,7 @@ async function main() {
stdout: 'ignore',
stderr: 'ignore'
});
console.error('[ImplicitSentimentCapture] Triggered TrendingAnalysis update');
// Triggered TrendingAnalysis update
}

if (sentiment.rating < 6) {
Expand All @@ -477,17 +477,17 @@ async function main() {
detailedContext: sentiment.detailed_context || '',
sessionId: data.session_id,
});
console.error(`[ImplicitSentimentCapture] Created full failure capture for rating ${sentiment.rating}`);
// Created full failure capture
} catch (err) {
console.error(`[ImplicitSentimentCapture] Error creating failure capture: ${err}`);
// Error creating failure capture - non-critical
}
}
}

console.error('[ImplicitSentimentCapture] Done');
// ImplicitSentimentCapture done
process.exit(0);
} catch (err) {
console.error(`[ImplicitSentimentCapture] Error: ${err}`);
// ImplicitSentimentCapture error - non-blocking
process.exit(0);
}
}
Expand Down
Loading