@kernel.chat/kbot 2.11.0 → 2.13.0

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.
Files changed (56) hide show
  1. package/README.md +1 -1
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +11 -0
  4. package/dist/agent.js.map +1 -1
  5. package/dist/agents/agents.test.d.ts +2 -0
  6. package/dist/agents/agents.test.d.ts.map +1 -0
  7. package/dist/agents/agents.test.js +127 -0
  8. package/dist/agents/agents.test.js.map +1 -0
  9. package/dist/changelog.d.ts +21 -0
  10. package/dist/changelog.d.ts.map +1 -0
  11. package/dist/changelog.js +204 -0
  12. package/dist/changelog.js.map +1 -0
  13. package/dist/cli.js +110 -114
  14. package/dist/cli.js.map +1 -1
  15. package/dist/completions.d.ts +2 -0
  16. package/dist/completions.d.ts.map +1 -0
  17. package/dist/completions.js +526 -0
  18. package/dist/completions.js.map +1 -0
  19. package/dist/doctor.d.ts +15 -0
  20. package/dist/doctor.d.ts.map +1 -0
  21. package/dist/doctor.js +381 -0
  22. package/dist/doctor.js.map +1 -0
  23. package/dist/evolution.d.ts +112 -0
  24. package/dist/evolution.d.ts.map +1 -0
  25. package/dist/evolution.js +642 -0
  26. package/dist/evolution.js.map +1 -0
  27. package/dist/evolution.test.d.ts +2 -0
  28. package/dist/evolution.test.d.ts.map +1 -0
  29. package/dist/evolution.test.js +160 -0
  30. package/dist/evolution.test.js.map +1 -0
  31. package/dist/ide/acp-server.js +2 -2
  32. package/dist/quality-diversity.d.ts +106 -0
  33. package/dist/quality-diversity.d.ts.map +1 -0
  34. package/dist/quality-diversity.js +296 -0
  35. package/dist/quality-diversity.js.map +1 -0
  36. package/dist/tools/comfyui-plugin.d.ts +2 -0
  37. package/dist/tools/comfyui-plugin.d.ts.map +1 -0
  38. package/dist/tools/comfyui-plugin.js +523 -0
  39. package/dist/tools/comfyui-plugin.js.map +1 -0
  40. package/dist/tools/creative.test.d.ts +2 -0
  41. package/dist/tools/creative.test.d.ts.map +1 -0
  42. package/dist/tools/creative.test.js +281 -0
  43. package/dist/tools/creative.test.js.map +1 -0
  44. package/dist/tools/index.d.ts.map +1 -1
  45. package/dist/tools/index.js +5 -1
  46. package/dist/tools/index.js.map +1 -1
  47. package/dist/tools/magenta-plugin.d.ts +2 -0
  48. package/dist/tools/magenta-plugin.d.ts.map +1 -0
  49. package/dist/tools/magenta-plugin.js +405 -0
  50. package/dist/tools/magenta-plugin.js.map +1 -0
  51. package/dist/tutorial.d.ts +3 -0
  52. package/dist/tutorial.d.ts.map +1 -0
  53. package/dist/tutorial.js +195 -0
  54. package/dist/tutorial.js.map +1 -0
  55. package/dist/ui.js +1 -1
  56. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -20,9 +20,10 @@ import { createAgent, removeAgent, getAgent, formatAgentList, formatAgentDetail,
20
20
  import { getExtendedStats, incrementSessions, learnFact, selfTrain, getTrainingLog, flushPendingWrites } from './learning.js';
21
21
  import { banner, bannerCompact, bannerAuth, prompt as kbotPrompt, printError, printSuccess, printInfo, printResponse, printHelp, printGoodbye, setQuiet, } from './ui.js';
22
22
  import { checkForUpdate, selfUpdate } from './updater.js';
23
+ import { runTutorial } from './tutorial.js';
23
24
  import { syncOnStartup, schedulePush, flushCloudSync, isCloudSyncEnabled, setCloudToken, getCloudToken } from './cloud-sync.js';
24
25
  import chalk from 'chalk';
25
- const VERSION = '2.11.0';
26
+ const VERSION = '2.13.0';
26
27
  async function main() {
27
28
  const program = new Command();
28
29
  program
@@ -241,82 +242,11 @@ async function main() {
241
242
  .command('doctor')
242
243
  .description('Diagnose your kbot setup — check everything is working')
243
244
  .action(async () => {
245
+ const { runDoctor, formatDoctorReport } = await import('./doctor.js');
244
246
  process.stderr.write('\n');
245
247
  printInfo('K:BOT Doctor — Checking your setup...');
246
- process.stderr.write('\n');
247
- // 1. Check BYOK provider
248
- const config = loadConfig();
249
- if (config?.byok_enabled && config?.byok_provider) {
250
- const p = PROVIDERS[config.byok_provider];
251
- printSuccess(`BYOK provider: ${p?.name || config.byok_provider}`);
252
- }
253
- // 3. Check Ollama
254
- const ollamaUp = await isOllamaRunning();
255
- if (ollamaUp) {
256
- const models = await listOllamaModels();
257
- printSuccess(`Ollama: running (${models.length} models)`);
258
- for (const m of models)
259
- printInfo(` ${m}`);
260
- }
261
- else {
262
- printInfo(' Ollama: not running (optional — run: ollama serve)');
263
- }
264
- // 4. Check OpenClaw
265
- try {
266
- const res = await fetch('http://127.0.0.1:18789/health', { signal: AbortSignal.timeout(2000) });
267
- if (res.ok) {
268
- printSuccess('OpenClaw: gateway running at 127.0.0.1:18789');
269
- }
270
- else {
271
- printInfo(' OpenClaw: gateway not responding (optional)');
272
- }
273
- }
274
- catch {
275
- printInfo(' OpenClaw: gateway offline (optional — run: openclaw-cmd start)');
276
- }
277
- // 5. Check Docker (for sandbox tools)
278
- try {
279
- const { execSync } = await import('node:child_process');
280
- execSync('docker info', { timeout: 5000, stdio: 'pipe' });
281
- printSuccess('Docker: running (sandbox execution available)');
282
- }
283
- catch {
284
- printInfo(' Docker: not running (optional — needed for sandbox_run)');
285
- }
286
- // 6. Check git
287
- try {
288
- const { execSync } = await import('node:child_process');
289
- const ver = execSync('git --version', { encoding: 'utf-8', timeout: 3000 }).trim();
290
- printSuccess(`Git: ${ver}`);
291
- }
292
- catch {
293
- printError('Git: not found (needed for git tools)');
294
- }
295
- // 7. Check Node.js version
296
- printSuccess(`Node.js: ${process.version}`);
297
- // 8. Check config directory
298
- const { existsSync } = await import('node:fs');
299
- const { homedir } = await import('node:os');
300
- const { join } = await import('node:path');
301
- const kbotDir = join(homedir(), '.kbot');
302
- if (existsSync(kbotDir)) {
303
- printSuccess(`Config: ${kbotDir}`);
304
- }
305
- else {
306
- printInfo(` Config directory will be created at: ${kbotDir}`);
307
- }
308
- process.stderr.write('\n');
309
- // Summary
310
- const hasProvider = !!((config?.byok_enabled && config?.byok_provider) || ollamaUp);
311
- if (hasProvider) {
312
- printSuccess('Ready to go! Run: kbot');
313
- }
314
- else {
315
- printInfo('Get started with one of:');
316
- printInfo(' kbot local — Free local AI');
317
- printInfo(' kbot byok — Use your own API key');
318
- }
319
- process.stderr.write('\n');
248
+ const report = await runDoctor();
249
+ process.stderr.write(formatDoctorReport(report));
320
250
  });
321
251
  program
322
252
  .command('pull')
@@ -549,6 +479,28 @@ async function main() {
549
479
  }
550
480
  }
551
481
  });
