wave-agent-sdk 0.11.5 → 0.11.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/builtin/skills/init/SKILL.md +2 -0
  2. package/builtin/skills/settings/SKILLS.md +3 -2
  3. package/builtin/skills/settings/SUBAGENTS.md +1 -3
  4. package/dist/agent.d.ts +6 -0
  5. package/dist/agent.d.ts.map +1 -1
  6. package/dist/agent.js +18 -1
  7. package/dist/constants/tools.d.ts +1 -1
  8. package/dist/constants/tools.d.ts.map +1 -1
  9. package/dist/constants/tools.js +1 -1
  10. package/dist/managers/MemoryRuleManager.d.ts.map +1 -1
  11. package/dist/managers/MemoryRuleManager.js +1 -9
  12. package/dist/managers/aiManager.d.ts.map +1 -1
  13. package/dist/managers/aiManager.js +22 -3
  14. package/dist/managers/mcpManager.d.ts.map +1 -1
  15. package/dist/managers/mcpManager.js +32 -13
  16. package/dist/managers/messageManager.d.ts +13 -5
  17. package/dist/managers/messageManager.d.ts.map +1 -1
  18. package/dist/managers/messageManager.js +62 -34
  19. package/dist/managers/permissionManager.js +4 -4
  20. package/dist/managers/pluginManager.d.ts.map +1 -1
  21. package/dist/managers/pluginManager.js +4 -2
  22. package/dist/managers/slashCommandManager.d.ts +2 -0
  23. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  24. package/dist/managers/slashCommandManager.js +98 -4
  25. package/dist/managers/toolManager.d.ts.map +1 -1
  26. package/dist/managers/toolManager.js +8 -2
  27. package/dist/prompts/index.d.ts +2 -0
  28. package/dist/prompts/index.d.ts.map +1 -1
  29. package/dist/prompts/index.js +5 -0
  30. package/dist/services/GitService.d.ts +1 -0
  31. package/dist/services/GitService.d.ts.map +1 -1
  32. package/dist/services/GitService.js +16 -0
  33. package/dist/services/MarketplaceService.d.ts +7 -0
  34. package/dist/services/MarketplaceService.d.ts.map +1 -1
  35. package/dist/services/MarketplaceService.js +321 -252
  36. package/dist/services/aiService.d.ts +34 -0
  37. package/dist/services/aiService.d.ts.map +1 -1
  38. package/dist/services/aiService.js +124 -1
  39. package/dist/services/initializationService.d.ts.map +1 -1
  40. package/dist/services/initializationService.js +18 -0
  41. package/dist/tools/agentTool.js +3 -3
  42. package/dist/tools/bashTool.d.ts.map +1 -1
  43. package/dist/tools/bashTool.js +4 -4
  44. package/dist/tools/editTool.d.ts.map +1 -1
  45. package/dist/tools/editTool.js +2 -0
  46. package/dist/tools/globTool.d.ts.map +1 -1
  47. package/dist/tools/globTool.js +15 -3
  48. package/dist/tools/grepTool.d.ts.map +1 -1
  49. package/dist/tools/grepTool.js +38 -12
  50. package/dist/tools/readTool.d.ts.map +1 -1
  51. package/dist/tools/readTool.js +61 -0
  52. package/dist/tools/skillTool.js +2 -2
  53. package/dist/tools/types.d.ts +16 -0
  54. package/dist/tools/types.d.ts.map +1 -1
  55. package/dist/tools/webFetchTool.d.ts +3 -0
  56. package/dist/tools/webFetchTool.d.ts.map +1 -0
  57. package/dist/tools/webFetchTool.js +171 -0
  58. package/dist/tools/writeTool.d.ts.map +1 -1
  59. package/dist/tools/writeTool.js +2 -0
  60. package/dist/types/commands.d.ts +1 -1
  61. package/dist/types/commands.d.ts.map +1 -1
  62. package/dist/types/messaging.d.ts +1 -0
  63. package/dist/types/messaging.d.ts.map +1 -1
  64. package/dist/utils/bashParser.d.ts +20 -2
  65. package/dist/utils/bashParser.d.ts.map +1 -1
  66. package/dist/utils/bashParser.js +281 -146
  67. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  68. package/dist/utils/convertMessagesForAPI.js +7 -0
  69. package/dist/utils/fileUtils.d.ts +8 -0
  70. package/dist/utils/fileUtils.d.ts.map +1 -1
  71. package/dist/utils/fileUtils.js +52 -0
  72. package/dist/utils/messageOperations.d.ts +12 -3
  73. package/dist/utils/messageOperations.d.ts.map +1 -1
  74. package/dist/utils/messageOperations.js +77 -9
  75. package/package.json +4 -2
  76. package/src/agent.ts +19 -1
  77. package/src/constants/tools.ts +1 -1
  78. package/src/managers/MemoryRuleManager.ts +1 -10
  79. package/src/managers/aiManager.ts +23 -3
  80. package/src/managers/mcpManager.ts +37 -16
  81. package/src/managers/messageManager.ts +76 -38
  82. package/src/managers/permissionManager.ts +4 -4
  83. package/src/managers/pluginManager.ts +4 -2
  84. package/src/managers/slashCommandManager.ts +130 -4
  85. package/src/managers/toolManager.ts +11 -2
  86. package/src/prompts/index.ts +6 -0
  87. package/src/services/GitService.ts +20 -0
  88. package/src/services/MarketplaceService.ts +397 -324
  89. package/src/services/aiService.ts +197 -1
  90. package/src/services/initializationService.ts +38 -0
  91. package/src/tools/agentTool.ts +3 -3
  92. package/src/tools/bashTool.ts +3 -4
  93. package/src/tools/editTool.ts +3 -0
  94. package/src/tools/globTool.ts +16 -3
  95. package/src/tools/grepTool.ts +41 -13
  96. package/src/tools/readTool.ts +69 -0
  97. package/src/tools/skillTool.ts +2 -2
  98. package/src/tools/types.ts +13 -0
  99. package/src/tools/webFetchTool.ts +194 -0
  100. package/src/tools/writeTool.ts +3 -0
  101. package/src/types/commands.ts +1 -1
  102. package/src/types/messaging.ts +1 -0
  103. package/src/utils/bashParser.ts +316 -161
  104. package/src/utils/convertMessagesForAPI.ts +8 -0
  105. package/src/utils/fileUtils.ts +69 -0
  106. package/src/utils/messageOperations.ts +84 -9
  107. package/dist/tools/taskOutputTool.d.ts +0 -3
  108. package/dist/tools/taskOutputTool.d.ts.map +0 -1
  109. package/dist/tools/taskOutputTool.js +0 -198
  110. package/src/tools/taskOutputTool.ts +0 -222
