@kernel.chat/kbot 2.9.1 → 2.10.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.
Files changed (54) hide show
  1. package/README.md +5 -5
  2. package/dist/agent.js +1 -1
  3. package/dist/agent.js.map +1 -1
  4. package/dist/cli.js +221 -24
  5. package/dist/cli.js.map +1 -1
  6. package/dist/context-manager.d.ts.map +1 -1
  7. package/dist/context-manager.js +31 -5
  8. package/dist/context-manager.js.map +1 -1
  9. package/dist/context-manager.test.d.ts +2 -0
  10. package/dist/context-manager.test.d.ts.map +1 -0
  11. package/dist/context-manager.test.js +121 -0
  12. package/dist/context-manager.test.js.map +1 -0
  13. package/dist/export.d.ts +20 -0
  14. package/dist/export.d.ts.map +1 -0
  15. package/dist/export.js +301 -0
  16. package/dist/export.js.map +1 -0
  17. package/dist/ide/acp-server.js +2 -2
  18. package/dist/ide/acp-server.js.map +1 -1
  19. package/dist/marketplace.d.ts +25 -0
  20. package/dist/marketplace.d.ts.map +1 -0
  21. package/dist/marketplace.js +327 -0
  22. package/dist/marketplace.js.map +1 -0
  23. package/dist/rate-limiter.d.ts +45 -0
  24. package/dist/rate-limiter.d.ts.map +1 -0
  25. package/dist/rate-limiter.js +200 -0
  26. package/dist/rate-limiter.js.map +1 -0
  27. package/dist/sessions.test.d.ts +2 -0
  28. package/dist/sessions.test.d.ts.map +1 -0
  29. package/dist/sessions.test.js +55 -0
  30. package/dist/sessions.test.js.map +1 -0
  31. package/dist/streaming.d.ts.map +1 -1
  32. package/dist/streaming.js +87 -24
  33. package/dist/streaming.js.map +1 -1
  34. package/dist/streaming.test.d.ts +2 -0
  35. package/dist/streaming.test.d.ts.map +1 -0
  36. package/dist/streaming.test.js +41 -0
  37. package/dist/streaming.test.js.map +1 -0
  38. package/dist/tools/index.d.ts.map +1 -1
  39. package/dist/tools/index.js +3 -1
  40. package/dist/tools/index.js.map +1 -1
  41. package/dist/tools/test-runner.d.ts +2 -0
  42. package/dist/tools/test-runner.d.ts.map +1 -0
  43. package/dist/tools/test-runner.js +550 -0
  44. package/dist/tools/test-runner.js.map +1 -0
  45. package/dist/ui.js +1 -1
  46. package/dist/voice.d.ts +25 -0
  47. package/dist/voice.d.ts.map +1 -0
  48. package/dist/voice.js +336 -0
  49. package/dist/voice.js.map +1 -0
  50. package/dist/watch.d.ts +37 -0
  51. package/dist/watch.d.ts.map +1 -0
  52. package/dist/watch.js +369 -0
  53. package/dist/watch.js.map +1 -0
  54. package/package.json +3 -3
