mirror of
https://github.com/thedotmack/claude-mem
synced 2026-04-25 17:15:04 +02:00
* Refactor worker version checks and increase timeout settings - Updated the default hook timeout from 5000ms to 120000ms for improved stability. - Modified the worker version check to log a warning instead of restarting the worker on version mismatch. - Removed legacy PM2 cleanup and worker start logic, simplifying the ensureWorkerRunning function. - Enhanced polling mechanism for worker readiness with increased retries and reduced interval. * feat: implement worker queue polling to ensure processing completion before proceeding * refactor: change worker command from start to restart in hooks configuration * refactor: remove session management complexity - Simplify createSDKSession to pure INSERT OR IGNORE - Remove auto-create logic from storeObservation/storeSummary - Delete 11 unused session management methods - Derive prompt_number from user_prompts count - Keep sdk_sessions table schema unchanged for compatibility * refactor: simplify session management by removing unused methods and auto-creation logic * Refactor session prompt number retrieval in SessionRoutes - Updated the method of obtaining the prompt number from the session. - Replaced `store.getPromptCounter(sessionDbId)` with `store.getPromptNumberFromUserPrompts(claudeSessionId)` for better clarity and accuracy. - Adjusted the logic for incrementing the prompt number to derive it from the user prompts count instead of directly incrementing a counter. * refactor: replace getPromptCounter with getPromptNumberFromUserPrompts in SessionManager Phase 7 of session management simplification. Updates SessionManager to derive prompt numbers from user_prompts table count instead of using the deprecated prompt_counter column. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * refactor: simplify SessionCompletionHandler to use direct SQL query Phase 8: Remove call to findActiveSDKSession() and replace with direct database query in SessionCompletionHandler.completeByClaudeId(). This removes dependency on the deleted findActiveSDKSession() method and simplifies the code by using a straightforward SELECT query. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * refactor: remove markSessionCompleted call from SDKAgent - Delete call to markSessionCompleted() in SDKAgent.ts - Session status is no longer tracked or updated - Part of phase 9: simplifying session management 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * refactor: remove markSessionComplete method (Phase 10) - Deleted markSessionComplete() method from DatabaseManager - Removed markSessionComplete call from SessionCompletionHandler - Session completion status no longer tracked in database - Part of session management simplification effort 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * refactor: replace deleted updateSDKSessionId calls in import script (Phase 11) - Replace updateSDKSessionId() calls with direct SQL UPDATE statements - Method was deleted in Phase 3 as part of session management simplification - Import script now uses direct database access consistently 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * test: add validation for SQL updates in sdk_sessions table * refactor: enhance worker-cli to support manual and automated runs * Remove cleanup hook and associated session completion logic - Deleted the cleanup-hook implementation from the hooks directory. - Removed the session completion endpoint that was used by the cleanup hook. - Updated the SessionCompletionHandler to eliminate the completeByClaudeId method and its dependencies. - Adjusted the SessionRoutes to reflect the removal of the session completion route. * fix: update worker-cli command to use bun for consistency * feat: Implement timestamp fix for observations and enhance processing logic - Added `earliestPendingTimestamp` to `ActiveSession` to track the original timestamp of the earliest pending message. - Updated `SDKAgent` to capture and utilize the earliest pending timestamp during response processing. - Modified `SessionManager` to track the earliest timestamp when yielding messages. - Created scripts for fixing corrupted timestamps, validating fixes, and investigating timestamp issues. - Verified that all corrupted observations have been repaired and logic for future processing is sound. - Ensured orphan processing can be safely re-enabled after validation. * feat: Enhance SessionStore to support custom database paths and add timestamp fields for observations and summaries * Refactor pending queue processing and add management endpoints - Disabled automatic recovery of orphaned queues on startup; users must now use the new /api/pending-queue/process endpoint. - Updated processOrphanedQueues method to processPendingQueues with improved session handling and return detailed results. - Added new API endpoints for managing pending queues: GET /api/pending-queue and POST /api/pending-queue/process. - Introduced a new script (check-pending-queue.ts) for checking and processing pending observation queues interactively or automatically. - Enhanced logging and error handling for better monitoring of session processing. * updated agent sdk * feat: Add manual recovery guide and queue management endpoints to documentation --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
145 lines
5.6 KiB
TypeScript
Executable File
145 lines
5.6 KiB
TypeScript
Executable File
#!/usr/bin/env bun
|
||
|
||
/**
|
||
* Verify Timestamp Fix
|
||
*
|
||
* This script verifies that the timestamp corruption has been properly fixed.
|
||
* It checks for any remaining observations in the bad window that shouldn't be there.
|
||
*/
|
||
|
||
import Database from 'bun:sqlite';
|
||
import { resolve } from 'path';
|
||
|
||
const DB_PATH = resolve(process.env.HOME!, '.claude-mem/claude-mem.db');
|
||
|
||
// Bad window: Dec 24 19:45-20:31 (using actual epoch format from database)
|
||
const BAD_WINDOW_START = 1766623500000; // Dec 24 19:45 PST
|
||
const BAD_WINDOW_END = 1766626260000; // Dec 24 20:31 PST
|
||
|
||
// Original corruption window: Dec 16-22 (when sessions actually started)
|
||
const ORIGINAL_WINDOW_START = 1765914000000; // Dec 16 00:00 PST
|
||
const ORIGINAL_WINDOW_END = 1766613600000; // Dec 23 23:59 PST
|
||
|
||
interface Observation {
|
||
id: number;
|
||
sdk_session_id: string;
|
||
created_at_epoch: number;
|
||
created_at: string;
|
||
title: string;
|
||
}
|
||
|
||
function formatTimestamp(epoch: number): string {
|
||
return new Date(epoch).toLocaleString('en-US', {
|
||
timeZone: 'America/Los_Angeles',
|
||
year: 'numeric',
|
||
month: 'short',
|
||
day: 'numeric',
|
||
hour: '2-digit',
|
||
minute: '2-digit',
|
||
second: '2-digit'
|
||
});
|
||
}
|
||
|
||
function main() {
|
||
console.log('🔍 Verifying timestamp fix...\n');
|
||
|
||
const db = new Database(DB_PATH);
|
||
|
||
try {
|
||
// Check 1: Observations still in bad window
|
||
console.log('Check 1: Looking for observations still in bad window (Dec 24 19:45-20:31)...');
|
||
const badWindowObs = db.query<Observation, []>(`
|
||
SELECT id, sdk_session_id, created_at_epoch, created_at, title
|
||
FROM observations
|
||
WHERE created_at_epoch >= ${BAD_WINDOW_START}
|
||
AND created_at_epoch <= ${BAD_WINDOW_END}
|
||
ORDER BY id
|
||
`).all();
|
||
|
||
if (badWindowObs.length === 0) {
|
||
console.log('✅ No observations found in bad window - GOOD!\n');
|
||
} else {
|
||
console.log(`⚠️ Found ${badWindowObs.length} observations still in bad window:\n`);
|
||
for (const obs of badWindowObs) {
|
||
console.log(` Observation #${obs.id}: ${obs.title || '(no title)'}`);
|
||
console.log(` Timestamp: ${formatTimestamp(obs.created_at_epoch)}`);
|
||
console.log(` Session: ${obs.sdk_session_id}\n`);
|
||
}
|
||
}
|
||
|
||
// Check 2: Observations now in original window
|
||
console.log('Check 2: Counting observations in original window (Dec 17-20)...');
|
||
const originalWindowObs = db.query<{ count: number }, []>(`
|
||
SELECT COUNT(*) as count
|
||
FROM observations
|
||
WHERE created_at_epoch >= ${ORIGINAL_WINDOW_START}
|
||
AND created_at_epoch <= ${ORIGINAL_WINDOW_END}
|
||
`).get();
|
||
|
||
console.log(`Found ${originalWindowObs?.count || 0} observations in Dec 17-20 window`);
|
||
console.log('(These should be the corrected observations)\n');
|
||
|
||
// Check 3: Session distribution
|
||
console.log('Check 3: Session distribution of corrected observations...');
|
||
const sessionDist = db.query<{ sdk_session_id: string; count: number }, []>(`
|
||
SELECT sdk_session_id, COUNT(*) as count
|
||
FROM observations
|
||
WHERE created_at_epoch >= ${ORIGINAL_WINDOW_START}
|
||
AND created_at_epoch <= ${ORIGINAL_WINDOW_END}
|
||
GROUP BY sdk_session_id
|
||
ORDER BY count DESC
|
||
`).all();
|
||
|
||
if (sessionDist.length > 0) {
|
||
console.log(`Observations distributed across ${sessionDist.length} sessions:\n`);
|
||
for (const dist of sessionDist.slice(0, 10)) {
|
||
console.log(` ${dist.sdk_session_id}: ${dist.count} observations`);
|
||
}
|
||
if (sessionDist.length > 10) {
|
||
console.log(` ... and ${sessionDist.length - 10} more sessions`);
|
||
}
|
||
console.log();
|
||
}
|
||
|
||
// Check 4: Pending messages processed count
|
||
console.log('Check 4: Verifying processed pending_messages...');
|
||
const processedCount = db.query<{ count: number }, []>(`
|
||
SELECT COUNT(*) as count
|
||
FROM pending_messages
|
||
WHERE status = 'processed'
|
||
AND completed_at_epoch >= ${BAD_WINDOW_START}
|
||
AND completed_at_epoch <= ${BAD_WINDOW_END}
|
||
`).get();
|
||
|
||
console.log(`${processedCount?.count || 0} pending messages were processed during bad window\n`);
|
||
|
||
// Summary
|
||
console.log('═══════════════════════════════════════════════════════════════════════');
|
||
console.log('VERIFICATION SUMMARY:');
|
||
console.log('═══════════════════════════════════════════════════════════════════════\n');
|
||
|
||
if (badWindowObs.length === 0 && (originalWindowObs?.count || 0) > 0) {
|
||
console.log('✅ SUCCESS: Timestamp fix appears to be working correctly!');
|
||
console.log(` - No observations remain in bad window (Dec 24 19:45-20:31)`);
|
||
console.log(` - ${originalWindowObs?.count} observations restored to Dec 17-20`);
|
||
console.log(` - Processed ${processedCount?.count} pending messages`);
|
||
console.log('\n💡 Safe to re-enable orphan processing in worker-service.ts\n');
|
||
} else if (badWindowObs.length > 0) {
|
||
console.log('⚠️ WARNING: Some observations still have incorrect timestamps!');
|
||
console.log(` - ${badWindowObs.length} observations still in bad window`);
|
||
console.log(' - Run fix-corrupted-timestamps.ts again or investigate manually\n');
|
||
} else {
|
||
console.log('ℹ️ No corrupted observations detected');
|
||
console.log(' - Either already fixed or corruption never occurred\n');
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('❌ Error:', error);
|
||
process.exit(1);
|
||
} finally {
|
||
db.close();
|
||
}
|
||
}
|
||
|
||
main();
|