@kernel.chat/kbot 2.12.0 → 2.13.1
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 +17 -6
- package/dist/changelog.d.ts +21 -0
- package/dist/changelog.d.ts.map +1 -0
- package/dist/changelog.js +204 -0
- package/dist/changelog.js.map +1 -0
- package/dist/cli.js +43 -114
- package/dist/cli.js.map +1 -1
- package/dist/completions.d.ts +2 -0
- package/dist/completions.d.ts.map +1 -0
- package/dist/completions.js +526 -0
- package/dist/completions.js.map +1 -0
- package/dist/doctor.d.ts +15 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +381 -0
- package/dist/doctor.js.map +1 -0
- package/dist/ide/acp-server.js +1 -1
- package/dist/tutorial.d.ts +3 -0
- package/dist/tutorial.d.ts.map +1 -0
- package/dist/tutorial.js +195 -0
- package/dist/tutorial.js.map +1 -0
- package/package.json +19 -13
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<strong>K:BOT</strong><br>
|
|
3
|
-
Open-source terminal AI agent. 39 specialists, 167 tools, 19 providers, local-first.
|
|
3
|
+
Open-source terminal AI agent. 39 specialists, 167 tools, 19 providers, local-first. The first CLI agent that evolves its own source code.
|
|
4
4
|
</p>
|
|
5
5
|
|
|
6
6
|
<p align="center">
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
- **19 providers, zero lock-in** — Claude, GPT, Gemini, Mistral, Grok, DeepSeek, SambaNova, Cerebras, OpenRouter, and more
|
|
16
16
|
- **Runs fully offline** — `kbot local` for $0 local AI, no data leaves your machine
|
|
17
17
|
- **Learns your patterns** — remembers what worked, gets faster over time
|
|
18
|
-
- **
|
|
18
|
+
- **39 specialist agents** — auto-routes to the right expert for each task
|
|
19
|
+
- **Self-evolving** — diagnoses its own weaknesses and improves its own code (`/evolve`)
|
|
20
|
+
- **Shell completions** — tab completion for bash, zsh, and fish (`kbot completions zsh`)
|
|
19
21
|
- **MCP server built in** — plug kbot into any IDE as a tool provider
|
|
20
22
|
|
|
21
23
|
## Quick Start
|
|
@@ -34,6 +36,14 @@ kbot local
|
|
|
34
36
|
kbot
|
|
35
37
|
```
|
|
36
38
|
|
|
39
|
+
## What's New in v2.13.0
|
|
40
|
+
|
|
41
|
+
- **Self-evolution engine** — K:BOT diagnoses weaknesses, proposes code changes, validates them (typecheck + tests), and applies improvements automatically (`/evolve`)
|
|
42
|
+
- **Shell completions** — Tab completion for bash, zsh, fish (`kbot completions zsh >> ~/.zshrc`)
|
|
43
|
+
- **Interactive tutorial** — Step-by-step walkthrough for new users (`/tutorial`)
|
|
44
|
+
- **Changelog generator** — Auto-generate release notes from git history (`kbot changelog`)
|
|
45
|
+
- **Doctor diagnostics** — 10-point health check for your setup (`kbot doctor`)
|
|
46
|
+
|
|
37
47
|
## One-Shot Mode
|
|
38
48
|
|
|
39
49
|
```bash
|
|
@@ -43,18 +53,19 @@ kbot "deploy to production"
|
|
|
43
53
|
kbot -p "generate a migration for user roles" > migration.sql
|
|
44
54
|
```
|
|
45
55
|
|
|
46
|
-
## Specialists (
|
|
56
|
+
## Specialists (39)
|
|
47
57
|
|
|
48
58
|
Auto-routed or manual with `kbot --agent <name>`:
|
|
49
59
|
|
|
50
60
|
**Core**: kernel, researcher, coder, writer, analyst
|
|
51
61
|
**Extended**: aesthete, guardian, curator, strategist, infrastructure, quant, investigator, oracle, chronist, sage, communicator, adapter
|
|
52
62
|
**Domain**: physicist, mathematician, biologist, economist, psychologist, engineer, medic, linguist, ethicist, educator, diplomat
|
|
63
|
+
**Creative**: creative, developer, hacker, operator, dreamer
|
|
53
64
|
**Systems**: session, scholar, auditor, benchmarker, synthesizer, debugger
|
|
54
65
|
|
|
55
66
|
## Features
|
|
56
67
|
|
|
57
|
-
- **
|
|
68
|
+
- **167 Tools** — File ops, bash, git, GitHub, web search, Jupyter, Docker sandbox, browser, MCP client
|
|
58
69
|
- **Local-First** — File reads, git, grep run instantly without an API call
|
|
59
70
|
- **Learning Engine** — Patterns, solutions, and user preferences cached across sessions
|
|
60
71
|
- **Mimic Matrix** — Code like Claude Code, Cursor, Copilot, Next.js, React, Rust, Python
|
|
@@ -109,7 +120,7 @@ Works with Claude Code, Cursor, VS Code, Windsurf, Zed, Neovim. Exposes 14 tools
|
|
|
109
120
|
kbot serve --port 7437 --token mysecret
|
|
110
121
|
```
|
|
111
122
|
|
|
112
|
-
REST API exposing all
|
|
123
|
+
REST API exposing all 167 tools for any LLM or automation pipeline.
|
|
113
124
|
|
|
114
125
|
## Commands
|
|
115
126
|
|
|
@@ -136,7 +147,7 @@ REST API exposing all 60+ tools for any LLM or automation pipeline.
|
|
|
136
147
|
|
|
137
148
|
## Web Companion
|
|
138
149
|
|
|
139
|
-
[kernel.chat](https://kernel.chat) — same
|
|
150
|
+
[kernel.chat](https://kernel.chat) — same 39 agents with a visual interface. Free (20 msgs/day).
|
|
140
151
|
|
|
141
152
|
## Links
|
|
142
153
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface ChangelogOptions {
|
|
2
|
+
/** Git ref to start from (default: last tag or last 20 commits) */
|
|
3
|
+
since?: string;
|
|
4
|
+
/** Output format — 'markdown' for release notes, 'terminal' for CLI display */
|
|
5
|
+
format?: 'markdown' | 'terminal';
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Generate a changelog from git history.
|
|
9
|
+
*
|
|
10
|
+
* Groups commits by conventional commit prefix and formats them
|
|
11
|
+
* as either markdown (for release notes / piping) or terminal
|
|
12
|
+
* (colored output for the REPL).
|
|
13
|
+
*/
|
|
14
|
+
export declare function generateChangelog(options?: ChangelogOptions): string;
|
|
15
|
+
/**
|
|
16
|
+
* Format a markdown changelog string for colored terminal output.
|
|
17
|
+
* Use this to colorize changelog text that was already generated
|
|
18
|
+
* in markdown format.
|
|
19
|
+
*/
|
|
20
|
+
export declare function formatChangelogTerminal(changelog: string): string;
|
|
21
|
+
//# sourceMappingURL=changelog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changelog.d.ts","sourceRoot":"","sources":["../src/changelog.ts"],"names":[],"mappings":"AA8GA,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+EAA+E;IAC/E,MAAM,CAAC,EAAE,UAAU,GAAG,UAAU,CAAA;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM,CA2BpE;AA4ED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAqBjE"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// K:BOT Changelog Generator — Auto-generate release notes from git history
|
|
2
|
+
//
|
|
3
|
+
// Usage:
|
|
4
|
+
// import { generateChangelog, formatChangelogTerminal } from './changelog.js'
|
|
5
|
+
// const md = generateChangelog({ since: 'v2.11.0', format: 'markdown' })
|
|
6
|
+
// const colored = formatChangelogTerminal(md)
|
|
7
|
+
//
|
|
8
|
+
// CLI:
|
|
9
|
+
// $ kbot changelog # Markdown to stdout (pipeable)
|
|
10
|
+
// $ kbot changelog --since v2.11.0
|
|
11
|
+
// REPL: /changelog # Colored terminal output
|
|
12
|
+
import { execSync } from 'node:child_process';
|
|
13
|
+
import { readFileSync } from 'node:fs';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
import chalk from 'chalk';
|
|
16
|
+
const CATEGORY_MAP = {
|
|
17
|
+
'feat': 'Features',
|
|
18
|
+
'fix': 'Bug Fixes',
|
|
19
|
+
'perf': 'Performance',
|
|
20
|
+
'refactor': 'Refactoring',
|
|
21
|
+
'test': 'Tests',
|
|
22
|
+
'docs': 'Documentation',
|
|
23
|
+
'chore': 'Maintenance',
|
|
24
|
+
};
|
|
25
|
+
const CATEGORY_ORDER = [
|
|
26
|
+
'Features',
|
|
27
|
+
'Bug Fixes',
|
|
28
|
+
'Performance',
|
|
29
|
+
'Refactoring',
|
|
30
|
+
'Tests',
|
|
31
|
+
'Documentation',
|
|
32
|
+
'Maintenance',
|
|
33
|
+
'Other Changes',
|
|
34
|
+
];
|
|
35
|
+
// ── Git helpers ──
|
|
36
|
+
function getLastTag() {
|
|
37
|
+
try {
|
|
38
|
+
return execSync('git describe --tags --abbrev=0', {
|
|
39
|
+
cwd: process.cwd(),
|
|
40
|
+
encoding: 'utf-8',
|
|
41
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
42
|
+
}).trim();
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function getCommits(since) {
|
|
49
|
+
const range = since ? `${since}..HEAD` : '';
|
|
50
|
+
const limit = since ? '' : '-20';
|
|
51
|
+
const format = '%h %s'; // short hash + subject
|
|
52
|
+
const cmd = `git log ${range} ${limit} --format="${format}"`.replace(/\s+/g, ' ').trim();
|
|
53
|
+
let output;
|
|
54
|
+
try {
|
|
55
|
+
output = execSync(cmd, {
|
|
56
|
+
cwd: process.cwd(),
|
|
57
|
+
encoding: 'utf-8',
|
|
58
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
59
|
+
}).trim();
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
if (!output)
|
|
65
|
+
return [];
|
|
66
|
+
return output.split('\n').map(line => {
|
|
67
|
+
const spaceIdx = line.indexOf(' ');
|
|
68
|
+
const hash = line.slice(0, spaceIdx);
|
|
69
|
+
const subject = line.slice(spaceIdx + 1);
|
|
70
|
+
const category = categorize(subject);
|
|
71
|
+
return { hash, subject, category };
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function categorize(subject) {
|
|
75
|
+
const match = subject.match(/^(\w+)(?:\(.+?\))?:\s/);
|
|
76
|
+
if (match) {
|
|
77
|
+
const prefix = match[1].toLowerCase();
|
|
78
|
+
return CATEGORY_MAP[prefix] || 'Other Changes';
|
|
79
|
+
}
|
|
80
|
+
return 'Other Changes';
|
|
81
|
+
}
|
|
82
|
+
function getVersion() {
|
|
83
|
+
try {
|
|
84
|
+
const pkgPath = join(process.cwd(), 'package.json');
|
|
85
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
86
|
+
return pkg.version || 'unreleased';
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return 'unreleased';
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Generate a changelog from git history.
|
|
94
|
+
*
|
|
95
|
+
* Groups commits by conventional commit prefix and formats them
|
|
96
|
+
* as either markdown (for release notes / piping) or terminal
|
|
97
|
+
* (colored output for the REPL).
|
|
98
|
+
*/
|
|
99
|
+
export function generateChangelog(options) {
|
|
100
|
+
const format = options?.format || 'markdown';
|
|
101
|
+
const since = options?.since || getLastTag() || undefined;
|
|
102
|
+
const commits = getCommits(since);
|
|
103
|
+
if (commits.length === 0) {
|
|
104
|
+
return format === 'terminal'
|
|
105
|
+
? 'No commits found.'
|
|
106
|
+
: '> No commits found.\n';
|
|
107
|
+
}
|
|
108
|
+
// Group by category
|
|
109
|
+
const groups = {};
|
|
110
|
+
for (const commit of commits) {
|
|
111
|
+
if (!groups[commit.category])
|
|
112
|
+
groups[commit.category] = [];
|
|
113
|
+
groups[commit.category].push(commit);
|
|
114
|
+
}
|
|
115
|
+
const version = getVersion();
|
|
116
|
+
const date = new Date().toISOString().slice(0, 10);
|
|
117
|
+
const sinceLabel = since ? ` (since ${since})` : '';
|
|
118
|
+
if (format === 'terminal') {
|
|
119
|
+
return buildTerminalChangelog(version, date, sinceLabel, groups);
|
|
120
|
+
}
|
|
121
|
+
return buildMarkdownChangelog(version, date, sinceLabel, groups);
|
|
122
|
+
}
|
|
123
|
+
// ── Markdown output (pipeable) ──
|
|
124
|
+
function buildMarkdownChangelog(version, date, sinceLabel, groups) {
|
|
125
|
+
const lines = [];
|
|
126
|
+
lines.push(`# ${version}${sinceLabel}`);
|
|
127
|
+
lines.push('');
|
|
128
|
+
lines.push(`_${date}_`);
|
|
129
|
+
lines.push('');
|
|
130
|
+
for (const category of CATEGORY_ORDER) {
|
|
131
|
+
const entries = groups[category];
|
|
132
|
+
if (!entries || entries.length === 0)
|
|
133
|
+
continue;
|
|
134
|
+
lines.push(`## ${category}`);
|
|
135
|
+
lines.push('');
|
|
136
|
+
for (const entry of entries) {
|
|
137
|
+
// Strip the prefix from the subject for cleaner display
|
|
138
|
+
const clean = stripPrefix(entry.subject);
|
|
139
|
+
lines.push(`- ${clean} (\`${entry.hash}\`)`);
|
|
140
|
+
}
|
|
141
|
+
lines.push('');
|
|
142
|
+
}
|
|
143
|
+
return lines.join('\n');
|
|
144
|
+
}
|
|
145
|
+
// ── Terminal output (colored) ──
|
|
146
|
+
function buildTerminalChangelog(version, date, sinceLabel, groups) {
|
|
147
|
+
const useColor = !process.env.NO_COLOR && process.stdout.isTTY !== false;
|
|
148
|
+
const ACCENT = useColor ? chalk.hex('#A78BFA') : (s) => s;
|
|
149
|
+
const DIM = useColor ? chalk.dim : (s) => s;
|
|
150
|
+
const GREEN = useColor ? chalk.hex('#4ADE80') : (s) => s;
|
|
151
|
+
const CYAN = useColor ? chalk.hex('#67E8F9') : (s) => s;
|
|
152
|
+
const lines = [];
|
|
153
|
+
lines.push('');
|
|
154
|
+
lines.push(` ${chalk.bold(ACCENT(`v${version}`))} ${DIM(date)}${DIM(sinceLabel)}`);
|
|
155
|
+
lines.push(` ${DIM('─'.repeat(50))}`);
|
|
156
|
+
for (const category of CATEGORY_ORDER) {
|
|
157
|
+
const entries = groups[category];
|
|
158
|
+
if (!entries || entries.length === 0)
|
|
159
|
+
continue;
|
|
160
|
+
lines.push('');
|
|
161
|
+
lines.push(` ${chalk.bold(category)}`);
|
|
162
|
+
for (const entry of entries) {
|
|
163
|
+
const clean = stripPrefix(entry.subject);
|
|
164
|
+
lines.push(` ${DIM('•')} ${clean} ${CYAN(entry.hash)}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const total = Object.values(groups).reduce((sum, g) => sum + g.length, 0);
|
|
168
|
+
lines.push('');
|
|
169
|
+
lines.push(` ${GREEN(`${total} commits`)}${DIM(sinceLabel || ' (last 20)')}`);
|
|
170
|
+
lines.push('');
|
|
171
|
+
return lines.join('\n');
|
|
172
|
+
}
|
|
173
|
+
// ── Formatting helpers ──
|
|
174
|
+
/**
|
|
175
|
+
* Format a markdown changelog string for colored terminal output.
|
|
176
|
+
* Use this to colorize changelog text that was already generated
|
|
177
|
+
* in markdown format.
|
|
178
|
+
*/
|
|
179
|
+
export function formatChangelogTerminal(changelog) {
|
|
180
|
+
const useColor = !process.env.NO_COLOR && process.stdout.isTTY !== false;
|
|
181
|
+
if (!useColor)
|
|
182
|
+
return changelog;
|
|
183
|
+
const ACCENT = chalk.hex('#A78BFA');
|
|
184
|
+
const DIM = chalk.dim;
|
|
185
|
+
const CYAN = chalk.hex('#67E8F9');
|
|
186
|
+
return changelog
|
|
187
|
+
// H1 headers — version line
|
|
188
|
+
.replace(/^# (.+)$/gm, (_m, h) => ` ${chalk.bold(ACCENT(h))}`)
|
|
189
|
+
// H2 headers — category
|
|
190
|
+
.replace(/^## (.+)$/gm, (_m, h) => `\n ${chalk.bold(h)}`)
|
|
191
|
+
// Date line (italic in markdown)
|
|
192
|
+
.replace(/^_(.+)_$/gm, (_m, d) => ` ${DIM(d)}`)
|
|
193
|
+
// Bullet points with inline code (commit hash)
|
|
194
|
+
.replace(/^- (.+?) \(`([^`]+)`\)$/gm, (_m, text, hash) => ` ${DIM('•')} ${text} ${CYAN(hash)}`)
|
|
195
|
+
// Remaining bullet points
|
|
196
|
+
.replace(/^- (.+)$/gm, (_m, t) => ` ${DIM('•')} ${t}`)
|
|
197
|
+
// Inline code
|
|
198
|
+
.replace(/`([^`]+)`/g, (_m, c) => CYAN(c));
|
|
199
|
+
}
|
|
200
|
+
function stripPrefix(subject) {
|
|
201
|
+
// Remove "feat(scope): " or "fix: " prefixes for cleaner display
|
|
202
|
+
return subject.replace(/^\w+(?:\(.+?\))?:\s*/, '');
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=changelog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changelog.js","sourceRoot":"","sources":["../src/changelog.ts"],"names":[],"mappings":"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"}
|
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.
|
|
26
|
+
const VERSION = '2.13.1';
|
|
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
|
-
|
|
247
|
-
|
|
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
|
-
|
|
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':
|
|
@@ -1952,6 +1867,13 @@ async function handleSlashCommand(input, opts, rl) {
|
|
|
1952
1867
|
}
|
|
1953
1868
|
break;
|
|
1954
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
|
+
}
|
|
1955
1877
|
case 'local':
|
|
1956
1878
|
case 'ollama': {
|
|
1957
1879
|
if (args[0] === 'off') {
|
|
@@ -2164,6 +2086,13 @@ async function handleSlashCommand(input, opts, rl) {
|
|
|
2164
2086
|
console.log(formatRateLimitStatus());
|
|
2165
2087
|
break;
|
|
2166
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
|
+
}
|
|
2167
2096
|
case 'quit':
|
|
2168
2097
|
case 'exit':
|
|
2169
2098
|
rl.close();
|