@@ -53,7 +53,7 @@ export function splitBashCommand(command) {
53
53
  opLen = 1;
54
54
  else if (char === "|")
55
55
  opLen = 1;
56
- else if (char === "&" && nextChar !== ">")
56
+ else if (char === "&" && nextChar !== ">" && command[i - 1] !== ">")
57
57
  opLen = 1;
58
58
  if (opLen > 0) {
59
59
  // Check if preceded by an odd number of backslashes
@@ -361,10 +361,44 @@ export function hasWriteRedirections(command) {
361
361
  return false;
362
362
  }
363
363
  /**
364
- * Alias for hasWriteRedirections, used for semantic clarity in permission checks.
364
+ * Checks if a bash command contains any heredocs (<<, <<-).
365
365
  */
366
- export function isBashWriteRedirect(command) {
367
- return hasWriteRedirections(command);
366
+ export function hasHeredoc(command) {
367
+ let inSingleQuote = false;
368
+ let inDoubleQuote = false;
369
+ let escaped = false;
370
+ for (let i = 0; i < command.length; i++) {
371
+ const char = command[i];
372
+ if (escaped) {
373
+ escaped = false;
374
+ continue;
375
+ }
376
+ if (char === "\\") {
377
+ escaped = true;
378
+ continue;
379
+ }
380
+ if (char === "'" && !inDoubleQuote) {
381
+ inSingleQuote = !inSingleQuote;
382
+ continue;
383
+ }
384
+ if (char === '"' && !inSingleQuote) {
385
+ inDoubleQuote = !inDoubleQuote;
386
+ continue;
387
+ }
388
+ if (inSingleQuote || inDoubleQuote) {
389
+ continue;
390
+ }
391
+ if (char === "<" && command[i + 1] === "<") {
392
+ return true;
393
+ }
394
+ }
395
+ return false;
396
+ }
397
+ /**
398
+ * Checks if a bash command is a heredoc write operation (e.g., cat <<EOF > file).
399
+ */
400
+ export function isBashHeredocWrite(command) {
401
+ return hasHeredoc(command) && hasWriteRedirections(command);
368
402
  }
369
403
  /**
370
404
  * Blacklist of dangerous commands that should not be safely prefix-matched
@@ -377,13 +411,139 @@ export const DANGEROUS_COMMANDS = [
377
411
  "chown",
378
412
  "sh",
379
413
  "bash",
414
+ "zsh",
415
+ "fish",
416
+ "pwsh",
417
+ "cmd.exe",
418
+ "powershell.exe",
380
419
  "sudo",
381
420
  "dd",
382
421
  "apt",
383
422
  "apt-get",
384
423
  "yum",
385
424
  "dnf",
425
+ "ssh",
426
+ "scp",
427
+ "sftp",
428
+ "ftp",
429
+ "telnet",
430
+ "nc",
431
+ "netcat",
386
432
  ];
433
+ export const TOOL_RULES = {
434
+ // Node/JS
435
+ npm: { depth: 2, scopeFlags: ["--prefix", "-C", "--registry"] },
436
+ "npm run": { depth: 3, scopeFlags: ["--prefix", "-C", "--registry"] },
437
+ pnpm: { depth: 2, scopeFlags: ["-C", "--dir", "-F", "--filter"] },
438
+ "pnpm run": { depth: 3, scopeFlags: ["-C", "--dir", "-F", "--filter"] },
439
+ yarn: { depth: 2, scopeFlags: ["workspace", "--cwd"] },
440
+ "yarn run": { depth: 3, scopeFlags: ["workspace", "--cwd"] },
441
+ "yarn workspace": { depth: 4, scopeFlags: ["--cwd"] },
442
+ bun: { depth: 2 },
443
+ "bun run": { depth: 3 },
444
+ deno: { depth: 2 },
445
+ "deno run": { depth: 3 },
446
+ "deno task": { depth: 3 },
447
+ // Git
448
+ git: {
449
+ depth: 2,
450
+ scopeFlags: ["-C", "-c", "--directory", "--work-tree", "--git-dir"],
451
+ },
452
+ // Python
453
+ python: { depth: 2 },
454
+ python3: { depth: 2 },
455
+ "python -m": { depth: 2 },
456
+ "python3 -m": { depth: 2 },
457
+ "python -m pip install": { depth: 3 },
458
+ "python3 -m pip install": { depth: 3 },
459
+ pip: { depth: 2 },
460
+ pip3: { depth: 2 },
461
+ poetry: { depth: 2 },
462
+ conda: { depth: 2 },
463
+ // Java
464
+ mvn: { depth: 2 },
465
+ gradle: { depth: 2 },
466
+ java: { depth: 1 },
467
+ "java -jar": { depth: 1 },
468
+ // Rust & Go
469
+ cargo: { depth: 2 },
470
+ go: { depth: 2 },
471
+ // Containers & Infrastructure
472
+ docker: { depth: 2 },
473
+ "docker-compose": { depth: 2 },
474
+ kubectl: { depth: 2 },
475
+ terraform: { depth: 2 },
476
+ gcloud: { depth: 2 },
477
+ "gcloud compute": { depth: 4 },
478
+ "gcloud container": { depth: 4 },
479
+ aws: { depth: 2 },
480
+ };
481
+ /**
482
+ * Registry of dangerous subcommands for specific tools.
483
+ */
484
+ export const DANGEROUS_SUBCOMMANDS = {
485
+ docker: ["rm", "rmi", "system", "volume", "network", "image", "container"],
486
+ git: ["reset", "clean"],
487
+ npm: ["uninstall", "un", "remove", "rm"],
488
+ pnpm: ["uninstall", "un", "remove", "rm"],
489
+ yarn: ["remove"],
490
+ deno: ["uninstall"],
491
+ bun: ["remove", "rm"],
492
+ };
493
+ /**
494
+ * Heuristic to determine if a flag takes an argument.
495
+ * If nextArg doesn't start with '-' and isn't a known subcommand, assume it's a flag value.
496
+ */
497
+ function flagTakesArg(flag, nextArg) {
498
+ if (!nextArg)
499
+ return false;
500
+ if (nextArg.startsWith("-"))
501
+ return false;
502
+ // If it's a common subcommand, it's probably not a flag argument
503
+ const commonSubcommands = [
504
+ "install",
505
+ "add",
506
+ "remove",
507
+ "run",
508
+ "test",
509
+ "build",
510
+ "status",
511
+ "diff",
512
+ "commit",
513
+ "push",
514
+ "pull",
515
+ "checkout",
516
+ "log",
517
+ "fetch",
518
+ "merge",
519
+ "rebase",
520
+ ];
521
+ if (commonSubcommands.includes(nextArg))
522
+ return false;
523
+ return true;
524
+ }
525
+ /**
526
+ * Detects if an argument is a file path or URL.
527
+ */
528
+ function shouldStopAtArg(arg) {
529
+ if (!arg)
530
+ return false;
531
+ // URLs
532
+ if (/^(https?|ftp|ssh|git):\/\//.test(arg))
533
+ return true;
534
+ // File paths (starts with /, ./, ../, or ~/)
535
+ if (arg.startsWith("/") ||
536
+ arg.startsWith("./") ||
537
+ arg.startsWith("../") ||
538
+ arg.startsWith("~/"))
539
+ return true;
540
+ // Common file extensions (but not scoped packages or common subcommands)
541
+ if (/\.(ts|js|py|sh|md|txt|json|yml|yaml|html|css|go|rs|java|cpp|c|h|php|rb|pl|sql)$/.test(arg) &&
542
+ !arg.includes("@") &&
543
+ !arg.includes("/"))
544
+ return true;
545
+ return false;
546
+ }
387
547
  /**
388
548
  * Extracts a "smart prefix" from a bash command based on common developer tools.
389
549
  * Returns null if the command is blacklisted or cannot be safely prefix-matched.
@@ -395,167 +555,142 @@ export function getSmartPrefix(command) {
395
555
  // For now, we only support prefix matching for single commands or the first command in a chain
396
556
  // to keep it simple and safe.
397
557
  const firstCommand = parts[0];
398
- let stripped = stripRedirections(stripEnvVars(firstCommand));
399
- // Handle sudo
400
- if (stripped.startsWith("sudo ")) {
401
- stripped = stripped.substring(5).trim();
402
- }
558
+ // Safety check: don't allow heredoc writes
559
+ if (isBashHeredocWrite(firstCommand))
560
+ return null;
561
+ const stripped = stripRedirections(stripEnvVars(firstCommand));
403
562
  const tokens = stripped.split(/\s+/);
404
563
  if (tokens.length === 0)
405
564
  return null;
406
- const exe = tokens[0];
407
- const sub = tokens[1];
565
+ const prefixParts = [];
566
+ let i = 0;
567
+ // Handle prefix tools like sudo
568
+ const prefixTools = ["sudo", "time", "stdbuf", "timeout"];
569
+ while (i < tokens.length && prefixTools.includes(tokens[i])) {
570
+ prefixParts.push(tokens[i]);
571
+ i++;
572
+ }
573
+ if (i >= tokens.length)
574
+ return null;
575
+ const exe = tokens[i];
408
576
  // Blacklist - Hard blacklist for dangerous commands
409
577
  if (DANGEROUS_COMMANDS.includes(exe))
410
578
  return null;
411
- // Node/JS
412
- if (["npm", "pnpm", "yarn", "deno", "bun"].includes(exe)) {
413
- let currentIdx = 1;
414
- const prefixParts = [exe];
415
- // Handle workspace/filter flags
416
- if (exe === "pnpm") {
417
- while ((tokens[currentIdx] === "-F" || tokens[currentIdx] === "--filter") &&
418
- tokens[currentIdx + 1]) {
419
- prefixParts.push(tokens[currentIdx], tokens[currentIdx + 1]);
420
- currentIdx += 2;
579
+ // Find the longest matching rule in TOOL_RULES
580
+ let bestRuleKey = "";
581
+ let rule;
582
+ for (const [key, r] of Object.entries(TOOL_RULES)) {
583
+ const keyTokens = key.split(/\s+/);
584
+ let match = true;
585
+ for (let j = 0; j < keyTokens.length; j++) {
586
+ if (tokens[i + j] !== keyTokens[j]) {
587
+ match = false;
588
+ break;
421
589
  }
422
590
  }
423
- else if (exe === "npm" &&
424
- (tokens[currentIdx] === "--prefix" || tokens[currentIdx] === "-C") &&
425
- tokens[currentIdx + 1]) {
426
- prefixParts.push(tokens[currentIdx], tokens[currentIdx + 1]);
427
- currentIdx += 2;
428
- }
429
- else if (exe === "yarn" &&
430
- tokens[currentIdx] === "workspace" &&
431
- tokens[currentIdx + 1]) {
432
- prefixParts.push(tokens[currentIdx], tokens[currentIdx + 1]);
433
- currentIdx += 2;
434
- }
435
- const subCommand = tokens[currentIdx];
436
- const safeSubcommands = [
437
- "install",
438
- "i",
439
- "add",
440
- "remove",
441
- "rm",
442
- "uninstall",
443
- "un",
444
- "test",
445
- "t",
446
- "build",
447
- "start",
448
- "dev",
449
- ];
450
- if (safeSubcommands.includes(subCommand)) {
451
- prefixParts.push(subCommand);
452
- return prefixParts.join(" ");
453
- }
454
- if ((subCommand === "run" || (exe === "deno" && subCommand === "task")) &&
455
- tokens[currentIdx + 1]) {
456
- prefixParts.push(subCommand, tokens[currentIdx + 1]);
457
- return prefixParts.join(" ");
591
+ if (match && key.length > bestRuleKey.length) {
592
+ bestRuleKey = key;
593
+ rule = r;
458
594
  }
459
- return null;
460
595
  }
461
- // Git
462
- if (exe === "git") {
463
- let currentIdx = 1;
464
- const prefixParts = [exe];
465
- // Handle -C <path>
466
- if (tokens[currentIdx] === "-C" && tokens[currentIdx + 1]) {
467
- prefixParts.push(tokens[currentIdx], tokens[currentIdx + 1]);
468
- currentIdx += 2;
469
- }
470
- const subCommand = tokens[currentIdx];
471
- const safeGitSubcommands = [
472
- "commit",
473
- "push",
474
- "pull",
475
- "checkout",
476
- "add",
477
- "status",
478
- "diff",
479
- "branch",
480
- "merge",
481
- "rebase",
482
- "log",
483
- "fetch",
484
- "remote",
485
- "stash",
486
- ];
487
- if (safeGitSubcommands.includes(subCommand)) {
488
- if (subCommand === "branch") {
489
- // Check for destructive flags
490
- const destructiveFlags = ["-d", "-D", "--delete"];
491
- if (tokens.some((t) => destructiveFlags.includes(t))) {
492
- return null;
493
- }
494
- }
495
- prefixParts.push(subCommand);
496
- return prefixParts.join(" ");
497
- }
596
+ // If no rule found, we don't suggest a prefix
597
+ if (!rule)
498
598
  return null;
499
- }
500
- // Python
501
- if (["python", "python3", "pip", "pip3", "poetry", "conda"].includes(exe)) {
502
- if (exe === "python" || exe === "python3") {
503
- if (tokens[1] === "-m" && tokens[2]) {
504
- if (tokens[2] === "pip" && tokens[3] === "install") {
505
- return `${exe} -m pip install`;
506
- }
507
- return `${exe} -m ${tokens[2]}`;
508
- }
509
- return null;
510
- }
511
- if (["install", "add", "remove", "test", "run"].includes(sub)) {
512
- return `${exe} ${sub}`;
599
+ const depth = rule.depth;
600
+ const scopeFlags = rule.scopeFlags || [];
601
+ let currentDepth = 0;
602
+ // Safety check: only allow safe subcommands for git
603
+ const safeGitSubcommands = [
604
+ "commit",
605
+ "push",
606
+ "pull",
607
+ "checkout",
608
+ "add",
609
+ "status",
610
+ "diff",
611
+ "branch",
612
+ "merge",
613
+ "rebase",
614
+ "log",
615
+ "fetch",
616
+ "remote",
617
+ "stash",
618
+ ];
619
+ const destructiveGitFlags = [
620
+ "-d",
621
+ "-D",
622
+ "--delete",
623
+ "--hard",
624
+ "--force",
625
+ "-f",
626
+ ];
627
+ // Global safety check: scan ALL tokens for dangerous flags/subcommands
628
+ for (let j = i; j < tokens.length; j++) {
629
+ const token = tokens[j];
630
+ if (token.startsWith("-")) {
631
+ if (exe === "git" && destructiveGitFlags.includes(token))
632
+ return null;
513
633
  }
514
- return null;
515
- }
516
- // Java
517
- if (["mvn", "gradle"].includes(exe)) {
518
- if (sub && !sub.startsWith("-")) {
519
- return `${exe} ${sub}`;
634
+ else {
635
+ if (DANGEROUS_SUBCOMMANDS[exe]?.includes(token))
636
+ return null;
520
637
  }
521
- return null;
522
- }
523
- if (exe === "java") {
524
- if (sub === "-jar")
525
- return "java -jar";
526
- return "java";
527
638
  }
528
- // Rust & Go
529
- if (exe === "cargo") {
530
- if (["build", "test", "run", "add", "check"].includes(sub)) {
531
- return `${exe} ${sub}`;
639
+ // Include all tokens from the best matching rule
640
+ const ruleTokens = bestRuleKey.split(/\s+/);
641
+ for (let j = 0; j < ruleTokens.length; j++) {
642
+ const token = tokens[i];
643
+ if (!token)
644
+ break;
645
+ if (token.startsWith("-")) {
646
+ if (exe === "git" && destructiveGitFlags.includes(token))
647
+ return null;
532
648
  }
533
- return null;
534
- }
535
- if (exe === "go") {
536
- if (["build", "test", "run", "get", "mod"].includes(sub)) {
537
- return `${exe} ${sub}`;
649
+ else {
650
+ if (DANGEROUS_SUBCOMMANDS[exe]?.includes(token))
651
+ return null;
652
+ if (exe === "git" &&
653
+ currentDepth > 0 &&
654
+ !safeGitSubcommands.includes(token)) {
655
+ return null;
656
+ }
657
+ currentDepth++;
538
658
  }
539
- return null;
659
+ prefixParts.push(token);
660
+ i++;
540
661
  }
541
- // Containers & Infrastructure
542
- if (exe === "docker" || exe === "docker-compose") {
543
- if (["run", "build", "ps", "exec", "up", "down"].includes(sub)) {
544
- return `${exe} ${sub}`;
662
+ // Continue until we reach the required depth
663
+ while (i < tokens.length && currentDepth < depth) {
664
+ const token = tokens[i];
665
+ if (token.startsWith("-")) {
666
+ // Safety checks for flags
667
+ if (exe === "git" && destructiveGitFlags.includes(token))
668
+ return null;
669
+ prefixParts.push(token);
670
+ if (scopeFlags.includes(token) || flagTakesArg(token, tokens[i + 1])) {
671
+ if (i + 1 < tokens.length) {
672
+ prefixParts.push(tokens[++i]);
673
+ }
674
+ }
545
675
  }
546
- return null;
547
- }
548
- if (exe === "kubectl") {
549
- if (["get", "describe", "apply", "logs"].includes(sub)) {
550
- return `${exe} ${sub}`;
676
+ else {
677
+ // Safety checks for subcommands
678
+ if (DANGEROUS_SUBCOMMANDS[exe]?.includes(token))
679
+ return null;
680
+ if (exe === "git" &&
681
+ currentDepth > 0 &&
682
+ !safeGitSubcommands.includes(token)) {
683
+ return null;
684
+ }
685
+ // Stop at data/paths
686
+ if (shouldStopAtArg(token) && currentDepth > 0)
687
+ break;
688
+ prefixParts.push(token);
689
+ currentDepth++;
551
690
  }
552
- return null;
691
+ i++;
553
692
  }
554
- if (exe === "terraform") {
555
- if (["plan", "apply", "destroy", "init"].includes(sub)) {
556
- return `${exe} ${sub}`;
557
- }
693
+ if (currentDepth < depth)
558
694
  return null;
559
- }
560
- return null;
695
+ return prefixParts.join(" ");
561
696
  }
@@ -1 +1 @@
1
- {"version":3,"file":"convertMessagesForAPI.d.ts","sourceRoot":"","sources":["../../src/utils/convertMessagesForAPI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAIjD,OAAO,EAEL,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AA0B7B;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,OAAO,EAAE,GAClB,0BAA0B,EAAE,CAsN9B"}
1
+ {"version":3,"file":"convertMessagesForAPI.d.ts","sourceRoot":"","sources":["../../src/utils/convertMessagesForAPI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAIjD,OAAO,EAEL,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AA0B7B;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,OAAO,EAAE,GAClB,0BAA0B,EAAE,CA8N9B"}
@@ -182,6 +182,13 @@ export function convertMessagesForAPI(messages) {
182
182
  });
183
183
  });
184
184
  }
185
+ // If there is a tool block in user message, add its result
186
+ if (block.type === "tool" && block.stage === "end" && block.result) {
187
+ contentParts.push({
188
+ type: "text",
189
+ text: `<local-command-stdout>\n${stripAnsiColors(block.result)}\n</local-command-stdout>`,
190
+ });
191
+ }
185
192
  });
186
193
  // Only add user message if there is meaningful content
187
194
  if (contentParts.length > 0) {
@@ -24,4 +24,12 @@ export declare function getLastLine(filePath: string, minLength?: number): Promi
24
24
  * @param {string} pattern - The pattern to add to global git ignore.
25
25
  */
26
26
  export declare function ensureGlobalGitIgnore(pattern: string): Promise<void>;
27
+ /**
28
+ * Suggests similar paths if a file is not found.
29
+ */
30
+ export declare function suggestPathUnderCwd(targetPath: string, workdir: string): Promise<string[]>;
31
+ /**
32
+ * Uses fuzzy matching to find the intended file.
33
+ */
34
+ export declare function findSimilarFile(targetPath: string, workdir: string): Promise<string | null>;
27
35
  //# sourceMappingURL=fileUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fileUtils.d.ts","sourceRoot":"","sources":["../../src/utils/fileUtils.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBrE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,SAAS,SAAI,GACZ,OAAO,CAAC,MAAM,CAAC,CA8DjB;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC1E"}
1
+ {"version":3,"file":"fileUtils.d.ts","sourceRoot":"","sources":["../../src/utils/fileUtils.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBrE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,SAAS,SAAI,GACZ,OAAO,CAAC,MAAM,CAAC,CA8DjB;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC1E;AA2BD;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,EAAE,CAAC,CAwBnB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGxB"}
@@ -3,6 +3,7 @@ import { createReadStream } from "node:fs";
3
3
  import path from "node:path";
4
4
  import { execSync } from "node:child_process";
5
5
  import { homedir } from "node:os";
6
+ import { glob } from "glob";
6
7
  /**
7
8
  * Reads the first line of a file efficiently using Node.js readline.
8
9
  *
@@ -143,3 +144,54 @@ export async function ensureGlobalGitIgnore(pattern) {
143
144
  // Ignore errors
144
145
  }
145
146
  }
147
+ /**
148
+ * Simple Levenshtein distance implementation
149
+ */
150
+ function levenshtein(a, b) {
151
+ const matrix = Array.from({ length: a.length + 1 }, () => Array.from({ length: b.length + 1 }, () => 0));
152
+ for (let i = 0; i <= a.length; i++)
153
+ matrix[i][0] = i;
154
+ for (let j = 0; j <= b.length; j++)
155
+ matrix[0][j] = j;
156
+ for (let i = 1; i <= a.length; i++) {
157
+ for (let j = 1; j <= b.length; j++) {
158
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
159
+ matrix[i][j] = Math.min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + cost);
160
+ }
161
+ }
162
+ return matrix[a.length][b.length];
163
+ }
164
+ /**
165
+ * Suggests similar paths if a file is not found.
166
+ */
167
+ export async function suggestPathUnderCwd(targetPath, workdir) {
168
+ try {
169
+ const allFiles = await glob("**/*", {
170
+ cwd: workdir,
171
+ nodir: true,
172
+ dot: true,
173
+ ignore: ["**/.git/**", "**/node_modules/**"],
174
+ });
175
+ const targetBasename = path.basename(targetPath);
176
+ const suggestions = allFiles
177
+ .map((file) => ({
178
+ path: file,
179
+ distance: levenshtein(targetBasename, path.basename(file)),
180
+ }))
181
+ .filter((item) => item.distance <= 3) // Threshold for similarity
182
+ .sort((a, b) => a.distance - b.distance)
183
+ .slice(0, 5)
184
+ .map((item) => item.path);
185
+ return suggestions;
186
+ }
187
+ catch {
188
+ return [];
189
+ }
190
+ }
191
+ /**
192
+ * Uses fuzzy matching to find the intended file.
193
+ */
194
+ export async function findSimilarFile(targetPath, workdir) {
195
+ const suggestions = await suggestPathUnderCwd(targetPath, workdir);
196
+ return suggestions.length > 0 ? suggestions[0] : null;
197
+ }
@@ -9,6 +9,7 @@ export interface UserMessageParams {
9
9
  }>;
10
10
  customCommandContent?: string;
11
11
  source?: MessageSource;
12
+ isMeta?: boolean;
12
13
  }
13
14
  export interface AddUserMessageParams extends UserMessageParams {
14
15
  messages: Message[];
@@ -17,6 +18,7 @@ export interface AddUserMessageParams extends UserMessageParams {
17
18
  export interface UpdateToolBlockParams {
18
19
  messages: Message[];
19
20
  id: string;
21
+ messageId?: string;
20
22
  parameters?: string;
21
23
  result?: string;
22
24
  success?: boolean;
@@ -28,7 +30,7 @@ export interface UpdateToolBlockParams {
28
30
  * - 'running': Tool execution in progress
29
31
  * - 'end': Tool execution completed with final result
30
32
  */
31
- stage: "start" | "streaming" | "running" | "end";
33
+ stage?: "start" | "streaming" | "running" | "end";
32
34
  name?: string;
33
35
  shortResult?: string;
34
36
  startLineNumber?: number;
@@ -67,13 +69,20 @@ export interface CompleteBangParams {
67
69
  */
68
70
  export declare const convertImageToBase64: (imagePath: string) => string;
69
71
  export declare const generateMessageId: () => string;
70
- export declare const addUserMessageToMessages: ({ messages, content, images, customCommandContent, source, id, }: AddUserMessageParams) => Message[];
72
+ export declare const addUserMessageToMessages: ({ messages, content, images, customCommandContent, source, id, isMeta, }: AddUserMessageParams) => Message[];
71
73
  /**
72
74
  * Update a user message's content or customCommandContent by its ID.
73
75
  */
74
76
  export declare const updateUserMessageInMessages: (messages: Message[], id: string, params: Partial<UserMessageParams>) => Message[];
75
77
  export declare const addAssistantMessageToMessages: (messages: Message[], content?: string, toolCalls?: ChatCompletionMessageFunctionToolCall[], usage?: Usage, additionalFields?: Record<string, unknown>) => Message[];
76
- export declare const updateToolBlockInMessage: ({ messages, id, parameters, result, success, error, stage, name, shortResult, startLineNumber, images, compactParams, parametersChunk, isManuallyBackgrounded, }: UpdateToolBlockParams) => Message[];
78
+ /**
79
+ * Add a tool block to a specific message by ID.
80
+ */
81
+ export declare const addToolBlockToMessageInMessages: (messages: Message[], messageId: string, params: Omit<AgentToolBlockUpdateParams, "id">) => {
82
+ messages: Message[];
83
+ toolBlockId: string;
84
+ };
85
+ export declare const updateToolBlockInMessage: ({ messages, id, messageId, parameters, result, success, error, stage, name, shortResult, startLineNumber, images, compactParams, parametersChunk, isManuallyBackgrounded, }: UpdateToolBlockParams) => Message[];
77
86
  export declare const addErrorBlockToMessage: ({ messages, error, }: AddErrorBlockParams) => Message[];
78
87
  export declare const addBangMessage: ({ messages, command, }: AddBangParams) => Message[];
79
88
  export declare const updateBangInMessage: ({ messages, command, output, }: UpdateBangParams) => Message[];
@@ -1 +1 @@
1
- {"version":3,"file":"messageOperations.d.ts","sourceRoot":"","sources":["../../src/utils/messageOperations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"messageOperations.d.ts","sourceRoot":"","sources":["../../src/utils/messageOperations.ts"],"names":[],"mappings":"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"}