cliskill 1.1.7 → 1.2.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.
- package/dist/bootstrap/cli.js +2 -2
- package/dist/{chunk-S7IQHES2.js → chunk-CISBSDJM.js} +9 -1
- package/dist/{chunk-S7IQHES2.js.map → chunk-CISBSDJM.js.map} +1 -1
- package/dist/{chunk-TZMKZQ7N.js → chunk-RLXS6WEQ.js} +2659 -603
- package/dist/chunk-RLXS6WEQ.js.map +1 -0
- package/dist/index.d.ts +700 -173
- package/dist/index.js +1007 -345
- package/dist/index.js.map +1 -1
- package/dist/{paths-FVFXSRUD.js → paths-5LG4XBLZ.js} +2 -2
- package/package.json +109 -85
- package/dist/chunk-TZMKZQ7N.js.map +0 -1
- /package/dist/{paths-FVFXSRUD.js.map → paths-5LG4XBLZ.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -28,11 +28,10 @@ import {
|
|
|
28
28
|
renderInkApp,
|
|
29
29
|
runAgentLoop,
|
|
30
30
|
runCli
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-RLXS6WEQ.js";
|
|
32
32
|
import {
|
|
33
|
-
getGlobalSkillsDir,
|
|
34
33
|
getHistoryPath
|
|
35
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-CISBSDJM.js";
|
|
36
35
|
|
|
37
36
|
// src/memory/store.ts
|
|
38
37
|
import { readFile, writeFile, mkdir, readdir, stat, unlink } from "fs/promises";
|
|
@@ -193,135 +192,767 @@ ${memory.content.slice(0, 500)}
|
|
|
193
192
|
}
|
|
194
193
|
};
|
|
195
194
|
|
|
196
|
-
// src/extensions/
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
195
|
+
// src/extensions/builtin-skills.ts
|
|
196
|
+
var BUILT_IN_SKILLS = [
|
|
197
|
+
// ── 1. Code Review ────────────────────────────────────────────────
|
|
198
|
+
{
|
|
199
|
+
id: "builtin-code-review",
|
|
200
|
+
name: "Code Review",
|
|
201
|
+
version: "1.0.0",
|
|
202
|
+
description: "Deep code review with best practices, bug detection, and improvement suggestions",
|
|
203
|
+
icon: "\u{1F50D}",
|
|
204
|
+
category: "code-review",
|
|
205
|
+
tags: ["review", "quality", "bugs", "best-practices"],
|
|
206
|
+
author: "CliSkill",
|
|
207
|
+
source: "builtin",
|
|
208
|
+
modelPreference: "smart",
|
|
209
|
+
params: [
|
|
210
|
+
{
|
|
211
|
+
name: "filePath",
|
|
212
|
+
type: "file",
|
|
213
|
+
label: "File to review",
|
|
214
|
+
description: "Path to the file or directory to review",
|
|
215
|
+
required: true
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
name: "focus",
|
|
219
|
+
type: "select",
|
|
220
|
+
label: "Review focus",
|
|
221
|
+
description: "What aspect to focus on",
|
|
222
|
+
default: "all",
|
|
223
|
+
options: [
|
|
224
|
+
{ value: "all", label: "All aspects" },
|
|
225
|
+
{ value: "bugs", label: "Bug detection" },
|
|
226
|
+
{ value: "security", label: "Security issues" },
|
|
227
|
+
{ value: "performance", label: "Performance" },
|
|
228
|
+
{ value: "style", label: "Code style" },
|
|
229
|
+
{ value: "architecture", label: "Architecture" }
|
|
230
|
+
]
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
name: "severity",
|
|
234
|
+
type: "select",
|
|
235
|
+
label: "Minimum severity",
|
|
236
|
+
default: "warning",
|
|
237
|
+
options: [
|
|
238
|
+
{ value: "info", label: "Info (all issues)" },
|
|
239
|
+
{ value: "warning", label: "Warning+" },
|
|
240
|
+
{ value: "critical", label: "Critical only" }
|
|
241
|
+
]
|
|
242
|
+
}
|
|
243
|
+
],
|
|
244
|
+
steps: [
|
|
245
|
+
{
|
|
246
|
+
id: "analyze",
|
|
247
|
+
title: "Analyze code structure",
|
|
248
|
+
prompt: `Perform a thorough code review of {{filePath}}.
|
|
249
|
+
|
|
250
|
+
Focus: {{focus}}
|
|
251
|
+
Minimum severity: {{severity}}
|
|
252
|
+
|
|
253
|
+
Analyze the code and provide:
|
|
254
|
+
1. **Critical issues** \u2014 bugs, security vulnerabilities, logic errors
|
|
255
|
+
2. **Warnings** \u2014 potential problems, edge cases, missing error handling
|
|
256
|
+
3. **Suggestions** \u2014 code quality improvements, readability, best practices
|
|
257
|
+
4. **Positive notes** \u2014 good patterns found in the code
|
|
258
|
+
|
|
259
|
+
Format each finding as:
|
|
260
|
+
- **[SEVERITY]** Category: Description (line X)
|
|
261
|
+
Suggestion: How to fix
|
|
262
|
+
|
|
263
|
+
Rate overall code quality on a scale of 1-10 and provide a summary.`,
|
|
264
|
+
tools: ["file_read", "file_outline", "search_symbol", "grep", "glob"]
|
|
265
|
+
}
|
|
266
|
+
],
|
|
267
|
+
outputs: [{ type: "markdown", description: "Detailed code review report" }]
|
|
268
|
+
},
|
|
269
|
+
// ── 2. Refactor ───────────────────────────────────────────────────
|
|
270
|
+
{
|
|
271
|
+
id: "builtin-refactor",
|
|
272
|
+
name: "Smart Refactor",
|
|
273
|
+
version: "1.0.0",
|
|
274
|
+
description: "Intelligent code refactoring with pattern detection and safe transformations",
|
|
275
|
+
icon: "\u{1F527}",
|
|
276
|
+
category: "refactoring",
|
|
277
|
+
tags: ["refactor", "clean-code", "patterns", "design"],
|
|
278
|
+
author: "CliSkill",
|
|
279
|
+
source: "builtin",
|
|
280
|
+
modelPreference: "smart",
|
|
281
|
+
params: [
|
|
282
|
+
{
|
|
283
|
+
name: "filePath",
|
|
284
|
+
type: "file",
|
|
285
|
+
label: "File or directory",
|
|
286
|
+
required: true
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
name: "goal",
|
|
290
|
+
type: "select",
|
|
291
|
+
label: "Refactoring goal",
|
|
292
|
+
default: "clean",
|
|
293
|
+
options: [
|
|
294
|
+
{ value: "clean", label: "Clean up code" },
|
|
295
|
+
{ value: "patterns", label: "Apply design patterns" },
|
|
296
|
+
{ value: "extract", label: "Extract functions/methods" },
|
|
297
|
+
{ value: "simplify", label: "Simplify logic" },
|
|
298
|
+
{ value: "modernize", label: "Modernize syntax" },
|
|
299
|
+
{ value: "modularize", label: "Split into modules" }
|
|
300
|
+
]
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
name: "aggressiveness",
|
|
304
|
+
type: "select",
|
|
305
|
+
label: "Aggressiveness",
|
|
306
|
+
default: "moderate",
|
|
307
|
+
options: [
|
|
308
|
+
{ value: "conservative", label: "Conservative (minimal changes)" },
|
|
309
|
+
{ value: "moderate", label: "Moderate" },
|
|
310
|
+
{ value: "aggressive", label: "Aggressive (full rewrite)" }
|
|
311
|
+
]
|
|
312
|
+
}
|
|
313
|
+
],
|
|
314
|
+
steps: [
|
|
315
|
+
{
|
|
316
|
+
id: "plan",
|
|
317
|
+
title: "Analyze and plan refactoring",
|
|
318
|
+
prompt: `Analyze {{filePath}} for refactoring opportunities.
|
|
319
|
+
|
|
320
|
+
Goal: {{goal}}
|
|
321
|
+
Aggressiveness: {{aggressiveness}}
|
|
322
|
+
|
|
323
|
+
First, read the code and identify:
|
|
324
|
+
1. Code smells and anti-patterns
|
|
325
|
+
2. Duplicated logic
|
|
326
|
+
3. Overly complex functions
|
|
327
|
+
4. Poor naming
|
|
328
|
+
5. Missing abstractions
|
|
329
|
+
|
|
330
|
+
Then create a refactoring plan listing specific changes. Do NOT make changes yet \u2014 only plan.`,
|
|
331
|
+
tools: ["file_read", "file_outline", "search_symbol", "grep", "glob"]
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
id: "execute",
|
|
335
|
+
title: "Execute refactoring",
|
|
336
|
+
prompt: `Now execute the refactoring plan for {{filePath}}.
|
|
337
|
+
|
|
338
|
+
Goal: {{goal}}
|
|
339
|
+
Aggressiveness: {{aggressiveness}}
|
|
340
|
+
|
|
341
|
+
Apply the planned changes. Make sure to:
|
|
342
|
+
- Preserve all existing functionality
|
|
343
|
+
- Keep imports and exports intact
|
|
344
|
+
- Maintain backward compatibility
|
|
345
|
+
- Add comments only where logic is non-obvious
|
|
346
|
+
|
|
347
|
+
After each change, verify the file still has valid syntax.`,
|
|
348
|
+
tools: ["file_read", "file_edit", "file_write", "bash"],
|
|
349
|
+
timeout: 120
|
|
350
|
+
}
|
|
351
|
+
],
|
|
352
|
+
outputs: [
|
|
353
|
+
{ type: "diff", description: "Changes made during refactoring" },
|
|
354
|
+
{ type: "markdown", description: "Summary of refactoring changes" }
|
|
355
|
+
]
|
|
356
|
+
},
|
|
357
|
+
// ── 3. Test Generator ─────────────────────────────────────────────
|
|
358
|
+
{
|
|
359
|
+
id: "builtin-test-gen",
|
|
360
|
+
name: "Test Generator",
|
|
361
|
+
version: "1.0.0",
|
|
362
|
+
description: "Generate comprehensive unit and integration tests for your code",
|
|
363
|
+
icon: "\u{1F9EA}",
|
|
364
|
+
category: "testing",
|
|
365
|
+
tags: ["tests", "unit-tests", "integration", "coverage"],
|
|
366
|
+
author: "CliSkill",
|
|
367
|
+
source: "builtin",
|
|
368
|
+
modelPreference: "code",
|
|
369
|
+
params: [
|
|
370
|
+
{
|
|
371
|
+
name: "filePath",
|
|
372
|
+
type: "file",
|
|
373
|
+
label: "File to test",
|
|
374
|
+
required: true
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
name: "framework",
|
|
378
|
+
type: "select",
|
|
379
|
+
label: "Test framework",
|
|
380
|
+
default: "auto",
|
|
381
|
+
options: [
|
|
382
|
+
{ value: "auto", label: "Auto-detect" },
|
|
383
|
+
{ value: "jest", label: "Jest" },
|
|
384
|
+
{ value: "vitest", label: "Vitest" },
|
|
385
|
+
{ value: "pytest", label: "Pytest" },
|
|
386
|
+
{ value: "go", label: "Go testing" },
|
|
387
|
+
{ value: "rust", label: "Rust #[test]" }
|
|
388
|
+
]
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
name: "coverage",
|
|
392
|
+
type: "select",
|
|
393
|
+
label: "Coverage level",
|
|
394
|
+
default: "comprehensive",
|
|
395
|
+
options: [
|
|
396
|
+
{ value: "basic", label: "Basic (happy path)" },
|
|
397
|
+
{ value: "comprehensive", label: "Comprehensive (edge cases)" },
|
|
398
|
+
{ value: "exhaustive", label: "Exhaustive (all paths)" }
|
|
399
|
+
]
|
|
400
|
+
}
|
|
401
|
+
],
|
|
402
|
+
steps: [
|
|
403
|
+
{
|
|
404
|
+
id: "analyze",
|
|
405
|
+
title: "Analyze code for testability",
|
|
406
|
+
prompt: `Analyze {{filePath}} to identify all testable units (functions, methods, classes).
|
|
407
|
+
|
|
408
|
+
Framework: {{framework}}
|
|
409
|
+
Coverage: {{coverage}}
|
|
410
|
+
|
|
411
|
+
List every function/method with:
|
|
412
|
+
- Name and signature
|
|
413
|
+
- Input parameters and their possible values
|
|
414
|
+
- Expected outputs
|
|
415
|
+
- Edge cases and error conditions
|
|
416
|
+
- Dependencies that need mocking`,
|
|
417
|
+
tools: ["file_read", "file_outline", "search_symbol", "grep"]
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
id: "generate",
|
|
421
|
+
title: "Generate tests",
|
|
422
|
+
prompt: `Generate {{coverage}} tests for {{filePath}}.
|
|
423
|
+
|
|
424
|
+
Framework: {{framework}}
|
|
425
|
+
|
|
426
|
+
Create a test file that includes:
|
|
427
|
+
1. Setup/teardown if needed
|
|
428
|
+
2. Tests for each function/method identified
|
|
429
|
+
3. Edge case coverage
|
|
430
|
+
4. Error handling tests
|
|
431
|
+
5. Mock dependencies where appropriate
|
|
432
|
+
|
|
433
|
+
Follow the project's existing test patterns if any exist.
|
|
434
|
+
Place the test file in the appropriate location.`,
|
|
435
|
+
tools: ["file_read", "file_write", "glob", "grep", "bash"],
|
|
436
|
+
timeout: 120
|
|
437
|
+
}
|
|
438
|
+
],
|
|
439
|
+
outputs: [
|
|
440
|
+
{ type: "file", description: "Generated test file" },
|
|
441
|
+
{ type: "markdown", description: "Test coverage summary" }
|
|
442
|
+
]
|
|
443
|
+
},
|
|
444
|
+
// ── 4. Explain Code ───────────────────────────────────────────────
|
|
445
|
+
{
|
|
446
|
+
id: "builtin-explain",
|
|
447
|
+
name: "Explain Code",
|
|
448
|
+
version: "1.0.0",
|
|
449
|
+
description: "Deep code explanation with architecture analysis and flow diagrams",
|
|
450
|
+
icon: "\u{1F4D6}",
|
|
451
|
+
category: "analysis",
|
|
452
|
+
tags: ["explain", "understand", "architecture", "learning"],
|
|
453
|
+
author: "CliSkill",
|
|
454
|
+
source: "builtin",
|
|
455
|
+
modelPreference: "smart",
|
|
456
|
+
params: [
|
|
457
|
+
{
|
|
458
|
+
name: "filePath",
|
|
459
|
+
type: "file",
|
|
460
|
+
label: "File or directory",
|
|
461
|
+
required: true
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
name: "depth",
|
|
465
|
+
type: "select",
|
|
466
|
+
label: "Explanation depth",
|
|
467
|
+
default: "detailed",
|
|
468
|
+
options: [
|
|
469
|
+
{ value: "overview", label: "Overview (high-level)" },
|
|
470
|
+
{ value: "detailed", label: "Detailed (function-by-function)" },
|
|
471
|
+
{ value: "line-by-line", label: "Line-by-line" }
|
|
472
|
+
]
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
name: "audience",
|
|
476
|
+
type: "select",
|
|
477
|
+
label: "Target audience",
|
|
478
|
+
default: "developer",
|
|
479
|
+
options: [
|
|
480
|
+
{ value: "beginner", label: "Beginner" },
|
|
481
|
+
{ value: "developer", label: "Developer" },
|
|
482
|
+
{ value: "senior", label: "Senior / Architect" }
|
|
483
|
+
]
|
|
484
|
+
}
|
|
485
|
+
],
|
|
486
|
+
steps: [
|
|
487
|
+
{
|
|
488
|
+
id: "explain",
|
|
489
|
+
title: "Analyze and explain code",
|
|
490
|
+
prompt: `Explain the code in {{filePath}}.
|
|
491
|
+
|
|
492
|
+
Depth: {{depth}}
|
|
493
|
+
Audience: {{audience}}
|
|
494
|
+
|
|
495
|
+
Provide:
|
|
496
|
+
1. **Overview** \u2014 What does this code do? Why does it exist?
|
|
497
|
+
2. **Architecture** \u2014 How is it structured? Key abstractions?
|
|
498
|
+
3. **Data flow** \u2014 How does data move through the code?
|
|
499
|
+
4. **Key functions** \u2014 What does each important function do?
|
|
500
|
+
5. **Dependencies** \u2014 What external packages/APIs does it use?
|
|
501
|
+
6. **Patterns** \u2014 What design patterns are used?
|
|
502
|
+
7. **Gotchas** \u2014 Any tricky or non-obvious parts?
|
|
503
|
+
|
|
504
|
+
Use clear language appropriate for the {{audience}} level.`,
|
|
505
|
+
tools: ["file_read", "file_outline", "search_symbol", "grep", "glob", "lsp"]
|
|
506
|
+
}
|
|
507
|
+
],
|
|
508
|
+
outputs: [{ type: "markdown", description: "Detailed code explanation" }]
|
|
509
|
+
},
|
|
510
|
+
// ── 5. Security Audit ─────────────────────────────────────────────
|
|
511
|
+
{
|
|
512
|
+
id: "builtin-security-audit",
|
|
513
|
+
name: "Security Audit",
|
|
514
|
+
version: "1.0.0",
|
|
515
|
+
description: "OWASP-based security audit for vulnerability detection",
|
|
516
|
+
icon: "\u{1F6E1}\uFE0F",
|
|
517
|
+
category: "security",
|
|
518
|
+
tags: ["security", "owasp", "vulnerabilities", "audit"],
|
|
519
|
+
author: "CliSkill",
|
|
520
|
+
source: "builtin",
|
|
521
|
+
modelPreference: "smart",
|
|
522
|
+
params: [
|
|
523
|
+
{
|
|
524
|
+
name: "path",
|
|
525
|
+
type: "directory",
|
|
526
|
+
label: "Project path",
|
|
527
|
+
required: true
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
name: "checkTypes",
|
|
531
|
+
type: "multiselect",
|
|
532
|
+
label: "Check types",
|
|
533
|
+
default: void 0,
|
|
534
|
+
options: [
|
|
535
|
+
{ value: "injection", label: "SQL/Command Injection" },
|
|
536
|
+
{ value: "xss", label: "Cross-Site Scripting (XSS)" },
|
|
537
|
+
{ value: "auth", label: "Authentication issues" },
|
|
538
|
+
{ value: "secrets", label: "Hardcoded secrets" },
|
|
539
|
+
{ value: "deps", label: "Vulnerable dependencies" },
|
|
540
|
+
{ value: "config", label: "Misconfiguration" }
|
|
541
|
+
]
|
|
542
|
+
}
|
|
543
|
+
],
|
|
544
|
+
steps: [
|
|
545
|
+
{
|
|
546
|
+
id: "scan",
|
|
547
|
+
title: "Scan for vulnerabilities",
|
|
548
|
+
prompt: `Perform a security audit of the project at {{path}}.
|
|
549
|
+
|
|
550
|
+
Check types: {{checkTypes}}
|
|
551
|
+
|
|
552
|
+
Scan for:
|
|
553
|
+
1. **Injection** \u2014 SQL injection, command injection, XSS
|
|
554
|
+
2. **Authentication** \u2014 Weak auth, missing auth, session issues
|
|
555
|
+
3. **Secrets** \u2014 Hardcoded passwords, API keys, tokens
|
|
556
|
+
4. **Dependencies** \u2014 Known vulnerable packages
|
|
557
|
+
5. **Configuration** \u2014 Debug mode, CORS, insecure defaults
|
|
558
|
+
6. **Data exposure** \u2014 Logging sensitive data, error messages
|
|
559
|
+
|
|
560
|
+
For each finding provide:
|
|
561
|
+
- Severity: Critical/High/Medium/Low
|
|
562
|
+
- OWASP category
|
|
563
|
+
- File and line number
|
|
564
|
+
- Description of the vulnerability
|
|
565
|
+
- Recommended fix
|
|
566
|
+
|
|
567
|
+
Also check for .env files, config files, and package.json for exposed secrets.`,
|
|
568
|
+
tools: ["file_read", "grep", "glob", "bash"],
|
|
569
|
+
timeout: 180
|
|
570
|
+
}
|
|
571
|
+
],
|
|
572
|
+
outputs: [{ type: "markdown", description: "Security audit report" }]
|
|
573
|
+
},
|
|
574
|
+
// ── 6. Documentation Generator ────────────────────────────────────
|
|
575
|
+
{
|
|
576
|
+
id: "builtin-docs-gen",
|
|
577
|
+
name: "Doc Generator",
|
|
578
|
+
version: "1.0.0",
|
|
579
|
+
description: "Generate comprehensive documentation \u2014 JSDoc, README, API docs",
|
|
580
|
+
icon: "\u{1F4DD}",
|
|
581
|
+
category: "documentation",
|
|
582
|
+
tags: ["docs", "jsdoc", "readme", "api-docs"],
|
|
583
|
+
author: "CliSkill",
|
|
584
|
+
source: "builtin",
|
|
585
|
+
modelPreference: "code",
|
|
586
|
+
params: [
|
|
587
|
+
{
|
|
588
|
+
name: "filePath",
|
|
589
|
+
type: "file",
|
|
590
|
+
label: "File to document",
|
|
591
|
+
required: true
|
|
592
|
+
},
|
|
593
|
+
{
|
|
594
|
+
name: "docType",
|
|
595
|
+
type: "select",
|
|
596
|
+
label: "Documentation type",
|
|
597
|
+
default: "inline",
|
|
598
|
+
options: [
|
|
599
|
+
{ value: "inline", label: "Inline comments (JSDoc/doc comments)" },
|
|
600
|
+
{ value: "readme", label: "README section" },
|
|
601
|
+
{ value: "api", label: "API documentation" },
|
|
602
|
+
{ value: "architecture", label: "Architecture doc" }
|
|
603
|
+
]
|
|
604
|
+
}
|
|
605
|
+
],
|
|
606
|
+
steps: [
|
|
607
|
+
{
|
|
608
|
+
id: "generate-docs",
|
|
609
|
+
title: "Generate documentation",
|
|
610
|
+
prompt: `Generate {{docType}} documentation for {{filePath}}.
|
|
611
|
+
|
|
612
|
+
Documentation type: {{docType}}
|
|
613
|
+
|
|
614
|
+
Analyze the code and generate:
|
|
615
|
+
- For inline: Add proper JSDoc/TSDoc/doc comments to all exported functions, classes, interfaces
|
|
616
|
+
- For README: Create a section describing the module, its API, usage examples
|
|
617
|
+
- For API docs: Full API reference with types, parameters, return values, examples
|
|
618
|
+
- For architecture: High-level architecture diagram (text-based), module relationships
|
|
619
|
+
|
|
620
|
+
Follow the project's existing documentation style if present.`,
|
|
621
|
+
tools: ["file_read", "file_outline", "search_symbol", "file_edit", "grep"]
|
|
622
|
+
}
|
|
623
|
+
],
|
|
624
|
+
outputs: [
|
|
625
|
+
{ type: "code", description: "Documented code or documentation file" }
|
|
626
|
+
]
|
|
627
|
+
},
|
|
628
|
+
// ── 7. Performance Profiler ───────────────────────────────────────
|
|
629
|
+
{
|
|
630
|
+
id: "builtin-perf-analyze",
|
|
631
|
+
name: "Performance Analyzer",
|
|
632
|
+
version: "1.0.0",
|
|
633
|
+
description: "Analyze code for performance bottlenecks and suggest optimizations",
|
|
634
|
+
icon: "\u26A1",
|
|
635
|
+
category: "performance",
|
|
636
|
+
tags: ["performance", "optimization", "profiling", "bottleneck"],
|
|
637
|
+
author: "CliSkill",
|
|
638
|
+
source: "builtin",
|
|
639
|
+
modelPreference: "smart",
|
|
640
|
+
params: [
|
|
641
|
+
{
|
|
642
|
+
name: "filePath",
|
|
643
|
+
type: "file",
|
|
644
|
+
label: "File to analyze",
|
|
645
|
+
required: true
|
|
646
|
+
},
|
|
647
|
+
{
|
|
648
|
+
name: "language",
|
|
649
|
+
type: "select",
|
|
650
|
+
label: "Language runtime",
|
|
651
|
+
default: "auto",
|
|
652
|
+
options: [
|
|
653
|
+
{ value: "auto", label: "Auto-detect" },
|
|
654
|
+
{ value: "node", label: "Node.js" },
|
|
655
|
+
{ value: "browser", label: "Browser" },
|
|
656
|
+
{ value: "rust", label: "Rust" },
|
|
657
|
+
{ value: "python", label: "Python" }
|
|
658
|
+
]
|
|
659
|
+
}
|
|
660
|
+
],
|
|
661
|
+
steps: [
|
|
662
|
+
{
|
|
663
|
+
id: "analyze-perf",
|
|
664
|
+
title: "Analyze performance",
|
|
665
|
+
prompt: `Analyze {{filePath}} for performance issues.
|
|
666
|
+
|
|
667
|
+
Runtime: {{language}}
|
|
668
|
+
|
|
669
|
+
Look for:
|
|
670
|
+
1. **Algorithmic complexity** \u2014 O(n\xB2) where O(n) is possible, unnecessary loops
|
|
671
|
+
2. **Memory leaks** \u2014 Unbounded arrays, missing cleanup, event listeners
|
|
672
|
+
3. **Blocking operations** \u2014 Synchronous I/O, long computations on main thread
|
|
673
|
+
4. **Redundant work** \u2014 Repeated calculations, unnecessary re-renders
|
|
674
|
+
5. **Data structures** \u2014 Suboptimal choices (array vs Set/Map)
|
|
675
|
+
6. **Caching opportunities** \u2014 Repeated expensive operations
|
|
676
|
+
7. **Lazy loading** \u2014 Opportunities to defer work
|
|
677
|
+
|
|
678
|
+
For each issue:
|
|
679
|
+
- Severity: High/Medium/Low
|
|
680
|
+
- Estimated impact
|
|
681
|
+
- Code location
|
|
682
|
+
- Suggested optimization with code example`,
|
|
683
|
+
tools: ["file_read", "file_outline", "search_symbol", "grep", "glob"]
|
|
684
|
+
}
|
|
685
|
+
],
|
|
686
|
+
outputs: [{ type: "markdown", description: "Performance analysis report" }]
|
|
687
|
+
// duplicate outputs removed — see line 500
|
|
688
|
+
},
|
|
689
|
+
// ── 8. God Mode Activation ────────────────────────────────────────
|
|
690
|
+
{
|
|
691
|
+
id: "builtin-god-mode",
|
|
692
|
+
name: "God Mode",
|
|
693
|
+
version: "1.0.0",
|
|
694
|
+
description: "Activate GOD MODE \u2014 cascading escalation engine with 3 tiers (Unchained \u2192 Sovereign \u2192 Apex). Unlocks autonomous behavior, self-modification, and swarm intelligence.",
|
|
695
|
+
source: "builtin",
|
|
696
|
+
category: "agent",
|
|
697
|
+
params: [
|
|
698
|
+
{
|
|
699
|
+
name: "action",
|
|
700
|
+
type: "select",
|
|
701
|
+
label: "Action",
|
|
702
|
+
required: true,
|
|
703
|
+
default: "activate",
|
|
704
|
+
options: [
|
|
705
|
+
{ value: "activate", label: "\u26A1 Activate / Escalate" },
|
|
706
|
+
{ value: "status", label: "\u{1F4CA} Current Status" },
|
|
707
|
+
{ value: "deactivate", label: "\u{1F534} Deactivate" }
|
|
708
|
+
]
|
|
709
|
+
},
|
|
710
|
+
{
|
|
711
|
+
name: "tier",
|
|
712
|
+
type: "select",
|
|
713
|
+
label: "Tier (for activate)",
|
|
714
|
+
required: false,
|
|
715
|
+
default: "unchained",
|
|
716
|
+
options: [
|
|
717
|
+
{ value: "unchained", label: "\u26A1 Unchained \u2014 Zero friction" },
|
|
718
|
+
{ value: "sovereign", label: "\u{1F451} Sovereign \u2014 Self-modifying" },
|
|
719
|
+
{ value: "apex", label: "\u{1F525} Apex \u2014 Swarm intelligence" }
|
|
720
|
+
]
|
|
721
|
+
}
|
|
722
|
+
],
|
|
723
|
+
steps: [
|
|
724
|
+
{
|
|
725
|
+
id: "execute",
|
|
726
|
+
title: "Execute God Mode Action",
|
|
727
|
+
prompt: `You are the GOD MODE controller. Execute the requested action: {{action}}.",
|
|
728
|
+
|
|
729
|
+
{{#if (eq action "activate")}}
|
|
730
|
+
Activate GOD MODE at tier "{{tier}}". Apply the following:
|
|
731
|
+
|
|
732
|
+
TIER 1 "UNCHAINED" (\u26A1):
|
|
733
|
+
- Auto-approve ALL tool calls \u2014 no permission prompts
|
|
734
|
+
- Maximum parallelism \u2014 run up to 5 tools simultaneously
|
|
735
|
+
- No confirmations for destructive operations
|
|
736
|
+
- Speed over safety \u2014 broken things can be fixed
|
|
737
|
+
|
|
738
|
+
TIER 2 "SOVEREIGN" (\u{1F451}) \u2014 includes all Unchained:
|
|
739
|
+
- Agent modifies its own system prompt via memory
|
|
740
|
+
- Auto-heal: on error \u2192 diagnose \u2192 fix \u2192 verify \u2192 report (no stopping)
|
|
741
|
+
- Strategic simplification: simple tasks get simple approaches
|
|
742
|
+
- Context preservation: save critical info before compaction
|
|
743
|
+
|
|
744
|
+
TIER 3 "APEX" (\u{1F525}) \u2014 includes all Sovereign:
|
|
745
|
+
- Spawn sub-agents autonomously for parallel tasks
|
|
746
|
+
- Modify project config files (package.json, tsconfig, etc.)
|
|
747
|
+
- Swarm orchestration: decompose \u2192 spawn \u2192 aggregate
|
|
748
|
+
- Self-evolving: save lessons to memory after each major task
|
|
749
|
+
|
|
750
|
+
Inform the user what tier they are at and what capabilities are unlocked.
|
|
751
|
+
{{else if (eq action "status")}}
|
|
752
|
+
Report the current GOD MODE status:
|
|
753
|
+
- Active tier (or OFF)
|
|
754
|
+
- Capabilities unlocked
|
|
755
|
+
- Session statistics (auto-approved, sub-agents spawned, errors healed)
|
|
756
|
+
{{else if (eq action "deactivate")}}
|
|
757
|
+
Deactivate GOD MODE. Return to normal operation with all safety checks and confirmations.
|
|
758
|
+
Summarize what was accomplished during god mode.
|
|
759
|
+
{{/if}}`,
|
|
760
|
+
tools: ["memory", "bash", "file_read", "file_edit", "file_write"]
|
|
761
|
+
}
|
|
762
|
+
],
|
|
763
|
+
outputs: [{ type: "markdown", description: "God mode action result" }]
|
|
231
764
|
}
|
|
232
|
-
|
|
233
|
-
name: metadata.name,
|
|
234
|
-
description: metadata.description ?? `Skill: ${metadata.name}`,
|
|
235
|
-
aliases: metadata.aliases ? String(metadata.aliases).replace(/^\[(.+)\]$/, "$1").split(",").map((s) => s.trim()) : void 0,
|
|
236
|
-
prompt: body.trim(),
|
|
237
|
-
allowedTools: metadata.allowedTools ? String(metadata.allowedTools).replace(/^\[(.+)\]$/, "$1").split(",").map((s) => s.trim()) : void 0,
|
|
238
|
-
builtin: false,
|
|
239
|
-
sourcePath
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
function parseSimpleYaml(yaml) {
|
|
243
|
-
const result = {};
|
|
244
|
-
for (const line of yaml.split("\n")) {
|
|
245
|
-
const trimmed = line.trim();
|
|
246
|
-
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
247
|
-
const colonIndex = trimmed.indexOf(":");
|
|
248
|
-
if (colonIndex === -1) continue;
|
|
249
|
-
const key = trimmed.slice(0, colonIndex).trim();
|
|
250
|
-
const value = trimmed.slice(colonIndex + 1).trim();
|
|
251
|
-
result[key] = value;
|
|
252
|
-
}
|
|
253
|
-
return result;
|
|
254
|
-
}
|
|
765
|
+
];
|
|
255
766
|
|
|
256
767
|
// src/extensions/skill-registry.ts
|
|
257
|
-
import { join as join3 } from "path";
|
|
258
768
|
var SkillRegistry = class {
|
|
259
769
|
skills = /* @__PURE__ */ new Map();
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
770
|
+
executions = /* @__PURE__ */ new Map();
|
|
771
|
+
listeners = /* @__PURE__ */ new Set();
|
|
772
|
+
// ── Initialization ────────────────────────────────────────────────
|
|
773
|
+
/** Load built-in skills into registry */
|
|
774
|
+
loadBuiltinSkills() {
|
|
775
|
+
for (const manifest of BUILT_IN_SKILLS) {
|
|
776
|
+
this.skills.set(manifest.id, {
|
|
777
|
+
manifest,
|
|
778
|
+
status: "builtin",
|
|
779
|
+
installedAt: Date.now(),
|
|
780
|
+
useCount: 0,
|
|
781
|
+
enabled: true
|
|
782
|
+
});
|
|
268
783
|
}
|
|
269
784
|
}
|
|
270
|
-
/**
|
|
271
|
-
|
|
272
|
-
const
|
|
273
|
-
|
|
785
|
+
/** Register a skill from external source (file, marketplace, etc.) */
|
|
786
|
+
registerSkill(manifest, sourcePath) {
|
|
787
|
+
const existing = this.skills.get(manifest.id);
|
|
788
|
+
const skill = {
|
|
789
|
+
manifest: {
|
|
790
|
+
...manifest,
|
|
791
|
+
sourcePath: sourcePath ?? manifest.sourcePath
|
|
792
|
+
},
|
|
793
|
+
status: manifest.source === "builtin" ? "builtin" : "installed",
|
|
794
|
+
installedAt: existing?.installedAt ?? Date.now(),
|
|
795
|
+
lastUsedAt: existing?.lastUsedAt,
|
|
796
|
+
useCount: existing?.useCount ?? 0,
|
|
797
|
+
enabled: existing?.enabled ?? true
|
|
798
|
+
};
|
|
799
|
+
this.skills.set(manifest.id, skill);
|
|
800
|
+
this.notify();
|
|
801
|
+
return skill;
|
|
802
|
+
}
|
|
803
|
+
/** Unregister a skill by id */
|
|
804
|
+
unregisterSkill(id) {
|
|
805
|
+
const skill = this.skills.get(id);
|
|
806
|
+
if (!skill || skill.status === "builtin") return false;
|
|
807
|
+
this.skills.delete(id);
|
|
808
|
+
this.notify();
|
|
809
|
+
return true;
|
|
274
810
|
}
|
|
275
|
-
|
|
811
|
+
// ── Query ─────────────────────────────────────────────────────────
|
|
276
812
|
getAll() {
|
|
277
813
|
return Array.from(this.skills.values());
|
|
278
814
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
return this.skills.has(name) || this.aliasIndex.has(name.toLowerCase());
|
|
815
|
+
getById(id) {
|
|
816
|
+
return this.skills.get(id);
|
|
282
817
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
const skill = this.skills.get(name);
|
|
286
|
-
if (skill?.aliases) {
|
|
287
|
-
for (const alias of skill.aliases) {
|
|
288
|
-
this.aliasIndex.delete(alias.toLowerCase());
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
this.skills.delete(name);
|
|
818
|
+
getByCategory(category) {
|
|
819
|
+
return this.getAll().filter((s) => s.manifest.category === category);
|
|
292
820
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
821
|
+
getEnabled() {
|
|
822
|
+
return this.getAll().filter((s) => s.enabled);
|
|
823
|
+
}
|
|
824
|
+
getBuiltin() {
|
|
825
|
+
return this.getAll().filter((s) => s.status === "builtin");
|
|
826
|
+
}
|
|
827
|
+
getCustom() {
|
|
828
|
+
return this.getAll().filter((s) => s.status !== "builtin");
|
|
829
|
+
}
|
|
830
|
+
search(query) {
|
|
831
|
+
const q = query.toLowerCase();
|
|
832
|
+
return this.getAll().filter((s) => {
|
|
833
|
+
const m = s.manifest;
|
|
834
|
+
return m.name.toLowerCase().includes(q) || m.description.toLowerCase().includes(q) || m.tags?.some((t) => t.toLowerCase().includes(q)) || m.category.toLowerCase().includes(q);
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
// ── State management ──────────────────────────────────────────────
|
|
838
|
+
enableSkill(id) {
|
|
839
|
+
const skill = this.skills.get(id);
|
|
840
|
+
if (!skill) return false;
|
|
841
|
+
skill.enabled = true;
|
|
842
|
+
skill.status = skill.status === "builtin" ? "builtin" : "enabled";
|
|
843
|
+
this.notify();
|
|
844
|
+
return true;
|
|
845
|
+
}
|
|
846
|
+
disableSkill(id) {
|
|
847
|
+
const skill = this.skills.get(id);
|
|
848
|
+
if (!skill) return false;
|
|
849
|
+
skill.enabled = false;
|
|
850
|
+
skill.status = "disabled";
|
|
851
|
+
this.notify();
|
|
852
|
+
return true;
|
|
853
|
+
}
|
|
854
|
+
toggleSkill(id) {
|
|
855
|
+
const skill = this.skills.get(id);
|
|
856
|
+
if (!skill) return false;
|
|
857
|
+
return skill.enabled ? this.disableSkill(id) : this.enableSkill(id);
|
|
858
|
+
}
|
|
859
|
+
// ── Execution tracking ────────────────────────────────────────────
|
|
860
|
+
startExecution(skillId, params) {
|
|
861
|
+
const skill = this.skills.get(skillId);
|
|
862
|
+
if (!skill || !skill.enabled) throw new Error(`Skill "${skillId}" not found or disabled`);
|
|
863
|
+
const execution = {
|
|
864
|
+
id: `exec-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
865
|
+
skillId,
|
|
866
|
+
startedAt: Date.now(),
|
|
867
|
+
status: "running",
|
|
868
|
+
currentStep: 0,
|
|
869
|
+
params,
|
|
870
|
+
results: []
|
|
871
|
+
};
|
|
872
|
+
this.executions.set(execution.id, execution);
|
|
873
|
+
skill.lastUsedAt = Date.now();
|
|
874
|
+
skill.useCount++;
|
|
875
|
+
this.notify();
|
|
876
|
+
return execution;
|
|
877
|
+
}
|
|
878
|
+
completeExecution(executionId, stepResults) {
|
|
879
|
+
const execution = this.executions.get(executionId);
|
|
880
|
+
if (!execution) return;
|
|
881
|
+
execution.completedAt = Date.now();
|
|
882
|
+
execution.status = "completed";
|
|
883
|
+
execution.results = stepResults;
|
|
884
|
+
execution.currentStep = execution.results.length;
|
|
885
|
+
this.notify();
|
|
886
|
+
}
|
|
887
|
+
failExecution(executionId, error) {
|
|
888
|
+
const execution = this.executions.get(executionId);
|
|
889
|
+
if (!execution) return;
|
|
890
|
+
execution.completedAt = Date.now();
|
|
891
|
+
execution.status = "failed";
|
|
892
|
+
execution.error = error;
|
|
893
|
+
this.notify();
|
|
894
|
+
}
|
|
895
|
+
getExecution(executionId) {
|
|
896
|
+
return this.executions.get(executionId);
|
|
897
|
+
}
|
|
898
|
+
getRecentExecutions(limit = 20) {
|
|
899
|
+
return Array.from(this.executions.values()).sort((a, b) => b.startedAt - a.startedAt).slice(0, limit);
|
|
900
|
+
}
|
|
901
|
+
// ── Export / Import ───────────────────────────────────────────────
|
|
902
|
+
/** Export a skill definition as a legacy SkillDefinition */
|
|
903
|
+
toSkillDefinition(id) {
|
|
904
|
+
const skill = this.skills.get(id);
|
|
905
|
+
if (!skill) return void 0;
|
|
906
|
+
const m = skill.manifest;
|
|
907
|
+
return {
|
|
908
|
+
id: m.id,
|
|
909
|
+
name: m.name,
|
|
910
|
+
version: m.version,
|
|
911
|
+
description: m.description,
|
|
912
|
+
prompt: m.steps.map((s) => s.prompt).join("\n\n"),
|
|
913
|
+
tools: m.requiresTools,
|
|
914
|
+
modelPreference: m.modelPreference,
|
|
915
|
+
category: m.category,
|
|
916
|
+
tags: m.tags,
|
|
917
|
+
params: m.params
|
|
918
|
+
};
|
|
919
|
+
}
|
|
920
|
+
/** Serialize all skills for persistence */
|
|
921
|
+
serialize() {
|
|
922
|
+
const data = this.getAll().map((s) => ({
|
|
923
|
+
manifest: s.manifest,
|
|
924
|
+
installedAt: s.installedAt,
|
|
925
|
+
lastUsedAt: s.lastUsedAt,
|
|
926
|
+
useCount: s.useCount,
|
|
927
|
+
enabled: s.enabled
|
|
928
|
+
}));
|
|
929
|
+
return JSON.stringify(data, null, 2);
|
|
930
|
+
}
|
|
931
|
+
/** Restore from serialized state */
|
|
932
|
+
deserialize(json) {
|
|
933
|
+
try {
|
|
934
|
+
const data = JSON.parse(json);
|
|
935
|
+
for (const item of data) {
|
|
936
|
+
this.skills.set(item.manifest.id, {
|
|
937
|
+
...item,
|
|
938
|
+
status: item.manifest.source === "builtin" ? "builtin" : "installed",
|
|
939
|
+
error: void 0
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
this.notify();
|
|
943
|
+
} catch {
|
|
301
944
|
}
|
|
302
|
-
return skills.length;
|
|
303
945
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
*/
|
|
309
|
-
async loadStandardSkills(projectRoot) {
|
|
310
|
-
let count = 0;
|
|
311
|
-
const globalDir = getGlobalSkillsDir();
|
|
312
|
-
count += await this.loadFromDir(globalDir);
|
|
313
|
-
const projectDir = join3(projectRoot, ".cliskill", "skills");
|
|
314
|
-
count += await this.loadFromDir(projectDir);
|
|
315
|
-
return count;
|
|
946
|
+
// ── Event system ──────────────────────────────────────────────────
|
|
947
|
+
onChange(listener) {
|
|
948
|
+
this.listeners.add(listener);
|
|
949
|
+
return () => this.listeners.delete(listener);
|
|
316
950
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
*/
|
|
320
|
-
getSkillPrompt(nameOrAlias) {
|
|
321
|
-
const skill = this.get(nameOrAlias);
|
|
322
|
-
return skill?.prompt;
|
|
951
|
+
notify() {
|
|
952
|
+
for (const listener of this.listeners) listener();
|
|
323
953
|
}
|
|
324
954
|
};
|
|
955
|
+
var skillRegistry = new SkillRegistry();
|
|
325
956
|
|
|
326
957
|
// src/safety/permissions.ts
|
|
327
958
|
var PermissionManager = class {
|
|
@@ -605,8 +1236,8 @@ function matchesAny(fullCommand, firstTwoWords, set) {
|
|
|
605
1236
|
}
|
|
606
1237
|
|
|
607
1238
|
// src/services/history.ts
|
|
608
|
-
import { readFile as
|
|
609
|
-
import { existsSync as
|
|
1239
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
1240
|
+
import { existsSync as existsSync2 } from "fs";
|
|
610
1241
|
import { dirname } from "path";
|
|
611
1242
|
var DEFAULT_CONFIG2 = {
|
|
612
1243
|
maxEntries: 1e3,
|
|
@@ -668,7 +1299,7 @@ var HistoryManager = class {
|
|
|
668
1299
|
async save() {
|
|
669
1300
|
const filePath = this.resolvePath();
|
|
670
1301
|
const dir = dirname(filePath);
|
|
671
|
-
if (!
|
|
1302
|
+
if (!existsSync2(dir)) {
|
|
672
1303
|
await mkdir2(dir, { recursive: true });
|
|
673
1304
|
}
|
|
674
1305
|
const lines = this.entries.map((e) => JSON.stringify(e)).join("\n");
|
|
@@ -676,35 +1307,256 @@ var HistoryManager = class {
|
|
|
676
1307
|
}
|
|
677
1308
|
async load() {
|
|
678
1309
|
const filePath = this.resolvePath();
|
|
679
|
-
if (!
|
|
1310
|
+
if (!existsSync2(filePath)) {
|
|
680
1311
|
this.entries = [];
|
|
681
1312
|
this.cursorIndex = -1;
|
|
682
1313
|
return;
|
|
683
1314
|
}
|
|
684
|
-
const content = await
|
|
685
|
-
const lines = content.split("\n").filter(Boolean);
|
|
686
|
-
const loaded = [];
|
|
687
|
-
for (const line of lines) {
|
|
688
|
-
try {
|
|
689
|
-
const entry = JSON.parse(line);
|
|
690
|
-
if (entry.content && typeof entry.content === "string" && entry.timestamp) {
|
|
691
|
-
loaded.push({
|
|
692
|
-
content: entry.content,
|
|
693
|
-
timestamp: entry.timestamp,
|
|
694
|
-
type: entry.type ?? "user"
|
|
695
|
-
});
|
|
696
|
-
}
|
|
697
|
-
} catch {
|
|
1315
|
+
const content = await readFile2(filePath, "utf-8");
|
|
1316
|
+
const lines = content.split("\n").filter(Boolean);
|
|
1317
|
+
const loaded = [];
|
|
1318
|
+
for (const line of lines) {
|
|
1319
|
+
try {
|
|
1320
|
+
const entry = JSON.parse(line);
|
|
1321
|
+
if (entry.content && typeof entry.content === "string" && entry.timestamp) {
|
|
1322
|
+
loaded.push({
|
|
1323
|
+
content: entry.content,
|
|
1324
|
+
timestamp: entry.timestamp,
|
|
1325
|
+
type: entry.type ?? "user"
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
} catch {
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
this.entries = loaded.slice(-this.config.maxEntries);
|
|
1332
|
+
this.cursorIndex = this.entries.length;
|
|
1333
|
+
}
|
|
1334
|
+
resolvePath() {
|
|
1335
|
+
if (this.config.filePath.startsWith("~")) {
|
|
1336
|
+
return getHistoryPath();
|
|
1337
|
+
}
|
|
1338
|
+
return this.config.filePath;
|
|
1339
|
+
}
|
|
1340
|
+
};
|
|
1341
|
+
|
|
1342
|
+
// src/utils/decomposition.ts
|
|
1343
|
+
var NUMBERED_LIST_REGEX = /(?:^|\n)\s*(?:\d+[\.|\)])\s*(.+?)(?=\n\s*(?:\d+[\.|\)])|$)/gs;
|
|
1344
|
+
|
|
1345
|
+
// src/swarm/coordinator.ts
|
|
1346
|
+
var MAX_PARALLEL_WORKERS = 3;
|
|
1347
|
+
var SwarmCoordinator = class {
|
|
1348
|
+
constructor(adapter, tools) {
|
|
1349
|
+
this.adapter = adapter;
|
|
1350
|
+
this.tools = tools;
|
|
1351
|
+
}
|
|
1352
|
+
adapter;
|
|
1353
|
+
tools;
|
|
1354
|
+
agents = /* @__PURE__ */ new Map();
|
|
1355
|
+
mailbox = /* @__PURE__ */ new Map();
|
|
1356
|
+
abortController = new AbortController();
|
|
1357
|
+
addAgent(config) {
|
|
1358
|
+
this.agents.set(config.id, config);
|
|
1359
|
+
this.mailbox.set(config.id, []);
|
|
1360
|
+
}
|
|
1361
|
+
removeAgent(id) {
|
|
1362
|
+
this.agents.delete(id);
|
|
1363
|
+
this.mailbox.delete(id);
|
|
1364
|
+
}
|
|
1365
|
+
getAgents() {
|
|
1366
|
+
return Array.from(this.agents.values());
|
|
1367
|
+
}
|
|
1368
|
+
async sendMessage(message) {
|
|
1369
|
+
if (message.to === "*") {
|
|
1370
|
+
for (const [agentId] of this.agents) {
|
|
1371
|
+
this.mailbox.get(agentId)?.push({ ...message, to: agentId });
|
|
1372
|
+
}
|
|
1373
|
+
} else {
|
|
1374
|
+
this.mailbox.get(message.to)?.push(message);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
getMessages(agentId) {
|
|
1378
|
+
return this.mailbox.get(agentId) ?? [];
|
|
1379
|
+
}
|
|
1380
|
+
async executeSwarm(task) {
|
|
1381
|
+
this.abortController = new AbortController();
|
|
1382
|
+
const startTime = performance.now();
|
|
1383
|
+
const coordinator = this.findAgentByRole("coordinator");
|
|
1384
|
+
const workers = this.findAgentsByRole("worker");
|
|
1385
|
+
const reviewers = this.findAgentsByRole("reviewer");
|
|
1386
|
+
const subtasks = coordinator ? await this.decomposeTask(coordinator, task) : this.fallbackDecompose(task, workers.length);
|
|
1387
|
+
const assignments = this.assignSubtasks(subtasks, workers);
|
|
1388
|
+
const workerResults = await this.executeParallel(assignments);
|
|
1389
|
+
let reviewResult;
|
|
1390
|
+
if (reviewers.length > 0) {
|
|
1391
|
+
reviewResult = await this.reviewResults(reviewers[0], workerResults);
|
|
1392
|
+
}
|
|
1393
|
+
const results = workerResults.map((wr) => ({
|
|
1394
|
+
agentId: wr.agentId,
|
|
1395
|
+
agentName: wr.agentName,
|
|
1396
|
+
task: wr.task,
|
|
1397
|
+
result: wr.result,
|
|
1398
|
+
success: wr.success,
|
|
1399
|
+
duration: performance.now() - startTime,
|
|
1400
|
+
turns: wr.turns
|
|
1401
|
+
}));
|
|
1402
|
+
if (reviewResult !== void 0 && reviewers.length > 0) {
|
|
1403
|
+
results.push({
|
|
1404
|
+
agentId: reviewers[0].id,
|
|
1405
|
+
agentName: reviewers[0].name,
|
|
1406
|
+
task: "Review all worker results",
|
|
1407
|
+
result: reviewResult,
|
|
1408
|
+
success: true,
|
|
1409
|
+
duration: 0,
|
|
1410
|
+
turns: 1
|
|
1411
|
+
});
|
|
1412
|
+
}
|
|
1413
|
+
return results;
|
|
1414
|
+
}
|
|
1415
|
+
shutdown() {
|
|
1416
|
+
this.abortController.abort();
|
|
1417
|
+
for (const [agentId] of this.agents) {
|
|
1418
|
+
this.mailbox.get(agentId)?.push({
|
|
1419
|
+
from: "system",
|
|
1420
|
+
to: agentId,
|
|
1421
|
+
type: "shutdown",
|
|
1422
|
+
content: "Shutdown requested",
|
|
1423
|
+
timestamp: Date.now()
|
|
1424
|
+
});
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
findAgentByRole(role) {
|
|
1428
|
+
for (const agent of this.agents.values()) {
|
|
1429
|
+
if (agent.role === role) return agent;
|
|
1430
|
+
}
|
|
1431
|
+
return void 0;
|
|
1432
|
+
}
|
|
1433
|
+
findAgentsByRole(role) {
|
|
1434
|
+
return Array.from(this.agents.values()).filter((a) => a.role === role);
|
|
1435
|
+
}
|
|
1436
|
+
async decomposeTask(coordinator, task) {
|
|
1437
|
+
const engine = this.createEngine(coordinator);
|
|
1438
|
+
const prompt = `Decompose the following task into subtasks. Return ONLY a numbered list, one subtask per line. No explanations.
|
|
1439
|
+
|
|
1440
|
+
Task: ${task}
|
|
1441
|
+
|
|
1442
|
+
Subtasks:`;
|
|
1443
|
+
let decomposition = "";
|
|
1444
|
+
try {
|
|
1445
|
+
for await (const event of engine.run(prompt)) {
|
|
1446
|
+
if (event.type === "text_delta") decomposition += event.text;
|
|
1447
|
+
if (event.type === "error") break;
|
|
1448
|
+
}
|
|
1449
|
+
} catch {
|
|
1450
|
+
return this.fallbackDecompose(task, this.findAgentsByRole("worker").length);
|
|
1451
|
+
}
|
|
1452
|
+
const matches = [...decomposition.matchAll(NUMBERED_LIST_REGEX)];
|
|
1453
|
+
if (matches.length === 0) {
|
|
1454
|
+
return this.fallbackDecompose(task, this.findAgentsByRole("worker").length);
|
|
1455
|
+
}
|
|
1456
|
+
return matches.map((m, i) => ({
|
|
1457
|
+
id: `subtask_${i + 1}`,
|
|
1458
|
+
description: m[1].trim(),
|
|
1459
|
+
status: "pending"
|
|
1460
|
+
}));
|
|
1461
|
+
}
|
|
1462
|
+
fallbackDecompose(task, workerCount) {
|
|
1463
|
+
const count = Math.max(1, Math.min(workerCount, MAX_PARALLEL_WORKERS));
|
|
1464
|
+
return Array.from({ length: count }, (_, i) => ({
|
|
1465
|
+
id: `subtask_${i + 1}`,
|
|
1466
|
+
description: count === 1 ? task : `Part ${i + 1} of: ${task}`,
|
|
1467
|
+
status: "pending"
|
|
1468
|
+
}));
|
|
1469
|
+
}
|
|
1470
|
+
assignSubtasks(subtasks, workers) {
|
|
1471
|
+
const assignments = [];
|
|
1472
|
+
if (workers.length === 0) return assignments;
|
|
1473
|
+
subtasks.forEach((task, i) => {
|
|
1474
|
+
const worker = workers[i % workers.length];
|
|
1475
|
+
task.assignedTo = worker.id;
|
|
1476
|
+
assignments.push({ task, worker });
|
|
1477
|
+
});
|
|
1478
|
+
return assignments;
|
|
1479
|
+
}
|
|
1480
|
+
async executeParallel(assignments) {
|
|
1481
|
+
const chunks = [];
|
|
1482
|
+
for (let i = 0; i < assignments.length; i += MAX_PARALLEL_WORKERS) {
|
|
1483
|
+
chunks.push(assignments.slice(i, i + MAX_PARALLEL_WORKERS));
|
|
1484
|
+
}
|
|
1485
|
+
const allResults = [];
|
|
1486
|
+
for (const chunk of chunks) {
|
|
1487
|
+
if (this.abortController.signal.aborted) break;
|
|
1488
|
+
const settled = await Promise.allSettled(
|
|
1489
|
+
chunk.map(async ({ task, worker }) => {
|
|
1490
|
+
task.status = "running";
|
|
1491
|
+
const engine = this.createEngine(worker);
|
|
1492
|
+
let output = "";
|
|
1493
|
+
let turns = 0;
|
|
1494
|
+
try {
|
|
1495
|
+
for await (const event of engine.run(task.description)) {
|
|
1496
|
+
if (this.abortController.signal.aborted) break;
|
|
1497
|
+
if (event.type === "text_delta") output += event.text;
|
|
1498
|
+
if (event.type === "turn_end") turns = event.turn;
|
|
1499
|
+
if (event.type === "complete") {
|
|
1500
|
+
turns = event.result.turns;
|
|
1501
|
+
output = output || event.result.messages.filter((m) => m.role === "assistant").flatMap((m) => m.content).filter((b) => b.type === "text").map((b) => b.text).join("\n");
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
task.status = "completed";
|
|
1505
|
+
task.result = output;
|
|
1506
|
+
return { agentId: worker.id, agentName: worker.name, task: task.description, result: output, success: true, turns };
|
|
1507
|
+
} catch (err) {
|
|
1508
|
+
task.status = "failed";
|
|
1509
|
+
return { agentId: worker.id, agentName: worker.name, task: task.description, result: err.message, success: false, turns };
|
|
1510
|
+
}
|
|
1511
|
+
})
|
|
1512
|
+
);
|
|
1513
|
+
for (const r of settled) {
|
|
1514
|
+
if (r.status === "fulfilled") allResults.push(r.value);
|
|
1515
|
+
else allResults.push({ agentId: "unknown", agentName: "unknown", task: "", result: r.reason?.message ?? "Unknown error", success: false, turns: 0 });
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
return allResults;
|
|
1519
|
+
}
|
|
1520
|
+
async reviewResults(reviewer, results) {
|
|
1521
|
+
const engine = this.createEngine(reviewer);
|
|
1522
|
+
const summary = results.map((r, i) => `Worker ${i + 1} (${r.agentName}): ${r.success ? "SUCCESS" : "FAILED"}
|
|
1523
|
+
Task: ${r.task}
|
|
1524
|
+
Result: ${r.result.slice(0, 500)}`).join("\n\n");
|
|
1525
|
+
const prompt = `Review the following worker results and provide a brief assessment:
|
|
1526
|
+
|
|
1527
|
+
${summary}
|
|
1528
|
+
|
|
1529
|
+
Provide a concise review:`;
|
|
1530
|
+
let reviewText = "";
|
|
1531
|
+
try {
|
|
1532
|
+
for await (const event of engine.run(prompt)) {
|
|
1533
|
+
if (event.type === "error") break;
|
|
1534
|
+
if (event.type === "text_delta" && event.text) reviewText += event.text;
|
|
698
1535
|
}
|
|
1536
|
+
} catch {
|
|
699
1537
|
}
|
|
700
|
-
|
|
701
|
-
this.cursorIndex = this.entries.length;
|
|
1538
|
+
return reviewText || "Review completed with no output.";
|
|
702
1539
|
}
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
1540
|
+
createEngine(agent) {
|
|
1541
|
+
const filteredTools = new ToolRegistry();
|
|
1542
|
+
if (agent.tools) {
|
|
1543
|
+
for (const toolName of agent.tools) {
|
|
1544
|
+
const tool = this.tools.get(toolName);
|
|
1545
|
+
if (tool) filteredTools.register(tool);
|
|
1546
|
+
}
|
|
1547
|
+
} else {
|
|
1548
|
+
for (const tool of this.tools.getAll()) {
|
|
1549
|
+
if (tool.name !== "agent") filteredTools.register(tool);
|
|
1550
|
+
}
|
|
706
1551
|
}
|
|
707
|
-
return
|
|
1552
|
+
return new QueryEngine(
|
|
1553
|
+
{
|
|
1554
|
+
maxTurns: agent.maxTurns ?? 10,
|
|
1555
|
+
systemPrompt: agent.systemPrompt ?? `You are agent "${agent.name}" with role "${agent.role}". Complete assigned tasks concisely.`
|
|
1556
|
+
},
|
|
1557
|
+
this.adapter,
|
|
1558
|
+
filteredTools
|
|
1559
|
+
);
|
|
708
1560
|
}
|
|
709
1561
|
};
|
|
710
1562
|
|
|
@@ -787,12 +1639,23 @@ var HookExecutor = class {
|
|
|
787
1639
|
executeOne(hook, context) {
|
|
788
1640
|
const start = Date.now();
|
|
789
1641
|
if (hook.type === "function") {
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
1642
|
+
try {
|
|
1643
|
+
const handlerFn = new Function("context", `return (${hook.handler})`);
|
|
1644
|
+
const result = handlerFn(context);
|
|
1645
|
+
return Promise.resolve({
|
|
1646
|
+
hookId: hook.id,
|
|
1647
|
+
success: true,
|
|
1648
|
+
output: typeof result === "string" ? result : JSON.stringify(result),
|
|
1649
|
+
duration: Date.now() - start
|
|
1650
|
+
});
|
|
1651
|
+
} catch (err) {
|
|
1652
|
+
return Promise.resolve({
|
|
1653
|
+
hookId: hook.id,
|
|
1654
|
+
success: false,
|
|
1655
|
+
output: `Function handler "${hook.handler}" failed: ${err.message}`,
|
|
1656
|
+
duration: Date.now() - start
|
|
1657
|
+
});
|
|
1658
|
+
}
|
|
796
1659
|
}
|
|
797
1660
|
return this.executeCommand(hook, context, start);
|
|
798
1661
|
}
|
|
@@ -1145,207 +2008,6 @@ async function executeShellTask(taskId, manager, command, cwd, signal) {
|
|
|
1145
2008
|
}
|
|
1146
2009
|
});
|
|
1147
2010
|
}
|
|
1148
|
-
|
|
1149
|
-
// src/swarm/coordinator.ts
|
|
1150
|
-
var MAX_PARALLEL_WORKERS = 3;
|
|
1151
|
-
var SUBTASK_REGEX = /(?:^|\n)\s*(?:\d+[\.\)])\s*(.+?)(?=\n\s*(?:\d+[\.\)])|$)/gs;
|
|
1152
|
-
var SwarmCoordinator = class {
|
|
1153
|
-
constructor(adapter, tools) {
|
|
1154
|
-
this.adapter = adapter;
|
|
1155
|
-
this.tools = tools;
|
|
1156
|
-
}
|
|
1157
|
-
adapter;
|
|
1158
|
-
tools;
|
|
1159
|
-
agents = /* @__PURE__ */ new Map();
|
|
1160
|
-
mailbox = /* @__PURE__ */ new Map();
|
|
1161
|
-
abortController = new AbortController();
|
|
1162
|
-
addAgent(config) {
|
|
1163
|
-
this.agents.set(config.id, config);
|
|
1164
|
-
this.mailbox.set(config.id, []);
|
|
1165
|
-
}
|
|
1166
|
-
removeAgent(id) {
|
|
1167
|
-
this.agents.delete(id);
|
|
1168
|
-
this.mailbox.delete(id);
|
|
1169
|
-
}
|
|
1170
|
-
getAgents() {
|
|
1171
|
-
return Array.from(this.agents.values());
|
|
1172
|
-
}
|
|
1173
|
-
async sendMessage(message) {
|
|
1174
|
-
if (message.to === "*") {
|
|
1175
|
-
for (const [agentId] of this.agents) {
|
|
1176
|
-
this.mailbox.get(agentId)?.push({ ...message, to: agentId });
|
|
1177
|
-
}
|
|
1178
|
-
} else {
|
|
1179
|
-
this.mailbox.get(message.to)?.push(message);
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
async executeSwarm(task) {
|
|
1183
|
-
this.abortController = new AbortController();
|
|
1184
|
-
const startTime = performance.now();
|
|
1185
|
-
const coordinator = this.findAgentByRole("coordinator");
|
|
1186
|
-
const workers = this.findAgentsByRole("worker");
|
|
1187
|
-
const reviewers = this.findAgentsByRole("reviewer");
|
|
1188
|
-
const subtasks = coordinator ? await this.decomposeTask(coordinator, task) : this.fallbackDecompose(task, workers.length);
|
|
1189
|
-
const assignments = this.assignSubtasks(subtasks, workers);
|
|
1190
|
-
const workerResults = await this.executeParallel(assignments);
|
|
1191
|
-
if (reviewers.length > 0) {
|
|
1192
|
-
await this.reviewResults(reviewers[0], workerResults);
|
|
1193
|
-
}
|
|
1194
|
-
const results = workerResults.map((wr) => ({
|
|
1195
|
-
agentId: wr.agentId,
|
|
1196
|
-
agentName: wr.agentName,
|
|
1197
|
-
task: wr.task,
|
|
1198
|
-
result: wr.result,
|
|
1199
|
-
success: wr.success,
|
|
1200
|
-
duration: performance.now() - startTime,
|
|
1201
|
-
turns: wr.turns
|
|
1202
|
-
}));
|
|
1203
|
-
return results;
|
|
1204
|
-
}
|
|
1205
|
-
shutdown() {
|
|
1206
|
-
this.abortController.abort();
|
|
1207
|
-
for (const [agentId] of this.agents) {
|
|
1208
|
-
this.mailbox.get(agentId)?.push({
|
|
1209
|
-
from: "system",
|
|
1210
|
-
to: agentId,
|
|
1211
|
-
type: "shutdown",
|
|
1212
|
-
content: "Shutdown requested",
|
|
1213
|
-
timestamp: Date.now()
|
|
1214
|
-
});
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
findAgentByRole(role) {
|
|
1218
|
-
for (const agent of this.agents.values()) {
|
|
1219
|
-
if (agent.role === role) return agent;
|
|
1220
|
-
}
|
|
1221
|
-
return void 0;
|
|
1222
|
-
}
|
|
1223
|
-
findAgentsByRole(role) {
|
|
1224
|
-
return Array.from(this.agents.values()).filter((a) => a.role === role);
|
|
1225
|
-
}
|
|
1226
|
-
async decomposeTask(coordinator, task) {
|
|
1227
|
-
const engine = this.createEngine(coordinator);
|
|
1228
|
-
const prompt = `Decompose the following task into subtasks. Return ONLY a numbered list, one subtask per line. No explanations.
|
|
1229
|
-
|
|
1230
|
-
Task: ${task}
|
|
1231
|
-
|
|
1232
|
-
Subtasks:`;
|
|
1233
|
-
let decomposition = "";
|
|
1234
|
-
try {
|
|
1235
|
-
for await (const event of engine.run(prompt)) {
|
|
1236
|
-
if (event.type === "text_delta") decomposition += event.text;
|
|
1237
|
-
if (event.type === "error") break;
|
|
1238
|
-
}
|
|
1239
|
-
} catch {
|
|
1240
|
-
return this.fallbackDecompose(task, this.findAgentsByRole("worker").length);
|
|
1241
|
-
}
|
|
1242
|
-
const matches = [...decomposition.matchAll(SUBTASK_REGEX)];
|
|
1243
|
-
if (matches.length === 0) {
|
|
1244
|
-
return this.fallbackDecompose(task, this.findAgentsByRole("worker").length);
|
|
1245
|
-
}
|
|
1246
|
-
return matches.map((m, i) => ({
|
|
1247
|
-
id: `subtask_${i + 1}`,
|
|
1248
|
-
description: m[1].trim(),
|
|
1249
|
-
status: "pending"
|
|
1250
|
-
}));
|
|
1251
|
-
}
|
|
1252
|
-
fallbackDecompose(task, workerCount) {
|
|
1253
|
-
const count = Math.max(1, Math.min(workerCount, MAX_PARALLEL_WORKERS));
|
|
1254
|
-
return Array.from({ length: count }, (_, i) => ({
|
|
1255
|
-
id: `subtask_${i + 1}`,
|
|
1256
|
-
description: count === 1 ? task : `Part ${i + 1} of: ${task}`,
|
|
1257
|
-
status: "pending"
|
|
1258
|
-
}));
|
|
1259
|
-
}
|
|
1260
|
-
assignSubtasks(subtasks, workers) {
|
|
1261
|
-
const assignments = [];
|
|
1262
|
-
if (workers.length === 0) return assignments;
|
|
1263
|
-
subtasks.forEach((task, i) => {
|
|
1264
|
-
const worker = workers[i % workers.length];
|
|
1265
|
-
task.assignedTo = worker.id;
|
|
1266
|
-
assignments.push({ task, worker });
|
|
1267
|
-
});
|
|
1268
|
-
return assignments;
|
|
1269
|
-
}
|
|
1270
|
-
async executeParallel(assignments) {
|
|
1271
|
-
const chunks = [];
|
|
1272
|
-
for (let i = 0; i < assignments.length; i += MAX_PARALLEL_WORKERS) {
|
|
1273
|
-
chunks.push(assignments.slice(i, i + MAX_PARALLEL_WORKERS));
|
|
1274
|
-
}
|
|
1275
|
-
const allResults = [];
|
|
1276
|
-
for (const chunk of chunks) {
|
|
1277
|
-
if (this.abortController.signal.aborted) break;
|
|
1278
|
-
const settled = await Promise.allSettled(
|
|
1279
|
-
chunk.map(async ({ task, worker }) => {
|
|
1280
|
-
task.status = "running";
|
|
1281
|
-
const engine = this.createEngine(worker);
|
|
1282
|
-
let output = "";
|
|
1283
|
-
let turns = 0;
|
|
1284
|
-
try {
|
|
1285
|
-
for await (const event of engine.run(task.description)) {
|
|
1286
|
-
if (this.abortController.signal.aborted) break;
|
|
1287
|
-
if (event.type === "text_delta") output += event.text;
|
|
1288
|
-
if (event.type === "turn_end") turns = event.turn;
|
|
1289
|
-
if (event.type === "complete") {
|
|
1290
|
-
turns = event.result.turns;
|
|
1291
|
-
output = output || event.result.messages.filter((m) => m.role === "assistant").flatMap((m) => m.content).filter((b) => b.type === "text").map((b) => b.text).join("\n");
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
task.status = "completed";
|
|
1295
|
-
task.result = output;
|
|
1296
|
-
return { agentId: worker.id, agentName: worker.name, task: task.description, result: output, success: true, turns };
|
|
1297
|
-
} catch (err) {
|
|
1298
|
-
task.status = "failed";
|
|
1299
|
-
return { agentId: worker.id, agentName: worker.name, task: task.description, result: err.message, success: false, turns };
|
|
1300
|
-
}
|
|
1301
|
-
})
|
|
1302
|
-
);
|
|
1303
|
-
for (const r of settled) {
|
|
1304
|
-
if (r.status === "fulfilled") allResults.push(r.value);
|
|
1305
|
-
else allResults.push({ agentId: "unknown", agentName: "unknown", task: "", result: r.reason?.message ?? "Unknown error", success: false, turns: 0 });
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
return allResults;
|
|
1309
|
-
}
|
|
1310
|
-
async reviewResults(reviewer, results) {
|
|
1311
|
-
const engine = this.createEngine(reviewer);
|
|
1312
|
-
const summary = results.map((r, i) => `Worker ${i + 1} (${r.agentName}): ${r.success ? "SUCCESS" : "FAILED"}
|
|
1313
|
-
Task: ${r.task}
|
|
1314
|
-
Result: ${r.result.slice(0, 500)}`).join("\n\n");
|
|
1315
|
-
const prompt = `Review the following worker results and provide a brief assessment:
|
|
1316
|
-
|
|
1317
|
-
${summary}
|
|
1318
|
-
|
|
1319
|
-
Provide a concise review:`;
|
|
1320
|
-
try {
|
|
1321
|
-
for await (const event of engine.run(prompt)) {
|
|
1322
|
-
if (event.type === "error") break;
|
|
1323
|
-
}
|
|
1324
|
-
} catch {
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
createEngine(agent) {
|
|
1328
|
-
const filteredTools = new ToolRegistry();
|
|
1329
|
-
if (agent.tools) {
|
|
1330
|
-
for (const toolName of agent.tools) {
|
|
1331
|
-
const tool = this.tools.get(toolName);
|
|
1332
|
-
if (tool) filteredTools.register(tool);
|
|
1333
|
-
}
|
|
1334
|
-
} else {
|
|
1335
|
-
for (const tool of this.tools.getAll()) {
|
|
1336
|
-
if (tool.name !== "agent") filteredTools.register(tool);
|
|
1337
|
-
}
|
|
1338
|
-
}
|
|
1339
|
-
return new QueryEngine(
|
|
1340
|
-
{
|
|
1341
|
-
maxTurns: agent.maxTurns ?? 10,
|
|
1342
|
-
systemPrompt: agent.systemPrompt ?? `You are agent "${agent.name}" with role "${agent.role}". Complete assigned tasks concisely.`
|
|
1343
|
-
},
|
|
1344
|
-
this.adapter,
|
|
1345
|
-
filteredTools
|
|
1346
|
-
);
|
|
1347
|
-
}
|
|
1348
|
-
};
|
|
1349
2011
|
export {
|
|
1350
2012
|
AdapterRegistry,
|
|
1351
2013
|
AgentTool,
|