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.
- package/builtin/skills/init/SKILL.md +2 -0
- package/builtin/skills/settings/SKILLS.md +3 -2
- package/builtin/skills/settings/SUBAGENTS.md +1 -3
- package/dist/agent.d.ts +6 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +18 -1
- package/dist/constants/tools.d.ts +1 -1
- package/dist/constants/tools.d.ts.map +1 -1
- package/dist/constants/tools.js +1 -1
- package/dist/managers/MemoryRuleManager.d.ts.map +1 -1
- package/dist/managers/MemoryRuleManager.js +1 -9
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +22 -3
- package/dist/managers/mcpManager.d.ts.map +1 -1
- package/dist/managers/mcpManager.js +32 -13
- package/dist/managers/messageManager.d.ts +13 -5
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +62 -34
- package/dist/managers/permissionManager.js +4 -4
- package/dist/managers/pluginManager.d.ts.map +1 -1
- package/dist/managers/pluginManager.js +4 -2
- package/dist/managers/slashCommandManager.d.ts +2 -0
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +98 -4
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +8 -2
- package/dist/prompts/index.d.ts +2 -0
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +5 -0
- package/dist/services/GitService.d.ts +1 -0
- package/dist/services/GitService.d.ts.map +1 -1
- package/dist/services/GitService.js +16 -0
- package/dist/services/MarketplaceService.d.ts +7 -0
- package/dist/services/MarketplaceService.d.ts.map +1 -1
- package/dist/services/MarketplaceService.js +321 -252
- package/dist/services/aiService.d.ts +34 -0
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +124 -1
- package/dist/services/initializationService.d.ts.map +1 -1
- package/dist/services/initializationService.js +18 -0
- package/dist/tools/agentTool.js +3 -3
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +4 -4
- package/dist/tools/editTool.d.ts.map +1 -1
- package/dist/tools/editTool.js +2 -0
- package/dist/tools/globTool.d.ts.map +1 -1
- package/dist/tools/globTool.js +15 -3
- package/dist/tools/grepTool.d.ts.map +1 -1
- package/dist/tools/grepTool.js +38 -12
- package/dist/tools/readTool.d.ts.map +1 -1
- package/dist/tools/readTool.js +61 -0
- package/dist/tools/skillTool.js +2 -2
- package/dist/tools/types.d.ts +16 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/webFetchTool.d.ts +3 -0
- package/dist/tools/webFetchTool.d.ts.map +1 -0
- package/dist/tools/webFetchTool.js +171 -0
- package/dist/tools/writeTool.d.ts.map +1 -1
- package/dist/tools/writeTool.js +2 -0
- package/dist/types/commands.d.ts +1 -1
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/types/messaging.d.ts +1 -0
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/utils/bashParser.d.ts +20 -2
- package/dist/utils/bashParser.d.ts.map +1 -1
- package/dist/utils/bashParser.js +281 -146
- package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
- package/dist/utils/convertMessagesForAPI.js +7 -0
- package/dist/utils/fileUtils.d.ts +8 -0
- package/dist/utils/fileUtils.d.ts.map +1 -1
- package/dist/utils/fileUtils.js +52 -0
- package/dist/utils/messageOperations.d.ts +12 -3
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +77 -9
- package/package.json +4 -2
- package/src/agent.ts +19 -1
- package/src/constants/tools.ts +1 -1
- package/src/managers/MemoryRuleManager.ts +1 -10
- package/src/managers/aiManager.ts +23 -3
- package/src/managers/mcpManager.ts +37 -16
- package/src/managers/messageManager.ts +76 -38
- package/src/managers/permissionManager.ts +4 -4
- package/src/managers/pluginManager.ts +4 -2
- package/src/managers/slashCommandManager.ts +130 -4
- package/src/managers/toolManager.ts +11 -2
- package/src/prompts/index.ts +6 -0
- package/src/services/GitService.ts +20 -0
- package/src/services/MarketplaceService.ts +397 -324
- package/src/services/aiService.ts +197 -1
- package/src/services/initializationService.ts +38 -0
- package/src/tools/agentTool.ts +3 -3
- package/src/tools/bashTool.ts +3 -4
- package/src/tools/editTool.ts +3 -0
- package/src/tools/globTool.ts +16 -3
- package/src/tools/grepTool.ts +41 -13
- package/src/tools/readTool.ts +69 -0
- package/src/tools/skillTool.ts +2 -2
- package/src/tools/types.ts +13 -0
- package/src/tools/webFetchTool.ts +194 -0
- package/src/tools/writeTool.ts +3 -0
- package/src/types/commands.ts +1 -1
- package/src/types/messaging.ts +1 -0
- package/src/utils/bashParser.ts +316 -161
- package/src/utils/convertMessagesForAPI.ts +8 -0
- package/src/utils/fileUtils.ts +69 -0
- package/src/utils/messageOperations.ts +84 -9
- package/dist/tools/taskOutputTool.d.ts +0 -3
- package/dist/tools/taskOutputTool.d.ts.map +0 -1
- package/dist/tools/taskOutputTool.js +0 -198
- package/src/tools/taskOutputTool.ts +0 -222
package/dist/utils/bashParser.js
CHANGED
|
@@ -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
|
-
*
|
|
364
|
+
* Checks if a bash command contains any heredocs (<<, <<-).
|
|
365
365
|
*/
|
|
366
|
-
export function
|
|
367
|
-
|
|
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
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
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
|
|
407
|
-
|
|
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
|
-
//
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
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
|
-
|
|
424
|
-
|
|
425
|
-
|
|
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
|
-
//
|
|
462
|
-
if (
|
|
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
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
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
|
-
|
|
515
|
-
|
|
516
|
-
|
|
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
|
-
//
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
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
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
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
|
-
|
|
659
|
+
prefixParts.push(token);
|
|
660
|
+
i++;
|
|
540
661
|
}
|
|
541
|
-
//
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
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
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
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
|
-
|
|
691
|
+
i++;
|
|
553
692
|
}
|
|
554
|
-
if (
|
|
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,
|
|
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":"
|
|
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"}
|
package/dist/utils/fileUtils.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"messageOperations.d.ts","sourceRoot":"","sources":["../../src/utils/messageOperations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAa,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,OAAO,EAAE,qCAAqC,EAAE,MAAM,qBAAqB,CAAC;AAI5E,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAGD,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,GAAG,KAAK,CAAC;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAGD,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAC3C,qBAAqB,EACrB,UAAU,CACX,CAAC;AAEF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,WAAW,MAAM,KAAG,MAmCxD,CAAC;AAEF,eAAO,MAAM,iBAAiB,QAAO,MAA+B,CAAC;AAGrE,eAAO,MAAM,wBAAwB,GAAI,0EAQtC,oBAAoB,KAAG,OAAO,EA4BhC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,2BAA2B,GACtC,UAAU,OAAO,EAAE,EACnB,IAAI,MAAM,EACV,QAAQ,OAAO,CAAC,iBAAiB,CAAC,KACjC,OAAO,EAwBT,CAAC;AAGF,eAAO,MAAM,6BAA6B,GACxC,UAAU,OAAO,EAAE,EACnB,UAAU,MAAM,EAChB,YAAY,qCAAqC,EAAE,EACnD,QAAQ,KAAK,EACb,mBAAmB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACzC,OAAO,EA+BT,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,+BAA+B,GAC1C,UAAU,OAAO,EAAE,EACnB,WAAW,MAAM,EACjB,QAAQ,IAAI,CAAC,0BAA0B,EAAE,IAAI,CAAC,KAC7C;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAuB5C,CAAC;AAGF,eAAO,MAAM,wBAAwB,GAAI,6KAgBtC,qBAAqB,KAAG,OAAO,EAsFjC,CAAC;AAGF,eAAO,MAAM,sBAAsB,GAAI,sBAGpC,mBAAmB,KAAG,OAAO,EAgC/B,CAAC;AAGF,eAAO,MAAM,cAAc,GAAI,wBAG5B,aAAa,KAAG,OAAO,EAgBzB,CAAC;AAGF,eAAO,MAAM,mBAAmB,GAAI,gCAIjC,gBAAgB,KAAG,OAAO,EAiB5B,CAAC;AAGF,eAAO,MAAM,qBAAqB,GAAI,0CAKnC,kBAAkB,KAAG,OAAO,EAqB9B,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAU3D;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAI,UAAU,OAAO,EAAE,KAAG,OAAO,EASlE,CAAC;AAEF;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,MAAM,CAUR"}
|