@@ -0,0 +1,550 @@
1
+ import { registerTool } from './index.js';
2
+ import { execSync } from 'node:child_process';
3
+ import { existsSync, readFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ function detectFramework(projectPath) {
6
+ // 1. Vitest — explicit config or vite config with test section
7
+ const vitestConfigs = [
8
+ 'vitest.config.ts',
9
+ 'vitest.config.js',
10
+ 'vitest.config.mts',
11
+ 'vitest.config.mjs',
12
+ ];
13
+ for (const cfg of vitestConfigs) {
14
+ if (existsSync(join(projectPath, cfg)))
15
+ return 'vitest';
16
+ }
17
+ // Check vite.config.* for a `test` key (lightweight heuristic)
18
+ const viteConfigs = [
19
+ 'vite.config.ts',
20
+ 'vite.config.js',
21
+ 'vite.config.mts',
22
+ 'vite.config.mjs',
23
+ ];
24
+ for (const cfg of viteConfigs) {
25
+ const p = join(projectPath, cfg);
26
+ if (existsSync(p)) {
27
+ try {
28
+ const content = readFileSync(p, 'utf-8');
29
+ if (/\btest\s*[:{]/.test(content))
30
+ return 'vitest';
31
+ }
32
+ catch {
33
+ // ignore read errors
34
+ }
35
+ }
36
+ }
37
+ // 2. Jest — explicit config or "jest" key in package.json
38
+ const jestConfigs = [
39
+ 'jest.config.ts',
40
+ 'jest.config.js',
41
+ 'jest.config.mjs',
42
+ 'jest.config.cjs',
43
+ 'jest.config.json',
44
+ ];
45
+ for (const cfg of jestConfigs) {
46
+ if (existsSync(join(projectPath, cfg)))
47
+ return 'jest';
48
+ }
49
+ const pkgPath = join(projectPath, 'package.json');
50
+ if (existsSync(pkgPath)) {
51
+ try {
52
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
53
+ if (pkg.jest)
54
+ return 'jest';
55
+ }
56
+ catch {
57
+ // ignore parse errors
58
+ }
59
+ }
60
+ // 3. Pytest
61
+ if (existsSync(join(projectPath, 'pytest.ini')))
62
+ return 'pytest';
63
+ if (existsSync(join(projectPath, 'setup.cfg'))) {
64
+ try {
65
+ const content = readFileSync(join(projectPath, 'setup.cfg'), 'utf-8');
66
+ if (/\[tool:pytest\]/.test(content))
67
+ return 'pytest';
68
+ }
69
+ catch {
70
+ // ignore
71
+ }
72
+ }
73
+ if (existsSync(join(projectPath, 'pyproject.toml'))) {
74
+ try {
75
+ const content = readFileSync(join(projectPath, 'pyproject.toml'), 'utf-8');
76
+ if (/\[tool\.pytest/.test(content))
77
+ return 'pytest';
78
+ }
79
+ catch {
80
+ // ignore
81
+ }
82
+ }
83
+ // 4. Cargo (Rust)
84
+ if (existsSync(join(projectPath, 'Cargo.toml')))
85
+ return 'cargo';
86
+ // 5. Go
87
+ if (existsSync(join(projectPath, 'go.mod')))
88
+ return 'go';
89
+ // 6. Fallback — npm test script
90
+ if (existsSync(pkgPath)) {
91
+ try {
92
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
93
+ if (pkg.scripts?.test && pkg.scripts.test !== 'echo "Error: no test specified" && exit 1') {
94
+ return 'npm';
95
+ }
96
+ }
97
+ catch {
98
+ // ignore
99
+ }
100
+ }
101
+ return null;
102
+ }
103
+ // ---------------------------------------------------------------------------
104
+ // Command builders
105
+ // ---------------------------------------------------------------------------
106
+ function buildCommand(framework, opts) {
107
+ switch (framework) {
108
+ case 'vitest': {
109
+ let cmd = 'npx vitest run --reporter=json';
110
+ if (opts.file)
111
+ cmd += ` ${opts.file}`;
112
+ else if (opts.pattern)
113
+ cmd += ` --testPathPattern="${opts.pattern}"`;
114
+ return cmd;
115
+ }
116
+ case 'jest': {
117
+ let cmd = 'npx jest --json';
118
+ if (opts.file)
119
+ cmd += ` ${opts.file}`;
120
+ else if (opts.pattern)
121
+ cmd += ` --testPathPattern="${opts.pattern}"`;
122
+ return cmd;
123
+ }
124
+ case 'pytest': {
125
+ let cmd = 'python -m pytest --tb=short -q';
126
+ if (opts.file)
127
+ cmd += ` ${opts.file}`;
128
+ else if (opts.pattern)
129
+ cmd += ` -k "${opts.pattern}"`;
130
+ if (opts.verbose)
131
+ cmd += ' -v';
132
+ return cmd;
133
+ }
134
+ case 'cargo': {
135
+ let cmd = 'cargo test';
136
+ if (opts.file)
137
+ cmd += ` --test ${opts.file}`;
138
+ else if (opts.pattern)
139
+ cmd += ` ${opts.pattern}`;
140
+ cmd += ' 2>&1';
141
+ return cmd;
142
+ }
143
+ case 'go': {
144
+ let cmd = 'go test';
145
+ if (opts.file)
146
+ cmd += ` ${opts.file}`;
147
+ else
148
+ cmd += ' ./...';
149
+ if (opts.verbose)
150
+ cmd += ' -v';
151
+ cmd += ' 2>&1';
152
+ return cmd;
153
+ }
154
+ case 'npm': {
155
+ return 'npm test 2>&1';
156
+ }
157
+ }
158
+ }
159
+ // ---------------------------------------------------------------------------
160
+ // Output parsers
161
+ // ---------------------------------------------------------------------------
162
+ function parseVitestJson(raw) {
163
+ const result = {
164
+ framework: 'vitest',
165
+ total: 0,
166
+ passed: 0,
167
+ failed: 0,
168
+ skipped: 0,
169
+ failures: [],
170
+ };
171
+ try {
172
+ // vitest --reporter=json may prefix non-JSON output; find the JSON object
173
+ const jsonStart = raw.indexOf('{');
174
+ const jsonEnd = raw.lastIndexOf('}');
175
+ if (jsonStart === -1 || jsonEnd === -1)
176
+ return { ...result, raw };
177
+ const data = JSON.parse(raw.substring(jsonStart, jsonEnd + 1));
178
+ result.total = data.numTotalTests ?? 0;
179
+ result.passed = data.numPassedTests ?? 0;
180
+ result.failed = data.numFailedTests ?? 0;
181
+ result.skipped = (data.numPendingTests ?? 0) + (data.numTodoTests ?? 0);
182
+ if (Array.isArray(data.testResults)) {
183
+ for (const suite of data.testResults) {
184
+ if (suite.status === 'failed' && Array.isArray(suite.assertionResults)) {
185
+ for (const assertion of suite.assertionResults) {
186
+ if (assertion.status === 'failed') {
187
+ result.failures.push({
188
+ name: assertion.ancestorTitles
189
+ ? [...assertion.ancestorTitles, assertion.title].join(' > ')
190
+ : assertion.fullName ?? assertion.title ?? 'unknown',
191
+ message: Array.isArray(assertion.failureMessages)
192
+ ? assertion.failureMessages.join('\n').slice(0, 500)
193
+ : String(assertion.failureMessages ?? '').slice(0, 500),
194
+ });
195
+ }
196
+ }
197
+ }
198
+ }
199
+ }
200
+ }
201
+ catch {
202
+ result.raw = raw;
203
+ }
204
+ return result;
205
+ }
206
+ function parseJestJson(raw) {
207
+ const result = {
208
+ framework: 'jest',
209
+ total: 0,
210
+ passed: 0,
211
+ failed: 0,
212
+ skipped: 0,
213
+ failures: [],
214
+ };
215
+ try {
216
+ const jsonStart = raw.indexOf('{');
217
+ const jsonEnd = raw.lastIndexOf('}');
218
+ if (jsonStart === -1 || jsonEnd === -1)
219
+ return { ...result, raw };
220
+ const data = JSON.parse(raw.substring(jsonStart, jsonEnd + 1));
221
+ result.total = data.numTotalTests ?? 0;
222
+ result.passed = data.numPassedTests ?? 0;
223
+ result.failed = data.numFailedTests ?? 0;
224
+ result.skipped = data.numPendingTests ?? 0;
225
+ if (Array.isArray(data.testResults)) {
226
+ for (const suite of data.testResults) {
227
+ if (Array.isArray(suite.assertionResults)) {
228
+ for (const assertion of suite.assertionResults) {
229
+ if (assertion.status === 'failed') {
230
+ result.failures.push({
231
+ name: assertion.ancestorTitles
232
+ ? [...assertion.ancestorTitles, assertion.title].join(' > ')
233
+ : assertion.fullName ?? assertion.title ?? 'unknown',
234
+ message: Array.isArray(assertion.failureMessages)
235
+ ? assertion.failureMessages.join('\n').slice(0, 500)
236
+ : String(assertion.failureMessages ?? '').slice(0, 500),
237
+ });
238
+ }
239
+ }
240
+ }
241
+ }
242
+ }
243
+ }
244
+ catch {
245
+ result.raw = raw;
246
+ }
247
+ return result;
248
+ }
249
+ function parsePytestOutput(raw) {
250
+ const result = {
251
+ framework: 'pytest',
252
+ total: 0,
253
+ passed: 0,
254
+ failed: 0,
255
+ skipped: 0,
256
+ failures: [],
257
+ };
258
+ // Match summary line: "X passed, Y failed, Z skipped" etc.
259
+ const summaryMatch = raw.match(/(\d+)\s+passed|(\d+)\s+failed|(\d+)\s+error|(\d+)\s+skipped|(\d+)\s+warning/g);
260
+ if (summaryMatch) {
261
+ for (const part of summaryMatch) {
262
+ const numMatch = part.match(/(\d+)\s+(\w+)/);
263
+ if (!numMatch)
264
+ continue;
265
+ const count = parseInt(numMatch[1], 10);
266
+ const label = numMatch[2];
267
+ if (label === 'passed')
268
+ result.passed = count;
269
+ else if (label === 'failed' || label === 'error')
270
+ result.failed += count;
271
+ else if (label === 'skipped')
272
+ result.skipped = count;
273
+ }
274
+ result.total = result.passed + result.failed + result.skipped;
275
+ }
276
+ // Extract FAILED lines
277
+ const failedLines = raw.match(/FAILED\s+(.+?)(?:\s+-\s+(.+))?$/gm);
278
+ if (failedLines) {
279
+ for (const line of failedLines) {
280
+ const m = line.match(/FAILED\s+(.+?)(?:\s+-\s+(.+))?$/);
281
+ if (m) {
282
+ result.failures.push({
283
+ name: m[1].trim(),
284
+ message: m[2]?.trim() ?? '',
285
+ });
286
+ }
287
+ }
288
+ }
289
+ if (result.total === 0)
290
+ result.raw = raw;
291
+ return result;
292
+ }
293
+ function parseCargoOutput(raw) {
294
+ const result = {
295
+ framework: 'cargo',
296
+ total: 0,
297
+ passed: 0,
298
+ failed: 0,
299
+ skipped: 0,
300
+ failures: [],
301
+ };
302
+ // Match "test result: ok/FAILED. X passed; Y failed; Z ignored"
303
+ const summaryMatch = raw.match(/test result:\s*\w+\.\s*(\d+)\s+passed;\s*(\d+)\s+failed;\s*(\d+)\s+ignored/);
304
+ if (summaryMatch) {
305
+ result.passed = parseInt(summaryMatch[1], 10);
306
+ result.failed = parseInt(summaryMatch[2], 10);
307
+ result.skipped = parseInt(summaryMatch[3], 10);
308
+ result.total = result.passed + result.failed + result.skipped;
309
+ }
310
+ // Extract failures: lines matching "---- <test_name> stdout ----" followed by failure text
311
+ const failureBlocks = raw.split(/----\s+(.+?)\s+stdout\s+----/);
312
+ for (let i = 1; i < failureBlocks.length; i += 2) {
313
+ const testName = failureBlocks[i];
314
+ const body = failureBlocks[i + 1] ?? '';
315
+ // Only include if there's an assertion failure
316
+ if (body.includes("thread '") && body.includes('panicked at')) {
317
+ const msgMatch = body.match(/panicked at\s+'([^']+)'/);
318
+ result.failures.push({
319
+ name: testName,
320
+ message: msgMatch ? msgMatch[1].slice(0, 500) : body.slice(0, 500),
321
+ });
322
+ }
323
+ }
324
+ if (result.total === 0)
325
+ result.raw = raw;
326
+ return result;
327
+ }
328
+ function parseGoOutput(raw) {
329
+ const result = {
330
+ framework: 'go',
331
+ total: 0,
332
+ passed: 0,
333
+ failed: 0,
334
+ skipped: 0,
335
+ failures: [],
336
+ };
337
+ // Count pass/fail from "--- PASS:" and "--- FAIL:" lines
338
+ const passMatches = raw.match(/---\s+PASS:/g);
339
+ const failMatches = raw.match(/---\s+FAIL:/g);
340
+ const skipMatches = raw.match(/---\s+SKIP:/g);
341
+ result.passed = passMatches?.length ?? 0;
342
+ result.failed = failMatches?.length ?? 0;
343
+ result.skipped = skipMatches?.length ?? 0;
344
+ result.total = result.passed + result.failed + result.skipped;
345
+ // Extract failure details
346
+ const failLines = raw.match(/---\s+FAIL:\s+(\S+)\s+\([\d.]+s\)/g);
347
+ if (failLines) {
348
+ for (const line of failLines) {
349
+ const m = line.match(/---\s+FAIL:\s+(\S+)/);
350
+ if (m) {
351
+ // Try to find the error message above this FAIL line
352
+ const idx = raw.indexOf(line);
353
+ const preceding = raw.substring(Math.max(0, idx - 500), idx);
354
+ const errLines = preceding
355
+ .split('\n')
356
+ .filter((l) => l.includes('Error') || l.includes('expected') || l.includes('got'))
357
+ .slice(-3);
358
+ result.failures.push({
359
+ name: m[1],
360
+ message: errLines.join('\n').slice(0, 500) || 'Test failed',
361
+ });
362
+ }
363
+ }
364
+ }
365
+ // Fallback: check for "FAIL" at package level if no individual tests found
366
+ if (result.total === 0) {
367
+ const pkgFail = raw.match(/^FAIL\s+\S+/gm);
368
+ const pkgOk = raw.match(/^ok\s+\S+/gm);
369
+ if (pkgFail || pkgOk) {
370
+ result.failed = pkgFail?.length ?? 0;
371
+ result.passed = pkgOk?.length ?? 0;
372
+ result.total = result.passed + result.failed;
373
+ }
374
+ }
375
+ if (result.total === 0)
376
+ result.raw = raw;
377
+ return result;
378
+ }
379
+ function parseGenericOutput(raw) {
380
+ const result = {
381
+ framework: 'npm',
382
+ total: 0,
383
+ passed: 0,
384
+ failed: 0,
385
+ skipped: 0,
386
+ failures: [],
387
+ raw,
388
+ };
389
+ // Try common patterns
390
+ // "X passing", "Y failing", "Z pending"
391
+ const passingMatch = raw.match(/(\d+)\s+passing/i);
392
+ const failingMatch = raw.match(/(\d+)\s+failing/i);
393
+ const pendingMatch = raw.match(/(\d+)\s+pending/i);
394
+ if (passingMatch)
395
+ result.passed = parseInt(passingMatch[1], 10);
396
+ if (failingMatch)
397
+ result.failed = parseInt(failingMatch[1], 10);
398
+ if (pendingMatch)
399
+ result.skipped = parseInt(pendingMatch[1], 10);
400
+ // "Tests: X passed, Y failed, Z total"
401
+ const testsLine = raw.match(/Tests:\s*(\d+)\s+passed.*?(\d+)\s+failed.*?(\d+)\s+total/i);
402
+ if (testsLine) {
403
+ result.passed = parseInt(testsLine[1], 10);
404
+ result.failed = parseInt(testsLine[2], 10);
405
+ result.total = parseInt(testsLine[3], 10);
406
+ }
407
+ if (result.total === 0) {
408
+ result.total = result.passed + result.failed + result.skipped;
409
+ }
410
+ return result;
411
+ }
412
+ function parseOutput(framework, raw) {
413
+ switch (framework) {
414
+ case 'vitest':
415
+ return parseVitestJson(raw);
416
+ case 'jest':
417
+ return parseJestJson(raw);
418
+ case 'pytest':
419
+ return parsePytestOutput(raw);
420
+ case 'cargo':
421
+ return parseCargoOutput(raw);
422
+ case 'go':
423
+ return parseGoOutput(raw);
424
+ case 'npm':
425
+ return parseGenericOutput(raw);
426
+ }
427
+ }
428
+ // ---------------------------------------------------------------------------
429
+ // Format result for agent consumption
430
+ // ---------------------------------------------------------------------------
431
+ function formatResult(result) {
432
+ const lines = [];
433
+ lines.push(`Framework: ${result.framework}`);
434
+ lines.push(`Total: ${result.total} | Passed: ${result.passed} | Failed: ${result.failed}${result.skipped ? ` | Skipped: ${result.skipped}` : ''}`);
435
+ if (result.failures.length > 0) {
436
+ lines.push('');
437
+ lines.push('Failures:');
438
+ for (let i = 0; i < result.failures.length; i++) {
439
+ const f = result.failures[i];
440
+ lines.push(` ${i + 1}. ${f.name}`);
441
+ if (f.message) {
442
+ const msgLines = f.message.split('\n').filter(Boolean);
443
+ for (const ml of msgLines) {
444
+ lines.push(` ${ml.trim()}`);
445
+ }
446
+ }
447
+ }
448
+ }
449
+ if (result.failed === 0 && result.total > 0) {
450
+ lines.push('');
451
+ lines.push('All tests passed.');
452
+ }
453
+ if (result.raw && result.total === 0) {
454
+ lines.push('');
455
+ lines.push('Could not parse test output. Raw output:');
456
+ lines.push(result.raw.slice(0, 2000));
457
+ }
458
+ return lines.join('\n');
459
+ }
460
+ // ---------------------------------------------------------------------------
461
+ // Run tests
462
+ // ---------------------------------------------------------------------------
463
+ function runTests(projectPath, opts = {}) {
464
+ const resolvedPath = projectPath || process.cwd();
465
+ if (!existsSync(resolvedPath)) {
466
+ return `Error: path does not exist: ${resolvedPath}`;
467
+ }
468
+ const framework = detectFramework(resolvedPath);
469
+ if (!framework) {
470
+ return ('No test framework detected. Looked for:\n' +
471
+ ' - vitest.config.* or vite.config.* with test section\n' +
472
+ ' - jest.config.* or "jest" in package.json\n' +
473
+ ' - pytest.ini, pyproject.toml with [tool.pytest]\n' +
474
+ ' - Cargo.toml\n' +
475
+ ' - go.mod\n' +
476
+ ' - package.json with "test" script');
477
+ }
478
+ const cmd = buildCommand(framework, opts);
479
+ let stdout;
480
+ try {
481
+ stdout = execSync(cmd, {
482
+ cwd: resolvedPath,
483
+ timeout: 120_000,
484
+ maxBuffer: 10 * 1024 * 1024, // 10 MB
485
+ encoding: 'utf-8',
486
+ stdio: ['pipe', 'pipe', 'pipe'],
487
+ env: { ...process.env, FORCE_COLOR: '0', CI: 'true' },
488
+ });
489
+ }
490
+ catch (err) {
491
+ // Test failures cause non-zero exit codes — capture stdout anyway
492
+ const execErr = err;
493
+ stdout = execErr.stdout ?? execErr.stderr ?? execErr.message ?? 'Unknown error';
494
+ }
495
+ const result = parseOutput(framework, stdout);
496
+ return formatResult(result);
497
+ }
498
+ // ---------------------------------------------------------------------------
499
+ // Registration
500
+ // ---------------------------------------------------------------------------
501
+ export function registerTestRunnerTools() {
502
+ registerTool({
503
+ name: 'run_tests',
504
+ description: 'Run project tests. Auto-detects the test framework (vitest, jest, pytest, cargo, go, npm) by checking config files, runs tests, and returns structured pass/fail results with failure details the agent can use to auto-fix issues.',
505
+ parameters: {
506
+ path: { type: 'string', description: 'Project root path. Defaults to current working directory.' },
507
+ pattern: { type: 'string', description: 'Test file pattern or filter to narrow which tests to run.' },
508
+ verbose: { type: 'boolean', description: 'Enable verbose output from the test runner.' },
509
+ },
510
+ tier: 'free',
511
+ async execute(args) {
512
+ return runTests(String(args.path || process.cwd()), {
513
+ pattern: args.pattern ? String(args.pattern) : undefined,
514
+ verbose: args.verbose === true,
515
+ });
516
+ },
517
+ });
518
+ registerTool({
519
+ name: 'test_file',
520
+ description: 'Run tests for a specific file. Auto-detects the test framework and runs only the specified test file, returning structured results with failure details.',
521
+ parameters: {
522
+ path: { type: 'string', description: 'Absolute or relative path to the test file to run.', required: true },
523
+ },
524
+ tier: 'free',
525
+ async execute(args) {
526
+ const args_path = String(args.path || '');
527
+ if (!args_path) {
528
+ return 'Error: path is required. Provide the path to the test file.';
529
+ }
530
+ // Derive project root by walking up from the test file to find a config
531
+ const { dirname } = await import('node:path');
532
+ let dir = dirname(args_path.startsWith('/') ? args_path : join(process.cwd(), args_path));
533
+ let projectRoot = process.cwd();
534
+ // Walk up to find project root (look for package.json, Cargo.toml, go.mod, etc.)
535
+ const rootMarkers = ['package.json', 'Cargo.toml', 'go.mod', 'pyproject.toml', 'pytest.ini'];
536
+ for (let i = 0; i < 10; i++) {
537
+ if (rootMarkers.some((marker) => existsSync(join(dir, marker)))) {
538
+ projectRoot = dir;
539
+ break;
540
+ }
541
+ const parent = dirname(dir);
542
+ if (parent === dir)
543
+ break;
544
+ dir = parent;
545
+ }
546
+ return runTests(projectRoot, { file: args_path });
547
+ },
548
+ });
549
+ }
550
+ //# sourceMappingURL=test-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-runner.js","sourceRoot":"","sources":["../../src/tools/test-runner.ts"],"names":[],"mappings":"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"}
package/dist/ui.js CHANGED
@@ -252,7 +252,7 @@ export function printHelp() {
252
252
  ` ${chalk.white('/compact')} Compress conversation (saves tokens)`,
253
253
  ` ${chalk.white('/dashboard')} See usage stats and learning data`,
254
254
  '',
255
- ` ${DIM('37 specialist agents. 151 tools. Type anything to get started.')}`,
255
+ ` ${DIM('37 specialist agents. 153 tools. Type anything to get started.')}`,
256
256
  '',
257
257
  ];
258
258
  status(lines.join('\n'));
@@ -0,0 +1,25 @@
1
+ import { type ChildProcess } from 'node:child_process';
2
+ export interface VoiceOptions {
3
+ /** TTS voice name (macOS: Alex, Samantha, etc.) */
4
+ voice?: string;
5
+ /** TTS speech rate (words per minute, default: 200) */
6
+ rate?: number;
7
+ /** Enable TTS output (default: true) */
8
+ tts?: boolean;
9
+ /** Enable STT input (default: false — requires whisper) */
10
+ stt?: boolean;
11
+ }
12
+ export interface VoiceState {
13
+ enabled: boolean;
14
+ ttsProcess?: ChildProcess;
15
+ sttAvailable: boolean;
16
+ voice: string;
17
+ rate: number;
18
+ }
19
+ export declare function initVoice(options?: VoiceOptions): VoiceState;
20
+ export declare function speak(text: string, state: VoiceState): Promise<void>;
21
+ export declare function stopSpeaking(state: VoiceState): void;
22
+ export declare function listen(state: VoiceState): Promise<string>;
23
+ export declare function listVoices(): string[];
24
+ export declare function formatVoiceStatus(state: VoiceState): string;
25
+ //# sourceMappingURL=voice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice.d.ts","sourceRoot":"","sources":["../src/voice.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAWvE,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wCAAwC;IACxC,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,2DAA2D;IAC3D,GAAG,CAAC,EAAE,OAAO,CAAA;CACd;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,CAAC,EAAE,YAAY,CAAA;IACzB,YAAY,EAAE,OAAO,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACb;AAgGD,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,UAAU,CA8B5D;AAMD,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA0D1E;AAMD,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAKpD;AAMD,wBAAsB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAkF/D;AAoBD,wBAAgB,UAAU,IAAI,MAAM,EAAE,CAuDrC;AAMD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CA8B3D"}