stigmergy 1.2.13 → 1.3.1-beta
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 +39 -3
- package/STIGMERGY.md +3 -0
- package/config/builtin-skills.json +43 -0
- package/config/enhanced-cli-config.json +438 -0
- package/docs/CLI_TOOLS_AGENT_SKILL_ANALYSIS.md +463 -0
- package/docs/DESIGN_CLI_HELP_ANALYZER_REFACTOR.md +726 -0
- package/docs/ENHANCED_CLI_AGENT_SKILL_CONFIG.md +285 -0
- package/docs/IMPLEMENTATION_CHECKLIST_CLI_HELP_ANALYZER_REFACTOR.md +1268 -0
- package/docs/INSTALLER_ARCHITECTURE.md +257 -0
- package/docs/LESSONS_LEARNED.md +252 -0
- package/docs/SPECS_CLI_HELP_ANALYZER_REFACTOR.md +287 -0
- package/docs/SUDO_PROBLEM_AND_SOLUTION.md +529 -0
- package/docs/correct-skillsio-implementation.md +368 -0
- package/docs/development_guidelines.md +276 -0
- package/docs/independent-resume-implementation.md +198 -0
- package/docs/resumesession-final-implementation.md +195 -0
- package/docs/resumesession-usage.md +87 -0
- package/package.json +19 -9
- package/scripts/analyze-router.js +168 -0
- package/scripts/run-comprehensive-tests.js +230 -0
- package/scripts/run-quick-tests.js +90 -0
- package/scripts/test-runner.js +344 -0
- package/skills/resumesession/INDEPENDENT_SKILL.md +171 -0
- package/skills/resumesession/SKILL.md +127 -0
- package/skills/resumesession/__init__.py +33 -0
- package/skills/resumesession/implementations/simple-resume.js +13 -0
- package/src/adapters/claude/install_claude_integration.js +9 -1
- package/src/adapters/codebuddy/install_codebuddy_integration.js +3 -1
- package/src/adapters/codex/install_codex_integration.js +15 -5
- package/src/adapters/gemini/install_gemini_integration.js +3 -1
- package/src/adapters/qwen/install_qwen_integration.js +3 -1
- package/src/cli/commands/autoinstall.js +65 -0
- package/src/cli/commands/errors.js +190 -0
- package/src/cli/commands/independent-resume.js +395 -0
- package/src/cli/commands/install.js +179 -0
- package/src/cli/commands/permissions.js +108 -0
- package/src/cli/commands/project.js +485 -0
- package/src/cli/commands/scan.js +97 -0
- package/src/cli/commands/simple-resume.js +377 -0
- package/src/cli/commands/skills.js +158 -0
- package/src/cli/commands/status.js +113 -0
- package/src/cli/commands/stigmergy-resume.js +775 -0
- package/src/cli/commands/system.js +301 -0
- package/src/cli/commands/universal-resume.js +394 -0
- package/src/cli/router-beta.js +471 -0
- package/src/cli/utils/environment.js +75 -0
- package/src/cli/utils/formatters.js +47 -0
- package/src/cli/utils/skills_cache.js +92 -0
- package/src/core/cache_cleaner.js +1 -0
- package/src/core/cli_adapters.js +345 -0
- package/src/core/cli_help_analyzer.js +582 -26
- package/src/core/cli_path_detector.js +702 -709
- package/src/core/cli_tools.js +515 -160
- package/src/core/coordination/nodejs/CLIIntegrationManager.js +18 -0
- package/src/core/coordination/nodejs/HookDeploymentManager.js +242 -412
- package/src/core/coordination/nodejs/HookDeploymentManager.refactored.js +323 -0
- package/src/core/coordination/nodejs/generators/CLIAdapterGenerator.js +363 -0
- package/src/core/coordination/nodejs/generators/ResumeSessionGenerator.js +932 -0
- package/src/core/coordination/nodejs/generators/SkillsIntegrationGenerator.js +1395 -0
- package/src/core/coordination/nodejs/generators/index.js +12 -0
- package/src/core/enhanced_cli_installer.js +1208 -608
- package/src/core/enhanced_cli_parameter_handler.js +402 -0
- package/src/core/execution_mode_detector.js +222 -0
- package/src/core/installer.js +151 -106
- package/src/core/local_skill_scanner.js +732 -0
- package/src/core/multilingual/language-pattern-manager.js +1 -1
- package/src/core/skills/BuiltinSkillsDeployer.js +188 -0
- package/src/core/skills/StigmergySkillManager.js +123 -16
- package/src/core/skills/embedded-openskills/SkillParser.js +7 -3
- package/src/core/smart_router.js +291 -2
- package/src/index.js +10 -4
- package/src/utils.js +66 -7
- package/test/cli-integration.test.js +304 -0
- package/test/direct_smart_router_test.js +88 -0
- package/test/enhanced-cli-agent-skill-test.js +485 -0
- package/test/simple_test.js +82 -0
- package/test/smart_router_test_runner.js +123 -0
- package/test/smart_routing_edge_cases.test.js +284 -0
- package/test/smart_routing_simple_verification.js +139 -0
- package/test/smart_routing_verification.test.js +346 -0
- package/test/specific-cli-agent-skill-analysis.js +385 -0
- package/test/unit/smart_router.test.js +295 -0
- package/test/very_simple_test.js +54 -0
- package/src/cli/router.js +0 -1783
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Enhanced Test Runner for HookDeploymentManager Test Suite
|
|
5
|
+
* Provides comprehensive testing with reporting and analysis
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { execSync } = require('child_process');
|
|
9
|
+
const fs = require('fs-extra');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const chalk = require('chalk');
|
|
12
|
+
|
|
13
|
+
class TestRunner {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.testResults = {
|
|
16
|
+
unit: { passed: 0, failed: 0, total: 0, duration: 0 },
|
|
17
|
+
integration: { passed: 0, failed: 0, total: 0, duration: 0 },
|
|
18
|
+
regression: { passed: 0, failed: 0, total: 0, duration: 0 },
|
|
19
|
+
performance: { passed: 0, failed: 0, total: 0, duration: 0 }
|
|
20
|
+
};
|
|
21
|
+
this.startTime = Date.now();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
log(message, type = 'info') {
|
|
25
|
+
const colors = {
|
|
26
|
+
info: chalk.blue,
|
|
27
|
+
success: chalk.green,
|
|
28
|
+
warning: chalk.yellow,
|
|
29
|
+
error: chalk.red
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
console.log(colors[type](`[${new Date().toLocaleTimeString()}] ${message}`));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async runCommand(command, description) {
|
|
36
|
+
this.log(`Running: ${description}...`);
|
|
37
|
+
const startTime = Date.now();
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
const output = execSync(command, {
|
|
41
|
+
encoding: 'utf8',
|
|
42
|
+
stdio: 'pipe'
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const duration = Date.now() - startTime;
|
|
46
|
+
this.log(`${description} completed successfully (${duration}ms)`, 'success');
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
success: true,
|
|
50
|
+
output,
|
|
51
|
+
duration
|
|
52
|
+
};
|
|
53
|
+
} catch (error) {
|
|
54
|
+
const duration = Date.now() - startTime;
|
|
55
|
+
this.log(`${description} failed after ${duration}ms`, 'error');
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
error: error.message,
|
|
60
|
+
output: error.stdout,
|
|
61
|
+
duration
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
parseJestOutput(output) {
|
|
67
|
+
const lines = output.split('\n');
|
|
68
|
+
const results = {
|
|
69
|
+
passed: 0,
|
|
70
|
+
failed: 0,
|
|
71
|
+
total: 0,
|
|
72
|
+
suites: 0
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
lines.forEach(line => {
|
|
76
|
+
const match = line.match(/Tests:\s+(\d+)\s+passed,\s+(\d+)\s+failed/);
|
|
77
|
+
if (match) {
|
|
78
|
+
results.passed = parseInt(match[1]);
|
|
79
|
+
results.failed = parseInt(match[2]);
|
|
80
|
+
results.total = results.passed + results.failed;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const suiteMatch = line.match(/Test Suites:\s+(\d+)\s+passed,\s+(\d+)\s+failed/);
|
|
84
|
+
if (suiteMatch) {
|
|
85
|
+
results.suites = parseInt(suiteMatch[1]) + parseInt(suiteMatch[2]);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
return results;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async runUnitTests() {
|
|
93
|
+
this.log('\n🧪 Running Unit Tests', 'info');
|
|
94
|
+
|
|
95
|
+
const result = await this.runCommand(
|
|
96
|
+
'npm run test:unit -- --verbose --json',
|
|
97
|
+
'Unit Tests'
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
if (result.success) {
|
|
101
|
+
const jestOutput = result.output;
|
|
102
|
+
try {
|
|
103
|
+
const jsonMatch = jestOutput.match(/\{[\s\S]*\}/);
|
|
104
|
+
if (jsonMatch) {
|
|
105
|
+
const jestResults = JSON.parse(jsonMatch[0]);
|
|
106
|
+
this.testResults.unit.passed = jestResults.numPassedTests || 0;
|
|
107
|
+
this.testResults.unit.failed = jestResults.numFailedTests || 0;
|
|
108
|
+
this.testResults.unit.total = jestResults.numTotalTests || 0;
|
|
109
|
+
this.testResults.unit.duration = jestResults.testResults?.reduce(
|
|
110
|
+
(total, test) => total + (test.duration || 0), 0
|
|
111
|
+
) || 0;
|
|
112
|
+
} else {
|
|
113
|
+
const parsed = this.parseJestOutput(result.output);
|
|
114
|
+
Object.assign(this.testResults.unit, parsed);
|
|
115
|
+
}
|
|
116
|
+
} catch (parseError) {
|
|
117
|
+
this.log('Failed to parse Jest output, using fallback parsing', 'warning');
|
|
118
|
+
const parsed = this.parseJestOutput(result.output);
|
|
119
|
+
Object.assign(this.testResults.unit, parsed);
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
this.testResults.unit.failed = 1;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return result.success;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async runIntegrationTests() {
|
|
129
|
+
this.log('\n🔗 Running Integration Tests', 'info');
|
|
130
|
+
|
|
131
|
+
const result = await this.runCommand(
|
|
132
|
+
'npm run test:integration -- --verbose',
|
|
133
|
+
'Integration Tests'
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
if (result.success) {
|
|
137
|
+
const parsed = this.parseJestOutput(result.output);
|
|
138
|
+
Object.assign(this.testResults.integration, parsed);
|
|
139
|
+
this.testResults.integration.duration = result.duration;
|
|
140
|
+
} else {
|
|
141
|
+
this.testResults.integration.failed = 1;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return result.success;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async runRegressionTests() {
|
|
148
|
+
this.log('\n🔄 Running Regression Tests', 'info');
|
|
149
|
+
|
|
150
|
+
const result = await this.runCommand(
|
|
151
|
+
'npm run test:regression -- --verbose',
|
|
152
|
+
'Regression Tests'
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
if (result.success) {
|
|
156
|
+
const parsed = this.parseJestOutput(result.output);
|
|
157
|
+
Object.assign(this.testResults.regression, parsed);
|
|
158
|
+
this.testResults.regression.duration = result.duration;
|
|
159
|
+
} else {
|
|
160
|
+
this.testResults.regression.failed = 1;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return result.success;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async runPerformanceTests() {
|
|
167
|
+
this.log('\n⚡ Running Performance Tests', 'info');
|
|
168
|
+
|
|
169
|
+
const result = await this.runCommand(
|
|
170
|
+
'npm run test:performance -- --verbose',
|
|
171
|
+
'Performance Tests'
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
if (result.success) {
|
|
175
|
+
const parsed = this.parseJestOutput(result.output);
|
|
176
|
+
Object.assign(this.testResults.performance, parsed);
|
|
177
|
+
this.testResults.performance.duration = result.duration;
|
|
178
|
+
} else {
|
|
179
|
+
this.testResults.performance.failed = 1;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return result.success;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
generateReport() {
|
|
186
|
+
const totalDuration = Date.now() - this.startTime;
|
|
187
|
+
const allTests = Object.values(this.testResults);
|
|
188
|
+
const totalPassed = allTests.reduce((sum, cat) => sum + cat.passed, 0);
|
|
189
|
+
const totalFailed = allTests.reduce((sum, cat) => sum + cat.failed, 0);
|
|
190
|
+
const totalTests = totalPassed + totalFailed;
|
|
191
|
+
|
|
192
|
+
console.log('\n' + '='.repeat(80));
|
|
193
|
+
console.log(chalk.bold.blue('📊 TEST SUITE REPORT'));
|
|
194
|
+
console.log('='.repeat(80));
|
|
195
|
+
|
|
196
|
+
// Summary
|
|
197
|
+
console.log(chalk.bold('\n📋 SUMMARY:'));
|
|
198
|
+
console.log(`Total Duration: ${(totalDuration / 1000).toFixed(2)}s`);
|
|
199
|
+
console.log(`Total Tests: ${totalTests}`);
|
|
200
|
+
console.log(`Passed: ${chalk.green(totalPassed)}`);
|
|
201
|
+
console.log(`Failed: ${chalk.red(totalFailed)}`);
|
|
202
|
+
console.log(`Success Rate: ${((totalPassed / totalTests) * 100).toFixed(1)}%`);
|
|
203
|
+
|
|
204
|
+
// Category breakdown
|
|
205
|
+
console.log(chalk.bold('\n📂 TEST CATEGORIES:'));
|
|
206
|
+
|
|
207
|
+
const categories = [
|
|
208
|
+
{ name: 'Unit Tests', key: 'unit', icon: '🧪' },
|
|
209
|
+
{ name: 'Integration Tests', key: 'integration', icon: '🔗' },
|
|
210
|
+
{ name: 'Regression Tests', key: 'regression', icon: '🔄' },
|
|
211
|
+
{ name: 'Performance Tests', key: 'performance', icon: '⚡' }
|
|
212
|
+
];
|
|
213
|
+
|
|
214
|
+
categories.forEach(category => {
|
|
215
|
+
const results = this.testResults[category.key];
|
|
216
|
+
const success = results.failed === 0;
|
|
217
|
+
const status = success ? '✅' : '❌';
|
|
218
|
+
const color = success ? chalk.green : chalk.red;
|
|
219
|
+
|
|
220
|
+
console.log(`\n${category.icon} ${category.name}: ${status}`);
|
|
221
|
+
console.log(` Tests: ${results.total}`);
|
|
222
|
+
console.log(` Passed: ${color(results.passed)}`);
|
|
223
|
+
console.log(` Failed: ${results.failed > 0 ? chalk.red(results.failed) : results.failed}`);
|
|
224
|
+
console.log(` Duration: ${(results.duration / 1000).toFixed(2)}s`);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// Coverage information if available
|
|
228
|
+
const coveragePath = path.join(process.cwd(), 'coverage', 'coverage-summary.json');
|
|
229
|
+
if (fs.existsSync(coveragePath)) {
|
|
230
|
+
try {
|
|
231
|
+
const coverage = fs.readJsonSync(coveragePath);
|
|
232
|
+
console.log(chalk.bold('\n📈 COVERAGE SUMMARY:'));
|
|
233
|
+
console.log(`Lines: ${coverage.total.lines.pct}%`);
|
|
234
|
+
console.log(`Functions: ${coverage.total.functions.pct}%`);
|
|
235
|
+
console.log(`Branches: ${coverage.total.branches.pct}%`);
|
|
236
|
+
console.log(`Statements: ${coverage.total.statements.pct}%`);
|
|
237
|
+
} catch (error) {
|
|
238
|
+
this.log('Could not read coverage information', 'warning');
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
console.log('\n' + '='.repeat(80));
|
|
243
|
+
|
|
244
|
+
// Exit with appropriate code
|
|
245
|
+
const exitCode = totalFailed > 0 ? 1 : 0;
|
|
246
|
+
|
|
247
|
+
if (exitCode === 0) {
|
|
248
|
+
console.log(chalk.green.bold('\n🎉 ALL TESTS PASSED!'));
|
|
249
|
+
} else {
|
|
250
|
+
console.log(chalk.red.bold(`\n❌ ${totalFailed} TEST(S) FAILED!`));
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return exitCode;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async runTestSuite() {
|
|
257
|
+
console.log(chalk.bold.blue('🚀 Starting HookDeploymentManager Test Suite'));
|
|
258
|
+
console.log(`Node.js version: ${process.version}`);
|
|
259
|
+
console.log(`Platform: ${process.platform}`);
|
|
260
|
+
console.log(`Working directory: ${process.cwd()}`);
|
|
261
|
+
|
|
262
|
+
try {
|
|
263
|
+
// Clean previous results
|
|
264
|
+
await fs.remove('coverage');
|
|
265
|
+
await fs.remove('test-results');
|
|
266
|
+
|
|
267
|
+
const unitSuccess = await this.runUnitTests();
|
|
268
|
+
const integrationSuccess = await this.runIntegrationTests();
|
|
269
|
+
const regressionSuccess = await this.runRegressionTests();
|
|
270
|
+
|
|
271
|
+
// Run performance tests only if others pass (to save time)
|
|
272
|
+
let performanceSuccess = true;
|
|
273
|
+
if (unitSuccess && integrationSuccess && regressionSuccess) {
|
|
274
|
+
performanceSuccess = await this.runPerformanceTests();
|
|
275
|
+
} else {
|
|
276
|
+
this.log('Skipping performance tests due to failures in other categories', 'warning');
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Generate report and exit
|
|
280
|
+
const exitCode = this.generateReport();
|
|
281
|
+
process.exit(exitCode);
|
|
282
|
+
|
|
283
|
+
} catch (error) {
|
|
284
|
+
this.log(`Test runner error: ${error.message}`, 'error');
|
|
285
|
+
console.error(error.stack);
|
|
286
|
+
process.exit(1);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// CLI interface
|
|
292
|
+
if (require.main === module) {
|
|
293
|
+
const runner = new TestRunner();
|
|
294
|
+
|
|
295
|
+
// Parse command line arguments
|
|
296
|
+
const args = process.argv.slice(2);
|
|
297
|
+
|
|
298
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
299
|
+
console.log(`
|
|
300
|
+
HookDeploymentManager Test Runner
|
|
301
|
+
|
|
302
|
+
Usage: node scripts/test-runner.js [options]
|
|
303
|
+
|
|
304
|
+
Options:
|
|
305
|
+
--help, -h Show this help message
|
|
306
|
+
--unit-only Run only unit tests
|
|
307
|
+
--integration-only Run only integration tests
|
|
308
|
+
--regression-only Run only regression tests
|
|
309
|
+
--performance-only Run only performance tests
|
|
310
|
+
--no-performance Skip performance tests
|
|
311
|
+
--verbose Enable verbose output
|
|
312
|
+
|
|
313
|
+
Examples:
|
|
314
|
+
node scripts/test-runner.js # Run all tests
|
|
315
|
+
node scripts/test-runner.js --unit-only # Run only unit tests
|
|
316
|
+
node scripts/test-runner.js --no-performance # Skip performance tests
|
|
317
|
+
`);
|
|
318
|
+
process.exit(0);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Handle specific test category requests
|
|
322
|
+
if (args.includes('--unit-only')) {
|
|
323
|
+
runner.runUnitTests().then(success => {
|
|
324
|
+
process.exit(success ? 0 : 1);
|
|
325
|
+
});
|
|
326
|
+
} else if (args.includes('--integration-only')) {
|
|
327
|
+
runner.runIntegrationTests().then(success => {
|
|
328
|
+
process.exit(success ? 0 : 1);
|
|
329
|
+
});
|
|
330
|
+
} else if (args.includes('--regression-only')) {
|
|
331
|
+
runner.runRegressionTests().then(success => {
|
|
332
|
+
process.exit(success ? 0 : 1);
|
|
333
|
+
});
|
|
334
|
+
} else if (args.includes('--performance-only')) {
|
|
335
|
+
runner.runPerformanceTests().then(success => {
|
|
336
|
+
process.exit(success ? 0 : 1);
|
|
337
|
+
});
|
|
338
|
+
} else {
|
|
339
|
+
// Run all tests
|
|
340
|
+
runner.runTestSuite();
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
module.exports = TestRunner;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: resumesession
|
|
3
|
+
description: Cross-CLI session recovery and history management skill
|
|
4
|
+
author: stigmergy
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ResumeSession Skill
|
|
9
|
+
|
|
10
|
+
Cross-CLI session recovery and history management skill for Claude CLI.
|
|
11
|
+
|
|
12
|
+
## Description
|
|
13
|
+
|
|
14
|
+
This skill enables Claude CLI to:
|
|
15
|
+
- **Quickly recover the latest session** from all supported CLI tools
|
|
16
|
+
- Compare sessions across CLIs to find the most recent one
|
|
17
|
+
- Display full session content for immediate context recovery
|
|
18
|
+
- Advanced mode: list sessions or show summary only
|
|
19
|
+
- **Completely independent**: Does NOT depend on Stigmergy installation
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
### Default Mode - Recover Latest Session (Recommended)
|
|
24
|
+
|
|
25
|
+
To quickly recover the latest session from any CLI:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Use independent recovery tool (no Stigmergy dependency)
|
|
29
|
+
Bash("node {stigmergy_cli_path}/independent-resume.js")
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Important**: Since this tool is completely independent, you need to specify the path to the tool:
|
|
33
|
+
- Replace `{stigmergy_cli_path}` with the actual path to `independent-resume.js`
|
|
34
|
+
- For example: `C:\Users\YourName\.stigmergy\cli\independent-resume.js`
|
|
35
|
+
- Or install this tool globally and use: `resume-session`
|
|
36
|
+
|
|
37
|
+
This command:
|
|
38
|
+
- **Compares all CLIs** (Claude, Gemini, Qwen, iFlow, CodeBuddy, Codex, QoderCLI, Kode)
|
|
39
|
+
- **Finds the most recent session** across all tools
|
|
40
|
+
- **Displays full session content** for immediate context recovery
|
|
41
|
+
- **No intermediate steps** shown to user
|
|
42
|
+
- **Silent operation** - only the recovered session is displayed
|
|
43
|
+
|
|
44
|
+
### Advanced Options
|
|
45
|
+
|
|
46
|
+
For more advanced usage:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# List all sessions without recovering (show available sessions)
|
|
50
|
+
Bash("node {stigmergy_cli_path}/independent-resume.js --list")
|
|
51
|
+
|
|
52
|
+
# Show summary only (not full content)
|
|
53
|
+
Bash("node {stigmergy_cli_path}/independent-resume.js --summary")
|
|
54
|
+
|
|
55
|
+
# Recover latest session from specific CLI only
|
|
56
|
+
Bash("node {stigmergy_cli_path}/independent-resume.js --cli claude")
|
|
57
|
+
Bash("node {stigmergy_cli_path}/independent-resume.js --cli iflow")
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Workflow
|
|
61
|
+
|
|
62
|
+
### Standard Workflow (Default)
|
|
63
|
+
|
|
64
|
+
When a user asks to recover a previous conversation (e.g., "恢复上次对话", "恢复 Claude 的上次对话"):
|
|
65
|
+
|
|
66
|
+
1. **Execute recovery command**:
|
|
67
|
+
```bash
|
|
68
|
+
Bash("node {stigmergy_cli_path}/independent-resume.js")
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
2. **The tool will**:
|
|
72
|
+
- Scan all CLI session directories
|
|
73
|
+
- Compare modification times across all CLIs
|
|
74
|
+
- Find the most recent session
|
|
75
|
+
- Display complete session content
|
|
76
|
+
|
|
77
|
+
3. **Display result directly to the user**:
|
|
78
|
+
- Session metadata (source CLI, time, file)
|
|
79
|
+
- Full conversation content
|
|
80
|
+
- No intermediate steps or debug information
|
|
81
|
+
|
|
82
|
+
4. **Continue the conversation** based on the recovered context
|
|
83
|
+
|
|
84
|
+
### Advanced Workflow
|
|
85
|
+
|
|
86
|
+
When a user needs to explore sessions:
|
|
87
|
+
|
|
88
|
+
1. **List available sessions**:
|
|
89
|
+
```bash
|
|
90
|
+
Bash("node {stigmergy_cli_path}/independent-resume.js --list")
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
2. **User selects which session to recover** based on the list
|
|
94
|
+
|
|
95
|
+
3. **Recover specific CLI's latest session**:
|
|
96
|
+
```bash
|
|
97
|
+
Bash("node {stigmergy_cli_path}/independent-resume.js --cli <cli-name>")
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Installation & Deployment
|
|
101
|
+
|
|
102
|
+
This tool is designed to be **completely independent** and does not depend on Stigmergy.
|
|
103
|
+
|
|
104
|
+
### Option 1: Install Globally (Recommended)
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Copy to a global location
|
|
108
|
+
npm install -g https://github.com/your-repo/independent-resume
|
|
109
|
+
|
|
110
|
+
# Then you can use from anywhere
|
|
111
|
+
resume-session
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Option 2: Copy to Local Path
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Copy to your preferred location
|
|
118
|
+
cp independent-resume.js ~/.local/bin/resume-session
|
|
119
|
+
|
|
120
|
+
# Add to PATH in your shell config
|
|
121
|
+
export PATH="$PATH:$HOME/.local/bin"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Option 3: Use Relative Path from Current CLI
|
|
125
|
+
|
|
126
|
+
Since the skill file is deployed to CLI tools, it can reference the relative path to `independent-resume.js`:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Assuming skill is deployed to ~/.claude/skills/resumesession/
|
|
130
|
+
Bash("node ../independent-resume.js") # If in CLI root
|
|
131
|
+
Bash("node ~/.claude/skills/resumesession/independent-resume.js") # Full path
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Features
|
|
135
|
+
|
|
136
|
+
- ✅ **Universal Recovery**: Finds the latest session across all CLIs automatically
|
|
137
|
+
- ✅ **Smart Comparison**: Compares modification times to find the most recent session
|
|
138
|
+
- ✅ **Full Content Recovery**: Displays complete session content by default
|
|
139
|
+
- ✅ **Silent Operation**: No intermediate steps or debug output
|
|
140
|
+
- ✅ **Cross-CLI Support**: Works with Claude, Gemini, Qwen, iFlow, CodeBuddy, Codex, QoderCLI, Kode
|
|
141
|
+
- ✅ **Completely Independent**: Does NOT depend on Stigmergy installation
|
|
142
|
+
- ✅ **Flexible Deployment**: Can be installed globally or used from any location
|
|
143
|
+
- ✅ **Advanced Mode**: Optional listing and summary-only modes
|
|
144
|
+
|
|
145
|
+
## Command Options
|
|
146
|
+
|
|
147
|
+
- `--list` or `-l`: List all available sessions without recovering (advanced mode)
|
|
148
|
+
- `--summary` or `-s`: Show session summary only, not full content (advanced mode)
|
|
149
|
+
- `--cli <name>`: Recover latest session from a specific CLI only (advanced mode)
|
|
150
|
+
|
|
151
|
+
## Supported CLIs
|
|
152
|
+
|
|
153
|
+
- Claude (`.claude/projects/`)
|
|
154
|
+
- Gemini (`.config/gemini/tmp/`)
|
|
155
|
+
- Qwen (`.qwen/projects/`)
|
|
156
|
+
- iFlow (`.iflow/projects/`)
|
|
157
|
+
- CodeBuddy (`.codebuddy/`)
|
|
158
|
+
- Codex (`.config/codex/`)
|
|
159
|
+
- QoderCLI (`.qoder/projects/`)
|
|
160
|
+
- Kode (`.kode/projects/`)
|
|
161
|
+
|
|
162
|
+
## Notes
|
|
163
|
+
|
|
164
|
+
**Important**: This tool is completely independent and does NOT require Stigmergy to be installed.
|
|
165
|
+
|
|
166
|
+
**Default behavior**: Always recovers the latest session with full content for immediate context recovery without any user interaction or intermediate steps.
|
|
167
|
+
|
|
168
|
+
**Path Resolution**: You need to provide the correct path to `independent-resume.js` in the command. This can be:
|
|
169
|
+
- A global installation path
|
|
170
|
+
- A local path
|
|
171
|
+
- A relative path from the CLI's skill directory
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: resumesession
|
|
3
|
+
description: Cross-CLI session recovery and history management skill
|
|
4
|
+
author: stigmergy
|
|
5
|
+
version: 2.0.0
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ResumeSession Skill
|
|
9
|
+
|
|
10
|
+
Cross-CLI session recovery and history management skill for all CLI tools.
|
|
11
|
+
|
|
12
|
+
## Description
|
|
13
|
+
|
|
14
|
+
This skill enables session recovery across all supported CLI tools with intelligent project-based filtering.
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
### Default Behavior - Recover Current Project's Latest Session
|
|
19
|
+
|
|
20
|
+
To quickly recover current project's latest session:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Use stigmergy resume command
|
|
24
|
+
stigmergy resume
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
This command:
|
|
28
|
+
- **Filters by current project** (only shows sessions from current working directory)
|
|
29
|
+
- **Finds most recent session** from current project
|
|
30
|
+
- **Checks session content** - if latest session is empty, it recovers previous one
|
|
31
|
+
- **Displays context** for immediate recovery
|
|
32
|
+
|
|
33
|
+
### Show Multiple Sessions (Current Project Only)
|
|
34
|
+
|
|
35
|
+
To show multiple sessions from current project:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Show 5 most recent sessions
|
|
39
|
+
stigmergy resume 5
|
|
40
|
+
|
|
41
|
+
# Show 10 most recent sessions
|
|
42
|
+
stigmergy resume 10
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Show Sessions from Specific CLI
|
|
46
|
+
|
|
47
|
+
To show sessions from a specific CLI (current project only):
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Show iFlow sessions
|
|
51
|
+
stigmergy resume iflow
|
|
52
|
+
|
|
53
|
+
# Show 3 iFlow sessions
|
|
54
|
+
stigmergy resume iflow 3
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Show All Projects' Sessions
|
|
58
|
+
|
|
59
|
+
To show sessions from all projects:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Show all projects' sessions (default: 10 per CLI)
|
|
63
|
+
stigmergy resume --all
|
|
64
|
+
|
|
65
|
+
# Show all projects' sessions with limit
|
|
66
|
+
stigmergy resume --all 5
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Advanced Filters
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Search sessions by keyword
|
|
73
|
+
stigmergy resume --search "react"
|
|
74
|
+
|
|
75
|
+
# Show today's sessions
|
|
76
|
+
stigmergy resume --today
|
|
77
|
+
|
|
78
|
+
# Show sessions from last 7 days
|
|
79
|
+
stigmergy resume --week
|
|
80
|
+
|
|
81
|
+
# Show sessions from last 30 days
|
|
82
|
+
stigmergy resume --month
|
|
83
|
+
|
|
84
|
+
# Use different view formats
|
|
85
|
+
stigmergy resume --format timeline
|
|
86
|
+
stigmergy resume --format detailed
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Features
|
|
90
|
+
|
|
91
|
+
- ✅ **Project-Aware**: Automatically filters sessions by current working directory
|
|
92
|
+
- ✅ **Smart Content Check**: Skips empty sessions and finds previous one
|
|
93
|
+
- ✅ **Default Context Recovery**: Shows latest session context by default
|
|
94
|
+
- ✅ **Number-Based Control**: Use numbers to show multiple sessions
|
|
95
|
+
- ✅ **CLI Filtering**: Filter sessions by specific CLI tool
|
|
96
|
+
- ✅ **Content Search**: Search sessions by keywords
|
|
97
|
+
- ✅ **Time Filtering**: Filter by date ranges (today, week, month)
|
|
98
|
+
- ✅ **Multiple View Formats**: summary, timeline, detailed, context
|
|
99
|
+
- ✅ **Cross-CLI Support**: Works with Claude, Gemini, Qwen, iFlow, CodeBuddy, Codex, QoderCLI, Kode
|
|
100
|
+
|
|
101
|
+
## Command Behavior
|
|
102
|
+
|
|
103
|
+
| Command | Behavior |
|
|
104
|
+
|---------|----------|
|
|
105
|
+
| `stigmergy resume` | Shows **latest session** from **current project** (context format) |
|
|
106
|
+
| `stigmergy resume 5` | Shows **5 most recent sessions** from **current project** (summary format) |
|
|
107
|
+
| `stigmergy resume iflow` | Shows **latest iFlow session** from **current project** |
|
|
108
|
+
| `stigmergy resume iflow 5` | Shows **5 iFlow sessions** from **current project** |
|
|
109
|
+
| `stigmergy resume --all` | Shows **all projects' sessions** (10 per CLI) |
|
|
110
|
+
| `stigmergy resume --all 5` | Shows **all projects' sessions** (5 per CLI) |
|
|
111
|
+
|
|
112
|
+
## Supported CLIs
|
|
113
|
+
|
|
114
|
+
- Claude: `~/.claude/projects/{project-name}/`
|
|
115
|
+
- Gemini: `~/.config/gemini/tmp/{hash}/chats/`
|
|
116
|
+
- Qwen: `~/.qwen/projects/{project-name}/chats/`
|
|
117
|
+
- iFlow: `~/.iflow/projects/{project-name}/`
|
|
118
|
+
- CodeBuddy: `~/.codebuddy/projects/{project-name}/`
|
|
119
|
+
- Codex: `~/.config/codex/`
|
|
120
|
+
- QoderCLI: `~/.qoder/projects/{project-name}/`
|
|
121
|
+
- Kode: `~/.kode/projects/{project-name}/`
|
|
122
|
+
|
|
123
|
+
## Notes
|
|
124
|
+
|
|
125
|
+
**Best Practice**: Always open your terminal in project directory before using `stigmergy resume`. This ensures you recover sessions relevant to your current project.
|
|
126
|
+
|
|
127
|
+
**Important**: By default, only sessions from **current working directory** are shown. Use `--all` to see sessions from all projects.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "resumesession",
|
|
3
|
+
"displayName": "ResumeSession",
|
|
4
|
+
"version": "2.0.0",
|
|
5
|
+
"description": "Cross-CLI session recovery and history management with project-aware filtering",
|
|
6
|
+
"capabilities": [
|
|
7
|
+
"Recover latest session from current project",
|
|
8
|
+
"Check session content and skip empty sessions",
|
|
9
|
+
"Show multiple sessions from current project",
|
|
10
|
+
"Filter sessions by specific CLI",
|
|
11
|
+
"Search sessions by content keywords",
|
|
12
|
+
"Filter sessions by date range (today, week, month)",
|
|
13
|
+
"Show sessions from all projects with --all flag",
|
|
14
|
+
"Multiple view formats: summary, timeline, detailed, context",
|
|
15
|
+
"Cross-CLI support: Claude, Gemini, Qwen, iFlow, CodeBuddy, Codex, QoderCLI, Kode"
|
|
16
|
+
],
|
|
17
|
+
"protocols": ["chinese", "english"],
|
|
18
|
+
"hooks": [],
|
|
19
|
+
"enabled": true,
|
|
20
|
+
"category": "session-management",
|
|
21
|
+
"author": "stigmergy",
|
|
22
|
+
"dependencies": [],
|
|
23
|
+
"implementations": [
|
|
24
|
+
{
|
|
25
|
+
"name": "stigmergy-resume",
|
|
26
|
+
"version": "2.0.0",
|
|
27
|
+
"language": "javascript",
|
|
28
|
+
"description": "Project-aware session recovery tool",
|
|
29
|
+
"runtime": "node",
|
|
30
|
+
"entry_point": "src/cli/commands/stigmergy-resume.js"
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "simple-resume",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Simple cross-CLI session recovery tool",
|
|
5
|
+
"language": "javascript",
|
|
6
|
+
"runtime": "node",
|
|
7
|
+
"entry_point": "src/cli/commands/simple-resume.js",
|
|
8
|
+
"metadata": {
|
|
9
|
+
"cli_type": "cross-cli",
|
|
10
|
+
"session_scope": "all",
|
|
11
|
+
"output_format": "full"
|
|
12
|
+
}
|
|
13
|
+
}
|