482
+ program
483
+ .command('changelog')
484
+ .description('Generate a changelog from git history (outputs markdown to stdout)')
485
+ .option('--since <ref>', 'Git ref to start from (tag, commit, branch)')
486
+ .action(async (changelogOpts) => {
487
+ const { generateChangelog } = await import('./changelog.js');
488
+ const md = generateChangelog({ since: changelogOpts.since, format: 'markdown' });
489
+ process.stdout.write(md);
490
+ });
491
+ program
492
+ .command('completions')
493
+ .description('Generate shell tab-completion script (bash, zsh, fish)')
494
+ .argument('<shell>', 'Shell type: bash, zsh, or fish')
495
+ .action(async (shell) => {
496
+ const validShells = ['bash', 'zsh', 'fish'];
497
+ if (!validShells.includes(shell)) {
498
+ printError(`Unknown shell: ${shell}. Use: bash, zsh, or fish`);
499
+ process.exit(1);
500
+ }
501
+ const { generateCompletions } = await import('./completions.js');
502
+ process.stdout.write(generateCompletions(shell));
503
+ });
552
504
  program.parse(process.argv);
553
505
  const opts = program.opts();
554
506
  const promptArgs = program.args;
@@ -556,7 +508,7 @@ async function main() {
556
508
  if (opts.quiet)
557
509
  setQuiet(true);
558
510
  // If a sub-command was run, we're done
559
- if (['byok', 'auth', 'ide', 'local', 'ollama', 'openclaw', 'pull', 'doctor', 'serve', 'agents', 'watch', 'voice', 'export', 'plugins'].includes(program.args[0]))
511
+ if (['byok', 'auth', 'ide', 'local', 'ollama', 'openclaw', 'pull', 'doctor', 'serve', 'agents', 'watch', 'voice', 'export', 'plugins', 'changelog', 'completions'].includes(program.args[0]))
560
512
  return;
561
513
  // Check for API key (BYOK or local provider)
562
514
  let byokActive = isByokEnabled();
@@ -1316,44 +1268,7 @@ async function handleSlashCommand(input, opts, rl) {
1316
1268
  printHelp();
1317
1269
  break;
1318
1270
  case 'tutorial': {
1319
- console.log();
1320
- console.log(chalk.bold(' Let\'s build something together. Pick a track:'));
1321
- console.log();
1322
- console.log(` ${chalk.bold('1.')} ${chalk.hex('#4ADE80')('Build a website')} — Create an HTML page from scratch`);
1323
- console.log(` ${chalk.bold('2.')} ${chalk.hex('#60A5FA')('Fix a bug')} — Find and fix a problem in code`);
1324
- console.log(` ${chalk.bold('3.')} ${chalk.hex('#FB923C')('Write a script')} — Automate something with Python or JavaScript`);
1325
- console.log(` ${chalk.bold('4.')} ${chalk.hex('#F472B6')('Research a topic')} — Deep-dive into any subject`);
1326
- console.log(` ${chalk.bold('5.')} ${chalk.hex('#A78BFA')('Explore this project')} — Understand the code in this folder`);
1327
- console.log();
1328
- console.log(chalk.dim(' Pick a number, or just type what you want to build.'));
1329
- console.log();
1330
- const tutorialInput = await new Promise((resolve) => {
1331
- rl.question(' Your choice: ', (answer) => resolve(answer.trim()));
1332
- });
1333
- const tutorialPrompts = {
1334
- '1': 'Create a simple, beautiful HTML page with a heading, a paragraph about me, and some CSS styling. Save it as index.html. Walk me through what each part does.',
1335
- '2': 'Look at the files in this directory. Find any issues, bugs, or things that could be improved. Explain what you found and fix the most important one.',
1336
- '3': 'Write a short script that lists all files in the current directory, sorted by size. Use the language that makes the most sense for this project. Explain each line.',
1337
- '4': 'I want to understand how AI agents work. Research this topic and explain it simply — what are agents, how do they think, and what tools do they use? Give real examples.',
1338
- '5': 'Explore this project directory. What language is it written in? What does it do? What are the most important files? Give me a quick tour.',
1339
- };
1340
- const prompt = tutorialPrompts[tutorialInput] || tutorialInput;
1341
- if (prompt) {
1342
- console.log();
1343
- printInfo('Great choice! Let me work on that...');
1344
- console.log();
1345
- try {
1346
- const response = await runAgent(prompt, opts);
1347
- if (!response.streamed) {
1348
- printResponse(response.agent, response.content);
1349
- }
1350
- console.log();
1351
- printInfo(chalk.dim('That\'s the basics! Keep asking questions — I learn from every conversation.'));
1352
- }
1353
- catch (err) {
1354
- printError(err instanceof Error ? err.message : String(err));
1355
- }
1356
- }
1271
+ await runTutorial(rl);
1357
1272
  break;
1358
1273
  }
1359
1274
  case 'agent':
@@ -1557,6 +1472,73 @@ async function handleSlashCommand(input, opts, rl) {
1557
1472
  }
1558
1473
  break;
1559
1474
  }
1475
+ case 'map-elites':
1476
+ case 'elites':
1477
+ case 'qd': {
1478
+ const { initArchive, getArchiveStats, getArchiveCoverage } = await import('./quality-diversity.js');
1479
+ initArchive();
1480
+ const stats = getArchiveStats();
1481
+ printInfo(`MAP-Elites Archive: ${stats.totalElites} elites, ${(stats.coverage * 100).toFixed(0)}% coverage, avg fitness ${stats.avgFitness.toFixed(3)}`);
1482
+ console.log();
1483
+ console.log(getArchiveCoverage());
1484
+ if (stats.topElites.length > 0) {
1485
+ console.log();
1486
+ printInfo('Top elites:');
1487
+ for (const e of stats.topElites.slice(0, 5)) {
1488
+ printInfo(` fitness=${e.fitness.toFixed(3)} tools=${e.pattern.toolSequence.join('→')} uses=${e.metadata.uses}`);
1489
+ }
1490
+ }
1491
+ break;
1492
+ }
1493
+ case 'evolve': {
1494
+ const sub = args[0];
1495
+ if (sub === 'status') {
1496
+ const { formatEvolutionStatus } = await import('./evolution.js');
1497
+ console.log(formatEvolutionStatus());
1498
+ }
1499
+ else if (sub === 'diagnose') {
1500
+ const { diagnose, formatDiagnosis } = await import('./evolution.js');
1501
+ const weaknesses = diagnose();
1502
+ console.log(formatDiagnosis(weaknesses));
1503
+ }
1504
+ else if (sub === 'log') {
1505
+ const { getEvolutionLog } = await import('./evolution.js');
1506
+ const log = getEvolutionLog();
1507
+ if (log.length === 0) {
1508
+ printInfo('No evolution cycles recorded yet. Run /evolve to start one.');
1509
+ }
1510
+ else {
1511
+ for (const cycle of log.slice(-5)) {
1512
+ const applied = cycle.results.filter(r => r.status === 'applied').length;
1513
+ const rolled = cycle.results.filter(r => r.status === 'rolled-back').length;
1514
+ printInfo(`${cycle.id} ${cycle.status} applied=${applied} rolled-back=${rolled} ${cycle.startedAt}`);
1515
+ }
1516
+ }
1517
+ }
1518
+ else {
1519
+ // Run a full evolution cycle
1520
+ printInfo('Starting evolution cycle...');
1521
+ const { diagnose, formatDiagnosis, runEvolutionCycle } = await import('./evolution.js');
1522
+ const weaknesses = diagnose();
1523
+ console.log(formatDiagnosis(weaknesses));
1524
+ if (weaknesses.length > 0) {
1525
+ printInfo('Proposing improvements...');
1526
+ const cycle = await runEvolutionCycle();
1527
+ for (const r of cycle.results) {
1528
+ const icon = r.status === 'applied' ? '✓' : r.status === 'rolled-back' ? '✗' : '○';
1529
+ const msg = `${icon} ${r.weakness.area}: ${r.reason.slice(0, 80)}`;
1530
+ if (r.status === 'applied')
1531
+ printSuccess(msg);
1532
+ else if (r.status === 'rolled-back')
1533
+ printError(msg);
1534
+ else
1535
+ printInfo(msg);
1536
+ }
1537
+ printInfo(`Cycle ${cycle.id} ${cycle.status}`);
1538
+ }
1539
+ }
1540
+ break;
1541
+ }
1560
1542
  case 'confidence': {
1561
1543
  const task = args.join(' ') || 'general task';
1562
1544
  const { estimateConfidence, reportConfidence } = await import('./confidence.js');
@@ -1885,6 +1867,13 @@ async function handleSlashCommand(input, opts, rl) {
1885
1867
  }
1886
1868
  break;
1887
1869
  }
1870
+ case 'changelog': {
1871
+ const { generateChangelog } = await import('./changelog.js');
1872
+ const since = args[0] || undefined;
1873
+ const output = generateChangelog({ since, format: 'terminal' });
1874
+ console.log(output);
1875
+ break;
1876
+ }
1888
1877
  case 'local':
1889
1878
  case 'ollama': {
1890
1879
  if (args[0] === 'off') {
@@ -2097,6 +2086,13 @@ async function handleSlashCommand(input, opts, rl) {
2097
2086
  console.log(formatRateLimitStatus());
2098
2087
  break;
2099
2088
  }
2089
+ case 'doctor': {
2090
+ const { runDoctor, formatDoctorReport } = await import('./doctor.js');
2091
+ printInfo('Running diagnostics...');
2092
+ const doctorReport = await runDoctor();
2093
+ process.stderr.write(formatDoctorReport(doctorReport));
2094
+ break;
2095
+ }
2100
2096
  case 'quit':
2101
2097
  case 'exit':
2102
2098
  rl.close();