@probelabs/probe 0.6.0-rc104 → 0.6.0-rc106

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/cjs/index.cjs CHANGED
@@ -1234,7 +1234,7 @@ function createMessagePreview(message, charsPerSide = 200) {
1234
1234
  const end = message.substring(message.length - charsPerSide);
1235
1235
  return `${start}...${end}`;
1236
1236
  }
1237
- var import_zod, searchSchema, querySchema, extractSchema, delegateSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, delegateToolDefinition, attemptCompletionToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, DEFAULT_VALID_TOOLS;
1237
+ var import_zod, searchSchema, querySchema, extractSchema, delegateSchema, bashSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, delegateToolDefinition, attemptCompletionToolDefinition, bashToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, bashDescription, DEFAULT_VALID_TOOLS;
1238
1238
  var init_common = __esm({
1239
1239
  "src/tools/common.js"() {
1240
1240
  "use strict";
@@ -1266,6 +1266,12 @@ var init_common = __esm({
1266
1266
  delegateSchema = import_zod.z.object({
1267
1267
  task: import_zod.z.string().describe("The task to delegate to a subagent. Be specific about what needs to be accomplished.")
1268
1268
  });
1269
+ bashSchema = import_zod.z.object({
1270
+ command: import_zod.z.string().describe("The bash command to execute"),
1271
+ workingDirectory: import_zod.z.string().optional().describe("Directory to execute the command in (optional)"),
1272
+ timeout: import_zod.z.number().optional().describe("Command timeout in milliseconds (optional)"),
1273
+ env: import_zod.z.record(import_zod.z.string()).optional().describe("Additional environment variables (optional)")
1274
+ });
1269
1275
  attemptCompletionSchema = {
1270
1276
  // Custom validation that requires result parameter but allows direct XML response
1271
1277
  safeParse: (params) => {
@@ -1488,11 +1494,67 @@ Usage Example:
1488
1494
  <attempt_completion>
1489
1495
  I have refactored the search module according to the requirements and verified the tests pass. The module now uses the new BM25 ranking algorithm and has improved error handling.
1490
1496
  </attempt_completion>
1497
+ `;
1498
+ bashToolDefinition = `
1499
+ ## bash
1500
+ Description: Execute bash commands for system exploration and development tasks. This tool has built-in security with allow/deny lists. By default, only safe read-only commands are allowed for code exploration.
1501
+
1502
+ Parameters:
1503
+ - command: (required) The bash command to execute
1504
+ - workingDirectory: (optional) Directory to execute the command in
1505
+ - timeout: (optional) Command timeout in milliseconds
1506
+ - env: (optional) Additional environment variables as an object
1507
+
1508
+ Security: Commands are filtered through allow/deny lists for safety:
1509
+ - Allowed by default: ls, cat, git status, npm list, find, grep, etc.
1510
+ - Denied by default: rm -rf, sudo, npm install, dangerous system commands
1511
+
1512
+ Usage Examples:
1513
+
1514
+ <examples>
1515
+
1516
+ User: What files are in the src directory?
1517
+ <bash>
1518
+ <command>ls -la src/</command>
1519
+ </bash>
1520
+
1521
+ User: Show me the git status
1522
+ <bash>
1523
+ <command>git status</command>
1524
+ </bash>
1525
+
1526
+ User: Find all TypeScript files
1527
+ <bash>
1528
+ <command>find . -name "*.ts" -type f</command>
1529
+ </bash>
1530
+
1531
+ User: Check installed npm packages
1532
+ <bash>
1533
+ <command>npm list --depth=0</command>
1534
+ </bash>
1535
+
1536
+ User: Search for TODO comments in code
1537
+ <bash>
1538
+ <command>grep -r "TODO" src/</command>
1539
+ </bash>
1540
+
1541
+ User: Show recent git commits
1542
+ <bash>
1543
+ <command>git log --oneline -10</command>
1544
+ </bash>
1545
+
1546
+ User: Check system info
1547
+ <bash>
1548
+ <command>uname -a</command>
1549
+ </bash>
1550
+
1551
+ </examples>
1491
1552
  `;
1492
1553
  searchDescription = "Search code in the repository using Elasticsearch-like query syntax. Use this tool first for any code-related questions.";
1493
1554
  queryDescription = "Search code using ast-grep structural pattern matching. Use this tool to find specific code structures like functions, classes, or methods.";
1494
1555
  extractDescription = "Extract code blocks from files based on file paths and optional line numbers. Use this tool to see complete context after finding relevant files.";
1495
1556
  delegateDescription = "Automatically delegate big distinct tasks to specialized probe subagents within the agentic loop. Used by AI agents to break down complex requests into focused, parallel tasks.";
1557
+ bashDescription = "Execute bash commands for system exploration and development tasks. Secure by default with built-in allow/deny lists.";
1496
1558
  DEFAULT_VALID_TOOLS = [
1497
1559
  "search",
1498
1560
  "query",
@@ -1546,7 +1608,7 @@ async function delegate({ task, timeout = 300, debug = false, currentIteration =
1546
1608
  console.error(`[DELEGATE] Using binary at: ${binaryPath}`);
1547
1609
  console.error(`[DELEGATE] Command args: ${args.join(" ")}`);
1548
1610
  }
1549
- return new Promise((resolve2, reject) => {
1611
+ return new Promise((resolve4, reject) => {
1550
1612
  const delegationSpan = tracer ? tracer.createDelegationSpan(sessionId, task) : null;
1551
1613
  const process2 = (0, import_child_process5.spawn)(binaryPath, args, {
1552
1614
  stdio: ["pipe", "pipe", "pipe"],
@@ -1611,7 +1673,7 @@ async function delegate({ task, timeout = 300, debug = false, currentIteration =
1611
1673
  delegationSpan.end();
1612
1674
  }
1613
1675
  }
1614
- resolve2(response);
1676
+ resolve4(response);
1615
1677
  } else {
1616
1678
  const errorMessage = stderr.trim() || `Delegate process failed with exit code ${code}`;
1617
1679
  if (debug) {
@@ -1807,10 +1869,10 @@ var init_vercel = __esm({
1807
1869
  let extractOptions = { path: extractPath };
1808
1870
  if (input_content) {
1809
1871
  const { writeFileSync: writeFileSync2, unlinkSync } = await import("fs");
1810
- const { join: join2 } = await import("path");
1872
+ const { join: join3 } = await import("path");
1811
1873
  const { tmpdir } = await import("os");
1812
1874
  const { randomUUID: randomUUID5 } = await import("crypto");
1813
- tempFilePath = join2(tmpdir(), `probe-extract-${randomUUID5()}.txt`);
1875
+ tempFilePath = join3(tmpdir(), `probe-extract-${randomUUID5()}.txt`);
1814
1876
  writeFileSync2(tempFilePath, input_content);
1815
1877
  if (debug) {
1816
1878
  console.error(`Created temporary file for input content: ${tempFilePath}`);
@@ -1887,6 +1949,1248 @@ var init_vercel = __esm({
1887
1949
  }
1888
1950
  });
1889
1951
 
1952
+ // src/agent/bashDefaults.js
1953
+ var DEFAULT_ALLOW_PATTERNS, DEFAULT_DENY_PATTERNS;
1954
+ var init_bashDefaults = __esm({
1955
+ "src/agent/bashDefaults.js"() {
1956
+ "use strict";
1957
+ DEFAULT_ALLOW_PATTERNS = [
1958
+ // Basic navigation and listing
1959
+ "ls",
1960
+ "dir",
1961
+ "pwd",
1962
+ "cd",
1963
+ "cd:*",
1964
+ // File reading commands
1965
+ "cat",
1966
+ "cat:*",
1967
+ "head",
1968
+ "head:*",
1969
+ "tail",
1970
+ "tail:*",
1971
+ "less",
1972
+ "more",
1973
+ "view",
1974
+ // File information and metadata
1975
+ "file",
1976
+ "file:*",
1977
+ "stat",
1978
+ "stat:*",
1979
+ "wc",
1980
+ "wc:*",
1981
+ "du",
1982
+ "du:*",
1983
+ "df",
1984
+ "df:*",
1985
+ "realpath",
1986
+ "realpath:*",
1987
+ // Search and find commands (read-only) - find restricted to safe operations
1988
+ "find",
1989
+ "find:-name:*",
1990
+ "find:-type:*",
1991
+ "find:-size:*",
1992
+ "find:-mtime:*",
1993
+ "find:-newer:*",
1994
+ "find:-path:*",
1995
+ "find:-iname:*",
1996
+ "find:-maxdepth:*",
1997
+ "find:-mindepth:*",
1998
+ "find:-print",
1999
+ "grep",
2000
+ "grep:*",
2001
+ "egrep",
2002
+ "egrep:*",
2003
+ "fgrep",
2004
+ "fgrep:*",
2005
+ "rg",
2006
+ "rg:*",
2007
+ "ag",
2008
+ "ag:*",
2009
+ "ack",
2010
+ "ack:*",
2011
+ "which",
2012
+ "which:*",
2013
+ "whereis",
2014
+ "whereis:*",
2015
+ "locate",
2016
+ "locate:*",
2017
+ "type",
2018
+ "type:*",
2019
+ "command",
2020
+ "command:*",
2021
+ // Tree and structure visualization
2022
+ "tree",
2023
+ "tree:*",
2024
+ // Git read-only operations
2025
+ "git:status",
2026
+ "git:log",
2027
+ "git:log:*",
2028
+ "git:diff",
2029
+ "git:diff:*",
2030
+ "git:show",
2031
+ "git:show:*",
2032
+ "git:branch",
2033
+ "git:branch:*",
2034
+ "git:tag",
2035
+ "git:tag:*",
2036
+ "git:describe",
2037
+ "git:describe:*",
2038
+ "git:remote",
2039
+ "git:remote:*",
2040
+ "git:config:*",
2041
+ "git:blame",
2042
+ "git:blame:*",
2043
+ "git:shortlog",
2044
+ "git:reflog",
2045
+ "git:ls-files",
2046
+ "git:ls-tree",
2047
+ "git:rev-parse",
2048
+ "git:rev-list",
2049
+ "git:--version",
2050
+ "git:help",
2051
+ "git:help:*",
2052
+ // Package managers (information only)
2053
+ "npm:list",
2054
+ "npm:ls",
2055
+ "npm:view",
2056
+ "npm:info",
2057
+ "npm:show",
2058
+ "npm:outdated",
2059
+ "npm:audit",
2060
+ "npm:--version",
2061
+ "yarn:list",
2062
+ "yarn:info",
2063
+ "yarn:--version",
2064
+ "pnpm:list",
2065
+ "pnpm:--version",
2066
+ "pip:list",
2067
+ "pip:show",
2068
+ "pip:--version",
2069
+ "pip3:list",
2070
+ "pip3:show",
2071
+ "pip3:--version",
2072
+ "gem:list",
2073
+ "gem:--version",
2074
+ "bundle:list",
2075
+ "bundle:show",
2076
+ "bundle:--version",
2077
+ "composer:show",
2078
+ "composer:--version",
2079
+ // Language and runtime versions
2080
+ "node:--version",
2081
+ "node:-v",
2082
+ "python:--version",
2083
+ "python:-V",
2084
+ "python3:--version",
2085
+ "python3:-V",
2086
+ "ruby:--version",
2087
+ "ruby:-v",
2088
+ "go:version",
2089
+ "go:env",
2090
+ "go:list",
2091
+ "go:mod:graph",
2092
+ "rustc:--version",
2093
+ "cargo:--version",
2094
+ "cargo:tree",
2095
+ "cargo:metadata",
2096
+ "java:--version",
2097
+ "java:-version",
2098
+ "javac:--version",
2099
+ "mvn:--version",
2100
+ "gradle:--version",
2101
+ "php:--version",
2102
+ "dotnet:--version",
2103
+ "dotnet:list",
2104
+ // Database client versions (connection info only)
2105
+ "psql:--version",
2106
+ "mysql:--version",
2107
+ "redis-cli:--version",
2108
+ "mongo:--version",
2109
+ "sqlite3:--version",
2110
+ // System information
2111
+ "uname",
2112
+ "uname:*",
2113
+ "hostname",
2114
+ "whoami",
2115
+ "id",
2116
+ "groups",
2117
+ "date",
2118
+ "cal",
2119
+ "uptime",
2120
+ "w",
2121
+ "users",
2122
+ "sleep",
2123
+ "sleep:*",
2124
+ // Environment and shell
2125
+ "env",
2126
+ "printenv",
2127
+ "echo",
2128
+ "echo:*",
2129
+ "printf",
2130
+ "printf:*",
2131
+ "export",
2132
+ "export:*",
2133
+ "set",
2134
+ "unset",
2135
+ // Process information (read-only)
2136
+ "ps",
2137
+ "ps:*",
2138
+ "pgrep",
2139
+ "pgrep:*",
2140
+ "jobs",
2141
+ "top:-n:1",
2142
+ // Network information (read-only)
2143
+ "ifconfig",
2144
+ "ip:addr",
2145
+ "ip:link",
2146
+ "hostname:-I",
2147
+ "ping:-c:*",
2148
+ "traceroute",
2149
+ "nslookup",
2150
+ "dig",
2151
+ // Text processing and utilities (awk removed - too powerful)
2152
+ "sed:-n:*",
2153
+ "cut",
2154
+ "cut:*",
2155
+ "sort",
2156
+ "sort:*",
2157
+ "uniq",
2158
+ "uniq:*",
2159
+ "tr",
2160
+ "tr:*",
2161
+ "column",
2162
+ "column:*",
2163
+ "paste",
2164
+ "paste:*",
2165
+ "join",
2166
+ "join:*",
2167
+ "comm",
2168
+ "comm:*",
2169
+ "diff",
2170
+ "diff:*",
2171
+ "cmp",
2172
+ "cmp:*",
2173
+ "patch:--dry-run:*",
2174
+ // Hashing and encoding (read-only)
2175
+ "md5sum",
2176
+ "md5sum:*",
2177
+ "sha1sum",
2178
+ "sha1sum:*",
2179
+ "sha256sum",
2180
+ "sha256sum:*",
2181
+ "base64",
2182
+ "base64:-d",
2183
+ "od",
2184
+ "od:*",
2185
+ "hexdump",
2186
+ "hexdump:*",
2187
+ // Archive and compression (list/view only)
2188
+ "tar:-tf:*",
2189
+ "tar:-tzf:*",
2190
+ "unzip:-l:*",
2191
+ "zip:-l:*",
2192
+ "gzip:-l:*",
2193
+ "gunzip:-l:*",
2194
+ // Help and documentation
2195
+ "man",
2196
+ "man:*",
2197
+ "--help",
2198
+ "help",
2199
+ "info",
2200
+ "info:*",
2201
+ "whatis",
2202
+ "whatis:*",
2203
+ "apropos",
2204
+ "apropos:*",
2205
+ // Make (dry run and info)
2206
+ "make:-n",
2207
+ "make:--dry-run",
2208
+ "make:-p",
2209
+ "make:--print-data-base",
2210
+ // Docker (read-only operations)
2211
+ "docker:ps",
2212
+ "docker:images",
2213
+ "docker:version",
2214
+ "docker:info",
2215
+ "docker:logs:*",
2216
+ "docker:inspect:*",
2217
+ // Test runners (list/info only)
2218
+ "jest:--listTests",
2219
+ "mocha:--help",
2220
+ "pytest:--collect-only"
2221
+ ];
2222
+ DEFAULT_DENY_PATTERNS = [
2223
+ // Dangerous file operations
2224
+ "rm:-rf",
2225
+ "rm:-f:/",
2226
+ "rm:/",
2227
+ "rm:-rf:*",
2228
+ "rmdir",
2229
+ "chmod:777",
2230
+ "chmod:-R:777",
2231
+ "chown",
2232
+ "chgrp",
2233
+ "dd",
2234
+ "dd:*",
2235
+ "shred",
2236
+ "shred:*",
2237
+ // Dangerous find operations that can execute arbitrary commands
2238
+ "find:-exec:*",
2239
+ "find:*:-exec:*",
2240
+ "find:-execdir:*",
2241
+ "find:*:-execdir:*",
2242
+ "find:-ok:*",
2243
+ "find:*:-ok:*",
2244
+ "find:-okdir:*",
2245
+ "find:*:-okdir:*",
2246
+ // Powerful scripting tools that can execute arbitrary commands
2247
+ "awk",
2248
+ "awk:*",
2249
+ "perl",
2250
+ "perl:*",
2251
+ "python:-c:*",
2252
+ "node:-e:*",
2253
+ // System administration and modification
2254
+ "sudo:*",
2255
+ "su",
2256
+ "su:*",
2257
+ "passwd",
2258
+ "adduser",
2259
+ "useradd",
2260
+ "userdel",
2261
+ "usermod",
2262
+ "groupadd",
2263
+ "groupdel",
2264
+ "visudo",
2265
+ // Package installation and removal
2266
+ "npm:install",
2267
+ "npm:i",
2268
+ "npm:uninstall",
2269
+ "npm:publish",
2270
+ "npm:unpublish",
2271
+ "npm:link",
2272
+ "npm:update",
2273
+ "yarn:install",
2274
+ "yarn:add",
2275
+ "yarn:remove",
2276
+ "yarn:upgrade",
2277
+ "pnpm:install",
2278
+ "pnpm:add",
2279
+ "pnpm:remove",
2280
+ "pip:install",
2281
+ "pip:uninstall",
2282
+ "pip:upgrade",
2283
+ "pip3:install",
2284
+ "pip3:uninstall",
2285
+ "pip3:upgrade",
2286
+ "gem:install",
2287
+ "gem:uninstall",
2288
+ "gem:update",
2289
+ "bundle:install",
2290
+ "bundle:update",
2291
+ "composer:install",
2292
+ "composer:update",
2293
+ "composer:remove",
2294
+ "apt:*",
2295
+ "apt-get:*",
2296
+ "yum:*",
2297
+ "dnf:*",
2298
+ "zypper:*",
2299
+ "brew:install",
2300
+ "brew:uninstall",
2301
+ "brew:upgrade",
2302
+ "conda:install",
2303
+ "conda:remove",
2304
+ "conda:update",
2305
+ // Service and system control
2306
+ "systemctl:*",
2307
+ "service:*",
2308
+ "chkconfig:*",
2309
+ "initctl:*",
2310
+ "upstart:*",
2311
+ // Network operations that could be dangerous
2312
+ "curl:-d:*",
2313
+ "curl:--data:*",
2314
+ "curl:-X:POST:*",
2315
+ "curl:-X:PUT:*",
2316
+ "wget:-O:/",
2317
+ "wget:--post-data:*",
2318
+ "ssh",
2319
+ "ssh:*",
2320
+ "scp",
2321
+ "scp:*",
2322
+ "sftp",
2323
+ "sftp:*",
2324
+ "rsync:*",
2325
+ "nc",
2326
+ "nc:*",
2327
+ "netcat",
2328
+ "netcat:*",
2329
+ "telnet",
2330
+ "telnet:*",
2331
+ "ftp",
2332
+ "ftp:*",
2333
+ // Process control and termination
2334
+ "kill",
2335
+ "kill:*",
2336
+ "killall",
2337
+ "killall:*",
2338
+ "pkill",
2339
+ "pkill:*",
2340
+ "nohup:*",
2341
+ "disown:*",
2342
+ // System control and shutdown
2343
+ "shutdown",
2344
+ "shutdown:*",
2345
+ "reboot",
2346
+ "halt",
2347
+ "poweroff",
2348
+ "init",
2349
+ "telinit",
2350
+ // Kernel and module operations
2351
+ "insmod",
2352
+ "insmod:*",
2353
+ "rmmod",
2354
+ "rmmod:*",
2355
+ "modprobe",
2356
+ "modprobe:*",
2357
+ "sysctl:-w:*",
2358
+ // Dangerous git operations
2359
+ "git:push",
2360
+ "git:push:*",
2361
+ "git:force",
2362
+ "git:reset:--hard:*",
2363
+ "git:clean:-fd",
2364
+ "git:rm:*",
2365
+ "git:commit",
2366
+ "git:merge",
2367
+ "git:rebase",
2368
+ "git:cherry-pick",
2369
+ "git:stash:drop",
2370
+ // File system mounting and partitioning
2371
+ "mount",
2372
+ "mount:*",
2373
+ "umount",
2374
+ "umount:*",
2375
+ "fdisk",
2376
+ "fdisk:*",
2377
+ "parted",
2378
+ "parted:*",
2379
+ "mkfs",
2380
+ "mkfs:*",
2381
+ "fsck",
2382
+ "fsck:*",
2383
+ // Cron and scheduling
2384
+ "crontab",
2385
+ "crontab:*",
2386
+ "at",
2387
+ "at:*",
2388
+ "batch",
2389
+ "batch:*",
2390
+ // Compression with potential overwrite
2391
+ "tar:-xf:*",
2392
+ "unzip",
2393
+ "unzip:*",
2394
+ "gzip:*",
2395
+ "gunzip:*",
2396
+ // Build and compilation that might modify files
2397
+ "make",
2398
+ "make:install",
2399
+ "make:clean",
2400
+ "cargo:build",
2401
+ "cargo:install",
2402
+ "npm:run:build",
2403
+ "yarn:build",
2404
+ "mvn:install",
2405
+ "gradle:build",
2406
+ // Docker operations that could modify state
2407
+ "docker:run",
2408
+ "docker:run:*",
2409
+ "docker:exec",
2410
+ "docker:exec:*",
2411
+ "docker:build",
2412
+ "docker:build:*",
2413
+ "docker:pull",
2414
+ "docker:push",
2415
+ "docker:rm",
2416
+ "docker:rmi",
2417
+ "docker:stop",
2418
+ "docker:start",
2419
+ // Database operations
2420
+ "mysql:-e:DROP",
2421
+ "psql:-c:DROP",
2422
+ "redis-cli:FLUSHALL",
2423
+ "mongo:--eval:*",
2424
+ // Text editors that could modify files
2425
+ "vi",
2426
+ "vi:*",
2427
+ "vim",
2428
+ "vim:*",
2429
+ "nano",
2430
+ "nano:*",
2431
+ "emacs",
2432
+ "emacs:*",
2433
+ "sed:-i:*",
2434
+ "perl:-i:*",
2435
+ // Potentially dangerous utilities
2436
+ "eval",
2437
+ "eval:*",
2438
+ "exec",
2439
+ "exec:*",
2440
+ "source",
2441
+ "source:*",
2442
+ "bash:-c:*",
2443
+ "sh:-c:*",
2444
+ "zsh:-c:*"
2445
+ ];
2446
+ }
2447
+ });
2448
+
2449
+ // src/agent/bashCommandUtils.js
2450
+ function parseSimpleCommand(command) {
2451
+ if (!command || typeof command !== "string") {
2452
+ return {
2453
+ success: false,
2454
+ error: "Command must be a non-empty string",
2455
+ command: null,
2456
+ args: [],
2457
+ isComplex: false
2458
+ };
2459
+ }
2460
+ const trimmed = command.trim();
2461
+ if (!trimmed) {
2462
+ return {
2463
+ success: false,
2464
+ error: "Command cannot be empty",
2465
+ command: null,
2466
+ args: [],
2467
+ isComplex: false
2468
+ };
2469
+ }
2470
+ const complexPatterns = [
2471
+ /\|/,
2472
+ // Pipes
2473
+ /&&/,
2474
+ // Logical AND
2475
+ /\|\|/,
2476
+ // Logical OR
2477
+ /(?<!\\);/,
2478
+ // Command separator (but not escaped \;)
2479
+ /&$/,
2480
+ // Background execution
2481
+ /\$\(/,
2482
+ // Command substitution $()
2483
+ /`/,
2484
+ // Command substitution ``
2485
+ />/,
2486
+ // Redirection >
2487
+ /</,
2488
+ // Redirection <
2489
+ /\*\*/,
2490
+ // Glob patterns (potentially dangerous)
2491
+ /^\s*\{.*,.*\}|\{.*\.\.\.*\}/
2492
+ // Brace expansion like {a,b} or {1..10} (but not find {} placeholders)
2493
+ ];
2494
+ for (const pattern of complexPatterns) {
2495
+ if (pattern.test(trimmed)) {
2496
+ return {
2497
+ success: false,
2498
+ error: "Complex shell commands with pipes, operators, or redirections are not supported for security reasons",
2499
+ command: null,
2500
+ args: [],
2501
+ isComplex: true,
2502
+ detected: pattern.toString()
2503
+ };
2504
+ }
2505
+ }
2506
+ const args = [];
2507
+ let current = "";
2508
+ let inQuotes = false;
2509
+ let quoteChar = "";
2510
+ let escaped = false;
2511
+ for (let i3 = 0; i3 < trimmed.length; i3++) {
2512
+ const char = trimmed[i3];
2513
+ const nextChar = i3 + 1 < trimmed.length ? trimmed[i3 + 1] : "";
2514
+ if (escaped) {
2515
+ current += char;
2516
+ escaped = false;
2517
+ continue;
2518
+ }
2519
+ if (char === "\\" && !inQuotes) {
2520
+ escaped = true;
2521
+ continue;
2522
+ }
2523
+ if (!inQuotes && (char === '"' || char === "'")) {
2524
+ inQuotes = true;
2525
+ quoteChar = char;
2526
+ } else if (inQuotes && char === quoteChar) {
2527
+ inQuotes = false;
2528
+ quoteChar = "";
2529
+ } else if (!inQuotes && char === " ") {
2530
+ if (current.trim()) {
2531
+ args.push(current.trim());
2532
+ current = "";
2533
+ }
2534
+ } else {
2535
+ current += char;
2536
+ }
2537
+ }
2538
+ if (current.trim()) {
2539
+ args.push(current.trim());
2540
+ }
2541
+ if (inQuotes) {
2542
+ return {
2543
+ success: false,
2544
+ error: `Unclosed quote in command: ${quoteChar}`,
2545
+ command: null,
2546
+ args: [],
2547
+ isComplex: false
2548
+ };
2549
+ }
2550
+ if (args.length === 0) {
2551
+ return {
2552
+ success: false,
2553
+ error: "No command found after parsing",
2554
+ command: null,
2555
+ args: [],
2556
+ isComplex: false
2557
+ };
2558
+ }
2559
+ const [baseCommand, ...commandArgs] = args;
2560
+ return {
2561
+ success: true,
2562
+ error: null,
2563
+ command: baseCommand,
2564
+ args: commandArgs,
2565
+ fullArgs: args,
2566
+ isComplex: false,
2567
+ original: command
2568
+ };
2569
+ }
2570
+ function isComplexCommand(command) {
2571
+ const result = parseSimpleCommand(command);
2572
+ return result.isComplex;
2573
+ }
2574
+ function parseCommand(command) {
2575
+ const result = parseSimpleCommand(command);
2576
+ if (!result.success) {
2577
+ return {
2578
+ command: "",
2579
+ args: [],
2580
+ error: result.error,
2581
+ isComplex: result.isComplex
2582
+ };
2583
+ }
2584
+ return {
2585
+ command: result.command,
2586
+ args: result.args,
2587
+ error: null,
2588
+ isComplex: result.isComplex
2589
+ };
2590
+ }
2591
+ function parseCommandForExecution(command) {
2592
+ const result = parseSimpleCommand(command);
2593
+ if (!result.success) {
2594
+ return null;
2595
+ }
2596
+ return result.fullArgs;
2597
+ }
2598
+ var init_bashCommandUtils = __esm({
2599
+ "src/agent/bashCommandUtils.js"() {
2600
+ "use strict";
2601
+ }
2602
+ });
2603
+
2604
+ // src/agent/bashPermissions.js
2605
+ function matchesPattern(parsedCommand, pattern) {
2606
+ if (!parsedCommand || !pattern) return false;
2607
+ const { command, args } = parsedCommand;
2608
+ if (!command) return false;
2609
+ const patternParts = pattern.split(":");
2610
+ const commandName = patternParts[0];
2611
+ if (commandName === "*") {
2612
+ return true;
2613
+ } else if (commandName !== command) {
2614
+ return false;
2615
+ }
2616
+ if (patternParts.length === 1) {
2617
+ return true;
2618
+ }
2619
+ for (let i3 = 1; i3 < patternParts.length; i3++) {
2620
+ const patternArg = patternParts[i3];
2621
+ const argIndex = i3 - 1;
2622
+ if (patternArg === "*") {
2623
+ continue;
2624
+ }
2625
+ if (argIndex >= args.length) {
2626
+ return false;
2627
+ }
2628
+ const actualArg = args[argIndex];
2629
+ if (patternArg !== actualArg) {
2630
+ return false;
2631
+ }
2632
+ }
2633
+ return true;
2634
+ }
2635
+ function matchesAnyPattern(parsedCommand, patterns) {
2636
+ if (!patterns || patterns.length === 0) return false;
2637
+ return patterns.some((pattern) => matchesPattern(parsedCommand, pattern));
2638
+ }
2639
+ var BashPermissionChecker;
2640
+ var init_bashPermissions = __esm({
2641
+ "src/agent/bashPermissions.js"() {
2642
+ "use strict";
2643
+ init_bashDefaults();
2644
+ init_bashCommandUtils();
2645
+ BashPermissionChecker = class {
2646
+ /**
2647
+ * Create a permission checker
2648
+ * @param {Object} config - Configuration options
2649
+ * @param {string[]} [config.allow] - Additional allow patterns
2650
+ * @param {string[]} [config.deny] - Additional deny patterns
2651
+ * @param {boolean} [config.disableDefaultAllow] - Disable default allow list
2652
+ * @param {boolean} [config.disableDefaultDeny] - Disable default deny list
2653
+ * @param {boolean} [config.debug] - Enable debug logging
2654
+ */
2655
+ constructor(config = {}) {
2656
+ this.debug = config.debug || false;
2657
+ this.allowPatterns = [];
2658
+ if (!config.disableDefaultAllow) {
2659
+ this.allowPatterns.push(...DEFAULT_ALLOW_PATTERNS);
2660
+ if (this.debug) {
2661
+ console.log(`[BashPermissions] Added ${DEFAULT_ALLOW_PATTERNS.length} default allow patterns`);
2662
+ }
2663
+ }
2664
+ if (config.allow && Array.isArray(config.allow)) {
2665
+ this.allowPatterns.push(...config.allow);
2666
+ if (this.debug) {
2667
+ console.log(`[BashPermissions] Added ${config.allow.length} custom allow patterns:`, config.allow);
2668
+ }
2669
+ }
2670
+ this.denyPatterns = [];
2671
+ if (!config.disableDefaultDeny) {
2672
+ this.denyPatterns.push(...DEFAULT_DENY_PATTERNS);
2673
+ if (this.debug) {
2674
+ console.log(`[BashPermissions] Added ${DEFAULT_DENY_PATTERNS.length} default deny patterns`);
2675
+ }
2676
+ }
2677
+ if (config.deny && Array.isArray(config.deny)) {
2678
+ this.denyPatterns.push(...config.deny);
2679
+ if (this.debug) {
2680
+ console.log(`[BashPermissions] Added ${config.deny.length} custom deny patterns:`, config.deny);
2681
+ }
2682
+ }
2683
+ if (this.debug) {
2684
+ console.log(`[BashPermissions] Total patterns - Allow: ${this.allowPatterns.length}, Deny: ${this.denyPatterns.length}`);
2685
+ }
2686
+ }
2687
+ /**
2688
+ * Check if a simple command is allowed (rejects complex commands for security)
2689
+ * @param {string} command - Command to check
2690
+ * @returns {Object} Permission result
2691
+ */
2692
+ check(command) {
2693
+ if (!command || typeof command !== "string") {
2694
+ return {
2695
+ allowed: false,
2696
+ reason: "Invalid or empty command",
2697
+ command
2698
+ };
2699
+ }
2700
+ if (isComplexCommand(command)) {
2701
+ return {
2702
+ allowed: false,
2703
+ reason: "Complex shell commands with pipes, operators, or redirections are not supported for security reasons",
2704
+ command,
2705
+ isComplex: true
2706
+ };
2707
+ }
2708
+ const parsed = parseCommand(command);
2709
+ if (parsed.error) {
2710
+ return {
2711
+ allowed: false,
2712
+ reason: parsed.error,
2713
+ command
2714
+ };
2715
+ }
2716
+ if (!parsed.command) {
2717
+ return {
2718
+ allowed: false,
2719
+ reason: "No valid command found",
2720
+ command
2721
+ };
2722
+ }
2723
+ if (this.debug) {
2724
+ console.log(`[BashPermissions] Checking simple command: "${command}"`);
2725
+ console.log(`[BashPermissions] Parsed: ${parsed.command} with args: [${parsed.args.join(", ")}]`);
2726
+ }
2727
+ if (matchesAnyPattern(parsed, this.denyPatterns)) {
2728
+ const matchedPatterns = this.denyPatterns.filter((pattern) => matchesPattern(parsed, pattern));
2729
+ return {
2730
+ allowed: false,
2731
+ reason: `Command matches deny pattern: ${matchedPatterns[0]}`,
2732
+ command,
2733
+ parsed,
2734
+ matchedPatterns
2735
+ };
2736
+ }
2737
+ if (this.allowPatterns.length > 0) {
2738
+ if (!matchesAnyPattern(parsed, this.allowPatterns)) {
2739
+ return {
2740
+ allowed: false,
2741
+ reason: "Command not in allow list",
2742
+ command,
2743
+ parsed
2744
+ };
2745
+ }
2746
+ }
2747
+ const result = {
2748
+ allowed: true,
2749
+ command,
2750
+ parsed,
2751
+ isComplex: false
2752
+ };
2753
+ if (this.debug) {
2754
+ console.log(`[BashPermissions] ALLOWED - command passed all checks`);
2755
+ }
2756
+ return result;
2757
+ }
2758
+ /**
2759
+ * Get configuration summary
2760
+ * @returns {Object} Configuration info
2761
+ */
2762
+ getConfig() {
2763
+ return {
2764
+ allowPatterns: this.allowPatterns.length,
2765
+ denyPatterns: this.denyPatterns.length,
2766
+ totalPatterns: this.allowPatterns.length + this.denyPatterns.length
2767
+ };
2768
+ }
2769
+ };
2770
+ }
2771
+ });
2772
+
2773
+ // src/agent/bashExecutor.js
2774
+ async function executeBashCommand(command, options = {}) {
2775
+ const {
2776
+ workingDirectory = process.cwd(),
2777
+ timeout = 12e4,
2778
+ // 2 minutes default
2779
+ env = {},
2780
+ maxBuffer = 10 * 1024 * 1024,
2781
+ // 10MB
2782
+ debug = false
2783
+ } = options;
2784
+ let cwd = workingDirectory;
2785
+ try {
2786
+ cwd = (0, import_path4.resolve)(cwd);
2787
+ if (!(0, import_fs.existsSync)(cwd)) {
2788
+ throw new Error(`Working directory does not exist: ${cwd}`);
2789
+ }
2790
+ } catch (error2) {
2791
+ return {
2792
+ success: false,
2793
+ error: `Invalid working directory: ${error2.message}`,
2794
+ stdout: "",
2795
+ stderr: "",
2796
+ exitCode: 1,
2797
+ command,
2798
+ workingDirectory: cwd,
2799
+ duration: 0
2800
+ };
2801
+ }
2802
+ const startTime = Date.now();
2803
+ if (debug) {
2804
+ console.log(`[BashExecutor] Executing command: "${command}"`);
2805
+ console.log(`[BashExecutor] Working directory: "${cwd}"`);
2806
+ console.log(`[BashExecutor] Timeout: ${timeout}ms`);
2807
+ }
2808
+ return new Promise((resolve4, reject) => {
2809
+ const processEnv = {
2810
+ ...process.env,
2811
+ ...env
2812
+ };
2813
+ const args = parseCommandForExecution(command);
2814
+ if (!args || args.length === 0) {
2815
+ resolve4({
2816
+ success: false,
2817
+ error: "Failed to parse command",
2818
+ stdout: "",
2819
+ stderr: "",
2820
+ exitCode: 1,
2821
+ command,
2822
+ workingDirectory: cwd,
2823
+ duration: Date.now() - startTime
2824
+ });
2825
+ return;
2826
+ }
2827
+ const [cmd, ...cmdArgs] = args;
2828
+ const child = (0, import_child_process6.spawn)(cmd, cmdArgs, {
2829
+ cwd,
2830
+ env: processEnv,
2831
+ stdio: ["ignore", "pipe", "pipe"],
2832
+ // stdin ignored, capture stdout/stderr
2833
+ shell: false,
2834
+ // For security
2835
+ windowsHide: true
2836
+ });
2837
+ let stdout = "";
2838
+ let stderr = "";
2839
+ let killed = false;
2840
+ let timeoutHandle;
2841
+ if (timeout > 0) {
2842
+ timeoutHandle = setTimeout(() => {
2843
+ if (!killed) {
2844
+ killed = true;
2845
+ child.kill("SIGTERM");
2846
+ setTimeout(() => {
2847
+ if (child.exitCode === null) {
2848
+ child.kill("SIGKILL");
2849
+ }
2850
+ }, 5e3);
2851
+ }
2852
+ }, timeout);
2853
+ }
2854
+ child.stdout.on("data", (data2) => {
2855
+ const chunk = data2.toString();
2856
+ if (stdout.length + chunk.length <= maxBuffer) {
2857
+ stdout += chunk;
2858
+ } else {
2859
+ if (!killed) {
2860
+ killed = true;
2861
+ child.kill("SIGTERM");
2862
+ }
2863
+ }
2864
+ });
2865
+ child.stderr.on("data", (data2) => {
2866
+ const chunk = data2.toString();
2867
+ if (stderr.length + chunk.length <= maxBuffer) {
2868
+ stderr += chunk;
2869
+ } else {
2870
+ if (!killed) {
2871
+ killed = true;
2872
+ child.kill("SIGTERM");
2873
+ }
2874
+ }
2875
+ });
2876
+ child.on("close", (code, signal) => {
2877
+ if (timeoutHandle) {
2878
+ clearTimeout(timeoutHandle);
2879
+ }
2880
+ const duration = Date.now() - startTime;
2881
+ if (debug) {
2882
+ console.log(`[BashExecutor] Command completed - Code: ${code}, Signal: ${signal}, Duration: ${duration}ms`);
2883
+ console.log(`[BashExecutor] Stdout length: ${stdout.length}, Stderr length: ${stderr.length}`);
2884
+ }
2885
+ let success = true;
2886
+ let error2 = "";
2887
+ if (killed) {
2888
+ success = false;
2889
+ if (stdout.length + stderr.length > maxBuffer) {
2890
+ error2 = `Command output exceeded maximum buffer size (${maxBuffer} bytes)`;
2891
+ } else {
2892
+ error2 = `Command timed out after ${timeout}ms`;
2893
+ }
2894
+ } else if (code !== 0) {
2895
+ success = false;
2896
+ error2 = `Command exited with code ${code}`;
2897
+ }
2898
+ resolve4({
2899
+ success,
2900
+ error: error2,
2901
+ stdout: stdout.trim(),
2902
+ stderr: stderr.trim(),
2903
+ exitCode: code,
2904
+ signal,
2905
+ command,
2906
+ workingDirectory: cwd,
2907
+ duration,
2908
+ killed
2909
+ });
2910
+ });
2911
+ child.on("error", (error2) => {
2912
+ if (timeoutHandle) {
2913
+ clearTimeout(timeoutHandle);
2914
+ }
2915
+ if (debug) {
2916
+ console.log(`[BashExecutor] Spawn error:`, error2);
2917
+ }
2918
+ resolve4({
2919
+ success: false,
2920
+ error: `Failed to execute command: ${error2.message}`,
2921
+ stdout: "",
2922
+ stderr: "",
2923
+ exitCode: 1,
2924
+ command,
2925
+ workingDirectory: cwd,
2926
+ duration: Date.now() - startTime
2927
+ });
2928
+ });
2929
+ });
2930
+ }
2931
+ function formatExecutionResult(result, includeMetadata = false) {
2932
+ if (!result) {
2933
+ return "No result available";
2934
+ }
2935
+ let output = "";
2936
+ if (includeMetadata) {
2937
+ output += `Command: ${result.command}
2938
+ `;
2939
+ output += `Working directory: ${result.workingDirectory}
2940
+ `;
2941
+ output += `Duration: ${result.duration}ms
2942
+ `;
2943
+ output += `Exit Code: ${result.exitCode}
2944
+ `;
2945
+ if (result.signal) {
2946
+ output += `Signal: ${result.signal}
2947
+ `;
2948
+ }
2949
+ output += "\n";
2950
+ }
2951
+ if (result.stdout) {
2952
+ if (includeMetadata) {
2953
+ output += "--- STDOUT ---\n";
2954
+ }
2955
+ output += result.stdout;
2956
+ if (includeMetadata && result.stderr) {
2957
+ output += "\n";
2958
+ }
2959
+ }
2960
+ if (result.stderr) {
2961
+ if (includeMetadata) {
2962
+ if (result.stdout) output += "\n";
2963
+ output += "--- STDERR ---\n";
2964
+ } else if (result.stdout) {
2965
+ output += "\n--- STDERR ---\n";
2966
+ }
2967
+ output += result.stderr;
2968
+ }
2969
+ if (!result.success && result.error && !result.stderr) {
2970
+ if (output) output += "\n";
2971
+ output += `Error: ${result.error}`;
2972
+ }
2973
+ if (!result.success && result.exitCode !== void 0 && result.exitCode !== 0) {
2974
+ if (output) output += "\n";
2975
+ output += `Exit code: ${result.exitCode}`;
2976
+ }
2977
+ return output || (result.success ? "Command completed successfully (no output)" : "Command failed (no output)");
2978
+ }
2979
+ function validateExecutionOptions(options = {}) {
2980
+ const errors = [];
2981
+ const warnings = [];
2982
+ if (options.timeout !== void 0) {
2983
+ if (typeof options.timeout !== "number" || options.timeout < 0) {
2984
+ errors.push("timeout must be a non-negative number");
2985
+ } else if (options.timeout > 6e5) {
2986
+ warnings.push("timeout is very high (>10 minutes)");
2987
+ }
2988
+ }
2989
+ if (options.maxBuffer !== void 0) {
2990
+ if (typeof options.maxBuffer !== "number" || options.maxBuffer < 1024) {
2991
+ errors.push("maxBuffer must be at least 1024 bytes");
2992
+ } else if (options.maxBuffer > 100 * 1024 * 1024) {
2993
+ warnings.push("maxBuffer is very high (>100MB)");
2994
+ }
2995
+ }
2996
+ if (options.workingDirectory) {
2997
+ if (typeof options.workingDirectory !== "string") {
2998
+ errors.push("workingDirectory must be a string");
2999
+ } else if (!(0, import_fs.existsSync)(options.workingDirectory)) {
3000
+ errors.push(`workingDirectory does not exist: ${options.workingDirectory}`);
3001
+ }
3002
+ }
3003
+ if (options.env && typeof options.env !== "object") {
3004
+ errors.push("env must be an object");
3005
+ }
3006
+ return {
3007
+ valid: errors.length === 0,
3008
+ errors,
3009
+ warnings
3010
+ };
3011
+ }
3012
+ var import_child_process6, import_path4, import_fs;
3013
+ var init_bashExecutor = __esm({
3014
+ "src/agent/bashExecutor.js"() {
3015
+ "use strict";
3016
+ import_child_process6 = require("child_process");
3017
+ import_path4 = require("path");
3018
+ import_fs = require("fs");
3019
+ init_bashCommandUtils();
3020
+ }
3021
+ });
3022
+
3023
+ // src/tools/bash.js
3024
+ var import_ai2, import_path5, bashTool;
3025
+ var init_bash = __esm({
3026
+ "src/tools/bash.js"() {
3027
+ "use strict";
3028
+ import_ai2 = require("ai");
3029
+ import_path5 = require("path");
3030
+ init_bashPermissions();
3031
+ init_bashExecutor();
3032
+ bashTool = (options = {}) => {
3033
+ const {
3034
+ bashConfig = {},
3035
+ debug = false,
3036
+ defaultPath,
3037
+ allowedFolders = []
3038
+ } = options;
3039
+ const permissionChecker = new BashPermissionChecker({
3040
+ allow: bashConfig.allow,
3041
+ deny: bashConfig.deny,
3042
+ disableDefaultAllow: bashConfig.disableDefaultAllow,
3043
+ disableDefaultDeny: bashConfig.disableDefaultDeny,
3044
+ debug
3045
+ });
3046
+ const getDefaultWorkingDirectory = () => {
3047
+ if (bashConfig.workingDirectory) {
3048
+ return bashConfig.workingDirectory;
3049
+ }
3050
+ if (defaultPath) {
3051
+ return defaultPath;
3052
+ }
3053
+ if (allowedFolders && allowedFolders.length > 0) {
3054
+ return allowedFolders[0];
3055
+ }
3056
+ return process.cwd();
3057
+ };
3058
+ return (0, import_ai2.tool)({
3059
+ name: "bash",
3060
+ description: `Execute bash commands for system exploration and development tasks.
3061
+
3062
+ Security: This tool has built-in security with allow/deny lists. By default, only safe read-only commands are allowed for code exploration.
3063
+
3064
+ Parameters:
3065
+ - command: (required) The bash command to execute
3066
+ - workingDirectory: (optional) Directory to execute command in
3067
+ - timeout: (optional) Command timeout in milliseconds
3068
+ - env: (optional) Additional environment variables
3069
+
3070
+ Examples of allowed commands by default:
3071
+ - File exploration: ls, cat, head, tail, find, grep
3072
+ - Git operations: git status, git log, git diff, git show
3073
+ - Package info: npm list, pip list, cargo --version
3074
+ - System info: whoami, pwd, uname, date
3075
+
3076
+ Dangerous commands are blocked by default (rm -rf, sudo, npm install, etc.)`,
3077
+ inputSchema: {
3078
+ type: "object",
3079
+ properties: {
3080
+ command: {
3081
+ type: "string",
3082
+ description: "The bash command to execute"
3083
+ },
3084
+ workingDirectory: {
3085
+ type: "string",
3086
+ description: "Directory to execute the command in (optional)"
3087
+ },
3088
+ timeout: {
3089
+ type: "number",
3090
+ description: "Command timeout in milliseconds (optional)",
3091
+ minimum: 1e3,
3092
+ maximum: 6e5
3093
+ },
3094
+ env: {
3095
+ type: "object",
3096
+ description: "Additional environment variables (optional)",
3097
+ additionalProperties: {
3098
+ type: "string"
3099
+ }
3100
+ }
3101
+ },
3102
+ required: ["command"],
3103
+ additionalProperties: false
3104
+ },
3105
+ execute: async ({ command, workingDirectory, timeout, env }) => {
3106
+ try {
3107
+ if (command === null || command === void 0 || typeof command !== "string") {
3108
+ return "Error: Command is required and must be a string";
3109
+ }
3110
+ if (command.trim().length === 0) {
3111
+ return "Error: Command cannot be empty";
3112
+ }
3113
+ const permissionResult = permissionChecker.check(command.trim());
3114
+ if (!permissionResult.allowed) {
3115
+ if (debug) {
3116
+ console.log(`[BashTool] Permission denied for command: "${command}"`);
3117
+ console.log(`[BashTool] Reason: ${permissionResult.reason}`);
3118
+ }
3119
+ return `Permission denied: ${permissionResult.reason}
3120
+
3121
+ This command is not allowed by the current security policy.
3122
+
3123
+ Common reasons:
3124
+ 1. The command is in the deny list (potentially dangerous)
3125
+ 2. The command is not in the allow list (not a recognized safe command)
3126
+
3127
+ If you believe this command should be allowed, you can:
3128
+ - Use the --bash-allow option to add specific patterns
3129
+ - Use the --no-default-bash-deny flag to remove default restrictions (not recommended)
3130
+
3131
+ For code exploration, try these safe alternatives:
3132
+ - ls, cat, head, tail for file operations
3133
+ - find, grep, rg for searching
3134
+ - git status, git log, git show for git operations
3135
+ - npm list, pip list for package information`;
3136
+ }
3137
+ const workingDir = workingDirectory || getDefaultWorkingDirectory();
3138
+ if (allowedFolders && allowedFolders.length > 0) {
3139
+ const resolvedWorkingDir = (0, import_path5.resolve)(workingDir);
3140
+ const isAllowed = allowedFolders.some((folder) => {
3141
+ const resolvedFolder = (0, import_path5.resolve)(folder);
3142
+ return resolvedWorkingDir.startsWith(resolvedFolder);
3143
+ });
3144
+ if (!isAllowed) {
3145
+ return `Error: Working directory "${workingDir}" is not within allowed folders: ${allowedFolders.join(", ")}`;
3146
+ }
3147
+ }
3148
+ const executionOptions = {
3149
+ workingDirectory: workingDir,
3150
+ timeout: timeout || bashConfig.timeout || 12e4,
3151
+ env: { ...bashConfig.env, ...env },
3152
+ maxBuffer: bashConfig.maxBuffer,
3153
+ debug
3154
+ };
3155
+ const validation = validateExecutionOptions(executionOptions);
3156
+ if (!validation.valid) {
3157
+ return `Error: Invalid execution options: ${validation.errors.join(", ")}`;
3158
+ }
3159
+ if (validation.warnings.length > 0 && debug) {
3160
+ console.log("[BashTool] Warnings:", validation.warnings);
3161
+ }
3162
+ if (debug) {
3163
+ console.log(`[BashTool] Executing command: "${command}"`);
3164
+ console.log(`[BashTool] Working directory: "${workingDir}"`);
3165
+ console.log(`[BashTool] Timeout: ${executionOptions.timeout}ms`);
3166
+ }
3167
+ const result = await executeBashCommand(command.trim(), executionOptions);
3168
+ if (debug) {
3169
+ console.log(`[BashTool] Command completed - Success: ${result.success}, Duration: ${result.duration}ms`);
3170
+ }
3171
+ const formattedResult = formatExecutionResult(result, debug);
3172
+ if (!result.success) {
3173
+ let errorInfo = `
3174
+
3175
+ Command failed with exit code ${result.exitCode}`;
3176
+ if (result.killed) {
3177
+ errorInfo += ` (${result.error})`;
3178
+ }
3179
+ return formattedResult + errorInfo;
3180
+ }
3181
+ return formattedResult;
3182
+ } catch (error2) {
3183
+ if (debug) {
3184
+ console.error("[BashTool] Execution error:", error2);
3185
+ }
3186
+ return `Error executing bash command: ${error2.message}`;
3187
+ }
3188
+ }
3189
+ });
3190
+ };
3191
+ }
3192
+ });
3193
+
1890
3194
  // src/tools/langchain.js
1891
3195
  function createSearchTool() {
1892
3196
  return {
@@ -2104,6 +3408,10 @@ __export(tools_exports, {
2104
3408
  DEFAULT_SYSTEM_MESSAGE: () => DEFAULT_SYSTEM_MESSAGE,
2105
3409
  attemptCompletionSchema: () => attemptCompletionSchema,
2106
3410
  attemptCompletionToolDefinition: () => attemptCompletionToolDefinition,
3411
+ bashDescription: () => bashDescription,
3412
+ bashSchema: () => bashSchema,
3413
+ bashTool: () => bashTool,
3414
+ bashToolDefinition: () => bashToolDefinition,
2107
3415
  createExtractTool: () => createExtractTool,
2108
3416
  createQueryTool: () => createQueryTool,
2109
3417
  createSearchTool: () => createSearchTool,
@@ -2124,16 +3432,19 @@ var init_tools = __esm({
2124
3432
  "src/tools/index.js"() {
2125
3433
  "use strict";
2126
3434
  init_vercel();
3435
+ init_bash();
2127
3436
  init_langchain();
2128
3437
  init_common();
2129
3438
  init_system_message();
2130
3439
  init_vercel();
3440
+ init_bash();
2131
3441
  init_system_message();
2132
3442
  tools = {
2133
3443
  searchTool: searchTool(),
2134
3444
  queryTool: queryTool(),
2135
3445
  extractTool: extractTool(),
2136
3446
  delegateTool: delegateTool(),
3447
+ bashTool: bashTool(),
2137
3448
  DEFAULT_SYSTEM_MESSAGE
2138
3449
  };
2139
3450
  }
@@ -2146,10 +3457,10 @@ async function listFilesByLevel(options) {
2146
3457
  maxFiles = 100,
2147
3458
  respectGitignore = true
2148
3459
  } = options;
2149
- if (!import_fs.default.existsSync(directory)) {
3460
+ if (!import_fs2.default.existsSync(directory)) {
2150
3461
  throw new Error(`Directory does not exist: ${directory}`);
2151
3462
  }
2152
- const gitDirExists = import_fs.default.existsSync(import_path4.default.join(directory, ".git"));
3463
+ const gitDirExists = import_fs2.default.existsSync(import_path6.default.join(directory, ".git"));
2153
3464
  if (gitDirExists && respectGitignore) {
2154
3465
  try {
2155
3466
  return await listFilesUsingGit(directory, maxFiles);
@@ -2164,8 +3475,8 @@ async function listFilesUsingGit(directory, maxFiles) {
2164
3475
  const { stdout } = await execAsync4("git ls-files", { cwd: directory });
2165
3476
  const files = stdout.split("\n").filter(Boolean);
2166
3477
  const sortedFiles = files.sort((a3, b3) => {
2167
- const depthA = a3.split(import_path4.default.sep).length;
2168
- const depthB = b3.split(import_path4.default.sep).length;
3478
+ const depthA = a3.split(import_path6.default.sep).length;
3479
+ const depthB = b3.split(import_path6.default.sep).length;
2169
3480
  return depthA - depthB;
2170
3481
  });
2171
3482
  return sortedFiles.slice(0, maxFiles);
@@ -2180,19 +3491,19 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
2180
3491
  while (queue.length > 0 && result.length < maxFiles) {
2181
3492
  const { dir, level } = queue.shift();
2182
3493
  try {
2183
- const entries = import_fs.default.readdirSync(dir, { withFileTypes: true });
3494
+ const entries = import_fs2.default.readdirSync(dir, { withFileTypes: true });
2184
3495
  const files = entries.filter((entry) => entry.isFile());
2185
3496
  for (const file of files) {
2186
3497
  if (result.length >= maxFiles) break;
2187
- const filePath = import_path4.default.join(dir, file.name);
2188
- const relativePath = import_path4.default.relative(directory, filePath);
3498
+ const filePath = import_path6.default.join(dir, file.name);
3499
+ const relativePath = import_path6.default.relative(directory, filePath);
2189
3500
  if (shouldIgnore(relativePath, ignorePatterns)) continue;
2190
3501
  result.push(relativePath);
2191
3502
  }
2192
3503
  const dirs = entries.filter((entry) => entry.isDirectory());
2193
3504
  for (const subdir of dirs) {
2194
- const subdirPath = import_path4.default.join(dir, subdir.name);
2195
- const relativeSubdirPath = import_path4.default.relative(directory, subdirPath);
3505
+ const subdirPath = import_path6.default.join(dir, subdir.name);
3506
+ const relativeSubdirPath = import_path6.default.relative(directory, subdirPath);
2196
3507
  if (shouldIgnore(relativeSubdirPath, ignorePatterns)) continue;
2197
3508
  if (subdir.name === "node_modules" || subdir.name === ".git") continue;
2198
3509
  queue.push({ dir: subdirPath, level: level + 1 });
@@ -2204,12 +3515,12 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
2204
3515
  return result;
2205
3516
  }
2206
3517
  function loadGitignorePatterns(directory) {
2207
- const gitignorePath = import_path4.default.join(directory, ".gitignore");
2208
- if (!import_fs.default.existsSync(gitignorePath)) {
3518
+ const gitignorePath = import_path6.default.join(directory, ".gitignore");
3519
+ if (!import_fs2.default.existsSync(gitignorePath)) {
2209
3520
  return [];
2210
3521
  }
2211
3522
  try {
2212
- const content = import_fs.default.readFileSync(gitignorePath, "utf8");
3523
+ const content = import_fs2.default.readFileSync(gitignorePath, "utf8");
2213
3524
  return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
2214
3525
  } catch (error2) {
2215
3526
  console.error(`Warning: Could not read .gitignore: ${error2.message}`);
@@ -2227,15 +3538,15 @@ function shouldIgnore(filePath, ignorePatterns) {
2227
3538
  }
2228
3539
  return false;
2229
3540
  }
2230
- var import_fs, import_path4, import_util5, import_child_process6, execAsync4;
3541
+ var import_fs2, import_path6, import_util5, import_child_process7, execAsync4;
2231
3542
  var init_file_lister = __esm({
2232
3543
  "src/utils/file-lister.js"() {
2233
3544
  "use strict";
2234
- import_fs = __toESM(require("fs"), 1);
2235
- import_path4 = __toESM(require("path"), 1);
3545
+ import_fs2 = __toESM(require("fs"), 1);
3546
+ import_path6 = __toESM(require("path"), 1);
2236
3547
  import_util5 = require("util");
2237
- import_child_process6 = require("child_process");
2238
- execAsync4 = (0, import_util5.promisify)(import_child_process6.exec);
3548
+ import_child_process7 = require("child_process");
3549
+ execAsync4 = (0, import_util5.promisify)(import_child_process7.exec);
2239
3550
  }
2240
3551
  });
2241
3552
 
@@ -4390,7 +5701,7 @@ var require_headStream = __commonJS({
4390
5701
  if ((0, stream_type_check_1.isReadableStream)(stream)) {
4391
5702
  return (0, headStream_browser_1.headStream)(stream, bytes);
4392
5703
  }
4393
- return new Promise((resolve2, reject) => {
5704
+ return new Promise((resolve4, reject) => {
4394
5705
  const collector = new Collector();
4395
5706
  collector.limit = bytes;
4396
5707
  stream.pipe(collector);
@@ -4401,7 +5712,7 @@ var require_headStream = __commonJS({
4401
5712
  collector.on("error", reject);
4402
5713
  collector.on("finish", function() {
4403
5714
  const bytes2 = new Uint8Array(Buffer.concat(this.buffers));
4404
- resolve2(bytes2);
5715
+ resolve4(bytes2);
4405
5716
  });
4406
5717
  });
4407
5718
  };
@@ -4659,21 +5970,21 @@ var require_dist_cjs15 = __commonJS({
4659
5970
  let sendBody = true;
4660
5971
  if (expect === "100-continue") {
4661
5972
  sendBody = await Promise.race([
4662
- new Promise((resolve2) => {
4663
- timeoutId = Number(timing.setTimeout(() => resolve2(true), Math.max(MIN_WAIT_TIME, maxContinueTimeoutMs)));
5973
+ new Promise((resolve4) => {
5974
+ timeoutId = Number(timing.setTimeout(() => resolve4(true), Math.max(MIN_WAIT_TIME, maxContinueTimeoutMs)));
4664
5975
  }),
4665
- new Promise((resolve2) => {
5976
+ new Promise((resolve4) => {
4666
5977
  httpRequest.on("continue", () => {
4667
5978
  timing.clearTimeout(timeoutId);
4668
- resolve2(true);
5979
+ resolve4(true);
4669
5980
  });
4670
5981
  httpRequest.on("response", () => {
4671
5982
  timing.clearTimeout(timeoutId);
4672
- resolve2(false);
5983
+ resolve4(false);
4673
5984
  });
4674
5985
  httpRequest.on("error", () => {
4675
5986
  timing.clearTimeout(timeoutId);
4676
- resolve2(false);
5987
+ resolve4(false);
4677
5988
  });
4678
5989
  })
4679
5990
  ]);
@@ -4709,13 +6020,13 @@ var require_dist_cjs15 = __commonJS({
4709
6020
  constructor(options) {
4710
6021
  this.socketWarningTimestamp = 0;
4711
6022
  this.metadata = { handlerProtocol: "http/1.1" };
4712
- this.configProvider = new Promise((resolve2, reject) => {
6023
+ this.configProvider = new Promise((resolve4, reject) => {
4713
6024
  if (typeof options === "function") {
4714
6025
  options().then((_options) => {
4715
- resolve2(this.resolveDefaultConfig(_options));
6026
+ resolve4(this.resolveDefaultConfig(_options));
4716
6027
  }).catch(reject);
4717
6028
  } else {
4718
- resolve2(this.resolveDefaultConfig(options));
6029
+ resolve4(this.resolveDefaultConfig(options));
4719
6030
  }
4720
6031
  });
4721
6032
  }
@@ -4799,7 +6110,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
4799
6110
  return new Promise((_resolve, _reject) => {
4800
6111
  let writeRequestBodyPromise = void 0;
4801
6112
  const timeouts = [];
4802
- const resolve2 = /* @__PURE__ */ __name(async (arg) => {
6113
+ const resolve4 = /* @__PURE__ */ __name(async (arg) => {
4803
6114
  await writeRequestBodyPromise;
4804
6115
  timeouts.forEach(timing.clearTimeout);
4805
6116
  _resolve(arg);
@@ -4869,7 +6180,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
4869
6180
  headers: getTransformedHeaders(res.headers),
4870
6181
  body: res
4871
6182
  });
4872
- resolve2({ response: httpResponse });
6183
+ resolve4({ response: httpResponse });
4873
6184
  });
4874
6185
  req.on("error", (err) => {
4875
6186
  if (NODEJS_TIMEOUT_ERROR_CODES.includes(err.code)) {
@@ -5058,13 +6369,13 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
5058
6369
  constructor(options) {
5059
6370
  this.metadata = { handlerProtocol: "h2" };
5060
6371
  this.connectionManager = new NodeHttp2ConnectionManager({});
5061
- this.configProvider = new Promise((resolve2, reject) => {
6372
+ this.configProvider = new Promise((resolve4, reject) => {
5062
6373
  if (typeof options === "function") {
5063
6374
  options().then((opts) => {
5064
- resolve2(opts || {});
6375
+ resolve4(opts || {});
5065
6376
  }).catch(reject);
5066
6377
  } else {
5067
- resolve2(options || {});
6378
+ resolve4(options || {});
5068
6379
  }
5069
6380
  });
5070
6381
  }
@@ -5097,7 +6408,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
5097
6408
  return new Promise((_resolve, _reject) => {
5098
6409
  let fulfilled = false;
5099
6410
  let writeRequestBodyPromise = void 0;
5100
- const resolve2 = /* @__PURE__ */ __name(async (arg) => {
6411
+ const resolve4 = /* @__PURE__ */ __name(async (arg) => {
5101
6412
  await writeRequestBodyPromise;
5102
6413
  _resolve(arg);
5103
6414
  }, "resolve");
@@ -5153,7 +6464,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
5153
6464
  body: req
5154
6465
  });
5155
6466
  fulfilled = true;
5156
- resolve2({ response: httpResponse });
6467
+ resolve4({ response: httpResponse });
5157
6468
  if (disableConcurrentStreams) {
5158
6469
  session.close();
5159
6470
  this.connectionManager.deleteSession(authority, session);
@@ -5242,7 +6553,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
5242
6553
  if (isReadableStreamInstance(stream)) {
5243
6554
  return collectReadableStream(stream);
5244
6555
  }
5245
- return new Promise((resolve2, reject) => {
6556
+ return new Promise((resolve4, reject) => {
5246
6557
  const collector = new Collector();
5247
6558
  stream.pipe(collector);
5248
6559
  stream.on("error", (err) => {
@@ -5252,7 +6563,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
5252
6563
  collector.on("error", reject);
5253
6564
  collector.on("finish", function() {
5254
6565
  const bytes = new Uint8Array(Buffer.concat(this.bufferedBytes));
5255
- resolve2(bytes);
6566
+ resolve4(bytes);
5256
6567
  });
5257
6568
  });
5258
6569
  }, "streamCollector");
@@ -5317,7 +6628,7 @@ var require_dist_cjs16 = __commonJS({
5317
6628
  }
5318
6629
  __name(createRequest, "createRequest");
5319
6630
  function requestTimeout(timeoutInMs = 0) {
5320
- return new Promise((resolve2, reject) => {
6631
+ return new Promise((resolve4, reject) => {
5321
6632
  if (timeoutInMs) {
5322
6633
  setTimeout(() => {
5323
6634
  const timeoutError = new Error(`Request did not complete within ${timeoutInMs} ms`);
@@ -5444,7 +6755,7 @@ var require_dist_cjs16 = __commonJS({
5444
6755
  ];
5445
6756
  if (abortSignal) {
5446
6757
  raceOfPromises.push(
5447
- new Promise((resolve2, reject) => {
6758
+ new Promise((resolve4, reject) => {
5448
6759
  const onAbort = /* @__PURE__ */ __name(() => {
5449
6760
  const abortError = new Error("Request aborted");
5450
6761
  abortError.name = "AbortError";
@@ -5512,7 +6823,7 @@ var require_dist_cjs16 = __commonJS({
5512
6823
  }
5513
6824
  __name(collectStream, "collectStream");
5514
6825
  function readToBase64(blob) {
5515
- return new Promise((resolve2, reject) => {
6826
+ return new Promise((resolve4, reject) => {
5516
6827
  const reader = new FileReader();
5517
6828
  reader.onloadend = () => {
5518
6829
  if (reader.readyState !== 2) {
@@ -5521,7 +6832,7 @@ var require_dist_cjs16 = __commonJS({
5521
6832
  const result = reader.result ?? "";
5522
6833
  const commaIndex = result.indexOf(",");
5523
6834
  const dataOffset = commaIndex > -1 ? commaIndex + 1 : result.length;
5524
- resolve2(result.substring(dataOffset));
6835
+ resolve4(result.substring(dataOffset));
5525
6836
  };
5526
6837
  reader.onabort = () => reject(new Error("Read aborted"));
5527
6838
  reader.onerror = () => reject(reader.error);
@@ -6008,9 +7319,10 @@ var TypeRegistry;
6008
7319
  var init_TypeRegistry = __esm({
6009
7320
  "node_modules/@smithy/core/dist-es/submodules/schema/TypeRegistry.js"() {
6010
7321
  TypeRegistry = class _TypeRegistry {
6011
- constructor(namespace, schemas = /* @__PURE__ */ new Map()) {
7322
+ constructor(namespace, schemas = /* @__PURE__ */ new Map(), exceptions = /* @__PURE__ */ new Map()) {
6012
7323
  this.namespace = namespace;
6013
7324
  this.schemas = schemas;
7325
+ this.exceptions = exceptions;
6014
7326
  }
6015
7327
  static for(namespace) {
6016
7328
  if (!_TypeRegistry.registries.has(namespace)) {
@@ -6020,8 +7332,7 @@ var init_TypeRegistry = __esm({
6020
7332
  }
6021
7333
  register(shapeId, schema) {
6022
7334
  const qualifiedName = this.normalizeShapeId(shapeId);
6023
- const registry = _TypeRegistry.for(this.getNamespace(shapeId));
6024
- registry.schemas.set(qualifiedName, schema);
7335
+ this.schemas.set(qualifiedName, schema);
6025
7336
  }
6026
7337
  getSchema(shapeId) {
6027
7338
  const id = this.normalizeShapeId(shapeId);
@@ -6030,6 +7341,12 @@ var init_TypeRegistry = __esm({
6030
7341
  }
6031
7342
  return this.schemas.get(id);
6032
7343
  }
7344
+ registerError(errorSchema, ctor) {
7345
+ this.exceptions.set(errorSchema, ctor);
7346
+ }
7347
+ getErrorCtor(errorSchema) {
7348
+ return this.exceptions.get(errorSchema);
7349
+ }
6033
7350
  getBaseException() {
6034
7351
  for (const [id, schema] of this.schemas.entries()) {
6035
7352
  if (id.startsWith("smithy.ts.sdk.synthetic.") && id.endsWith("ServiceException")) {
@@ -6041,9 +7358,9 @@ var init_TypeRegistry = __esm({
6041
7358
  find(predicate) {
6042
7359
  return [...this.schemas.values()].find(predicate);
6043
7360
  }
6044
- destroy() {
6045
- _TypeRegistry.registries.delete(this.namespace);
7361
+ clear() {
6046
7362
  this.schemas.clear();
7363
+ this.exceptions.clear();
6047
7364
  }
6048
7365
  normalizeShapeId(shapeId) {
6049
7366
  if (shapeId.includes("#")) {
@@ -6191,7 +7508,7 @@ var init_ErrorSchema = __esm({
6191
7508
  traits,
6192
7509
  memberNames,
6193
7510
  memberList,
6194
- ctor
7511
+ ctor: null
6195
7512
  });
6196
7513
  }
6197
7514
  });
@@ -7160,11 +8477,11 @@ function __metadata(metadataKey, metadataValue) {
7160
8477
  }
7161
8478
  function __awaiter(thisArg, _arguments, P, generator) {
7162
8479
  function adopt(value) {
7163
- return value instanceof P ? value : new P(function(resolve2) {
7164
- resolve2(value);
8480
+ return value instanceof P ? value : new P(function(resolve4) {
8481
+ resolve4(value);
7165
8482
  });
7166
8483
  }
7167
- return new (P || (P = Promise))(function(resolve2, reject) {
8484
+ return new (P || (P = Promise))(function(resolve4, reject) {
7168
8485
  function fulfilled(value) {
7169
8486
  try {
7170
8487
  step(generator.next(value));
@@ -7180,7 +8497,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
7180
8497
  }
7181
8498
  }
7182
8499
  function step(result) {
7183
- result.done ? resolve2(result.value) : adopt(result.value).then(fulfilled, rejected);
8500
+ result.done ? resolve4(result.value) : adopt(result.value).then(fulfilled, rejected);
7184
8501
  }
7185
8502
  step((generator = generator.apply(thisArg, _arguments || [])).next());
7186
8503
  });
@@ -7371,14 +8688,14 @@ function __asyncValues(o3) {
7371
8688
  }, i3);
7372
8689
  function verb(n3) {
7373
8690
  i3[n3] = o3[n3] && function(v3) {
7374
- return new Promise(function(resolve2, reject) {
7375
- v3 = o3[n3](v3), settle(resolve2, reject, v3.done, v3.value);
8691
+ return new Promise(function(resolve4, reject) {
8692
+ v3 = o3[n3](v3), settle(resolve4, reject, v3.done, v3.value);
7376
8693
  });
7377
8694
  };
7378
8695
  }
7379
- function settle(resolve2, reject, d3, v3) {
8696
+ function settle(resolve4, reject, d3, v3) {
7380
8697
  Promise.resolve(v3).then(function(v4) {
7381
- resolve2({ value: v4, done: d3 });
8698
+ resolve4({ value: v4, done: d3 });
7382
8699
  }, reject);
7383
8700
  }
7384
8701
  }
@@ -12349,16 +13666,18 @@ var init_SmithyRpcV2CborProtocol = __esm({
12349
13666
  if (dataObject.Message) {
12350
13667
  dataObject.message = dataObject.Message;
12351
13668
  }
12352
- const baseExceptionSchema = TypeRegistry.for("smithy.ts.sdk.synthetic." + namespace).getBaseException();
13669
+ const synthetic = TypeRegistry.for("smithy.ts.sdk.synthetic." + namespace);
13670
+ const baseExceptionSchema = synthetic.getBaseException();
12353
13671
  if (baseExceptionSchema) {
12354
- const ErrorCtor = baseExceptionSchema.ctor;
12355
- throw Object.assign(new ErrorCtor({ name: errorName }), errorMetadata, dataObject);
13672
+ const ErrorCtor2 = synthetic.getErrorCtor(baseExceptionSchema);
13673
+ throw Object.assign(new ErrorCtor2({ name: errorName }), errorMetadata, dataObject);
12356
13674
  }
12357
13675
  throw Object.assign(new Error(errorName), errorMetadata, dataObject);
12358
13676
  }
12359
13677
  const ns = NormalizedSchema.of(errorSchema);
13678
+ const ErrorCtor = registry.getErrorCtor(errorSchema);
12360
13679
  const message = dataObject.message ?? dataObject.Message ?? "Unknown";
12361
- const exception = new errorSchema.ctor(message);
13680
+ const exception = new ErrorCtor(message);
12362
13681
  const output = {};
12363
13682
  for (const [name14, member] of ns.structIterator()) {
12364
13683
  output[name14] = this.deserializer.readValue(member, dataObject[name14]);
@@ -18024,7 +19343,7 @@ var require_dist_cjs37 = __commonJS({
18024
19343
  );
18025
19344
  }
18026
19345
  waitForReady(socket, connectionTimeout) {
18027
- return new Promise((resolve2, reject) => {
19346
+ return new Promise((resolve4, reject) => {
18028
19347
  const timeout = setTimeout(() => {
18029
19348
  this.removeNotUsableSockets(socket.url);
18030
19349
  reject({
@@ -18035,7 +19354,7 @@ var require_dist_cjs37 = __commonJS({
18035
19354
  }, connectionTimeout);
18036
19355
  socket.onopen = () => {
18037
19356
  clearTimeout(timeout);
18038
- resolve2();
19357
+ resolve4();
18039
19358
  };
18040
19359
  });
18041
19360
  }
@@ -18044,10 +19363,10 @@ var require_dist_cjs37 = __commonJS({
18044
19363
  let socketErrorOccurred = false;
18045
19364
  let reject = /* @__PURE__ */ __name(() => {
18046
19365
  }, "reject");
18047
- let resolve2 = /* @__PURE__ */ __name(() => {
19366
+ let resolve4 = /* @__PURE__ */ __name(() => {
18048
19367
  }, "resolve");
18049
19368
  socket.onmessage = (event) => {
18050
- resolve2({
19369
+ resolve4({
18051
19370
  done: false,
18052
19371
  value: new Uint8Array(event.data)
18053
19372
  });
@@ -18063,7 +19382,7 @@ var require_dist_cjs37 = __commonJS({
18063
19382
  if (streamError) {
18064
19383
  reject(streamError);
18065
19384
  } else {
18066
- resolve2({
19385
+ resolve4({
18067
19386
  done: true,
18068
19387
  value: void 0
18069
19388
  // unchecked because done=true.
@@ -18074,7 +19393,7 @@ var require_dist_cjs37 = __commonJS({
18074
19393
  [Symbol.asyncIterator]: () => ({
18075
19394
  next: /* @__PURE__ */ __name(() => {
18076
19395
  return new Promise((_resolve, _reject) => {
18077
- resolve2 = _resolve;
19396
+ resolve4 = _resolve;
18078
19397
  reject = _reject;
18079
19398
  });
18080
19399
  }, "next")
@@ -18597,13 +19916,13 @@ var require_dist_cjs42 = __commonJS({
18597
19916
  ...data2.default && { default: data2.default }
18598
19917
  }
18599
19918
  ), "getConfigData");
18600
- var import_path9 = require("path");
19919
+ var import_path11 = require("path");
18601
19920
  var import_getHomeDir = require_getHomeDir();
18602
19921
  var ENV_CONFIG_PATH = "AWS_CONFIG_FILE";
18603
- var getConfigFilepath = /* @__PURE__ */ __name(() => process.env[ENV_CONFIG_PATH] || (0, import_path9.join)((0, import_getHomeDir.getHomeDir)(), ".aws", "config"), "getConfigFilepath");
19922
+ var getConfigFilepath = /* @__PURE__ */ __name(() => process.env[ENV_CONFIG_PATH] || (0, import_path11.join)((0, import_getHomeDir.getHomeDir)(), ".aws", "config"), "getConfigFilepath");
18604
19923
  var import_getHomeDir2 = require_getHomeDir();
18605
19924
  var ENV_CREDENTIALS_PATH = "AWS_SHARED_CREDENTIALS_FILE";
18606
- var getCredentialsFilepath = /* @__PURE__ */ __name(() => process.env[ENV_CREDENTIALS_PATH] || (0, import_path9.join)((0, import_getHomeDir2.getHomeDir)(), ".aws", "credentials"), "getCredentialsFilepath");
19925
+ var getCredentialsFilepath = /* @__PURE__ */ __name(() => process.env[ENV_CREDENTIALS_PATH] || (0, import_path11.join)((0, import_getHomeDir2.getHomeDir)(), ".aws", "credentials"), "getCredentialsFilepath");
18607
19926
  var import_getHomeDir3 = require_getHomeDir();
18608
19927
  var prefixKeyRegex = /^([\w-]+)\s(["'])?([\w-@\+\.%:/]+)\2$/;
18609
19928
  var profileNameBlockList = ["__proto__", "profile __proto__"];
@@ -18661,11 +19980,11 @@ var require_dist_cjs42 = __commonJS({
18661
19980
  const relativeHomeDirPrefix = "~/";
18662
19981
  let resolvedFilepath = filepath;
18663
19982
  if (filepath.startsWith(relativeHomeDirPrefix)) {
18664
- resolvedFilepath = (0, import_path9.join)(homeDir, filepath.slice(2));
19983
+ resolvedFilepath = (0, import_path11.join)(homeDir, filepath.slice(2));
18665
19984
  }
18666
19985
  let resolvedConfigFilepath = configFilepath;
18667
19986
  if (configFilepath.startsWith(relativeHomeDirPrefix)) {
18668
- resolvedConfigFilepath = (0, import_path9.join)(homeDir, configFilepath.slice(2));
19987
+ resolvedConfigFilepath = (0, import_path11.join)(homeDir, configFilepath.slice(2));
18669
19988
  }
18670
19989
  const parsedFiles = await Promise.all([
18671
19990
  (0, import_slurpFile.slurpFile)(resolvedConfigFilepath, {
@@ -19320,7 +20639,7 @@ var require_dist_cjs46 = __commonJS({
19320
20639
  this.refillTokenBucket();
19321
20640
  if (amount > this.currentCapacity) {
19322
20641
  const delay = (amount - this.currentCapacity) / this.fillRate * 1e3;
19323
- await new Promise((resolve2) => _DefaultRateLimiter.setTimeoutFn(resolve2, delay));
20642
+ await new Promise((resolve4) => _DefaultRateLimiter.setTimeoutFn(resolve4, delay));
19324
20643
  }
19325
20644
  this.currentCapacity = this.currentCapacity - amount;
19326
20645
  }
@@ -19711,7 +21030,7 @@ var require_dist_cjs47 = __commonJS({
19711
21030
  const delayFromResponse = getDelayFromRetryAfterHeader(err.$response);
19712
21031
  const delay = Math.max(delayFromResponse || 0, delayFromDecider);
19713
21032
  totalDelay += delay;
19714
- await new Promise((resolve2) => setTimeout(resolve2, delay));
21033
+ await new Promise((resolve4) => setTimeout(resolve4, delay));
19715
21034
  continue;
19716
21035
  }
19717
21036
  if (!err.$metadata) {
@@ -19871,7 +21190,7 @@ var require_dist_cjs47 = __commonJS({
19871
21190
  attempts = retryToken.getRetryCount();
19872
21191
  const delay = retryToken.getRetryDelay();
19873
21192
  totalRetryDelay += delay;
19874
- await new Promise((resolve2) => setTimeout(resolve2, delay));
21193
+ await new Promise((resolve4) => setTimeout(resolve4, delay));
19875
21194
  }
19876
21195
  }
19877
21196
  } else {
@@ -20214,7 +21533,7 @@ var require_dist_cjs49 = __commonJS({
20214
21533
  var import_buffer = require("buffer");
20215
21534
  var import_http = require("http");
20216
21535
  function httpRequest(options) {
20217
- return new Promise((resolve2, reject) => {
21536
+ return new Promise((resolve4, reject) => {
20218
21537
  const req = (0, import_http.request)({
20219
21538
  method: "GET",
20220
21539
  ...options,
@@ -20243,7 +21562,7 @@ var require_dist_cjs49 = __commonJS({
20243
21562
  chunks.push(chunk);
20244
21563
  });
20245
21564
  res.on("end", () => {
20246
- resolve2(import_buffer.Buffer.concat(chunks));
21565
+ resolve4(import_buffer.Buffer.concat(chunks));
20247
21566
  req.destroy();
20248
21567
  });
20249
21568
  });
@@ -20678,7 +21997,7 @@ var require_retry_wrapper = __commonJS({
20678
21997
  try {
20679
21998
  return await toRetry();
20680
21999
  } catch (e3) {
20681
- await new Promise((resolve2) => setTimeout(resolve2, delayMs));
22000
+ await new Promise((resolve4) => setTimeout(resolve4, delayMs));
20682
22001
  }
20683
22002
  }
20684
22003
  return await toRetry();
@@ -21122,7 +22441,7 @@ var require_dist_cjs53 = __commonJS({
21122
22441
  calculateBodyLength: () => calculateBodyLength3
21123
22442
  });
21124
22443
  module2.exports = __toCommonJS2(index_exports2);
21125
- var import_fs7 = require("fs");
22444
+ var import_fs8 = require("fs");
21126
22445
  var calculateBodyLength3 = /* @__PURE__ */ __name((body) => {
21127
22446
  if (!body) {
21128
22447
  return 0;
@@ -21136,9 +22455,9 @@ var require_dist_cjs53 = __commonJS({
21136
22455
  } else if (typeof body.start === "number" && typeof body.end === "number") {
21137
22456
  return body.end + 1 - body.start;
21138
22457
  } else if (typeof body.path === "string" || Buffer.isBuffer(body.path)) {
21139
- return (0, import_fs7.lstatSync)(body.path).size;
22458
+ return (0, import_fs8.lstatSync)(body.path).size;
21140
22459
  } else if (typeof body.fd === "number") {
21141
- return (0, import_fs7.fstatSync)(body.fd).size;
22460
+ return (0, import_fs8.fstatSync)(body.fd).size;
21142
22461
  }
21143
22462
  throw new Error(`Body Length computation failed for ${body}`);
21144
22463
  }, "calculateBodyLength");
@@ -23176,8 +24495,8 @@ var require_dist_cjs57 = __commonJS({
23176
24495
  }
23177
24496
  }, "validateTokenKey");
23178
24497
  var import_shared_ini_file_loader = require_dist_cjs42();
23179
- var import_fs7 = require("fs");
23180
- var { writeFile } = import_fs7.promises;
24498
+ var import_fs8 = require("fs");
24499
+ var { writeFile } = import_fs8.promises;
23181
24500
  var writeSSOTokenToFile = /* @__PURE__ */ __name((id, ssoToken) => {
23182
24501
  const tokenFilepath = (0, import_shared_ini_file_loader.getSSOTokenFilepath)(id);
23183
24502
  const tokenString = JSON.stringify(ssoToken, null, 2);
@@ -24819,7 +26138,7 @@ var require_dist_cjs59 = __commonJS({
24819
26138
  module2.exports = __toCommonJS2(index_exports2);
24820
26139
  var import_property_provider2 = require_dist_cjs24();
24821
26140
  var import_shared_ini_file_loader = require_dist_cjs42();
24822
- var import_child_process8 = require("child_process");
26141
+ var import_child_process9 = require("child_process");
24823
26142
  var import_util7 = require("util");
24824
26143
  var import_client7 = (init_client(), __toCommonJS(client_exports));
24825
26144
  var getValidatedProcessCredentials = /* @__PURE__ */ __name((profileName, data2, profiles) => {
@@ -24856,7 +26175,7 @@ var require_dist_cjs59 = __commonJS({
24856
26175
  if (profiles[profileName]) {
24857
26176
  const credentialProcess = profile["credential_process"];
24858
26177
  if (credentialProcess !== void 0) {
24859
- const execPromise = (0, import_util7.promisify)(import_shared_ini_file_loader.externalDataInterceptor?.getTokenRecord?.().exec ?? import_child_process8.exec);
26178
+ const execPromise = (0, import_util7.promisify)(import_shared_ini_file_loader.externalDataInterceptor?.getTokenRecord?.().exec ?? import_child_process9.exec);
24860
26179
  try {
24861
26180
  const { stdout } = await execPromise(credentialProcess);
24862
26181
  let data2;
@@ -25595,7 +26914,7 @@ var require_dist_cjs64 = __commonJS({
25595
26914
  streamEnded = true;
25596
26915
  });
25597
26916
  while (!generationEnded) {
25598
- const value = await new Promise((resolve2) => setTimeout(() => resolve2(records.shift()), 0));
26917
+ const value = await new Promise((resolve4) => setTimeout(() => resolve4(records.shift()), 0));
25599
26918
  if (value) {
25600
26919
  yield value;
25601
26920
  }
@@ -28972,16 +30291,16 @@ function prepareTools(mode) {
28972
30291
  }
28973
30292
  const toolWarnings = [];
28974
30293
  const bedrockTools = [];
28975
- for (const tool2 of tools2) {
28976
- if (tool2.type === "provider-defined") {
28977
- toolWarnings.push({ type: "unsupported-tool", tool: tool2 });
30294
+ for (const tool3 of tools2) {
30295
+ if (tool3.type === "provider-defined") {
30296
+ toolWarnings.push({ type: "unsupported-tool", tool: tool3 });
28978
30297
  } else {
28979
30298
  bedrockTools.push({
28980
30299
  toolSpec: {
28981
- name: tool2.name,
28982
- description: tool2.description,
30300
+ name: tool3.name,
30301
+ description: tool3.description,
28983
30302
  inputSchema: {
28984
- json: tool2.parameters
30303
+ json: tool3.parameters
28985
30304
  }
28986
30305
  }
28987
30306
  });
@@ -29949,19 +31268,15 @@ var init_tokenCounter = __esm({
29949
31268
  }
29950
31269
  });
29951
31270
 
29952
- // src/agent/tools.js
29953
- function createTools(configOptions) {
29954
- return {
29955
- searchTool: searchTool(configOptions),
29956
- queryTool: queryTool(configOptions),
29957
- extractTool: extractTool(configOptions),
29958
- delegateTool: delegateTool(configOptions)
29959
- };
31271
+ // src/agent/xmlParsingUtils.js
31272
+ function removeThinkingTags(xmlString) {
31273
+ return xmlString.replace(/<thinking>[\s\S]*?<\/thinking>/g, "").trim();
29960
31274
  }
29961
- function parseXmlToolCallWithThinking(xmlString, validTools) {
31275
+ function extractThinkingContent(xmlString) {
29962
31276
  const thinkingMatch = xmlString.match(/<thinking>([\s\S]*?)<\/thinking>/);
29963
- const thinkingContent = thinkingMatch ? thinkingMatch[1].trim() : null;
29964
- let cleanedXmlString = xmlString.replace(/<thinking>[\s\S]*?<\/thinking>/g, "").trim();
31277
+ return thinkingMatch ? thinkingMatch[1].trim() : null;
31278
+ }
31279
+ function checkAttemptCompleteRecovery(cleanedXmlString, validTools = []) {
29965
31280
  const attemptCompletePatterns = [
29966
31281
  // Standard shorthand with optional whitespace
29967
31282
  /^<attempt_complete>\s*$/,
@@ -29991,29 +31306,65 @@ function parseXmlToolCallWithThinking(xmlString, validTools) {
29991
31306
  params: { result: "__PREVIOUS_RESPONSE__" }
29992
31307
  };
29993
31308
  }
29994
- const parsedTool = parseXmlToolCall(cleanedXmlString, validTools);
29995
- if (process.env.DEBUG === "1" && thinkingContent) {
29996
- console.log(`[DEBUG] AI Thinking Process:
29997
- ${thinkingContent}`);
29998
- }
29999
- return parsedTool;
31309
+ return null;
30000
31310
  }
30001
31311
  function hasOtherToolTags(xmlString, validTools = []) {
30002
31312
  const defaultTools = ["search", "query", "extract", "listFiles", "searchFiles", "implement", "attempt_completion"];
30003
31313
  const toolsToCheck = validTools.length > 0 ? validTools : defaultTools;
30004
- for (const tool2 of toolsToCheck) {
30005
- if (tool2 !== "attempt_completion" && xmlString.includes(`<${tool2}`)) {
31314
+ for (const tool3 of toolsToCheck) {
31315
+ if (tool3 !== "attempt_completion" && xmlString.includes(`<${tool3}`)) {
30006
31316
  return true;
30007
31317
  }
30008
31318
  }
30009
31319
  return false;
30010
31320
  }
31321
+ function processXmlWithThinkingAndRecovery(xmlString, validTools = []) {
31322
+ const thinkingContent = extractThinkingContent(xmlString);
31323
+ const cleanedXmlString = removeThinkingTags(xmlString);
31324
+ const recoveryResult = checkAttemptCompleteRecovery(cleanedXmlString, validTools);
31325
+ if (process.env.DEBUG === "1" && thinkingContent) {
31326
+ console.log(`[DEBUG] AI Thinking Process:
31327
+ ${thinkingContent}`);
31328
+ }
31329
+ return {
31330
+ cleanedXmlString,
31331
+ thinkingContent,
31332
+ recoveryResult
31333
+ };
31334
+ }
31335
+ var init_xmlParsingUtils = __esm({
31336
+ "src/agent/xmlParsingUtils.js"() {
31337
+ "use strict";
31338
+ }
31339
+ });
31340
+
31341
+ // src/agent/tools.js
31342
+ function createTools(configOptions) {
31343
+ const tools2 = {
31344
+ searchTool: searchTool(configOptions),
31345
+ queryTool: queryTool(configOptions),
31346
+ extractTool: extractTool(configOptions),
31347
+ delegateTool: delegateTool(configOptions)
31348
+ };
31349
+ if (configOptions.enableBash) {
31350
+ tools2.bashTool = bashTool(configOptions);
31351
+ }
31352
+ return tools2;
31353
+ }
31354
+ function parseXmlToolCallWithThinking(xmlString, validTools) {
31355
+ const { cleanedXmlString, recoveryResult } = processXmlWithThinkingAndRecovery(xmlString, validTools);
31356
+ if (recoveryResult) {
31357
+ return recoveryResult;
31358
+ }
31359
+ return parseXmlToolCall(cleanedXmlString, validTools);
31360
+ }
30011
31361
  var import_crypto3, implementToolDefinition, listFilesToolDefinition, searchFilesToolDefinition;
30012
31362
  var init_tools2 = __esm({
30013
31363
  "src/agent/tools.js"() {
30014
31364
  "use strict";
30015
31365
  init_index();
30016
31366
  import_crypto3 = require("crypto");
31367
+ init_xmlParsingUtils();
30017
31368
  implementToolDefinition = `
30018
31369
  ## implement
30019
31370
  Description: Implement a given task. Can modify files. Can be used ONLY if task explicitly stated that something requires modification or implementation.
@@ -30142,26 +31493,33 @@ function createWrappedTools(baseTools) {
30142
31493
  baseTools.delegateTool.execute
30143
31494
  );
30144
31495
  }
31496
+ if (baseTools.bashTool) {
31497
+ wrappedTools.bashToolInstance = wrapToolWithEmitter(
31498
+ baseTools.bashTool,
31499
+ "bash",
31500
+ baseTools.bashTool.execute
31501
+ );
31502
+ }
30145
31503
  return wrappedTools;
30146
31504
  }
30147
- var import_child_process7, import_util6, import_crypto4, import_events, import_fs2, import_fs3, import_path5, import_glob, toolCallEmitter, activeToolExecutions, wrapToolWithEmitter, listFilesTool, searchFilesTool, listFilesToolInstance, searchFilesToolInstance;
31505
+ var import_child_process8, import_util6, import_crypto4, import_events, import_fs3, import_fs4, import_path7, import_glob, toolCallEmitter, activeToolExecutions, wrapToolWithEmitter, listFilesTool, searchFilesTool, listFilesToolInstance, searchFilesToolInstance;
30148
31506
  var init_probeTool = __esm({
30149
31507
  "src/agent/probeTool.js"() {
30150
31508
  "use strict";
30151
31509
  init_index();
30152
- import_child_process7 = require("child_process");
31510
+ import_child_process8 = require("child_process");
30153
31511
  import_util6 = require("util");
30154
31512
  import_crypto4 = require("crypto");
30155
31513
  import_events = require("events");
30156
- import_fs2 = __toESM(require("fs"), 1);
30157
- import_fs3 = require("fs");
30158
- import_path5 = __toESM(require("path"), 1);
31514
+ import_fs3 = __toESM(require("fs"), 1);
31515
+ import_fs4 = require("fs");
31516
+ import_path7 = __toESM(require("path"), 1);
30159
31517
  import_glob = require("glob");
30160
31518
  toolCallEmitter = new import_events.EventEmitter();
30161
31519
  activeToolExecutions = /* @__PURE__ */ new Map();
30162
- wrapToolWithEmitter = (tool2, toolName, baseExecute) => {
31520
+ wrapToolWithEmitter = (tool3, toolName, baseExecute) => {
30163
31521
  return {
30164
- ...tool2,
31522
+ ...tool3,
30165
31523
  // Spread schema, description etc.
30166
31524
  execute: async (params) => {
30167
31525
  const debug = process.env.DEBUG === "1";
@@ -30243,9 +31601,9 @@ var init_probeTool = __esm({
30243
31601
  execute: async (params) => {
30244
31602
  const { directory = ".", workingDirectory } = params;
30245
31603
  const baseCwd = workingDirectory || process.cwd();
30246
- const secureBaseDir = import_path5.default.resolve(baseCwd);
30247
- const targetDir = import_path5.default.resolve(secureBaseDir, directory);
30248
- if (!targetDir.startsWith(secureBaseDir + import_path5.default.sep) && targetDir !== secureBaseDir) {
31604
+ const secureBaseDir = import_path7.default.resolve(baseCwd);
31605
+ const targetDir = import_path7.default.resolve(secureBaseDir, directory);
31606
+ if (!targetDir.startsWith(secureBaseDir + import_path7.default.sep) && targetDir !== secureBaseDir) {
30249
31607
  throw new Error("Path traversal attempt detected. Access denied.");
30250
31608
  }
30251
31609
  try {
@@ -30268,9 +31626,9 @@ var init_probeTool = __esm({
30268
31626
  throw new Error("Pattern is required for file search");
30269
31627
  }
30270
31628
  const baseCwd = workingDirectory || process.cwd();
30271
- const secureBaseDir = import_path5.default.resolve(baseCwd);
30272
- const targetDir = import_path5.default.resolve(secureBaseDir, directory);
30273
- if (!targetDir.startsWith(secureBaseDir + import_path5.default.sep) && targetDir !== secureBaseDir) {
31629
+ const secureBaseDir = import_path7.default.resolve(baseCwd);
31630
+ const targetDir = import_path7.default.resolve(secureBaseDir, directory);
31631
+ if (!targetDir.startsWith(secureBaseDir + import_path7.default.sep) && targetDir !== secureBaseDir) {
30274
31632
  throw new Error("Path traversal attempt detected. Access denied.");
30275
31633
  }
30276
31634
  try {
@@ -30302,7 +31660,7 @@ function createMockProvider() {
30302
31660
  provider: "mock",
30303
31661
  // Mock the doGenerate method used by Vercel AI SDK
30304
31662
  doGenerate: async ({ messages, tools: tools2 }) => {
30305
- await new Promise((resolve2) => setTimeout(resolve2, 10));
31663
+ await new Promise((resolve4) => setTimeout(resolve4, 10));
30306
31664
  return {
30307
31665
  text: "This is a mock response for testing",
30308
31666
  toolCalls: [],
@@ -30877,7 +32235,7 @@ ${decodedContent}
30877
32235
  }
30878
32236
  if (needsQuoting(content)) {
30879
32237
  wasFixed = true;
30880
- const safeContent = content.replace(/"/g, "'");
32238
+ const safeContent = content.replace(/"/g, "&quot;").replace(/'/g, "&#39;");
30881
32239
  return `["${safeContent}"]`;
30882
32240
  }
30883
32241
  return match;
@@ -30890,7 +32248,7 @@ ${decodedContent}
30890
32248
  }
30891
32249
  if (needsQuoting(content)) {
30892
32250
  wasFixed = true;
30893
- const safeContent = content.replace(/"/g, "'");
32251
+ const safeContent = content.replace(/"/g, "&quot;").replace(/'/g, "&#39;");
30894
32252
  return `{"${safeContent}"}`;
30895
32253
  }
30896
32254
  return match;
@@ -31060,7 +32418,7 @@ ${fixedContent}
31060
32418
  }
31061
32419
  if (needsQuoting(content)) {
31062
32420
  wasFixed = true;
31063
- const safeContent = content.replace(/"/g, "'");
32421
+ const safeContent = content.replace(/"/g, "&quot;").replace(/'/g, "&#39;");
31064
32422
  return `["${safeContent}"]`;
31065
32423
  }
31066
32424
  return match;
@@ -31073,7 +32431,7 @@ ${fixedContent}
31073
32431
  }
31074
32432
  if (needsQuoting(content)) {
31075
32433
  wasFixed = true;
31076
- const safeContent = content.replace(/"/g, "'");
32434
+ const safeContent = content.replace(/"/g, "&quot;").replace(/'/g, "&#39;");
31077
32435
  return `{"${safeContent}"}`;
31078
32436
  }
31079
32437
  return match;
@@ -31473,11 +32831,11 @@ function loadMCPConfigurationFromPath(configPath) {
31473
32831
  if (!configPath) {
31474
32832
  throw new Error("Config path is required");
31475
32833
  }
31476
- if (!(0, import_fs4.existsSync)(configPath)) {
32834
+ if (!(0, import_fs5.existsSync)(configPath)) {
31477
32835
  throw new Error(`MCP configuration file not found: ${configPath}`);
31478
32836
  }
31479
32837
  try {
31480
- const content = (0, import_fs4.readFileSync)(configPath, "utf8");
32838
+ const content = (0, import_fs5.readFileSync)(configPath, "utf8");
31481
32839
  const config = JSON.parse(content);
31482
32840
  if (process.env.DEBUG === "1") {
31483
32841
  console.error(`[MCP] Loaded configuration from: ${configPath}`);
@@ -31492,19 +32850,19 @@ function loadMCPConfiguration() {
31492
32850
  // Environment variable path
31493
32851
  process.env.MCP_CONFIG_PATH,
31494
32852
  // Local project paths
31495
- (0, import_path6.join)(process.cwd(), ".mcp", "config.json"),
31496
- (0, import_path6.join)(process.cwd(), "mcp.config.json"),
32853
+ (0, import_path8.join)(process.cwd(), ".mcp", "config.json"),
32854
+ (0, import_path8.join)(process.cwd(), "mcp.config.json"),
31497
32855
  // Home directory paths
31498
- (0, import_path6.join)((0, import_os3.homedir)(), ".config", "probe", "mcp.json"),
31499
- (0, import_path6.join)((0, import_os3.homedir)(), ".mcp", "config.json"),
32856
+ (0, import_path8.join)((0, import_os3.homedir)(), ".config", "probe", "mcp.json"),
32857
+ (0, import_path8.join)((0, import_os3.homedir)(), ".mcp", "config.json"),
31500
32858
  // Claude-style config location
31501
- (0, import_path6.join)((0, import_os3.homedir)(), "Library", "Application Support", "Claude", "mcp_config.json")
32859
+ (0, import_path8.join)((0, import_os3.homedir)(), "Library", "Application Support", "Claude", "mcp_config.json")
31502
32860
  ].filter(Boolean);
31503
32861
  let config = null;
31504
32862
  for (const configPath of configPaths) {
31505
- if ((0, import_fs4.existsSync)(configPath)) {
32863
+ if ((0, import_fs5.existsSync)(configPath)) {
31506
32864
  try {
31507
- const content = (0, import_fs4.readFileSync)(configPath, "utf8");
32865
+ const content = (0, import_fs5.readFileSync)(configPath, "utf8");
31508
32866
  config = JSON.parse(content);
31509
32867
  if (process.env.DEBUG === "1") {
31510
32868
  console.error(`[MCP] Loaded configuration from: ${configPath}`);
@@ -31600,22 +32958,22 @@ function parseEnabledServers(config) {
31600
32958
  }
31601
32959
  return servers;
31602
32960
  }
31603
- var import_fs4, import_path6, import_os3, import_url4, __filename4, __dirname4, DEFAULT_CONFIG;
32961
+ var import_fs5, import_path8, import_os3, import_url4, __filename4, __dirname4, DEFAULT_CONFIG;
31604
32962
  var init_config = __esm({
31605
32963
  "src/agent/mcp/config.js"() {
31606
32964
  "use strict";
31607
- import_fs4 = require("fs");
31608
- import_path6 = require("path");
32965
+ import_fs5 = require("fs");
32966
+ import_path8 = require("path");
31609
32967
  import_os3 = require("os");
31610
32968
  import_url4 = require("url");
31611
32969
  __filename4 = (0, import_url4.fileURLToPath)("file:///");
31612
- __dirname4 = (0, import_path6.dirname)(__filename4);
32970
+ __dirname4 = (0, import_path8.dirname)(__filename4);
31613
32971
  DEFAULT_CONFIG = {
31614
32972
  mcpServers: {
31615
32973
  // Example probe server configuration
31616
32974
  "probe-local": {
31617
32975
  command: "node",
31618
- args: [(0, import_path6.join)(__dirname4, "../../../examples/chat/mcpServer.js")],
32976
+ args: [(0, import_path8.join)(__dirname4, "../../../examples/chat/mcpServer.js")],
31619
32977
  transport: "stdio",
31620
32978
  enabled: false
31621
32979
  },
@@ -31772,12 +33130,12 @@ var init_client2 = __esm({
31772
33130
  });
31773
33131
  const toolsResponse = await client.listTools();
31774
33132
  if (toolsResponse && toolsResponse.tools) {
31775
- for (const tool2 of toolsResponse.tools) {
31776
- const qualifiedName = `${name14}_${tool2.name}`;
33133
+ for (const tool3 of toolsResponse.tools) {
33134
+ const qualifiedName = `${name14}_${tool3.name}`;
31777
33135
  this.tools.set(qualifiedName, {
31778
- ...tool2,
33136
+ ...tool3,
31779
33137
  serverName: name14,
31780
- originalName: tool2.name
33138
+ originalName: tool3.name
31781
33139
  });
31782
33140
  if (this.debug) {
31783
33141
  console.error(`[MCP] Registered tool: ${qualifiedName}`);
@@ -31799,20 +33157,20 @@ var init_client2 = __esm({
31799
33157
  * @param {Object} args - Tool arguments
31800
33158
  */
31801
33159
  async callTool(toolName, args) {
31802
- const tool2 = this.tools.get(toolName);
31803
- if (!tool2) {
33160
+ const tool3 = this.tools.get(toolName);
33161
+ if (!tool3) {
31804
33162
  throw new Error(`Unknown tool: ${toolName}`);
31805
33163
  }
31806
- const clientInfo = this.clients.get(tool2.serverName);
33164
+ const clientInfo = this.clients.get(tool3.serverName);
31807
33165
  if (!clientInfo) {
31808
- throw new Error(`Server ${tool2.serverName} not connected`);
33166
+ throw new Error(`Server ${tool3.serverName} not connected`);
31809
33167
  }
31810
33168
  try {
31811
33169
  if (this.debug) {
31812
33170
  console.error(`[MCP] Calling ${toolName} with args:`, args);
31813
33171
  }
31814
33172
  const result = await clientInfo.client.callTool({
31815
- name: tool2.originalName,
33173
+ name: tool3.originalName,
31816
33174
  arguments: args
31817
33175
  });
31818
33176
  return result;
@@ -31827,11 +33185,11 @@ var init_client2 = __esm({
31827
33185
  */
31828
33186
  getTools() {
31829
33187
  const tools2 = {};
31830
- for (const [name14, tool2] of this.tools.entries()) {
33188
+ for (const [name14, tool3] of this.tools.entries()) {
31831
33189
  tools2[name14] = {
31832
- description: tool2.description,
31833
- inputSchema: tool2.inputSchema,
31834
- serverName: tool2.serverName
33190
+ description: tool3.description,
33191
+ inputSchema: tool3.inputSchema,
33192
+ serverName: tool3.serverName
31835
33193
  };
31836
33194
  }
31837
33195
  return tools2;
@@ -31842,10 +33200,10 @@ var init_client2 = __esm({
31842
33200
  */
31843
33201
  getVercelTools() {
31844
33202
  const tools2 = {};
31845
- for (const [name14, tool2] of this.tools.entries()) {
33203
+ for (const [name14, tool3] of this.tools.entries()) {
31846
33204
  tools2[name14] = {
31847
- description: tool2.description,
31848
- inputSchema: tool2.inputSchema,
33205
+ description: tool3.description,
33206
+ inputSchema: tool3.inputSchema,
31849
33207
  execute: async (args) => {
31850
33208
  const result = await this.callTool(name14, args);
31851
33209
  if (result.content && result.content[0]) {
@@ -31882,9 +33240,9 @@ var init_client2 = __esm({
31882
33240
  });
31883
33241
 
31884
33242
  // src/agent/mcp/xmlBridge.js
31885
- function mcpToolToXmlDefinition(name14, tool2) {
31886
- const description = tool2.description || "MCP tool";
31887
- const inputSchema = tool2.inputSchema || tool2.parameters || {};
33243
+ function mcpToolToXmlDefinition(name14, tool3) {
33244
+ const description = tool3.description || "MCP tool";
33245
+ const inputSchema = tool3.inputSchema || tool3.parameters || {};
31888
33246
  let paramDocs = "";
31889
33247
  if (inputSchema.properties) {
31890
33248
  paramDocs = "\n\nParameters (provide as JSON object):";
@@ -31958,11 +33316,9 @@ function parseXmlMcpToolCall(xmlString, mcpToolNames = []) {
31958
33316
  return null;
31959
33317
  }
31960
33318
  function parseHybridXmlToolCall(xmlString, nativeTools = [], mcpBridge = null) {
31961
- for (const toolName of nativeTools) {
31962
- const nativeResult = parseNativeXmlTool(xmlString, toolName);
31963
- if (nativeResult) {
31964
- return { ...nativeResult, type: "native" };
31965
- }
33319
+ const nativeResult = parseNativeXmlToolWithThinking(xmlString, nativeTools);
33320
+ if (nativeResult) {
33321
+ return { ...nativeResult, type: "native" };
31966
33322
  }
31967
33323
  if (mcpBridge) {
31968
33324
  const mcpResult = parseXmlMcpToolCall(xmlString, mcpBridge.getToolNames());
@@ -31972,6 +33328,19 @@ function parseHybridXmlToolCall(xmlString, nativeTools = [], mcpBridge = null) {
31972
33328
  }
31973
33329
  return null;
31974
33330
  }
33331
+ function parseNativeXmlToolWithThinking(xmlString, validTools) {
33332
+ const { cleanedXmlString, recoveryResult } = processXmlWithThinkingAndRecovery(xmlString, validTools);
33333
+ if (recoveryResult) {
33334
+ return recoveryResult;
33335
+ }
33336
+ for (const toolName of validTools) {
33337
+ const result = parseNativeXmlTool(cleanedXmlString, toolName);
33338
+ if (result) {
33339
+ return result;
33340
+ }
33341
+ }
33342
+ return null;
33343
+ }
31975
33344
  function parseNativeXmlTool(xmlString, toolName) {
31976
33345
  const openTag = `<${toolName}>`;
31977
33346
  const closeTag = `</${toolName}>`;
@@ -32001,6 +33370,7 @@ var init_xmlBridge = __esm({
32001
33370
  "use strict";
32002
33371
  init_client2();
32003
33372
  init_config();
33373
+ init_xmlParsingUtils();
32004
33374
  MCPXmlBridge = class {
32005
33375
  constructor(options = {}) {
32006
33376
  this.debug = options.debug || false;
@@ -32032,8 +33402,8 @@ var init_xmlBridge = __esm({
32032
33402
  const result = await this.mcpManager.initialize(mcpConfigs);
32033
33403
  const vercelTools = this.mcpManager.getVercelTools();
32034
33404
  this.mcpTools = vercelTools;
32035
- for (const [name14, tool2] of Object.entries(vercelTools)) {
32036
- this.xmlDefinitions[name14] = mcpToolToXmlDefinition(name14, tool2);
33405
+ for (const [name14, tool3] of Object.entries(vercelTools)) {
33406
+ this.xmlDefinitions[name14] = mcpToolToXmlDefinition(name14, tool3);
32037
33407
  }
32038
33408
  if (this.debug) {
32039
33409
  console.error(`[MCP] Loaded ${Object.keys(vercelTools).length} MCP tools from ${result.connected} server(s)`);
@@ -32070,12 +33440,12 @@ var init_xmlBridge = __esm({
32070
33440
  if (this.debug) {
32071
33441
  console.error(`[MCP] Executing MCP tool: ${toolName} with params:`, params);
32072
33442
  }
32073
- const tool2 = this.mcpTools[toolName];
32074
- if (!tool2) {
33443
+ const tool3 = this.mcpTools[toolName];
33444
+ if (!tool3) {
32075
33445
  throw new Error(`Unknown MCP tool: ${toolName}`);
32076
33446
  }
32077
33447
  try {
32078
- const result = await tool2.execute(params);
33448
+ const result = await tool3.execute(params);
32079
33449
  return {
32080
33450
  success: true,
32081
33451
  toolName,
@@ -32127,7 +33497,7 @@ var ProbeAgent_exports = {};
32127
33497
  __export(ProbeAgent_exports, {
32128
33498
  ProbeAgent: () => ProbeAgent
32129
33499
  });
32130
- var import_anthropic, import_openai, import_google, import_ai2, import_crypto5, import_events2, import_fs5, import_promises, import_path7, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, SUPPORTED_IMAGE_EXTENSIONS, MAX_IMAGE_FILE_SIZE, ProbeAgent;
33500
+ var import_anthropic, import_openai, import_google, import_ai3, import_crypto5, import_events2, import_fs6, import_promises, import_path9, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, SUPPORTED_IMAGE_EXTENSIONS, MAX_IMAGE_FILE_SIZE, ProbeAgent;
32131
33501
  var init_ProbeAgent = __esm({
32132
33502
  "src/agent/ProbeAgent.js"() {
32133
33503
  "use strict";
@@ -32135,12 +33505,12 @@ var init_ProbeAgent = __esm({
32135
33505
  import_openai = require("@ai-sdk/openai");
32136
33506
  import_google = require("@ai-sdk/google");
32137
33507
  init_dist3();
32138
- import_ai2 = require("ai");
33508
+ import_ai3 = require("ai");
32139
33509
  import_crypto5 = require("crypto");
32140
33510
  import_events2 = require("events");
32141
- import_fs5 = require("fs");
33511
+ import_fs6 = require("fs");
32142
33512
  import_promises = require("fs/promises");
32143
- import_path7 = require("path");
33513
+ import_path9 = require("path");
32144
33514
  init_tokenCounter();
32145
33515
  init_tools2();
32146
33516
  init_common();
@@ -32184,6 +33554,8 @@ var init_ProbeAgent = __esm({
32184
33554
  this.outline = !!options.outline;
32185
33555
  this.maxResponseTokens = options.maxResponseTokens || parseInt(process.env.MAX_RESPONSE_TOKENS || "0", 10) || null;
32186
33556
  this.disableMermaidValidation = !!options.disableMermaidValidation;
33557
+ this.enableBash = !!options.enableBash;
33558
+ this.bashConfig = options.bashConfig || {};
32187
33559
  if (options.allowedFolders && Array.isArray(options.allowedFolders)) {
32188
33560
  this.allowedFolders = options.allowedFolders;
32189
33561
  } else if (options.path) {
@@ -32227,7 +33599,9 @@ var init_ProbeAgent = __esm({
32227
33599
  debug: this.debug,
32228
33600
  defaultPath: this.allowedFolders.length > 0 ? this.allowedFolders[0] : process.cwd(),
32229
33601
  allowedFolders: this.allowedFolders,
32230
- outline: this.outline
33602
+ outline: this.outline,
33603
+ enableBash: this.enableBash,
33604
+ bashConfig: this.bashConfig
32231
33605
  };
32232
33606
  const baseTools = createTools(configOptions);
32233
33607
  const wrappedTools = createWrappedTools(baseTools);
@@ -32239,6 +33613,9 @@ var init_ProbeAgent = __esm({
32239
33613
  listFiles: listFilesToolInstance,
32240
33614
  searchFiles: searchFilesToolInstance
32241
33615
  };
33616
+ if (this.enableBash && wrappedTools.bashToolInstance) {
33617
+ this.toolImplementations.bash = wrappedTools.bashToolInstance;
33618
+ }
32242
33619
  this.wrappedTools = wrappedTools;
32243
33620
  }
32244
33621
  /**
@@ -32425,13 +33802,13 @@ var init_ProbeAgent = __esm({
32425
33802
  const allowedDirs = this.allowedFolders && this.allowedFolders.length > 0 ? this.allowedFolders : [process.cwd()];
32426
33803
  let absolutePath;
32427
33804
  let isPathAllowed = false;
32428
- if ((0, import_path7.isAbsolute)(imagePath)) {
33805
+ if ((0, import_path9.isAbsolute)(imagePath)) {
32429
33806
  absolutePath = imagePath;
32430
- isPathAllowed = allowedDirs.some((dir) => absolutePath.startsWith((0, import_path7.resolve)(dir)));
33807
+ isPathAllowed = allowedDirs.some((dir) => absolutePath.startsWith((0, import_path9.resolve)(dir)));
32431
33808
  } else {
32432
33809
  for (const dir of allowedDirs) {
32433
- const resolvedPath3 = (0, import_path7.resolve)(dir, imagePath);
32434
- if (resolvedPath3.startsWith((0, import_path7.resolve)(dir))) {
33810
+ const resolvedPath3 = (0, import_path9.resolve)(dir, imagePath);
33811
+ if (resolvedPath3.startsWith((0, import_path9.resolve)(dir))) {
32435
33812
  absolutePath = resolvedPath3;
32436
33813
  isPathAllowed = true;
32437
33814
  break;
@@ -32926,7 +34303,7 @@ You are working with a repository located at: ${searchDirectory}
32926
34303
  try {
32927
34304
  const executeAIRequest = async () => {
32928
34305
  const messagesForAI = this.prepareMessagesWithImages(currentMessages);
32929
- const result = await (0, import_ai2.streamText)({
34306
+ const result = await (0, import_ai3.streamText)({
32930
34307
  model: this.provider(this.model),
32931
34308
  messages: messagesForAI,
32932
34309
  maxTokens: maxResponseTokens,
@@ -33603,12 +34980,12 @@ function initializeSimpleTelemetryFromOptions(options) {
33603
34980
  });
33604
34981
  return telemetry;
33605
34982
  }
33606
- var import_fs6, import_path8, SimpleTelemetry, SimpleAppTracer;
34983
+ var import_fs7, import_path10, SimpleTelemetry, SimpleAppTracer;
33607
34984
  var init_simpleTelemetry = __esm({
33608
34985
  "src/agent/simpleTelemetry.js"() {
33609
34986
  "use strict";
33610
- import_fs6 = require("fs");
33611
- import_path8 = require("path");
34987
+ import_fs7 = require("fs");
34988
+ import_path10 = require("path");
33612
34989
  SimpleTelemetry = class {
33613
34990
  constructor(options = {}) {
33614
34991
  this.serviceName = options.serviceName || "probe-agent";
@@ -33622,11 +34999,11 @@ var init_simpleTelemetry = __esm({
33622
34999
  }
33623
35000
  initializeFileExporter() {
33624
35001
  try {
33625
- const dir = (0, import_path8.dirname)(this.filePath);
33626
- if (!(0, import_fs6.existsSync)(dir)) {
33627
- (0, import_fs6.mkdirSync)(dir, { recursive: true });
35002
+ const dir = (0, import_path10.dirname)(this.filePath);
35003
+ if (!(0, import_fs7.existsSync)(dir)) {
35004
+ (0, import_fs7.mkdirSync)(dir, { recursive: true });
33628
35005
  }
33629
- this.stream = (0, import_fs6.createWriteStream)(this.filePath, { flags: "a" });
35006
+ this.stream = (0, import_fs7.createWriteStream)(this.filePath, { flags: "a" });
33630
35007
  this.stream.on("error", (error2) => {
33631
35008
  console.error(`[SimpleTelemetry] Stream error: ${error2.message}`);
33632
35009
  });
@@ -33687,20 +35064,20 @@ var init_simpleTelemetry = __esm({
33687
35064
  }
33688
35065
  async flush() {
33689
35066
  if (this.stream) {
33690
- return new Promise((resolve2) => {
33691
- this.stream.once("drain", resolve2);
35067
+ return new Promise((resolve4) => {
35068
+ this.stream.once("drain", resolve4);
33692
35069
  if (!this.stream.writableNeedDrain) {
33693
- resolve2();
35070
+ resolve4();
33694
35071
  }
33695
35072
  });
33696
35073
  }
33697
35074
  }
33698
35075
  async shutdown() {
33699
35076
  if (this.stream) {
33700
- return new Promise((resolve2) => {
35077
+ return new Promise((resolve4) => {
33701
35078
  this.stream.end(() => {
33702
35079
  console.log(`[SimpleTelemetry] File stream closed: ${this.filePath}`);
33703
- resolve2();
35080
+ resolve4();
33704
35081
  });
33705
35082
  });
33706
35083
  }
@@ -33827,6 +35204,9 @@ __export(index_exports, {
33827
35204
  SimpleTelemetry: () => SimpleTelemetry,
33828
35205
  attemptCompletionSchema: () => attemptCompletionSchema,
33829
35206
  attemptCompletionToolDefinition: () => attemptCompletionToolDefinition,
35207
+ bashSchema: () => bashSchema,
35208
+ bashTool: () => bashTool,
35209
+ bashToolDefinition: () => bashToolDefinition,
33830
35210
  delegate: () => delegate,
33831
35211
  delegateSchema: () => delegateSchema,
33832
35212
  delegateTool: () => delegateTool,
@@ -33863,6 +35243,7 @@ var init_index = __esm({
33863
35243
  init_system_message();
33864
35244
  init_common();
33865
35245
  init_vercel();
35246
+ init_bash();
33866
35247
  init_ProbeAgent();
33867
35248
  init_simpleTelemetry();
33868
35249
  }
@@ -33876,6 +35257,9 @@ init_index();
33876
35257
  SimpleTelemetry,
33877
35258
  attemptCompletionSchema,
33878
35259
  attemptCompletionToolDefinition,
35260
+ bashSchema,
35261
+ bashTool,
35262
+ bashToolDefinition,
33879
35263
  delegate,
33880
35264
  delegateSchema,
33881
35265
  delegateTool,