claude-recall 0.2.10 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -0
- package/dist/cli/claude-recall-cli.js +13 -2
- package/dist/cli/commands/live-test.js +245 -0
- package/dist/hooks/minimal/post-tool-trigger.js +117 -0
- package/dist/hooks/minimal/pre-tool-trigger.js +117 -0
- package/dist/hooks/minimal/user-prompt-submit-trigger.js +117 -0
- package/dist/mcp/queue-tools.js +532 -0
- package/dist/mcp/server.js +26 -2
- package/dist/mcp/tools/live-testing-tools.js +231 -0
- package/dist/mcp/tools/test-tools.js +320 -0
- package/dist/scripts/claude-integration.js +318 -0
- package/dist/scripts/fix-test-timeouts.js +77 -0
- package/dist/scripts/install.js +138 -0
- package/dist/scripts/live-mcp-test.sh +138 -0
- package/dist/scripts/mcp-postinstall.js +27 -0
- package/dist/scripts/platform-utils.js +258 -0
- package/dist/scripts/production-checklist.sh +104 -0
- package/dist/scripts/test-claude-code-integration.sh +38 -0
- package/dist/scripts/test-memory-search.sh +67 -0
- package/dist/scripts/test-persistence.sh +55 -0
- package/dist/scripts/test-rate-limiting.sh +63 -0
- package/dist/scripts/uninstall.js +100 -0
- package/dist/services/hook.js +507 -0
- package/dist/services/queue-api.js +549 -0
- package/dist/services/queue-consolidation.js +303 -0
- package/dist/services/queue-integration.js +378 -0
- package/dist/services/queue-migration.js +415 -0
- package/dist/services/queue-system-fixed.js +826 -0
- package/dist/services/queue-system.js +962 -0
- package/dist/services/restart-continuity.js +351 -0
- package/dist/testing/auto-correction-engine.js +338 -0
- package/dist/testing/live-testing-manager.js +402 -0
- package/dist/testing/mock-claude.js +249 -0
- package/dist/testing/observable-database.js +178 -0
- package/dist/testing/scenario-runner.js +354 -0
- package/dist/testing/test-orchestrator.js +328 -0
- package/docs/AI_TESTING_ARCHITECTURE.md +351 -0
- package/docs/AI_TESTING_IMPLEMENTATION_SUMMARY.md +226 -0
- package/docs/hook-configuration-COMPLETED.md +85 -0
- package/docs/hook-configuration-implementation-required.md +329 -0
- package/docs/sqlite-queue-implementation-final-review.md +219 -0
- package/docs/sqlite-queue-implementation-final-status.md +268 -0
- package/docs/sqlite-queue-implementation-fixes-summary.md +215 -0
- package/docs/sqlite-queue-implementation-fixes.md +255 -0
- package/docs/sqlite-queue-implementation-for-hooks-and-mcp-integration.md +428 -0
- package/docs/sqlite-queue-implementation-improvements-summary.md +211 -0
- package/docs/sqlite-queue-implementation-issues-5.md +211 -0
- package/docs/sqlite-queue-implementation-issues-6.md +273 -0
- package/docs/sqlite-queue-implementation-issues-7.md +253 -0
- package/docs/sqlite-queue-implementation-issues-8.md +252 -0
- package/docs/sqlite-queue-implementation-review.md +275 -0
- package/docs/test-isolation-improvements.md +222 -0
- package/package.json +3 -9
package/README.md
CHANGED
|
@@ -16,6 +16,8 @@ Every time you start a new conversation with Claude, you're starting from scratc
|
|
|
16
16
|
- **MCP Native**: Built on Anthropic's official Model Context Protocol for seamless integration
|
|
17
17
|
- **Zero Configuration**: Start capturing memories immediately after installation
|
|
18
18
|
- **Lightweight**: SQLite database with automatic memory management
|
|
19
|
+
- **Restart Continuity**: Maintains state across Claude Code restarts for uninterrupted workflows
|
|
20
|
+
- **Live Testing**: AI-driven testing with automatic restart and recovery capabilities
|
|
19
21
|
|
|
20
22
|
## 🚀 Quick Start
|
|
21
23
|
|
|
@@ -169,6 +171,40 @@ No manual configuration needed!
|
|
|
169
171
|
- **You Own Your Data**: Export and delete at any time
|
|
170
172
|
- **Open Source**: Inspect the code yourself
|
|
171
173
|
|
|
174
|
+
## Restart Continuity & Live Testing (v0.2.11+)
|
|
175
|
+
|
|
176
|
+
Claude Recall now includes advanced restart continuity and live testing capabilities, ensuring your workflows continue seamlessly even when Claude Code needs to restart.
|
|
177
|
+
|
|
178
|
+
### Restart Continuity
|
|
179
|
+
|
|
180
|
+
Maintains state across Claude Code restarts:
|
|
181
|
+
- **Automatic Recovery**: Resumes interrupted tests and workflows after restart
|
|
182
|
+
- **Checkpoint System**: Save progress points for granular recovery
|
|
183
|
+
- **Session Tracking**: Preserves session context through restarts
|
|
184
|
+
- **Pending Actions**: Queues actions to be processed after restart
|
|
185
|
+
|
|
186
|
+
### Live Testing
|
|
187
|
+
|
|
188
|
+
AI-driven testing with automatic restart capability:
|
|
189
|
+
```bash
|
|
190
|
+
# Start live testing with auto-restart
|
|
191
|
+
claude-recall live-test start -s memory_persistence search_compliance
|
|
192
|
+
|
|
193
|
+
# Check status
|
|
194
|
+
claude-recall live-test status
|
|
195
|
+
|
|
196
|
+
# View continuity state
|
|
197
|
+
claude-recall live-test continuity
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Features:**
|
|
201
|
+
- **Auto-Restart on Changes**: Detects hook/CLI changes and restarts automatically
|
|
202
|
+
- **Test Recovery**: Resumes tests from last checkpoint after restart
|
|
203
|
+
- **Result Injection**: Test results stored as searchable memories
|
|
204
|
+
- **Configurable Policies**: Control restart behavior and limits
|
|
205
|
+
|
|
206
|
+
See [RESTART_CONTINUITY.md](docs/RESTART_CONTINUITY.md) for detailed documentation.
|
|
207
|
+
|
|
172
208
|
## Advanced Usage
|
|
173
209
|
|
|
174
210
|
### Custom Memory Storage
|
|
@@ -43,6 +43,7 @@ const pattern_service_1 = require("../services/pattern-service");
|
|
|
43
43
|
const migrate_1 = require("./commands/migrate");
|
|
44
44
|
const server_1 = require("../mcp/server");
|
|
45
45
|
const search_monitor_1 = require("../services/search-monitor");
|
|
46
|
+
const live_test_1 = require("./commands/live-test");
|
|
46
47
|
const program = new commander_1.Command();
|
|
47
48
|
class ClaudeRecallCLI {
|
|
48
49
|
constructor(options) {
|
|
@@ -252,7 +253,7 @@ async function main() {
|
|
|
252
253
|
program
|
|
253
254
|
.name('claude-recall')
|
|
254
255
|
.description('Memory-enhanced Claude Code via MCP')
|
|
255
|
-
.version('0.2.
|
|
256
|
+
.version('0.2.12')
|
|
256
257
|
.option('--verbose', 'Enable verbose logging')
|
|
257
258
|
.option('--config <path>', 'Path to custom config file');
|
|
258
259
|
// MCP command
|
|
@@ -318,6 +319,8 @@ async function main() {
|
|
|
318
319
|
});
|
|
319
320
|
// Migration commands
|
|
320
321
|
migrate_1.MigrateCommand.register(program);
|
|
322
|
+
// Register live test command
|
|
323
|
+
new live_test_1.LiveTestCommand().register(program);
|
|
321
324
|
// Search command
|
|
322
325
|
program
|
|
323
326
|
.command('search <query>')
|
|
@@ -330,6 +333,7 @@ async function main() {
|
|
|
330
333
|
limit: parseInt(options.limit),
|
|
331
334
|
json: options.json
|
|
332
335
|
});
|
|
336
|
+
process.exit(0);
|
|
333
337
|
});
|
|
334
338
|
// Stats command
|
|
335
339
|
program
|
|
@@ -338,6 +342,7 @@ async function main() {
|
|
|
338
342
|
.action(() => {
|
|
339
343
|
const cli = new ClaudeRecallCLI(program.opts());
|
|
340
344
|
cli.showStats();
|
|
345
|
+
process.exit(0);
|
|
341
346
|
});
|
|
342
347
|
// Export command
|
|
343
348
|
program
|
|
@@ -347,6 +352,7 @@ async function main() {
|
|
|
347
352
|
.action(async (output, options) => {
|
|
348
353
|
const cli = new ClaudeRecallCLI(program.opts());
|
|
349
354
|
await cli.export(output, options);
|
|
355
|
+
process.exit(0);
|
|
350
356
|
});
|
|
351
357
|
// Import command
|
|
352
358
|
program
|
|
@@ -355,6 +361,7 @@ async function main() {
|
|
|
355
361
|
.action(async (input) => {
|
|
356
362
|
const cli = new ClaudeRecallCLI(program.opts());
|
|
357
363
|
await cli.import(input);
|
|
364
|
+
process.exit(0);
|
|
358
365
|
});
|
|
359
366
|
// Clear command
|
|
360
367
|
program
|
|
@@ -365,6 +372,7 @@ async function main() {
|
|
|
365
372
|
.action(async (options) => {
|
|
366
373
|
const cli = new ClaudeRecallCLI(program.opts());
|
|
367
374
|
await cli.clear(options);
|
|
375
|
+
process.exit(0);
|
|
368
376
|
});
|
|
369
377
|
// Status command
|
|
370
378
|
program
|
|
@@ -373,6 +381,7 @@ async function main() {
|
|
|
373
381
|
.action(async () => {
|
|
374
382
|
const cli = new ClaudeRecallCLI(program.opts());
|
|
375
383
|
await cli.status();
|
|
384
|
+
process.exit(0);
|
|
376
385
|
});
|
|
377
386
|
// Test memory search command
|
|
378
387
|
program
|
|
@@ -412,6 +421,7 @@ async function main() {
|
|
|
412
421
|
}
|
|
413
422
|
console.log('\n📊 Memory search monitoring is active.');
|
|
414
423
|
console.log(' Check logs to verify search calls are being made.\n');
|
|
424
|
+
process.exit(0);
|
|
415
425
|
});
|
|
416
426
|
// Search monitor command
|
|
417
427
|
program
|
|
@@ -423,7 +433,7 @@ async function main() {
|
|
|
423
433
|
if (options.clear) {
|
|
424
434
|
monitor.clearLogs();
|
|
425
435
|
console.log('✅ Search monitoring logs cleared.\n');
|
|
426
|
-
|
|
436
|
+
process.exit(0);
|
|
427
437
|
}
|
|
428
438
|
console.log('\n📊 Memory Search Monitoring Statistics\n');
|
|
429
439
|
const stats = monitor.getSearchStats();
|
|
@@ -459,6 +469,7 @@ async function main() {
|
|
|
459
469
|
});
|
|
460
470
|
}
|
|
461
471
|
console.log('\n');
|
|
472
|
+
process.exit(0);
|
|
462
473
|
});
|
|
463
474
|
// Parse arguments
|
|
464
475
|
await program.parseAsync(process.argv);
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LiveTestCommand = void 0;
|
|
4
|
+
const live_testing_manager_1 = require("../../testing/live-testing-manager");
|
|
5
|
+
const restart_continuity_1 = require("../../services/restart-continuity");
|
|
6
|
+
const logging_1 = require("../../services/logging");
|
|
7
|
+
class LiveTestCommand {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.liveTestManager = live_testing_manager_1.LiveTestingManager.getInstance();
|
|
10
|
+
this.continuityManager = restart_continuity_1.RestartContinuityManager.getInstance();
|
|
11
|
+
this.logger = logging_1.LoggingService.getInstance();
|
|
12
|
+
}
|
|
13
|
+
register(program) {
|
|
14
|
+
const liveTestCmd = program
|
|
15
|
+
.command('live-test')
|
|
16
|
+
.description('Manage live testing with automatic restart capability');
|
|
17
|
+
// Start live testing
|
|
18
|
+
liveTestCmd
|
|
19
|
+
.command('start')
|
|
20
|
+
.description('Start a live testing session')
|
|
21
|
+
.option('-s, --scenario <scenarios...>', 'Test scenarios to run', ['memory_persistence', 'search_compliance'])
|
|
22
|
+
.option('-a, --auto-restart', 'Enable automatic restart on changes', true)
|
|
23
|
+
.option('-r, --restart-on-failure', 'Restart on test failures', true)
|
|
24
|
+
.option('-m, --max-restarts <number>', 'Maximum restart attempts', '3')
|
|
25
|
+
.option('-i, --inject-results', 'Inject test results as memories', true)
|
|
26
|
+
.action(async (options) => {
|
|
27
|
+
await this.startLiveTest(options);
|
|
28
|
+
});
|
|
29
|
+
// Check status
|
|
30
|
+
liveTestCmd
|
|
31
|
+
.command('status')
|
|
32
|
+
.description('Check live testing and continuity status')
|
|
33
|
+
.action(() => {
|
|
34
|
+
this.showStatus();
|
|
35
|
+
});
|
|
36
|
+
// Stop testing
|
|
37
|
+
liveTestCmd
|
|
38
|
+
.command('stop')
|
|
39
|
+
.description('Stop the current live testing session')
|
|
40
|
+
.action(async () => {
|
|
41
|
+
await this.stopLiveTest();
|
|
42
|
+
});
|
|
43
|
+
// Check continuity
|
|
44
|
+
liveTestCmd
|
|
45
|
+
.command('continuity')
|
|
46
|
+
.description('Show continuity state and restart information')
|
|
47
|
+
.action(() => {
|
|
48
|
+
this.showContinuity();
|
|
49
|
+
});
|
|
50
|
+
// Add checkpoint
|
|
51
|
+
liveTestCmd
|
|
52
|
+
.command('checkpoint <name>')
|
|
53
|
+
.description('Add a checkpoint for restart recovery')
|
|
54
|
+
.action((name) => {
|
|
55
|
+
this.addCheckpoint(name);
|
|
56
|
+
});
|
|
57
|
+
// Simulate restart
|
|
58
|
+
liveTestCmd
|
|
59
|
+
.command('restart')
|
|
60
|
+
.description('Simulate a restart for testing')
|
|
61
|
+
.option('-r, --reason <reason>', 'Reason for restart', 'manual_test')
|
|
62
|
+
.action((options) => {
|
|
63
|
+
this.simulateRestart(options.reason);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
async startLiveTest(options) {
|
|
67
|
+
console.log('🚀 Starting Live Testing Session');
|
|
68
|
+
console.log('━'.repeat(50));
|
|
69
|
+
try {
|
|
70
|
+
// Parse scenarios
|
|
71
|
+
const scenarios = options.scenario.map((name) => ({
|
|
72
|
+
name,
|
|
73
|
+
params: {},
|
|
74
|
+
sessionId: `cli_${Date.now()}`
|
|
75
|
+
}));
|
|
76
|
+
// Configure live testing
|
|
77
|
+
this.liveTestManager.updateConfig({
|
|
78
|
+
autoRestart: options.autoRestart,
|
|
79
|
+
restartOnFailure: options.restartOnFailure,
|
|
80
|
+
maxRestartAttempts: parseInt(options.maxRestarts),
|
|
81
|
+
restartDelay: 2000,
|
|
82
|
+
watchFiles: [
|
|
83
|
+
'src/hooks/**/*.sh',
|
|
84
|
+
'src/cli/claude-recall-cli.ts',
|
|
85
|
+
'src/services/**/*.ts'
|
|
86
|
+
],
|
|
87
|
+
injectResults: options.injectResults
|
|
88
|
+
});
|
|
89
|
+
// Start session
|
|
90
|
+
const sessionId = await this.liveTestManager.startLiveTestSession(scenarios);
|
|
91
|
+
console.log('✅ Live testing session started');
|
|
92
|
+
console.log(`Session ID: ${sessionId}`);
|
|
93
|
+
console.log(`Scenarios: ${scenarios.map(s => s.name).join(', ')}`);
|
|
94
|
+
console.log();
|
|
95
|
+
console.log('Configuration:');
|
|
96
|
+
console.log(` • Auto-restart: ${options.autoRestart ? 'enabled' : 'disabled'}`);
|
|
97
|
+
console.log(` • Restart on failure: ${options.restartOnFailure ? 'enabled' : 'disabled'}`);
|
|
98
|
+
console.log(` • Max restarts: ${options.maxRestarts}`);
|
|
99
|
+
console.log(` • Inject results: ${options.injectResults ? 'enabled' : 'disabled'}`);
|
|
100
|
+
console.log();
|
|
101
|
+
console.log('Watching for file changes...');
|
|
102
|
+
console.log('Use "claude-recall live-test status" to check progress');
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
console.error('❌ Failed to start live testing:', error.message);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
showStatus() {
|
|
110
|
+
console.log('📊 Live Testing Status');
|
|
111
|
+
console.log('━'.repeat(50));
|
|
112
|
+
// Get live test status
|
|
113
|
+
const liveStatus = this.liveTestManager.getSessionStatus();
|
|
114
|
+
if (liveStatus.status === 'no_active_session') {
|
|
115
|
+
console.log('No active live testing session');
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
console.log(`Session ID: ${liveStatus.sessionId}`);
|
|
119
|
+
console.log(`Status: ${this.getStatusEmoji(liveStatus.status)} ${liveStatus.status}`);
|
|
120
|
+
console.log(`Progress: ${liveStatus.testsRun}/${liveStatus.totalTests} tests`);
|
|
121
|
+
console.log(`Restart attempts: ${liveStatus.restartAttempts}`);
|
|
122
|
+
if (liveStatus.results && liveStatus.results.length > 0) {
|
|
123
|
+
console.log();
|
|
124
|
+
console.log('Test Results:');
|
|
125
|
+
liveStatus.results.forEach((result) => {
|
|
126
|
+
const emoji = result.status === 'passed' ? '✅' : result.status === 'failed' ? '❌' : '⚠️';
|
|
127
|
+
console.log(` ${emoji} ${result.test}: ${result.status}`);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Get continuity status
|
|
132
|
+
const continuityState = this.continuityManager.getCurrentState();
|
|
133
|
+
if (continuityState) {
|
|
134
|
+
console.log();
|
|
135
|
+
console.log('🔄 Continuity State');
|
|
136
|
+
console.log('━'.repeat(50));
|
|
137
|
+
console.log(`Session: ${continuityState.sessionId}`);
|
|
138
|
+
console.log(`Restarts: ${continuityState.restartCount}`);
|
|
139
|
+
console.log(`Test in progress: ${continuityState.testInProgress ? 'yes' : 'no'}`);
|
|
140
|
+
if (continuityState.currentTest) {
|
|
141
|
+
console.log(`Current test: ${continuityState.currentTest.name}`);
|
|
142
|
+
console.log(`Checkpoints: ${continuityState.currentTest.checkpoints.length}`);
|
|
143
|
+
}
|
|
144
|
+
if (continuityState.pendingActions.length > 0) {
|
|
145
|
+
console.log();
|
|
146
|
+
console.log(`Pending actions: ${continuityState.pendingActions.length}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// Stop monitoring to allow process to exit
|
|
150
|
+
this.continuityManager.stopMonitoring();
|
|
151
|
+
}
|
|
152
|
+
async stopLiveTest() {
|
|
153
|
+
console.log('🛑 Stopping Live Testing');
|
|
154
|
+
try {
|
|
155
|
+
await this.liveTestManager.stopLiveTestSession();
|
|
156
|
+
console.log('✅ Live testing session stopped');
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
console.error('❌ Failed to stop live testing:', error.message);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
showContinuity() {
|
|
163
|
+
console.log('🔄 Continuity Information');
|
|
164
|
+
console.log('━'.repeat(50));
|
|
165
|
+
const state = this.continuityManager.getCurrentState();
|
|
166
|
+
if (!state) {
|
|
167
|
+
console.log('No continuity state available');
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
console.log('Session Information:');
|
|
171
|
+
console.log(` • ID: ${state.sessionId}`);
|
|
172
|
+
console.log(` • Restart count: ${state.restartCount}`);
|
|
173
|
+
console.log(` • Last activity: ${new Date(state.lastActivity).toLocaleString()}`);
|
|
174
|
+
console.log();
|
|
175
|
+
if (state.testInProgress && state.currentTest) {
|
|
176
|
+
console.log('Current Test:');
|
|
177
|
+
console.log(` • Name: ${state.currentTest.name}`);
|
|
178
|
+
console.log(` • Started: ${new Date(state.currentTest.startTime).toLocaleString()}`);
|
|
179
|
+
console.log(` • Checkpoints: ${state.currentTest.checkpoints.length}`);
|
|
180
|
+
if (state.currentTest.checkpoints.length > 0) {
|
|
181
|
+
console.log(' • Recent checkpoints:');
|
|
182
|
+
state.currentTest.checkpoints.slice(-3).forEach(cp => {
|
|
183
|
+
console.log(` - ${cp}`);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
console.log('No test currently in progress');
|
|
189
|
+
}
|
|
190
|
+
if (state.pendingActions.length > 0) {
|
|
191
|
+
console.log();
|
|
192
|
+
console.log(`Pending Actions (${state.pendingActions.length}):`);
|
|
193
|
+
state.pendingActions.forEach(action => {
|
|
194
|
+
console.log(` • ${action.type} - ${new Date(action.timestamp).toLocaleString()}`);
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
// Stop monitoring to allow process to exit
|
|
198
|
+
this.continuityManager.stopMonitoring();
|
|
199
|
+
}
|
|
200
|
+
addCheckpoint(name) {
|
|
201
|
+
console.log('➕ Adding Checkpoint');
|
|
202
|
+
try {
|
|
203
|
+
this.continuityManager.addCheckpoint(name);
|
|
204
|
+
console.log(`✅ Checkpoint added: ${name}`);
|
|
205
|
+
const state = this.continuityManager.getCurrentState();
|
|
206
|
+
if (state?.currentTest) {
|
|
207
|
+
console.log(`Total checkpoints: ${state.currentTest.checkpoints.length}`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
console.error('❌ Failed to add checkpoint:', error.message);
|
|
212
|
+
}
|
|
213
|
+
finally {
|
|
214
|
+
// Stop monitoring to allow process to exit
|
|
215
|
+
this.continuityManager.stopMonitoring();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
simulateRestart(reason) {
|
|
219
|
+
console.log('🔄 Simulating Restart');
|
|
220
|
+
console.log('━'.repeat(50));
|
|
221
|
+
console.log(`Reason: ${reason}`);
|
|
222
|
+
console.log('Note: This simulates a restart for testing purposes');
|
|
223
|
+
console.log('In production, Claude Code would actually restart');
|
|
224
|
+
// Add restart action to continuity
|
|
225
|
+
this.continuityManager.addPendingAction('simulated_restart', {
|
|
226
|
+
reason,
|
|
227
|
+
timestamp: Date.now()
|
|
228
|
+
});
|
|
229
|
+
console.log();
|
|
230
|
+
console.log('✅ Restart simulation recorded');
|
|
231
|
+
console.log('The restart will be detected on next actual restart');
|
|
232
|
+
// Stop monitoring to allow process to exit
|
|
233
|
+
this.continuityManager.stopMonitoring();
|
|
234
|
+
}
|
|
235
|
+
getStatusEmoji(status) {
|
|
236
|
+
switch (status) {
|
|
237
|
+
case 'running': return '🏃';
|
|
238
|
+
case 'completed': return '✅';
|
|
239
|
+
case 'failed': return '❌';
|
|
240
|
+
case 'restarting': return '🔄';
|
|
241
|
+
default: return '❓';
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
exports.LiveTestCommand = LiveTestCommand;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Minimal Post-Tool Hook Trigger
|
|
5
|
+
*
|
|
6
|
+
* This is a lightweight trigger that delegates all business logic
|
|
7
|
+
* to the claude-recall-cli service layer. This hook only handles
|
|
8
|
+
* data forwarding and process management.
|
|
9
|
+
*/
|
|
10
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}) : (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
o[k2] = m[k];
|
|
20
|
+
}));
|
|
21
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
+
}) : function(o, v) {
|
|
24
|
+
o["default"] = v;
|
|
25
|
+
});
|
|
26
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
27
|
+
var ownKeys = function(o) {
|
|
28
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
29
|
+
var ar = [];
|
|
30
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
31
|
+
return ar;
|
|
32
|
+
};
|
|
33
|
+
return ownKeys(o);
|
|
34
|
+
};
|
|
35
|
+
return function (mod) {
|
|
36
|
+
if (mod && mod.__esModule) return mod;
|
|
37
|
+
var result = {};
|
|
38
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
39
|
+
__setModuleDefault(result, mod);
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
})();
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
const child_process_1 = require("child_process");
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
// Determine CLI path - prefer built version, fallback to source
|
|
47
|
+
const CLI_PATHS = [
|
|
48
|
+
path.join(__dirname, '../../dist/cli/claude-recall-cli.js'),
|
|
49
|
+
path.join(__dirname, '../../cli/claude-recall-cli.js'),
|
|
50
|
+
'claude-recall-cli' // Global installation
|
|
51
|
+
];
|
|
52
|
+
function findCliPath() {
|
|
53
|
+
const fs = require('fs');
|
|
54
|
+
for (const cliPath of CLI_PATHS) {
|
|
55
|
+
try {
|
|
56
|
+
if (fs.existsSync(cliPath)) {
|
|
57
|
+
return cliPath;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
// Continue to next path
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Fallback to global command
|
|
65
|
+
return 'claude-recall-cli';
|
|
66
|
+
}
|
|
67
|
+
async function executeCLI() {
|
|
68
|
+
return new Promise((resolve, reject) => {
|
|
69
|
+
const cliPath = findCliPath();
|
|
70
|
+
const isGlobal = cliPath === 'claude-recall-cli';
|
|
71
|
+
// Spawn the CLI process
|
|
72
|
+
const child = (0, child_process_1.spawn)(isGlobal ? cliPath : 'node', isGlobal ? ['post-tool'] : [cliPath, 'post-tool'], {
|
|
73
|
+
stdio: ['pipe', 'inherit', 'inherit'],
|
|
74
|
+
env: process.env
|
|
75
|
+
});
|
|
76
|
+
// Forward stdin data to CLI
|
|
77
|
+
process.stdin.pipe(child.stdin);
|
|
78
|
+
child.on('close', (code) => {
|
|
79
|
+
if (code === 0) {
|
|
80
|
+
resolve();
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
reject(new Error(`CLI process exited with code ${code}`));
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
child.on('error', (error) => {
|
|
87
|
+
reject(error);
|
|
88
|
+
});
|
|
89
|
+
// Handle process signals
|
|
90
|
+
process.on('SIGTERM', () => child.kill('SIGTERM'));
|
|
91
|
+
process.on('SIGINT', () => child.kill('SIGINT'));
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
// Main execution
|
|
95
|
+
async function main() {
|
|
96
|
+
try {
|
|
97
|
+
await executeCLI();
|
|
98
|
+
process.exit(0);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
console.error('Post-tool hook error:', error);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Handle timeout at process level
|
|
106
|
+
const timeout = parseInt(process.env.CLAUDE_RECALL_HOOK_TIMEOUT || '5000');
|
|
107
|
+
const timeoutHandle = setTimeout(() => {
|
|
108
|
+
console.error('Post-tool hook timeout');
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}, timeout);
|
|
111
|
+
// Clear timeout when we start processing
|
|
112
|
+
process.stdin.once('data', () => {
|
|
113
|
+
clearTimeout(timeoutHandle);
|
|
114
|
+
});
|
|
115
|
+
if (require.main === module) {
|
|
116
|
+
main();
|
|
117
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Minimal Pre-Tool Hook Trigger
|
|
5
|
+
*
|
|
6
|
+
* This is a lightweight trigger that delegates all business logic
|
|
7
|
+
* to the claude-recall-cli service layer. This hook only handles
|
|
8
|
+
* data forwarding and process management.
|
|
9
|
+
*/
|
|
10
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}) : (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
o[k2] = m[k];
|
|
20
|
+
}));
|
|
21
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
+
}) : function(o, v) {
|
|
24
|
+
o["default"] = v;
|
|
25
|
+
});
|
|
26
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
27
|
+
var ownKeys = function(o) {
|
|
28
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
29
|
+
var ar = [];
|
|
30
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
31
|
+
return ar;
|
|
32
|
+
};
|
|
33
|
+
return ownKeys(o);
|
|
34
|
+
};
|
|
35
|
+
return function (mod) {
|
|
36
|
+
if (mod && mod.__esModule) return mod;
|
|
37
|
+
var result = {};
|
|
38
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
39
|
+
__setModuleDefault(result, mod);
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
})();
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
const child_process_1 = require("child_process");
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
// Determine CLI path - prefer built version, fallback to source
|
|
47
|
+
const CLI_PATHS = [
|
|
48
|
+
path.join(__dirname, '../../dist/cli/claude-recall-cli.js'),
|
|
49
|
+
path.join(__dirname, '../../cli/claude-recall-cli.js'),
|
|
50
|
+
'claude-recall-cli' // Global installation
|
|
51
|
+
];
|
|
52
|
+
function findCliPath() {
|
|
53
|
+
const fs = require('fs');
|
|
54
|
+
for (const cliPath of CLI_PATHS) {
|
|
55
|
+
try {
|
|
56
|
+
if (fs.existsSync(cliPath)) {
|
|
57
|
+
return cliPath;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
// Continue to next path
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Fallback to global command
|
|
65
|
+
return 'claude-recall-cli';
|
|
66
|
+
}
|
|
67
|
+
async function executeCLI() {
|
|
68
|
+
return new Promise((resolve, reject) => {
|
|
69
|
+
const cliPath = findCliPath();
|
|
70
|
+
const isGlobal = cliPath === 'claude-recall-cli';
|
|
71
|
+
// Spawn the CLI process
|
|
72
|
+
const child = (0, child_process_1.spawn)(isGlobal ? cliPath : 'node', isGlobal ? ['pre-tool'] : [cliPath, 'pre-tool'], {
|
|
73
|
+
stdio: ['pipe', 'inherit', 'inherit'],
|
|
74
|
+
env: process.env
|
|
75
|
+
});
|
|
76
|
+
// Forward stdin data to CLI
|
|
77
|
+
process.stdin.pipe(child.stdin);
|
|
78
|
+
child.on('close', (code) => {
|
|
79
|
+
if (code === 0) {
|
|
80
|
+
resolve();
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
reject(new Error(`CLI process exited with code ${code}`));
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
child.on('error', (error) => {
|
|
87
|
+
reject(error);
|
|
88
|
+
});
|
|
89
|
+
// Handle process signals
|
|
90
|
+
process.on('SIGTERM', () => child.kill('SIGTERM'));
|
|
91
|
+
process.on('SIGINT', () => child.kill('SIGINT'));
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
// Main execution
|
|
95
|
+
async function main() {
|
|
96
|
+
try {
|
|
97
|
+
await executeCLI();
|
|
98
|
+
process.exit(0);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
console.error('Pre-tool hook error:', error);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Handle timeout at process level
|
|
106
|
+
const timeout = parseInt(process.env.CLAUDE_RECALL_HOOK_TIMEOUT || '5000');
|
|
107
|
+
const timeoutHandle = setTimeout(() => {
|
|
108
|
+
console.error('Pre-tool hook timeout');
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}, timeout);
|
|
111
|
+
// Clear timeout when we start processing
|
|
112
|
+
process.stdin.once('data', () => {
|
|
113
|
+
clearTimeout(timeoutHandle);
|
|
114
|
+
});
|
|
115
|
+
if (require.main === module) {
|
|
116
|
+
main();
|
|
117
|
+
}
|