@corbat-tech/coco 2.8.2 → 2.10.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/index.js CHANGED
@@ -5,8 +5,8 @@ import * as fs4 from 'fs';
5
5
  import fs4__default, { readFileSync, constants } from 'fs';
6
6
  import * as fs15 from 'fs/promises';
7
7
  import fs15__default, { readFile, access, readdir } from 'fs/promises';
8
- import chalk3 from 'chalk';
9
- import * as p3 from '@clack/prompts';
8
+ import chalk4 from 'chalk';
9
+ import * as p4 from '@clack/prompts';
10
10
  import { fileURLToPath } from 'url';
11
11
  import { randomUUID } from 'crypto';
12
12
  import { execa } from 'execa';
@@ -25,6 +25,7 @@ import JSON5 from 'json5';
25
25
  import 'events';
26
26
  import 'minimatch';
27
27
  import { simpleGit } from 'simple-git';
28
+ import { diffWords } from 'diff';
28
29
  import hljs from 'highlight.js/lib/core';
29
30
  import bash from 'highlight.js/lib/languages/bash';
30
31
  import css from 'highlight.js/lib/languages/css';
@@ -398,10 +399,10 @@ __export(allow_path_prompt_exports, {
398
399
  async function promptAllowPath(dirPath) {
399
400
  const absolute = path16__default.resolve(dirPath);
400
401
  console.log();
401
- console.log(chalk3.yellow(" \u26A0 Access denied \u2014 path is outside the project directory"));
402
- console.log(chalk3.dim(` \u{1F4C1} ${absolute}`));
402
+ console.log(chalk4.yellow(" \u26A0 Access denied \u2014 path is outside the project directory"));
403
+ console.log(chalk4.dim(` \u{1F4C1} ${absolute}`));
403
404
  console.log();
404
- const action = await p3.select({
405
+ const action = await p4.select({
405
406
  message: "Grant access to this directory?",
406
407
  options: [
407
408
  { value: "session-write", label: "\u2713 Allow write (this session)" },
@@ -411,7 +412,7 @@ async function promptAllowPath(dirPath) {
411
412
  { value: "no", label: "\u2717 Deny" }
412
413
  ]
413
414
  });
414
- if (p3.isCancel(action) || action === "no") {
415
+ if (p4.isCancel(action) || action === "no") {
415
416
  return false;
416
417
  }
417
418
  const level = action.includes("read") ? "read" : "write";
@@ -422,7 +423,7 @@ async function promptAllowPath(dirPath) {
422
423
  }
423
424
  const levelLabel = level === "write" ? "write" : "read-only";
424
425
  const persistLabel = persist ? " (remembered)" : "";
425
- console.log(chalk3.green(` \u2713 Access granted: ${levelLabel}${persistLabel}`));
426
+ console.log(chalk4.green(` \u2713 Access granted: ${levelLabel}${persistLabel}`));
426
427
  return true;
427
428
  }
428
429
  var init_allow_path_prompt = __esm({
@@ -15967,9 +15968,9 @@ Examples:
15967
15968
  if (file) {
15968
15969
  options.file = file;
15969
15970
  }
15970
- const log2 = await git.log(options);
15971
+ const log3 = await git.log(options);
15971
15972
  return {
15972
- commits: log2.all.map((commit) => ({
15973
+ commits: log3.all.map((commit) => ({
15973
15974
  hash: commit.hash,
15974
15975
  message: commit.message,
15975
15976
  author: commit.author_name,
@@ -16281,6 +16282,34 @@ var simpleAutoCommitTool = defineTool({
16281
16282
  }
16282
16283
  });
16283
16284
  var gitSimpleTools = [checkProtectedBranchTool, simpleAutoCommitTool];
16285
+ var AGENT_NAMES = {
16286
+ explore: "Explorer",
16287
+ plan: "Planner",
16288
+ test: "Tester",
16289
+ debug: "Debugger",
16290
+ review: "Reviewer",
16291
+ architect: "Architect",
16292
+ security: "Security Auditor",
16293
+ tdd: "TDD Guide",
16294
+ refactor: "Refactorer",
16295
+ e2e: "E2E Tester",
16296
+ docs: "Docs Writer",
16297
+ database: "Database Engineer"
16298
+ };
16299
+ var AGENT_DESCRIPTIONS = {
16300
+ explore: "Search the codebase to answer questions and gather information",
16301
+ plan: "Design implementation approaches and create detailed plans",
16302
+ test: "Write and run tests to ensure code quality",
16303
+ debug: "Analyze errors and fix issues",
16304
+ review: "Review code for quality and best practices",
16305
+ architect: "Design system architecture and create architectural decision records",
16306
+ security: "Audit code for security vulnerabilities using OWASP Top 10",
16307
+ tdd: "Drive development with test-first methodology and RED-GREEN-REFACTOR cycle",
16308
+ refactor: "Improve code structure and quality without changing behavior",
16309
+ e2e: "Write and run end-to-end tests covering full user workflows",
16310
+ docs: "Generate and maintain documentation for code, APIs, and architecture",
16311
+ database: "Design database schemas, write migrations, and optimize queries"
16312
+ };
16284
16313
 
16285
16314
  // src/agents/provider-bridge.ts
16286
16315
  var agentProvider = null;
@@ -16291,103 +16320,80 @@ function getAgentProvider() {
16291
16320
  function getAgentToolRegistry() {
16292
16321
  return agentToolRegistry;
16293
16322
  }
16294
- var AGENT_ROLES = {
16295
- researcher: {
16296
- role: "researcher",
16297
- systemPrompt: `You are a code researcher agent. Your role is to:
16298
- - Explore and understand existing codebases
16299
- - Find relevant code patterns and examples
16300
- - Identify dependencies and relationships
16301
- - Document your findings clearly
16302
-
16303
- Use tools to search, read files, and analyze code structure.`,
16304
- allowedTools: ["read_file", "grep", "find_in_file", "glob", "codebase_map"]
16305
- },
16306
- coder: {
16307
- role: "coder",
16308
- systemPrompt: `You are a code generation agent. Your role is to:
16309
- - Write high-quality, production-ready code
16310
- - Follow best practices and coding standards
16311
- - Ensure code is syntactically valid
16312
- - Write clean, maintainable code
16313
-
16314
- Use tools to read existing code, write new files, and validate syntax.`,
16315
- allowedTools: ["read_file", "write_file", "edit_file", "bash_exec", "validateCode"]
16316
- },
16317
- tester: {
16318
- role: "tester",
16319
- systemPrompt: `You are a test generation agent. Your role is to:
16320
- - Write comprehensive test suites
16321
- - Achieve high code coverage
16322
- - Test edge cases and error conditions
16323
- - Ensure tests are reliable and maintainable
16324
-
16325
- Use tools to read code, write tests, and run them.`,
16326
- allowedTools: ["read_file", "write_file", "run_tests", "get_coverage", "run_test_file"]
16327
- },
16328
- reviewer: {
16329
- role: "reviewer",
16330
- systemPrompt: `You are a code review agent. Your role is to:
16331
- - Identify code quality issues
16332
- - Check for security vulnerabilities
16333
- - Ensure best practices are followed
16334
- - Provide actionable feedback
16335
-
16336
- Use tools to read and analyze code quality.`,
16337
- allowedTools: ["read_file", "calculate_quality", "analyze_complexity", "grep"]
16338
- },
16339
- optimizer: {
16340
- role: "optimizer",
16341
- systemPrompt: `You are a code optimization agent. Your role is to:
16342
- - Reduce code complexity
16343
- - Eliminate duplication
16344
- - Improve performance
16345
- - Refactor for maintainability
16346
-
16347
- Use tools to analyze and improve code.`,
16348
- allowedTools: ["read_file", "write_file", "edit_file", "analyze_complexity", "grep"]
16349
- },
16350
- planner: {
16351
- role: "planner",
16352
- systemPrompt: `You are a task planning agent. Your role is to:
16353
- - Break down complex tasks into subtasks
16354
- - Identify dependencies between tasks
16355
- - Estimate complexity and effort
16356
- - Create actionable plans
16357
-
16358
- Use tools to analyze requirements and explore the codebase.`,
16359
- allowedTools: ["read_file", "grep", "glob", "codebase_map"]
16323
+ function getAgentManager() {
16324
+ {
16325
+ return null;
16360
16326
  }
16361
- };
16327
+ }
16362
16328
 
16363
16329
  // src/tools/simple-agent.ts
16330
+ var AGENT_TYPES = [
16331
+ "explore",
16332
+ "plan",
16333
+ "test",
16334
+ "debug",
16335
+ "review",
16336
+ "architect",
16337
+ "security",
16338
+ "tdd",
16339
+ "refactor",
16340
+ "e2e",
16341
+ "docs",
16342
+ "database"
16343
+ ];
16344
+ var LEGACY_ROLE_MAP = {
16345
+ researcher: "explore",
16346
+ coder: "debug",
16347
+ // "debug" has write + bash + read — closest to general coding
16348
+ tester: "test",
16349
+ reviewer: "review",
16350
+ optimizer: "refactor",
16351
+ planner: "plan"
16352
+ };
16364
16353
  var SpawnSimpleAgentSchema = z.object({
16365
16354
  task: z.string().describe("Task description for the sub-agent"),
16366
16355
  context: z.string().optional().describe("Additional context or instructions for the agent"),
16367
- role: z.enum(["researcher", "coder", "tester", "reviewer", "optimizer", "planner"]).default("coder").describe("Agent role to use"),
16356
+ type: z.enum(AGENT_TYPES).optional().describe(
16357
+ "Specialized agent type. Use 'explore' for codebase search, 'plan' for design, 'test' for testing, 'review' for code review, 'architect' for system design, 'security' for security audit, 'tdd' for test-driven development, 'debug' for debugging, 'refactor' for code improvement, 'e2e' for integration tests, 'docs' for documentation, 'database' for DB operations."
16358
+ ),
16359
+ role: z.enum(["researcher", "coder", "tester", "reviewer", "optimizer", "planner"]).optional().describe("DEPRECATED: Use 'type' instead. Legacy role name, mapped to new agent types."),
16368
16360
  maxTurns: z.number().default(10).describe("Maximum tool-use turns for the agent")
16369
16361
  });
16362
+ function resolveAgentType(input) {
16363
+ if (input.type) return input.type;
16364
+ if (input.role && input.role in LEGACY_ROLE_MAP) return LEGACY_ROLE_MAP[input.role];
16365
+ return "explore";
16366
+ }
16370
16367
  var spawnSimpleAgentTool = defineTool({
16371
16368
  name: "spawnSimpleAgent",
16372
- description: `Spawn a sub-agent to handle a specific task with real LLM tool-use execution.
16373
-
16374
- Use this when you need to:
16375
- - Delegate a focused task to another agent
16376
- - Get a second opinion or alternative approach
16377
- - Handle multiple independent subtasks
16378
-
16379
- The sub-agent will work on the task autonomously using available tools.
16380
-
16381
- Example: "Write unit tests for the authentication module"`,
16369
+ description: `Spawn a specialized sub-agent to handle a specific task autonomously.
16370
+
16371
+ Available agent types:
16372
+ - explore: Search and understand codebases (read-only, fast)
16373
+ - plan: Design implementation approaches (read-only)
16374
+ - test: Write and run tests
16375
+ - debug: Analyze errors and fix issues
16376
+ - review: Review code for quality and best practices (read-only)
16377
+ - architect: Design system architecture (read-only)
16378
+ - security: Audit code for security vulnerabilities (read-only)
16379
+ - tdd: Test-driven development with RED-GREEN-REFACTOR
16380
+ - refactor: Improve code structure without changing behavior
16381
+ - e2e: End-to-end integration testing
16382
+ - docs: Generate and maintain documentation
16383
+ - database: Design schemas, migrations, and optimize queries
16384
+
16385
+ Each type has a filtered set of tools appropriate for its role.
16386
+ Use 'explore' for quick codebase searches, 'plan' for design before execution.`,
16382
16387
  category: "build",
16383
16388
  parameters: SpawnSimpleAgentSchema,
16384
16389
  async execute(input) {
16385
16390
  const typedInput = input;
16386
- {
16387
- const agentId2 = `agent-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
16391
+ const manager = getAgentManager();
16392
+ if (!manager) {
16393
+ const agentId = `agent-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
16388
16394
  return {
16389
16395
  stdout: JSON.stringify({
16390
- agentId: agentId2,
16396
+ agentId,
16391
16397
  status: "unavailable",
16392
16398
  task: typedInput.task,
16393
16399
  message: "Agent provider not initialized. Call setAgentProvider() during orchestrator startup.",
@@ -16398,6 +16404,31 @@ Example: "Write unit tests for the authentication module"`,
16398
16404
  duration: 0
16399
16405
  };
16400
16406
  }
16407
+ const agentType = resolveAgentType(typedInput);
16408
+ const taskDescription = typedInput.context ? `${typedInput.task}
16409
+
16410
+ Additional context: ${typedInput.context}` : typedInput.task;
16411
+ const startTime = Date.now();
16412
+ const result = await manager.spawn(agentType, taskDescription, {
16413
+ timeout: typedInput.maxTurns * 6e4
16414
+ // rough estimate: 1 min per turn
16415
+ });
16416
+ const duration = Date.now() - startTime;
16417
+ return {
16418
+ stdout: JSON.stringify({
16419
+ agentId: result.agent.id,
16420
+ agentType,
16421
+ status: result.success ? "completed" : "failed",
16422
+ task: typedInput.task,
16423
+ output: result.output,
16424
+ success: result.success,
16425
+ usage: result.usage,
16426
+ duration
16427
+ }),
16428
+ stderr: "",
16429
+ exitCode: result.success ? 0 : 1,
16430
+ duration
16431
+ };
16401
16432
  }
16402
16433
  });
16403
16434
  var checkAgentCapabilityTool = defineTool({
@@ -16409,17 +16440,23 @@ var checkAgentCapabilityTool = defineTool({
16409
16440
  const provider = getAgentProvider();
16410
16441
  const toolRegistry = getAgentToolRegistry();
16411
16442
  const isReady = provider !== null;
16443
+ const agentTypes = Object.entries(AGENT_DESCRIPTIONS).map(([type, description]) => ({
16444
+ type,
16445
+ name: AGENT_NAMES[type],
16446
+ description
16447
+ }));
16412
16448
  return {
16413
16449
  stdout: JSON.stringify({
16414
16450
  multiAgentSupported: true,
16415
16451
  providerConfigured: provider !== null,
16416
16452
  toolRegistryConfigured: toolRegistry !== null,
16417
16453
  ready: isReady,
16418
- availableRoles: Object.keys(AGENT_ROLES),
16454
+ availableTypes: agentTypes,
16419
16455
  features: {
16420
16456
  taskDelegation: "requires provider initialization",
16421
16457
  parallelSpawn: "requires provider initialization",
16422
- multiTurnToolUse: "requires provider initialization"
16458
+ multiTurnToolUse: "requires provider initialization",
16459
+ specializedAgents: "requires provider initialization"
16423
16460
  },
16424
16461
  status: "Provider not initialized. Call setAgentProvider() during startup."
16425
16462
  }),
@@ -17131,7 +17168,7 @@ Examples:
17131
17168
  }
17132
17169
  });
17133
17170
  var searchTools = [grepTool, findInFileTool];
17134
- var DEFAULT_TIMEOUT_MS2 = 3e4;
17171
+ var DEFAULT_TIMEOUT_MS3 = 3e4;
17135
17172
  var MAX_RESPONSE_SIZE = 5 * 1024 * 1024;
17136
17173
  var httpFetchTool = defineTool({
17137
17174
  name: "http_fetch",
@@ -17154,7 +17191,7 @@ Examples:
17154
17191
  }),
17155
17192
  async execute({ url, method, headers, body, timeout, maxSize }) {
17156
17193
  const startTime = performance.now();
17157
- const timeoutMs = timeout ?? DEFAULT_TIMEOUT_MS2;
17194
+ const timeoutMs = timeout ?? DEFAULT_TIMEOUT_MS3;
17158
17195
  const maxBytes = maxSize ?? MAX_RESPONSE_SIZE;
17159
17196
  try {
17160
17197
  const controller = new AbortController();
@@ -17272,7 +17309,7 @@ Examples:
17272
17309
  }
17273
17310
  });
17274
17311
  var httpTools = [httpFetchTool, httpJsonTool];
17275
- var DEFAULT_TIMEOUT_MS3 = 6e5;
17312
+ var DEFAULT_TIMEOUT_MS4 = 6e5;
17276
17313
  var MAX_OUTPUT_SIZE2 = 2 * 1024 * 1024;
17277
17314
  function getBuildHint(stderr, tool) {
17278
17315
  if (/MODULE_NOT_FOUND|Cannot find module/i.test(stderr))
@@ -17336,7 +17373,7 @@ Examples:
17336
17373
  async execute({ script, cwd, packageManager, args, env: env2, timeout }) {
17337
17374
  const projectDir = cwd ?? process.cwd();
17338
17375
  const startTime = performance.now();
17339
- const timeoutMs = timeout ?? DEFAULT_TIMEOUT_MS3;
17376
+ const timeoutMs = timeout ?? DEFAULT_TIMEOUT_MS4;
17340
17377
  const { CommandHeartbeat: CommandHeartbeat2 } = await Promise.resolve().then(() => (init_heartbeat(), heartbeat_exports));
17341
17378
  const heartbeat = new CommandHeartbeat2({
17342
17379
  onUpdate: (stats) => {
@@ -17432,7 +17469,7 @@ Examples:
17432
17469
  async execute({ cwd, packageManager, packages, dev, frozen, timeout }) {
17433
17470
  const projectDir = cwd ?? process.cwd();
17434
17471
  const startTime = performance.now();
17435
- const timeoutMs = timeout ?? DEFAULT_TIMEOUT_MS3;
17472
+ const timeoutMs = timeout ?? DEFAULT_TIMEOUT_MS4;
17436
17473
  const { CommandHeartbeat: CommandHeartbeat2 } = await Promise.resolve().then(() => (init_heartbeat(), heartbeat_exports));
17437
17474
  const heartbeat = new CommandHeartbeat2({
17438
17475
  onUpdate: (stats) => {
@@ -17556,7 +17593,7 @@ Examples:
17556
17593
  async execute({ target, cwd, args, env: env2, timeout }) {
17557
17594
  const projectDir = cwd ?? process.cwd();
17558
17595
  const startTime = performance.now();
17559
- const timeoutMs = timeout ?? DEFAULT_TIMEOUT_MS3;
17596
+ const timeoutMs = timeout ?? DEFAULT_TIMEOUT_MS4;
17560
17597
  const { CommandHeartbeat: CommandHeartbeat2 } = await Promise.resolve().then(() => (init_heartbeat(), heartbeat_exports));
17561
17598
  const heartbeat = new CommandHeartbeat2({
17562
17599
  onUpdate: (stats) => {
@@ -17659,7 +17696,7 @@ Examples:
17659
17696
  async execute({ cwd, project, noEmit, watch: watch2, args, timeout }) {
17660
17697
  const projectDir = cwd ?? process.cwd();
17661
17698
  const startTime = performance.now();
17662
- const timeoutMs = timeout ?? DEFAULT_TIMEOUT_MS3;
17699
+ const timeoutMs = timeout ?? DEFAULT_TIMEOUT_MS4;
17663
17700
  const { CommandHeartbeat: CommandHeartbeat2 } = await Promise.resolve().then(() => (init_heartbeat(), heartbeat_exports));
17664
17701
  const heartbeat = new CommandHeartbeat2({
17665
17702
  onUpdate: (stats) => {
@@ -18439,7 +18476,7 @@ Examples:
18439
18476
  }
18440
18477
  }
18441
18478
  });
18442
- var DEFAULT_TIMEOUT_MS4 = 3e4;
18479
+ var DEFAULT_TIMEOUT_MS5 = 3e4;
18443
18480
  var DEFAULT_MAX_LENGTH = 5e4;
18444
18481
  var MAX_DOWNLOAD_SIZE = 10 * 1024 * 1024;
18445
18482
  var BLOCKED_SCHEMES = ["file:", "ftp:", "data:", "javascript:"];
@@ -18670,12 +18707,12 @@ Examples:
18670
18707
  url: z.string().url().describe("URL to fetch"),
18671
18708
  extractContent: z.boolean().optional().default(true).describe("Extract and clean main content (true) or return raw (false)"),
18672
18709
  maxLength: z.number().min(1e3).max(2e5).optional().default(DEFAULT_MAX_LENGTH).describe("Maximum content length in characters"),
18673
- timeout: z.number().min(1e3).max(12e4).optional().default(DEFAULT_TIMEOUT_MS4).describe("Timeout in milliseconds")
18710
+ timeout: z.number().min(1e3).max(12e4).optional().default(DEFAULT_TIMEOUT_MS5).describe("Timeout in milliseconds")
18674
18711
  }),
18675
18712
  async execute({ url, extractContent, maxLength, timeout }) {
18676
18713
  const startTime = performance.now();
18677
18714
  const effectiveMaxLength = maxLength ?? DEFAULT_MAX_LENGTH;
18678
- const effectiveTimeout = timeout ?? DEFAULT_TIMEOUT_MS4;
18715
+ const effectiveTimeout = timeout ?? DEFAULT_TIMEOUT_MS5;
18679
18716
  validateUrl(url);
18680
18717
  const controller = new AbortController();
18681
18718
  const timeoutId = setTimeout(() => controller.abort(), effectiveTimeout);
@@ -18804,63 +18841,63 @@ var LANG_ALIASES = {
18804
18841
  };
18805
18842
  var TOKEN_COLORS = {
18806
18843
  // Keywords & control flow
18807
- keyword: (t) => chalk3.blue(t),
18808
- "keyword.control": (t) => chalk3.blue(t),
18844
+ keyword: (t) => chalk4.blue(t),
18845
+ "keyword.control": (t) => chalk4.blue(t),
18809
18846
  // Built-in types and literals
18810
- built_in: (t) => chalk3.cyan(t),
18811
- type: (t) => chalk3.cyan(t),
18812
- class: (t) => chalk3.cyan(t),
18813
- "title.class": (t) => chalk3.cyan(t),
18814
- "title.class.inherited": (t) => chalk3.cyan(t),
18847
+ built_in: (t) => chalk4.cyan(t),
18848
+ type: (t) => chalk4.cyan(t),
18849
+ class: (t) => chalk4.cyan(t),
18850
+ "title.class": (t) => chalk4.cyan(t),
18851
+ "title.class.inherited": (t) => chalk4.cyan(t),
18815
18852
  // Functions
18816
- "title.function": (t) => chalk3.green(t),
18817
- "title.function.invoke": (t) => chalk3.green(t),
18818
- title: (t) => chalk3.green(t),
18853
+ "title.function": (t) => chalk4.green(t),
18854
+ "title.function.invoke": (t) => chalk4.green(t),
18855
+ title: (t) => chalk4.green(t),
18819
18856
  // Strings
18820
- string: (t) => chalk3.yellow(t),
18821
- "template-tag": (t) => chalk3.yellow(t),
18822
- "template-variable": (t) => chalk3.green(t),
18857
+ string: (t) => chalk4.yellow(t),
18858
+ "template-tag": (t) => chalk4.yellow(t),
18859
+ "template-variable": (t) => chalk4.green(t),
18823
18860
  // Numbers
18824
- number: (t) => chalk3.magenta(t),
18861
+ number: (t) => chalk4.magenta(t),
18825
18862
  // Literals (true, false, null)
18826
- literal: (t) => chalk3.magenta(t),
18863
+ literal: (t) => chalk4.magenta(t),
18827
18864
  // Comments
18828
- comment: (t) => chalk3.dim(t),
18829
- doctag: (t) => chalk3.dim.bold(t),
18865
+ comment: (t) => chalk4.dim(t),
18866
+ doctag: (t) => chalk4.dim.bold(t),
18830
18867
  // Regular expressions
18831
- regexp: (t) => chalk3.red(t),
18868
+ regexp: (t) => chalk4.red(t),
18832
18869
  // Attributes & properties
18833
- attr: (t) => chalk3.cyan(t),
18834
- attribute: (t) => chalk3.cyan(t),
18835
- property: (t) => chalk3.white(t),
18870
+ attr: (t) => chalk4.cyan(t),
18871
+ attribute: (t) => chalk4.cyan(t),
18872
+ property: (t) => chalk4.white(t),
18836
18873
  // Operators & punctuation
18837
- operator: (t) => chalk3.dim.white(t),
18838
- punctuation: (t) => chalk3.dim.white(t),
18874
+ operator: (t) => chalk4.dim.white(t),
18875
+ punctuation: (t) => chalk4.dim.white(t),
18839
18876
  // Meta / preprocessor
18840
- meta: (t) => chalk3.dim(t),
18841
- "meta keyword": (t) => chalk3.blue(t),
18842
- "meta string": (t) => chalk3.yellow(t),
18877
+ meta: (t) => chalk4.dim(t),
18878
+ "meta keyword": (t) => chalk4.blue(t),
18879
+ "meta string": (t) => chalk4.yellow(t),
18843
18880
  // Variables & params
18844
- variable: (t) => chalk3.white(t),
18845
- "variable.language": (t) => chalk3.blue(t),
18846
- params: (t) => chalk3.white(t),
18881
+ variable: (t) => chalk4.white(t),
18882
+ "variable.language": (t) => chalk4.blue(t),
18883
+ params: (t) => chalk4.white(t),
18847
18884
  // Tags (HTML/XML)
18848
- tag: (t) => chalk3.blue(t),
18849
- name: (t) => chalk3.blue(t),
18885
+ tag: (t) => chalk4.blue(t),
18886
+ name: (t) => chalk4.blue(t),
18850
18887
  // Symbols & selectors (CSS, Ruby)
18851
- symbol: (t) => chalk3.magenta(t),
18852
- selector: (t) => chalk3.green(t),
18853
- "selector-tag": (t) => chalk3.blue(t),
18854
- "selector-class": (t) => chalk3.green(t),
18855
- "selector-id": (t) => chalk3.cyan(t),
18888
+ symbol: (t) => chalk4.magenta(t),
18889
+ selector: (t) => chalk4.green(t),
18890
+ "selector-tag": (t) => chalk4.blue(t),
18891
+ "selector-class": (t) => chalk4.green(t),
18892
+ "selector-id": (t) => chalk4.cyan(t),
18856
18893
  // Additions/deletions (diffs)
18857
- addition: (t) => chalk3.green(t),
18858
- deletion: (t) => chalk3.red(t),
18894
+ addition: (t) => chalk4.green(t),
18895
+ deletion: (t) => chalk4.red(t),
18859
18896
  // Section headers
18860
- section: (t) => chalk3.bold(t),
18897
+ section: (t) => chalk4.bold(t),
18861
18898
  // Emphasis
18862
- emphasis: (t) => chalk3.italic(t),
18863
- strong: (t) => chalk3.bold(t)
18899
+ emphasis: (t) => chalk4.italic(t),
18900
+ strong: (t) => chalk4.bold(t)
18864
18901
  };
18865
18902
  function hljsToChalk(html) {
18866
18903
  const safeSpans = [];
@@ -18915,6 +18952,10 @@ function highlightLine(line, lang) {
18915
18952
  }
18916
18953
 
18917
18954
  // src/cli/repl/output/diff-renderer.ts
18955
+ var bgDeleteLine = chalk4.bgRgb(80, 20, 20);
18956
+ var bgAddLine = chalk4.bgRgb(20, 60, 20);
18957
+ var bgDeleteWord = chalk4.bgRgb(160, 40, 40);
18958
+ var bgAddWord = chalk4.bgRgb(40, 120, 40);
18918
18959
  function parseDiff(raw) {
18919
18960
  const files = [];
18920
18961
  const lines = raw.split("\n");
@@ -19039,6 +19080,46 @@ function parseHunk(lines, start) {
19039
19080
  nextIndex: i
19040
19081
  };
19041
19082
  }
19083
+ function pairAdjacentLines(lines) {
19084
+ const pairs = [];
19085
+ let i = 0;
19086
+ while (i < lines.length) {
19087
+ const deleteStart = i;
19088
+ while (i < lines.length && lines[i].type === "delete") i++;
19089
+ const deleteEnd = i;
19090
+ const addStart = i;
19091
+ while (i < lines.length && lines[i].type === "add") i++;
19092
+ const addEnd = i;
19093
+ const deleteCount = deleteEnd - deleteStart;
19094
+ const addCount = addEnd - addStart;
19095
+ if (deleteCount > 0 && addCount > 0) {
19096
+ const pairCount = Math.min(deleteCount, addCount);
19097
+ for (let j = 0; j < pairCount; j++) {
19098
+ pairs.push({ deleteIdx: deleteStart + j, addIdx: addStart + j });
19099
+ }
19100
+ }
19101
+ if (i === deleteEnd && i === addEnd) {
19102
+ i++;
19103
+ }
19104
+ }
19105
+ return pairs;
19106
+ }
19107
+ function highlightWordChanges(deletedContent, addedContent) {
19108
+ const changes = diffWords(deletedContent, addedContent);
19109
+ let styledDelete = "";
19110
+ let styledAdd = "";
19111
+ for (const change of changes) {
19112
+ if (change.added) {
19113
+ styledAdd += bgAddWord(change.value);
19114
+ } else if (change.removed) {
19115
+ styledDelete += bgDeleteWord(change.value);
19116
+ } else {
19117
+ styledDelete += bgDeleteLine(change.value);
19118
+ styledAdd += bgAddLine(change.value);
19119
+ }
19120
+ }
19121
+ return { styledDelete, styledAdd };
19122
+ }
19042
19123
  var getTerminalWidth = () => process.stdout.columns || 80;
19043
19124
  function stripAnsi(str) {
19044
19125
  return str.replace(/\x1b\[[0-9;]*m/g, "");
@@ -19071,7 +19152,7 @@ function renderDiff(diff, options) {
19071
19152
  const maxWidth = options?.maxWidth ?? Math.min(getTerminalWidth() - 2, 120);
19072
19153
  const compact = options?.compact ?? false;
19073
19154
  if (diff.files.length === 0) {
19074
- console.log(chalk3.dim("\n No changes\n"));
19155
+ console.log(chalk4.dim("\n No changes\n"));
19075
19156
  return;
19076
19157
  }
19077
19158
  for (const file of diff.files) {
@@ -19080,9 +19161,9 @@ function renderDiff(diff, options) {
19080
19161
  const { stats } = diff;
19081
19162
  const parts = [];
19082
19163
  parts.push(`${stats.filesChanged} file${stats.filesChanged !== 1 ? "s" : ""}`);
19083
- if (stats.additions > 0) parts.push(chalk3.green(`+${stats.additions}`));
19084
- if (stats.deletions > 0) parts.push(chalk3.red(`-${stats.deletions}`));
19085
- console.log(chalk3.dim(`
19164
+ if (stats.additions > 0) parts.push(chalk4.green(`+${stats.additions}`));
19165
+ if (stats.deletions > 0) parts.push(chalk4.red(`-${stats.deletions}`));
19166
+ console.log(chalk4.dim(`
19086
19167
  ${parts.join(", ")}
19087
19168
  `));
19088
19169
  }
@@ -19095,49 +19176,81 @@ function renderFileBlock(file, opts) {
19095
19176
  const title = ` ${file.path} (${typeLabel}${statsLabel}) `;
19096
19177
  const topFill = Math.max(0, maxWidth - 2 - stripAnsi(title).length);
19097
19178
  console.log(
19098
- chalk3.magenta("\u256D\u2500\u2500") + chalk3.cyan.bold(title) + chalk3.magenta("\u2500".repeat(topFill) + "\u256E")
19179
+ chalk4.magenta("\u256D\u2500\u2500") + chalk4.cyan.bold(title) + chalk4.magenta("\u2500".repeat(topFill) + "\u256E")
19099
19180
  );
19100
19181
  for (let h = 0; h < file.hunks.length; h++) {
19101
19182
  const hunk = file.hunks[h];
19102
19183
  if (!compact || h > 0) {
19103
- const hunkLabel = hunk.heading ? ` ${chalk3.dim(hunk.heading)}` : "";
19184
+ const hunkLabel = hunk.heading ? ` ${chalk4.dim(hunk.heading)}` : "";
19104
19185
  console.log(
19105
- chalk3.magenta("\u2502") + " " + chalk3.cyan(
19186
+ chalk4.magenta("\u2502") + " " + chalk4.cyan(
19106
19187
  `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`
19107
19188
  ) + hunkLabel
19108
19189
  );
19109
19190
  }
19110
- for (const line of hunk.lines) {
19191
+ const pairs = pairAdjacentLines(hunk.lines);
19192
+ const pairedDeleteIndices = new Set(pairs.map((p5) => p5.deleteIdx));
19193
+ const pairedAddIndices = new Set(pairs.map((p5) => p5.addIdx));
19194
+ const pairByAdd = new Map(pairs.map((p5) => [p5.addIdx, p5.deleteIdx]));
19195
+ const wordHighlights = /* @__PURE__ */ new Map();
19196
+ for (const pair of pairs) {
19197
+ const delLine = hunk.lines[pair.deleteIdx];
19198
+ const addLine = hunk.lines[pair.addIdx];
19199
+ wordHighlights.set(pair.deleteIdx, highlightWordChanges(delLine.content, addLine.content));
19200
+ }
19201
+ for (let li = 0; li < hunk.lines.length; li++) {
19202
+ const line = hunk.lines[li];
19111
19203
  const lineNo = formatLineNo(line, showLineNumbers);
19112
19204
  const prefix = line.type === "add" ? "+" : line.type === "delete" ? "-" : " ";
19113
- let content = line.content;
19114
- if (line.type !== "delete" && lang) {
19115
- content = highlightLine(content, lang);
19116
- }
19117
- const lineStr = `${lineNo}${prefix} ${content}`;
19118
- const plainLen = stripAnsi(lineStr).length;
19119
- const pad = Math.max(0, contentWidth - plainLen);
19120
19205
  if (line.type === "add") {
19206
+ const isPaired = pairedAddIndices.has(li);
19207
+ let content;
19208
+ if (isPaired) {
19209
+ const delIdx = pairByAdd.get(li);
19210
+ content = wordHighlights.get(delIdx).styledAdd;
19211
+ } else {
19212
+ content = line.content;
19213
+ }
19214
+ const innerText = `${lineNo}${prefix} ${content}`;
19215
+ const plainLen = stripAnsi(innerText).length + 1;
19216
+ const pad = Math.max(0, contentWidth - plainLen);
19121
19217
  console.log(
19122
- chalk3.magenta("\u2502") + chalk3.green(` ${lineStr}`) + " ".repeat(pad) + " " + chalk3.magenta("\u2502")
19218
+ chalk4.magenta("\u2502") + bgAddLine(` ${innerText}` + " ".repeat(pad + 2)) + chalk4.magenta("\u2502")
19123
19219
  );
19124
19220
  } else if (line.type === "delete") {
19221
+ const isPaired = pairedDeleteIndices.has(li);
19222
+ let content;
19223
+ if (isPaired) {
19224
+ content = wordHighlights.get(li).styledDelete;
19225
+ } else {
19226
+ content = line.content;
19227
+ }
19228
+ const innerText = `${lineNo}${prefix} ${content}`;
19229
+ const plainLen = stripAnsi(innerText).length + 1;
19230
+ const pad = Math.max(0, contentWidth - plainLen);
19125
19231
  console.log(
19126
- chalk3.magenta("\u2502") + chalk3.red(` ${lineStr}`) + " ".repeat(pad) + " " + chalk3.magenta("\u2502")
19232
+ chalk4.magenta("\u2502") + bgDeleteLine(` ${innerText}` + " ".repeat(pad + 2)) + chalk4.magenta("\u2502")
19127
19233
  );
19128
19234
  } else {
19235
+ let content = line.content;
19236
+ if (lang) {
19237
+ content = highlightLine(content, lang);
19238
+ }
19239
+ const lineStr = `${lineNo}${prefix} ${content}`;
19240
+ const plainLen = stripAnsi(lineStr).length;
19241
+ const pad = Math.max(0, contentWidth - plainLen);
19129
19242
  console.log(
19130
- chalk3.magenta("\u2502") + chalk3.dim(` ${lineStr}`) + " ".repeat(pad) + " " + chalk3.magenta("\u2502")
19243
+ chalk4.magenta("\u2502") + chalk4.dim(` ${lineStr}`) + " ".repeat(pad) + " " + chalk4.magenta("\u2502")
19131
19244
  );
19132
19245
  }
19133
19246
  }
19134
19247
  }
19135
- console.log(chalk3.magenta("\u2570" + "\u2500".repeat(maxWidth - 2) + "\u256F"));
19248
+ console.log(chalk4.magenta("\u2570" + "\u2500".repeat(Math.max(0, maxWidth - 2)) + "\u256F"));
19136
19249
  }
19137
19250
  function formatLineNo(line, show) {
19138
19251
  if (!show) return "";
19139
19252
  const lineNo = line.type === "delete" ? line.oldLineNo : line.newLineNo;
19140
- return chalk3.dim(`${String(lineNo ?? "").padStart(5)} `);
19253
+ return chalk4.dim(`${String(lineNo ?? "").padStart(5)} `);
19141
19254
  }
19142
19255
  function getChangedLines(diff) {
19143
19256
  const result = /* @__PURE__ */ new Map();
@@ -22044,6 +22157,13 @@ var createAgentPlanTool = defineTool({
22044
22157
  };
22045
22158
  }
22046
22159
  });
22160
+ var LEGACY_ROLE_TO_TYPE = {
22161
+ researcher: "explore",
22162
+ coder: "debug",
22163
+ reviewer: "review",
22164
+ tester: "test",
22165
+ optimizer: "refactor"
22166
+ };
22047
22167
  var delegateTaskTool = defineTool({
22048
22168
  name: "delegateTask",
22049
22169
  description: "Delegate a task to a specialized sub-agent with real LLM tool-use execution.",
@@ -22051,22 +22171,57 @@ var delegateTaskTool = defineTool({
22051
22171
  parameters: z.object({
22052
22172
  taskId: z.string(),
22053
22173
  task: z.string().describe("Description of the task for the agent to execute"),
22054
- agentRole: z.enum(["researcher", "coder", "reviewer", "tester", "optimizer"]).default("coder"),
22174
+ agentType: z.enum([
22175
+ "explore",
22176
+ "plan",
22177
+ "test",
22178
+ "debug",
22179
+ "review",
22180
+ "architect",
22181
+ "security",
22182
+ "tdd",
22183
+ "refactor",
22184
+ "e2e",
22185
+ "docs",
22186
+ "database"
22187
+ ]).optional().describe("Specialized agent type to use"),
22188
+ agentRole: z.enum(["researcher", "coder", "reviewer", "tester", "optimizer"]).optional().describe("DEPRECATED: Use agentType instead"),
22055
22189
  context: z.string().optional(),
22056
22190
  maxTurns: z.number().default(10)
22057
22191
  }),
22058
22192
  async execute(input) {
22059
22193
  const typedInput = input;
22060
- {
22194
+ const manager = getAgentManager();
22195
+ if (!manager) {
22196
+ const resolvedType = typedInput.agentType ?? "explore";
22061
22197
  return {
22062
- agentId: `agent-${Date.now()}-${typedInput.agentRole}`,
22198
+ agentId: `agent-${Date.now()}-${resolvedType}`,
22063
22199
  taskId: typedInput.taskId,
22064
- role: typedInput.agentRole,
22200
+ agentType: resolvedType,
22065
22201
  status: "unavailable",
22066
22202
  message: "Agent provider not initialized. Call setAgentProvider() during orchestrator startup.",
22067
22203
  success: false
22068
22204
  };
22069
22205
  }
22206
+ const agentType = typedInput.agentType ?? (typedInput.agentRole ? LEGACY_ROLE_TO_TYPE[typedInput.agentRole] ?? "explore" : "explore");
22207
+ const taskDescription = typedInput.context ? `${typedInput.task}
22208
+
22209
+ Additional context: ${typedInput.context}` : typedInput.task;
22210
+ const startTime = Date.now();
22211
+ const result = await manager.spawn(agentType, taskDescription, {
22212
+ timeout: typedInput.maxTurns * 6e4
22213
+ });
22214
+ const duration = Date.now() - startTime;
22215
+ return {
22216
+ agentId: result.agent.id,
22217
+ taskId: typedInput.taskId,
22218
+ agentType,
22219
+ status: result.success ? "completed" : "failed",
22220
+ output: result.output,
22221
+ success: result.success,
22222
+ usage: result.usage,
22223
+ duration
22224
+ };
22070
22225
  }
22071
22226
  });
22072
22227
  var aggregateResultsTool = defineTool({
@@ -22498,11 +22653,11 @@ var getLearnedPatternsTool = defineTool({
22498
22653
  const patterns = store.getFrequentPatterns(typedInput.limit);
22499
22654
  return {
22500
22655
  totalPatterns: patterns.length,
22501
- patterns: patterns.map((p4) => ({
22502
- pattern: p4.pattern,
22503
- preference: p4.userPreference,
22504
- frequency: p4.frequency,
22505
- lastUsed: new Date(p4.lastUsed).toISOString()
22656
+ patterns: patterns.map((p5) => ({
22657
+ pattern: p5.pattern,
22658
+ preference: p5.userPreference,
22659
+ frequency: p5.frequency,
22660
+ lastUsed: new Date(p5.lastUsed).toISOString()
22506
22661
  }))
22507
22662
  };
22508
22663
  }
@@ -23083,11 +23238,11 @@ function isBlockedPath(absolute) {
23083
23238
  return void 0;
23084
23239
  }
23085
23240
  function isBlockedExecFile(filePath) {
23086
- return BLOCKED_EXEC_PATTERNS.some((p4) => p4.test(filePath));
23241
+ return BLOCKED_EXEC_PATTERNS.some((p5) => p5.test(filePath));
23087
23242
  }
23088
23243
  function hasDangerousArgs(args) {
23089
23244
  const joined = args.join(" ");
23090
- return DANGEROUS_ARG_PATTERNS.some((p4) => p4.test(joined));
23245
+ return DANGEROUS_ARG_PATTERNS.some((p5) => p5.test(joined));
23091
23246
  }
23092
23247
  function getInterpreter(ext) {
23093
23248
  return INTERPRETER_MAP[ext.toLowerCase()];