@probelabs/probe 0.6.0-rc255 → 0.6.0-rc257

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/README.md +5 -5
  2. package/bin/binaries/probe-v0.6.0-rc257-aarch64-apple-darwin.tar.gz +0 -0
  3. package/bin/binaries/probe-v0.6.0-rc257-aarch64-unknown-linux-musl.tar.gz +0 -0
  4. package/bin/binaries/probe-v0.6.0-rc257-x86_64-apple-darwin.tar.gz +0 -0
  5. package/bin/binaries/{probe-v0.6.0-rc255-x86_64-pc-windows-msvc.zip → probe-v0.6.0-rc257-x86_64-pc-windows-msvc.zip} +0 -0
  6. package/bin/binaries/probe-v0.6.0-rc257-x86_64-unknown-linux-musl.tar.gz +0 -0
  7. package/build/agent/FallbackManager.js +4 -4
  8. package/build/agent/ProbeAgent.js +23 -17
  9. package/build/agent/bashDefaults.js +175 -97
  10. package/build/agent/bashPermissions.js +98 -45
  11. package/build/agent/index.js +335 -205
  12. package/build/agent/mcp/xmlBridge.js +3 -2
  13. package/build/agent/schemaUtils.js +127 -0
  14. package/build/tools/bash.js +2 -2
  15. package/build/tools/common.js +20 -3
  16. package/cjs/agent/ProbeAgent.cjs +343 -203
  17. package/cjs/index.cjs +343 -203
  18. package/package.json +1 -1
  19. package/src/agent/FallbackManager.js +4 -4
  20. package/src/agent/ProbeAgent.js +23 -17
  21. package/src/agent/bashDefaults.js +175 -97
  22. package/src/agent/bashPermissions.js +98 -45
  23. package/src/agent/index.js +4 -4
  24. package/src/agent/mcp/xmlBridge.js +3 -2
  25. package/src/agent/schemaUtils.js +127 -0
  26. package/src/tools/bash.js +2 -2
  27. package/src/tools/common.js +20 -3
  28. package/bin/binaries/probe-v0.6.0-rc255-aarch64-apple-darwin.tar.gz +0 -0
  29. package/bin/binaries/probe-v0.6.0-rc255-aarch64-unknown-linux-musl.tar.gz +0 -0
  30. package/bin/binaries/probe-v0.6.0-rc255-x86_64-apple-darwin.tar.gz +0 -0
  31. package/bin/binaries/probe-v0.6.0-rc255-x86_64-unknown-linux-musl.tar.gz +0 -0
@@ -1844,6 +1844,7 @@ var require_ChecksumStream = __commonJS({
1844
1844
  checksum;
1845
1845
  source;
1846
1846
  base64Encoder;
1847
+ pendingCallback = null;
1847
1848
  constructor({ expectedChecksum, checksum, source, checksumSourceLocation, base64Encoder }) {
1848
1849
  super();
1849
1850
  if (typeof source.pipe === "function") {
@@ -1858,11 +1859,20 @@ var require_ChecksumStream = __commonJS({
1858
1859
  this.source.pipe(this);
1859
1860
  }
1860
1861
  _read(size) {
1862
+ if (this.pendingCallback) {
1863
+ const callback = this.pendingCallback;
1864
+ this.pendingCallback = null;
1865
+ callback();
1866
+ }
1861
1867
  }
1862
1868
  _write(chunk, encoding, callback) {
1863
1869
  try {
1864
1870
  this.checksum.update(chunk);
1865
- this.push(chunk);
1871
+ const canPushMore = this.push(chunk);
1872
+ if (!canPushMore) {
1873
+ this.pendingCallback = callback;
1874
+ return;
1875
+ }
1866
1876
  } catch (e5) {
1867
1877
  return callback(e5);
1868
1878
  }
@@ -39852,6 +39862,10 @@ function getValidParamsForTool(toolName) {
39852
39862
  }
39853
39863
  return [];
39854
39864
  }
39865
+ function unescapeXmlEntities(str) {
39866
+ if (typeof str !== "string") return str;
39867
+ return str.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&amp;/g, "&");
39868
+ }
39855
39869
  function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
39856
39870
  let earliestToolName = null;
39857
39871
  let earliestOpenIndex = Infinity;
@@ -39908,10 +39922,10 @@ function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
39908
39922
  }
39909
39923
  paramCloseIndex = nextTagIndex;
39910
39924
  }
39911
- let paramValue = innerContent.substring(
39925
+ let paramValue = unescapeXmlEntities(innerContent.substring(
39912
39926
  paramOpenIndex + paramOpenTag.length,
39913
39927
  paramCloseIndex
39914
- ).trim();
39928
+ ).trim());
39915
39929
  if (paramValue.toLowerCase() === "true") {
39916
39930
  paramValue = true;
39917
39931
  } else if (paramValue.toLowerCase() === "false") {
@@ -39925,7 +39939,7 @@ function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
39925
39939
  params[paramName] = paramValue;
39926
39940
  }
39927
39941
  if (toolName === "attempt_completion") {
39928
- params["result"] = innerContent.trim();
39942
+ params["result"] = unescapeXmlEntities(innerContent.trim());
39929
39943
  if (params.command) {
39930
39944
  delete params.command;
39931
39945
  }
@@ -41035,95 +41049,102 @@ var init_bashDefaults = __esm({
41035
41049
  "dir",
41036
41050
  "pwd",
41037
41051
  "cd",
41038
- "cd:*",
41039
41052
  // File reading commands
41040
41053
  "cat",
41041
- "cat:*",
41042
41054
  "head",
41043
- "head:*",
41044
41055
  "tail",
41045
- "tail:*",
41046
41056
  "less",
41047
41057
  "more",
41048
41058
  "view",
41049
41059
  // File information and metadata
41050
41060
  "file",
41051
- "file:*",
41052
41061
  "stat",
41053
- "stat:*",
41054
41062
  "wc",
41055
- "wc:*",
41056
41063
  "du",
41057
- "du:*",
41058
41064
  "df",
41059
- "df:*",
41060
41065
  "realpath",
41061
- "realpath:*",
41062
- // Search and find commands (read-only) - find restricted to safe operations
41066
+ // Search and find commands (read-only)
41067
+ // Note: bare 'find' allows all find variants; dangerous ones (find -exec) are blocked by deny list
41063
41068
  "find",
41064
- "find:-name:*",
41065
- "find:-type:*",
41066
- "find:-size:*",
41067
- "find:-mtime:*",
41068
- "find:-newer:*",
41069
- "find:-path:*",
41070
- "find:-iname:*",
41071
- "find:-maxdepth:*",
41072
- "find:-mindepth:*",
41073
- "find:-print",
41074
41069
  "grep",
41075
- "grep:*",
41076
41070
  "egrep",
41077
- "egrep:*",
41078
41071
  "fgrep",
41079
- "fgrep:*",
41080
41072
  "rg",
41081
- "rg:*",
41082
41073
  "ag",
41083
- "ag:*",
41084
41074
  "ack",
41085
- "ack:*",
41086
41075
  "which",
41087
- "which:*",
41088
41076
  "whereis",
41089
- "whereis:*",
41090
41077
  "locate",
41091
- "locate:*",
41092
41078
  "type",
41093
- "type:*",
41094
41079
  "command",
41095
- "command:*",
41096
41080
  // Tree and structure visualization
41097
41081
  "tree",
41098
- "tree:*",
41099
41082
  // Git read-only operations
41100
41083
  "git:status",
41101
41084
  "git:log",
41102
- "git:log:*",
41103
41085
  "git:diff",
41104
- "git:diff:*",
41105
41086
  "git:show",
41106
- "git:show:*",
41107
41087
  "git:branch",
41108
- "git:branch:*",
41109
41088
  "git:tag",
41110
- "git:tag:*",
41111
41089
  "git:describe",
41112
- "git:describe:*",
41113
41090
  "git:remote",
41114
- "git:remote:*",
41115
- "git:config:*",
41091
+ "git:config",
41116
41092
  "git:blame",
41117
- "git:blame:*",
41118
41093
  "git:shortlog",
41119
41094
  "git:reflog",
41120
41095
  "git:ls-files",
41121
41096
  "git:ls-tree",
41097
+ "git:ls-remote",
41122
41098
  "git:rev-parse",
41123
41099
  "git:rev-list",
41100
+ "git:cat-file",
41101
+ "git:diff-tree",
41102
+ "git:diff-files",
41103
+ "git:diff-index",
41104
+ "git:for-each-ref",
41105
+ "git:merge-base",
41106
+ "git:name-rev",
41107
+ "git:count-objects",
41108
+ "git:verify-commit",
41109
+ "git:verify-tag",
41110
+ "git:check-ignore",
41111
+ "git:check-attr",
41112
+ "git:stash:list",
41113
+ "git:stash:show",
41114
+ "git:worktree:list",
41115
+ "git:notes:list",
41116
+ "git:notes:show",
41124
41117
  "git:--version",
41125
41118
  "git:help",
41126
- "git:help:*",
41119
+ // GitHub CLI (gh) read-only operations
41120
+ "gh:--version",
41121
+ "gh:help",
41122
+ "gh:status",
41123
+ "gh:auth:status",
41124
+ "gh:issue:list",
41125
+ "gh:issue:view",
41126
+ "gh:issue:status",
41127
+ "gh:pr:list",
41128
+ "gh:pr:view",
41129
+ "gh:pr:status",
41130
+ "gh:pr:diff",
41131
+ "gh:pr:checks",
41132
+ "gh:repo:list",
41133
+ "gh:repo:view",
41134
+ "gh:release:list",
41135
+ "gh:release:view",
41136
+ "gh:run:list",
41137
+ "gh:run:view",
41138
+ "gh:workflow:list",
41139
+ "gh:workflow:view",
41140
+ "gh:gist:list",
41141
+ "gh:gist:view",
41142
+ "gh:search:issues",
41143
+ "gh:search:prs",
41144
+ "gh:search:repos",
41145
+ "gh:search:code",
41146
+ "gh:search:commits",
41147
+ "gh:api",
41127
41148
  // Package managers (information only)
41128
41149
  "npm:list",
41129
41150
  "npm:ls",
@@ -41184,7 +41205,6 @@ var init_bashDefaults = __esm({
41184
41205
  "sqlite3:--version",
41185
41206
  // System information
41186
41207
  "uname",
41187
- "uname:*",
41188
41208
  "hostname",
41189
41209
  "whoami",
41190
41210
  "id",
@@ -41195,23 +41215,17 @@ var init_bashDefaults = __esm({
41195
41215
  "w",
41196
41216
  "users",
41197
41217
  "sleep",
41198
- "sleep:*",
41199
41218
  // Environment and shell
41200
41219
  "env",
41201
41220
  "printenv",
41202
41221
  "echo",
41203
- "echo:*",
41204
41222
  "printf",
41205
- "printf:*",
41206
41223
  "export",
41207
- "export:*",
41208
41224
  "set",
41209
41225
  "unset",
41210
41226
  // Process information (read-only)
41211
41227
  "ps",
41212
- "ps:*",
41213
41228
  "pgrep",
41214
- "pgrep:*",
41215
41229
  "jobs",
41216
41230
  "top:-n:1",
41217
41231
  // Network information (read-only)
@@ -41226,39 +41240,24 @@ var init_bashDefaults = __esm({
41226
41240
  // Text processing and utilities (awk removed - too powerful)
41227
41241
  "sed:-n:*",
41228
41242
  "cut",
41229
- "cut:*",
41230
41243
  "sort",
41231
- "sort:*",
41232
41244
  "uniq",
41233
- "uniq:*",
41234
41245
  "tr",
41235
- "tr:*",
41236
41246
  "column",
41237
- "column:*",
41238
41247
  "paste",
41239
- "paste:*",
41240
41248
  "join",
41241
- "join:*",
41242
41249
  "comm",
41243
- "comm:*",
41244
41250
  "diff",
41245
- "diff:*",
41246
41251
  "cmp",
41247
- "cmp:*",
41248
41252
  "patch:--dry-run:*",
41249
41253
  // Hashing and encoding (read-only)
41250
41254
  "md5sum",
41251
- "md5sum:*",
41252
41255
  "sha1sum",
41253
- "sha1sum:*",
41254
41256
  "sha256sum",
41255
- "sha256sum:*",
41256
41257
  "base64",
41257
41258
  "base64:-d",
41258
41259
  "od",
41259
- "od:*",
41260
41260
  "hexdump",
41261
- "hexdump:*",
41262
41261
  // Archive and compression (list/view only)
41263
41262
  "tar:-tf:*",
41264
41263
  "tar:-tzf:*",
@@ -41268,15 +41267,11 @@ var init_bashDefaults = __esm({
41268
41267
  "gunzip:-l:*",
41269
41268
  // Help and documentation
41270
41269
  "man",
41271
- "man:*",
41272
41270
  "--help",
41273
41271
  "help",
41274
41272
  "info",
41275
- "info:*",
41276
41273
  "whatis",
41277
- "whatis:*",
41278
41274
  "apropos",
41279
- "apropos:*",
41280
41275
  // Make (dry run and info)
41281
41276
  "make:-n",
41282
41277
  "make:--dry-run",
@@ -41299,36 +41294,30 @@ var init_bashDefaults = __esm({
41299
41294
  "rm:-rf",
41300
41295
  "rm:-f:/",
41301
41296
  "rm:/",
41302
- "rm:-rf:*",
41303
41297
  "rmdir",
41304
41298
  "chmod:777",
41305
41299
  "chmod:-R:777",
41306
41300
  "chown",
41307
41301
  "chgrp",
41308
41302
  "dd",
41309
- "dd:*",
41310
41303
  "shred",
41311
- "shred:*",
41312
41304
  // Dangerous find operations that can execute arbitrary commands
41313
- "find:-exec:*",
41314
- "find:*:-exec:*",
41315
- "find:-execdir:*",
41316
- "find:*:-execdir:*",
41317
- "find:-ok:*",
41318
- "find:*:-ok:*",
41319
- "find:-okdir:*",
41320
- "find:*:-okdir:*",
41305
+ "find:-exec",
41306
+ "find:*:-exec",
41307
+ "find:-execdir",
41308
+ "find:*:-execdir",
41309
+ "find:-ok",
41310
+ "find:*:-ok",
41311
+ "find:-okdir",
41312
+ "find:*:-okdir",
41321
41313
  // Powerful scripting tools that can execute arbitrary commands
41322
41314
  "awk",
41323
- "awk:*",
41324
41315
  "perl",
41325
- "perl:*",
41326
41316
  "python:-c:*",
41327
41317
  "node:-e:*",
41328
41318
  // System administration and modification
41329
- "sudo:*",
41319
+ "sudo",
41330
41320
  "su",
41331
- "su:*",
41332
41321
  "passwd",
41333
41322
  "adduser",
41334
41323
  "useradd",
@@ -41366,11 +41355,11 @@ var init_bashDefaults = __esm({
41366
41355
  "composer:install",
41367
41356
  "composer:update",
41368
41357
  "composer:remove",
41369
- "apt:*",
41370
- "apt-get:*",
41371
- "yum:*",
41372
- "dnf:*",
41373
- "zypper:*",
41358
+ "apt",
41359
+ "apt-get",
41360
+ "yum",
41361
+ "dnf",
41362
+ "zypper",
41374
41363
  "brew:install",
41375
41364
  "brew:uninstall",
41376
41365
  "brew:upgrade",
@@ -41378,11 +41367,11 @@ var init_bashDefaults = __esm({
41378
41367
  "conda:remove",
41379
41368
  "conda:update",
41380
41369
  // Service and system control
41381
- "systemctl:*",
41382
- "service:*",
41383
- "chkconfig:*",
41384
- "initctl:*",
41385
- "upstart:*",
41370
+ "systemctl",
41371
+ "service",
41372
+ "chkconfig",
41373
+ "initctl",
41374
+ "upstart",
41386
41375
  // Network operations that could be dangerous
41387
41376
  "curl:-d:*",
41388
41377
  "curl:--data:*",
@@ -41391,32 +41380,21 @@ var init_bashDefaults = __esm({
41391
41380
  "wget:-O:/",
41392
41381
  "wget:--post-data:*",
41393
41382
  "ssh",
41394
- "ssh:*",
41395
41383
  "scp",
41396
- "scp:*",
41397
41384
  "sftp",
41398
- "sftp:*",
41399
- "rsync:*",
41385
+ "rsync",
41400
41386
  "nc",
41401
- "nc:*",
41402
41387
  "netcat",
41403
- "netcat:*",
41404
41388
  "telnet",
41405
- "telnet:*",
41406
41389
  "ftp",
41407
- "ftp:*",
41408
41390
  // Process control and termination
41409
41391
  "kill",
41410
- "kill:*",
41411
41392
  "killall",
41412
- "killall:*",
41413
41393
  "pkill",
41414
- "pkill:*",
41415
- "nohup:*",
41416
- "disown:*",
41394
+ "nohup",
41395
+ "disown",
41417
41396
  // System control and shutdown
41418
41397
  "shutdown",
41419
- "shutdown:*",
41420
41398
  "reboot",
41421
41399
  "halt",
41422
41400
  "poweroff",
@@ -41424,50 +41402,92 @@ var init_bashDefaults = __esm({
41424
41402
  "telinit",
41425
41403
  // Kernel and module operations
41426
41404
  "insmod",
41427
- "insmod:*",
41428
41405
  "rmmod",
41429
- "rmmod:*",
41430
41406
  "modprobe",
41431
- "modprobe:*",
41432
41407
  "sysctl:-w:*",
41433
41408
  // Dangerous git operations
41434
41409
  "git:push",
41435
- "git:push:*",
41436
41410
  "git:force",
41437
- "git:reset:--hard:*",
41438
- "git:clean:-fd",
41439
- "git:rm:*",
41411
+ "git:reset",
41412
+ "git:clean",
41413
+ "git:rm",
41440
41414
  "git:commit",
41441
41415
  "git:merge",
41442
41416
  "git:rebase",
41443
41417
  "git:cherry-pick",
41444
41418
  "git:stash:drop",
41419
+ "git:stash:pop",
41420
+ "git:stash:push",
41421
+ "git:stash:clear",
41422
+ "git:branch:-d",
41423
+ "git:branch:-D",
41424
+ "git:branch:--delete",
41425
+ "git:tag:-d",
41426
+ "git:tag:--delete",
41427
+ "git:remote:remove",
41428
+ "git:remote:rm",
41429
+ "git:checkout:--force",
41430
+ "git:checkout:-f",
41431
+ "git:submodule:deinit",
41432
+ "git:notes:add",
41433
+ "git:notes:remove",
41434
+ "git:worktree:add",
41435
+ "git:worktree:remove",
41436
+ // Dangerous GitHub CLI (gh) write operations
41437
+ "gh:issue:create",
41438
+ "gh:issue:close",
41439
+ "gh:issue:delete",
41440
+ "gh:issue:edit",
41441
+ "gh:issue:reopen",
41442
+ "gh:issue:comment",
41443
+ "gh:pr:create",
41444
+ "gh:pr:close",
41445
+ "gh:pr:merge",
41446
+ "gh:pr:edit",
41447
+ "gh:pr:reopen",
41448
+ "gh:pr:review",
41449
+ "gh:pr:comment",
41450
+ "gh:repo:create",
41451
+ "gh:repo:delete",
41452
+ "gh:repo:fork",
41453
+ "gh:repo:rename",
41454
+ "gh:repo:archive",
41455
+ "gh:repo:clone",
41456
+ "gh:release:create",
41457
+ "gh:release:delete",
41458
+ "gh:release:edit",
41459
+ "gh:run:cancel",
41460
+ "gh:run:rerun",
41461
+ "gh:workflow:run",
41462
+ "gh:workflow:enable",
41463
+ "gh:workflow:disable",
41464
+ "gh:gist:create",
41465
+ "gh:gist:delete",
41466
+ "gh:gist:edit",
41467
+ "gh:secret:set",
41468
+ "gh:secret:delete",
41469
+ "gh:variable:set",
41470
+ "gh:variable:delete",
41471
+ "gh:label:create",
41472
+ "gh:label:delete",
41473
+ "gh:ssh-key:add",
41474
+ "gh:ssh-key:delete",
41445
41475
  // File system mounting and partitioning
41446
41476
  "mount",
41447
- "mount:*",
41448
41477
  "umount",
41449
- "umount:*",
41450
41478
  "fdisk",
41451
- "fdisk:*",
41452
41479
  "parted",
41453
- "parted:*",
41454
41480
  "mkfs",
41455
- "mkfs:*",
41456
41481
  "fsck",
41457
- "fsck:*",
41458
41482
  // Cron and scheduling
41459
41483
  "crontab",
41460
- "crontab:*",
41461
41484
  "at",
41462
- "at:*",
41463
41485
  "batch",
41464
- "batch:*",
41465
41486
  // Compression with potential overwrite
41466
41487
  "tar:-xf:*",
41467
41488
  "unzip",
41468
- "unzip:*",
41469
- "gzip:*",
41470
- "gunzip:*",
41489
+ "gzip",
41490
+ "gunzip",
41471
41491
  // Build and compilation that might modify files
41472
41492
  "make",
41473
41493
  "make:install",
@@ -41480,11 +41500,8 @@ var init_bashDefaults = __esm({
41480
41500
  "gradle:build",
41481
41501
  // Docker operations that could modify state
41482
41502
  "docker:run",
41483
- "docker:run:*",
41484
41503
  "docker:exec",
41485
- "docker:exec:*",
41486
41504
  "docker:build",
41487
- "docker:build:*",
41488
41505
  "docker:pull",
41489
41506
  "docker:push",
41490
41507
  "docker:rm",
@@ -41498,22 +41515,15 @@ var init_bashDefaults = __esm({
41498
41515
  "mongo:--eval:*",
41499
41516
  // Text editors that could modify files
41500
41517
  "vi",
41501
- "vi:*",
41502
41518
  "vim",
41503
- "vim:*",
41504
41519
  "nano",
41505
- "nano:*",
41506
41520
  "emacs",
41507
- "emacs:*",
41508
41521
  "sed:-i:*",
41509
41522
  "perl:-i:*",
41510
41523
  // Potentially dangerous utilities
41511
41524
  "eval",
41512
- "eval:*",
41513
41525
  "exec",
41514
- "exec:*",
41515
41526
  "source",
41516
- "source:*",
41517
41527
  "bash:-c:*",
41518
41528
  "sh:-c:*",
41519
41529
  "zsh:-c:*"
@@ -41792,9 +41802,19 @@ var init_bashPermissions = __esm({
41792
41802
  BashPermissionChecker = class {
41793
41803
  /**
41794
41804
  * Create a permission checker
41805
+ *
41806
+ * Priority order (highest to lowest):
41807
+ * 1. Custom deny — always blocks (user explicitly blocked it)
41808
+ * 2. Custom allow — overrides default deny (user explicitly allowed it)
41809
+ * 3. Default deny — blocks by default
41810
+ * 4. Allow list — allows recognized safe commands
41811
+ *
41812
+ * This means `--bash-allow "git:push"` overrides the default deny for git:push
41813
+ * without requiring `--no-default-bash-deny`.
41814
+ *
41795
41815
  * @param {Object} config - Configuration options
41796
- * @param {string[]} [config.allow] - Additional allow patterns
41797
- * @param {string[]} [config.deny] - Additional deny patterns
41816
+ * @param {string[]} [config.allow] - Additional allow patterns (override default deny)
41817
+ * @param {string[]} [config.deny] - Additional deny patterns (always win)
41798
41818
  * @param {boolean} [config.disableDefaultAllow] - Disable default allow list
41799
41819
  * @param {boolean} [config.disableDefaultDeny] - Disable default deny list
41800
41820
  * @param {boolean} [config.debug] - Enable debug logging
@@ -41803,40 +41823,22 @@ var init_bashPermissions = __esm({
41803
41823
  constructor(config = {}) {
41804
41824
  this.debug = config.debug || false;
41805
41825
  this.tracer = config.tracer || null;
41806
- this.allowPatterns = [];
41807
- if (!config.disableDefaultAllow) {
41808
- this.allowPatterns.push(...DEFAULT_ALLOW_PATTERNS);
41809
- if (this.debug) {
41810
- console.log(`[BashPermissions] Added ${DEFAULT_ALLOW_PATTERNS.length} default allow patterns`);
41811
- }
41812
- }
41813
- if (config.allow && Array.isArray(config.allow)) {
41814
- this.allowPatterns.push(...config.allow);
41815
- if (this.debug) {
41816
- console.log(`[BashPermissions] Added ${config.allow.length} custom allow patterns:`, config.allow);
41817
- }
41818
- }
41819
- this.denyPatterns = [];
41820
- if (!config.disableDefaultDeny) {
41821
- this.denyPatterns.push(...DEFAULT_DENY_PATTERNS);
41822
- if (this.debug) {
41823
- console.log(`[BashPermissions] Added ${DEFAULT_DENY_PATTERNS.length} default deny patterns`);
41824
- }
41825
- }
41826
- if (config.deny && Array.isArray(config.deny)) {
41827
- this.denyPatterns.push(...config.deny);
41828
- if (this.debug) {
41829
- console.log(`[BashPermissions] Added ${config.deny.length} custom deny patterns:`, config.deny);
41830
- }
41831
- }
41826
+ this.defaultAllowPatterns = config.disableDefaultAllow ? [] : [...DEFAULT_ALLOW_PATTERNS];
41827
+ this.customAllowPatterns = config.allow && Array.isArray(config.allow) ? [...config.allow] : [];
41828
+ this.allowPatterns = [...this.defaultAllowPatterns, ...this.customAllowPatterns];
41829
+ this.defaultDenyPatterns = config.disableDefaultDeny ? [] : [...DEFAULT_DENY_PATTERNS];
41830
+ this.customDenyPatterns = config.deny && Array.isArray(config.deny) ? [...config.deny] : [];
41831
+ this.denyPatterns = [...this.defaultDenyPatterns, ...this.customDenyPatterns];
41832
41832
  if (this.debug) {
41833
+ console.log(`[BashPermissions] Default allow: ${this.defaultAllowPatterns.length}, Custom allow: ${this.customAllowPatterns.length}`);
41834
+ console.log(`[BashPermissions] Default deny: ${this.defaultDenyPatterns.length}, Custom deny: ${this.customDenyPatterns.length}`);
41833
41835
  console.log(`[BashPermissions] Total patterns - Allow: ${this.allowPatterns.length}, Deny: ${this.denyPatterns.length}`);
41834
41836
  }
41835
41837
  this.recordBashEvent("permissions.initialized", {
41836
41838
  allowPatternCount: this.allowPatterns.length,
41837
41839
  denyPatternCount: this.denyPatterns.length,
41838
- hasCustomAllowPatterns: !!(config.allow && config.allow.length > 0),
41839
- hasCustomDenyPatterns: !!(config.deny && config.deny.length > 0),
41840
+ hasCustomAllowPatterns: this.customAllowPatterns.length > 0,
41841
+ hasCustomDenyPatterns: this.customDenyPatterns.length > 0,
41840
41842
  disableDefaultAllow: !!config.disableDefaultAllow,
41841
41843
  disableDefaultDeny: !!config.disableDefaultDeny
41842
41844
  });
@@ -41906,8 +41908,11 @@ var init_bashPermissions = __esm({
41906
41908
  console.log(`[BashPermissions] Checking simple command: "${command}"`);
41907
41909
  console.log(`[BashPermissions] Parsed: ${parsed.command} with args: [${parsed.args.join(", ")}]`);
41908
41910
  }
41909
- if (matchesAnyPattern(parsed, this.denyPatterns)) {
41910
- const matchedPatterns = this.denyPatterns.filter((pattern) => matchesPattern(parsed, pattern));
41911
+ if (matchesAnyPattern(parsed, this.customDenyPatterns)) {
41912
+ const matchedPatterns = this.customDenyPatterns.filter((pattern) => matchesPattern(parsed, pattern));
41913
+ if (this.debug) {
41914
+ console.log(`[BashPermissions] DENIED - matches custom deny pattern: ${matchedPatterns[0]}`);
41915
+ }
41911
41916
  const result2 = {
41912
41917
  allowed: false,
41913
41918
  reason: `Command matches deny pattern: ${matchedPatterns[0]}`,
@@ -41920,7 +41925,31 @@ var init_bashPermissions = __esm({
41920
41925
  parsedCommand: parsed.command,
41921
41926
  reason: "matches_deny_pattern",
41922
41927
  matchedPattern: matchedPatterns[0],
41923
- isComplex: false
41928
+ isComplex: false,
41929
+ isCustomDeny: true
41930
+ });
41931
+ return result2;
41932
+ }
41933
+ const matchesCustomAllow = matchesAnyPattern(parsed, this.customAllowPatterns);
41934
+ if (!matchesCustomAllow && matchesAnyPattern(parsed, this.defaultDenyPatterns)) {
41935
+ const matchedPatterns = this.defaultDenyPatterns.filter((pattern) => matchesPattern(parsed, pattern));
41936
+ if (this.debug) {
41937
+ console.log(`[BashPermissions] DENIED - matches default deny pattern: ${matchedPatterns[0]}`);
41938
+ }
41939
+ const result2 = {
41940
+ allowed: false,
41941
+ reason: `Command matches deny pattern: ${matchedPatterns[0]}`,
41942
+ command,
41943
+ parsed,
41944
+ matchedPatterns
41945
+ };
41946
+ this.recordBashEvent("permission.denied", {
41947
+ command,
41948
+ parsedCommand: parsed.command,
41949
+ reason: "matches_deny_pattern",
41950
+ matchedPattern: matchedPatterns[0],
41951
+ isComplex: false,
41952
+ isCustomDeny: false
41924
41953
  });
41925
41954
  return result2;
41926
41955
  }
@@ -41945,15 +41974,21 @@ var init_bashPermissions = __esm({
41945
41974
  allowed: true,
41946
41975
  command,
41947
41976
  parsed,
41948
- isComplex: false
41977
+ isComplex: false,
41978
+ overriddenDeny: matchesCustomAllow && matchesAnyPattern(parsed, this.defaultDenyPatterns)
41949
41979
  };
41950
41980
  if (this.debug) {
41951
- console.log(`[BashPermissions] ALLOWED - command passed all checks`);
41981
+ if (result.overriddenDeny) {
41982
+ console.log(`[BashPermissions] ALLOWED - custom allow overrides default deny`);
41983
+ } else {
41984
+ console.log(`[BashPermissions] ALLOWED - command passed all checks`);
41985
+ }
41952
41986
  }
41953
41987
  this.recordBashEvent("permission.allowed", {
41954
41988
  command,
41955
41989
  parsedCommand: parsed.command,
41956
- isComplex: false
41990
+ isComplex: false,
41991
+ overriddenDeny: result.overriddenDeny || false
41957
41992
  });
41958
41993
  return result;
41959
41994
  }
@@ -42122,9 +42157,19 @@ var init_bashPermissions = __esm({
42122
42157
  deniedReason = parsed.error || "Component contains nested complex constructs";
42123
42158
  break;
42124
42159
  }
42125
- if (matchesAnyPattern(parsed, this.denyPatterns)) {
42160
+ if (matchesAnyPattern(parsed, this.customDenyPatterns)) {
42161
+ if (this.debug) {
42162
+ console.log(`[BashPermissions] Component "${component}" matches custom deny pattern`);
42163
+ }
42164
+ allAllowed = false;
42165
+ deniedComponent = component;
42166
+ deniedReason = "Component matches deny pattern";
42167
+ break;
42168
+ }
42169
+ const componentMatchesCustomAllow = matchesAnyPattern(parsed, this.customAllowPatterns);
42170
+ if (!componentMatchesCustomAllow && matchesAnyPattern(parsed, this.defaultDenyPatterns)) {
42126
42171
  if (this.debug) {
42127
- console.log(`[BashPermissions] Component "${component}" matches deny pattern`);
42172
+ console.log(`[BashPermissions] Component "${component}" matches default deny pattern`);
42128
42173
  }
42129
42174
  allAllowed = false;
42130
42175
  deniedComponent = component;
@@ -42204,6 +42249,10 @@ var init_bashPermissions = __esm({
42204
42249
  return {
42205
42250
  allowPatterns: this.allowPatterns.length,
42206
42251
  denyPatterns: this.denyPatterns.length,
42252
+ customAllowPatterns: this.customAllowPatterns.length,
42253
+ customDenyPatterns: this.customDenyPatterns.length,
42254
+ defaultAllowPatterns: this.defaultAllowPatterns.length,
42255
+ defaultDenyPatterns: this.defaultDenyPatterns.length,
42207
42256
  totalPatterns: this.allowPatterns.length + this.denyPatterns.length
42208
42257
  };
42209
42258
  }
@@ -42586,8 +42635,8 @@ Common reasons:
42586
42635
  2. The command is not in the allow list (not a recognized safe command)
42587
42636
 
42588
42637
  If you believe this command should be allowed, you can:
42589
- - Use the --bash-allow option to add specific patterns
42590
- - Use the --no-default-bash-deny flag to remove default restrictions (not recommended)
42638
+ - Use the --bash-allow option to add specific patterns (overrides default deny list)
42639
+ Example: --bash-allow "git:push" allows git push while keeping all other deny rules
42591
42640
 
42592
42641
  For code exploration, try these safe alternatives:
42593
42642
  - ls, cat, head, tail for file operations
@@ -98623,6 +98672,7 @@ __export(schemaUtils_exports, {
98623
98672
  replaceMermaidDiagramsInMarkdown: () => replaceMermaidDiagramsInMarkdown,
98624
98673
  sanitizeMarkdownEscapesInJson: () => sanitizeMarkdownEscapesInJson,
98625
98674
  tryAutoWrapForSimpleSchema: () => tryAutoWrapForSimpleSchema,
98675
+ tryExtractValidJsonPrefix: () => tryExtractValidJsonPrefix,
98626
98676
  tryMaidAutoFix: () => tryMaidAutoFix,
98627
98677
  validateAndFixMermaidResponse: () => validateAndFixMermaidResponse,
98628
98678
  validateJsonResponse: () => validateJsonResponse,
@@ -99009,6 +99059,13 @@ function validateJsonResponse(response, options = {}) {
99009
99059
  errorPosition = response.indexOf(problematicToken);
99010
99060
  }
99011
99061
  }
99062
+ const prefixResult = tryExtractValidJsonPrefix(responseToValidate, { schema, debug });
99063
+ if (prefixResult && prefixResult.isValid) {
99064
+ if (debug) {
99065
+ console.log(`[DEBUG] JSON validation: Recovered valid JSON prefix (${prefixResult.extracted.length} chars) from response with trailing content`);
99066
+ }
99067
+ return { isValid: true, parsed: prefixResult.parsed };
99068
+ }
99012
99069
  let enhancedError = error2.message;
99013
99070
  let errorContext = null;
99014
99071
  if (errorPosition !== null && errorPosition >= 0 && response && response.length > 0) {
@@ -99059,6 +99116,84 @@ ${errorContext.pointer}`);
99059
99116
  };
99060
99117
  }
99061
99118
  }
99119
+ function tryExtractValidJsonPrefix(response, options = {}) {
99120
+ const { schema = null, debug = false } = options;
99121
+ if (!response || typeof response !== "string") {
99122
+ return null;
99123
+ }
99124
+ const trimmed = response.trim();
99125
+ if (trimmed.length === 0) {
99126
+ return null;
99127
+ }
99128
+ const firstChar = trimmed[0];
99129
+ if (firstChar !== "{" && firstChar !== "[") {
99130
+ return null;
99131
+ }
99132
+ try {
99133
+ JSON.parse(trimmed);
99134
+ return null;
99135
+ } catch {
99136
+ }
99137
+ const openChar = firstChar;
99138
+ const closeChar = openChar === "{" ? "}" : "]";
99139
+ let depth = 0;
99140
+ let inString = false;
99141
+ let escapeNext = false;
99142
+ let endPos = -1;
99143
+ for (let i5 = 0; i5 < trimmed.length; i5++) {
99144
+ const char = trimmed[i5];
99145
+ if (escapeNext) {
99146
+ escapeNext = false;
99147
+ continue;
99148
+ }
99149
+ if (char === "\\" && inString) {
99150
+ escapeNext = true;
99151
+ continue;
99152
+ }
99153
+ if (char === '"') {
99154
+ inString = !inString;
99155
+ continue;
99156
+ }
99157
+ if (inString) {
99158
+ continue;
99159
+ }
99160
+ if (char === openChar) {
99161
+ depth++;
99162
+ } else if (char === closeChar) {
99163
+ depth--;
99164
+ if (depth === 0) {
99165
+ endPos = i5 + 1;
99166
+ break;
99167
+ }
99168
+ }
99169
+ }
99170
+ if (endPos <= 0 || endPos >= trimmed.length) {
99171
+ return null;
99172
+ }
99173
+ const remainder = trimmed.substring(endPos).trim();
99174
+ if (remainder.length === 0) {
99175
+ return null;
99176
+ }
99177
+ const prefix = trimmed.substring(0, endPos);
99178
+ try {
99179
+ const parsed = JSON.parse(prefix);
99180
+ if (debug) {
99181
+ console.log(`[DEBUG] tryExtractValidJsonPrefix: Extracted valid JSON prefix (${prefix.length} chars), stripped trailing content (${remainder.length} chars)`);
99182
+ }
99183
+ if (schema) {
99184
+ const schemaValidation = validateJsonResponse(prefix, { debug, schema });
99185
+ if (!schemaValidation.isValid) {
99186
+ if (debug) {
99187
+ console.log(`[DEBUG] tryExtractValidJsonPrefix: Prefix is valid JSON but fails schema validation: ${schemaValidation.error}`);
99188
+ }
99189
+ return null;
99190
+ }
99191
+ }
99192
+ return { isValid: true, parsed, extracted: prefix };
99193
+ } catch {
99194
+ return null;
99195
+ }
99196
+ }
99062
99197
  function validateXmlResponse(response) {
99063
99198
  const xmlPattern = /<\/?[\w\s="'.-]+>/g;
99064
99199
  const tags = response.match(xmlPattern);
@@ -101160,7 +101295,7 @@ function parseXmlMcpToolCall(xmlString, mcpToolNames = []) {
101160
101295
  let match2;
101161
101296
  while ((match2 = paramPattern.exec(content)) !== null) {
101162
101297
  const [, paramName, paramValue] = match2;
101163
- params[paramName] = paramValue.trim();
101298
+ params[paramName] = unescapeXmlEntities(paramValue.trim());
101164
101299
  }
101165
101300
  }
101166
101301
  return { toolName, params };
@@ -101210,7 +101345,7 @@ function parseNativeXmlTool(xmlString, toolName) {
101210
101345
  while ((match2 = paramPattern.exec(content)) !== null) {
101211
101346
  const [, paramName, paramValue] = match2;
101212
101347
  if (paramName !== "params") {
101213
- params[paramName] = paramValue.trim();
101348
+ params[paramName] = unescapeXmlEntities(paramValue.trim());
101214
101349
  }
101215
101350
  }
101216
101351
  if (Object.keys(params).length > 0) {
@@ -101225,6 +101360,7 @@ var init_xmlBridge = __esm({
101225
101360
  init_client2();
101226
101361
  init_config();
101227
101362
  init_xmlParsingUtils();
101363
+ init_common2();
101228
101364
  MCPXmlBridge = class {
101229
101365
  constructor(options = {}) {
101230
101366
  this.debug = options.debug || false;
@@ -109438,10 +109574,10 @@ var init_FallbackManager = __esm({
109438
109574
  // Use custom provider list
109439
109575
  };
109440
109576
  DEFAULT_MODELS = {
109441
- anthropic: "claude-sonnet-4-5-20250929",
109442
- openai: "gpt-4o",
109443
- google: "gemini-2.0-flash-exp",
109444
- bedrock: "anthropic.claude-sonnet-4-20250514-v1:0"
109577
+ anthropic: "claude-sonnet-4-6",
109578
+ openai: "gpt-5.2",
109579
+ google: "gemini-2.5-flash",
109580
+ bedrock: "anthropic.claude-sonnet-4-6"
109445
109581
  };
109446
109582
  FallbackManager = class {
109447
109583
  /**
@@ -111960,7 +112096,7 @@ var init_ProbeAgent = __esm({
111960
112096
  }
111961
112097
  this.clientApiProvider = "claude-code";
111962
112098
  this.provider = null;
111963
- this.model = this.clientApiModel || "claude-3-5-sonnet-20241022";
112099
+ this.model = this.clientApiModel || "claude-sonnet-4-6";
111964
112100
  this.apiType = "claude-code";
111965
112101
  } else if (codexAvailable) {
111966
112102
  if (this.debug) {
@@ -111969,7 +112105,7 @@ var init_ProbeAgent = __esm({
111969
112105
  }
111970
112106
  this.clientApiProvider = "codex";
111971
112107
  this.provider = null;
111972
- this.model = this.clientApiModel || "gpt-4o";
112108
+ this.model = this.clientApiModel || "gpt-5.2";
111973
112109
  this.apiType = "codex";
111974
112110
  } else {
111975
112111
  throw new Error("No API key provided and neither claude nor codex command found. Please either:\n1. Set an API key: ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY, or AWS credentials\n2. Install claude command from https://docs.claude.com/en/docs/claude-code\n3. Install codex command from https://openai.com/codex");
@@ -112207,7 +112343,7 @@ var init_ProbeAgent = __esm({
112207
112343
  }
112208
112344
  if (this.clientApiProvider === "claude-code" || process.env.USE_CLAUDE_CODE === "true") {
112209
112345
  this.provider = null;
112210
- this.model = modelName || "claude-3-5-sonnet-20241022";
112346
+ this.model = modelName || "claude-sonnet-4-6";
112211
112347
  this.apiType = "claude-code";
112212
112348
  if (this.debug) {
112213
112349
  console.log("[DEBUG] Claude Code engine selected - will use built-in access if available");
@@ -112574,7 +112710,7 @@ var init_ProbeAgent = __esm({
112574
112710
  apiKey,
112575
112711
  ...apiUrl && { baseURL: apiUrl }
112576
112712
  });
112577
- this.model = modelName || "claude-sonnet-4-5-20250929";
112713
+ this.model = modelName || "claude-sonnet-4-6";
112578
112714
  this.apiType = "anthropic";
112579
112715
  if (this.debug) {
112580
112716
  console.log(`Using Anthropic API with model: ${this.model}${apiUrl ? ` (URL: ${apiUrl})` : ""}`);
@@ -112589,7 +112725,7 @@ var init_ProbeAgent = __esm({
112589
112725
  apiKey,
112590
112726
  ...apiUrl && { baseURL: apiUrl }
112591
112727
  });
112592
- this.model = modelName || "gpt-5-thinking";
112728
+ this.model = modelName || "gpt-5.2";
112593
112729
  this.apiType = "openai";
112594
112730
  if (this.debug) {
112595
112731
  console.log(`Using OpenAI API with model: ${this.model}${apiUrl ? ` (URL: ${apiUrl})` : ""}`);
@@ -112693,7 +112829,7 @@ var init_ProbeAgent = __esm({
112693
112829
  config.baseURL = baseURL;
112694
112830
  }
112695
112831
  this.provider = createAmazonBedrock(config);
112696
- this.model = modelName || "anthropic.claude-sonnet-4-20250514-v1:0";
112832
+ this.model = modelName || "anthropic.claude-sonnet-4-6";
112697
112833
  this.apiType = "bedrock";
112698
112834
  if (this.debug) {
112699
112835
  const authMethod = apiKey ? "API Key" : "AWS Credentials";
@@ -112752,7 +112888,7 @@ var init_ProbeAgent = __esm({
112752
112888
  allowedTools: this.allowedTools,
112753
112889
  // Pass tool filtering configuration
112754
112890
  model: this.model
112755
- // Pass model name (e.g., gpt-4o, o3, etc.)
112891
+ // Pass model name (e.g., gpt-5.2, o3, etc.)
112756
112892
  });
112757
112893
  if (this.debug) {
112758
112894
  console.log("[DEBUG] Using Codex CLI engine with Probe tools");
@@ -113848,8 +113984,8 @@ You are working with a workspace. Available paths: ${workspaceDesc}
113848
113984
  let currentIteration = 0;
113849
113985
  let completionAttempted = false;
113850
113986
  let finalResult = "I was unable to complete your request due to reaching the maximum number of tool iterations.";
113851
- const baseMaxIterations = this.maxIterations || MAX_TOOL_ITERATIONS;
113852
- const maxIterations = options.schema ? baseMaxIterations + 4 : baseMaxIterations;
113987
+ const baseMaxIterations = options._maxIterationsOverride || this.maxIterations || MAX_TOOL_ITERATIONS;
113988
+ const maxIterations = options._maxIterationsOverride ? baseMaxIterations : options.schema ? baseMaxIterations + 4 : baseMaxIterations;
113853
113989
  const isClaudeCode = this.clientApiProvider === "claude-code" || process.env.USE_CLAUDE_CODE === "true";
113854
113990
  const isCodex = this.clientApiProvider === "codex" || process.env.USE_CODEX === "true";
113855
113991
  if (isClaudeCode) {
@@ -114007,9 +114143,7 @@ You are working with a workspace. Available paths: ${workspaceDesc}
114007
114143
  let maxResponseTokens = this.maxResponseTokens;
114008
114144
  if (!maxResponseTokens) {
114009
114145
  maxResponseTokens = 4e3;
114010
- if (this.model && this.model.includes("opus") || this.model && this.model.includes("sonnet") || this.model && this.model.startsWith("gpt-4-")) {
114011
- maxResponseTokens = 8192;
114012
- } else if (this.model && this.model.startsWith("gpt-4o")) {
114146
+ if (this.model && this.model.includes("opus") || this.model && this.model.includes("sonnet") || this.model && this.model.startsWith("gpt-4") || this.model && this.model.startsWith("gpt-5")) {
114013
114147
  maxResponseTokens = 8192;
114014
114148
  } else if (this.model && this.model.startsWith("gemini")) {
114015
114149
  maxResponseTokens = 32e3;
@@ -115086,13 +115220,16 @@ Convert your previous response content into actual JSON data that follows this s
115086
115220
  options.schema,
115087
115221
  0
115088
115222
  );
115223
+ const { schema: _unusedSchema1, ...schemaDefCorrectionOptions } = options;
115089
115224
  finalResult = await this.answer(schemaDefinitionPrompt, [], {
115090
- ...options,
115225
+ ...schemaDefCorrectionOptions,
115091
115226
  _schemaFormatted: true,
115092
115227
  _skipValidation: true,
115093
115228
  // Skip validation in recursive correction calls to prevent loops
115094
- _completionPromptProcessed: true
115229
+ _completionPromptProcessed: true,
115095
115230
  // Prevent cascading completion prompts in retry calls
115231
+ _maxIterationsOverride: 3
115232
+ // Correction should complete in 1-2 iterations (issue #447)
115096
115233
  });
115097
115234
  finalResult = cleanSchemaResponse(finalResult);
115098
115235
  validation = validateJsonResponse(finalResult);
@@ -115140,15 +115277,18 @@ Convert your previous response content into actual JSON data that follows this s
115140
115277
  retryCount
115141
115278
  );
115142
115279
  }
115280
+ const { schema: _unusedSchema2, ...correctionOptions } = options;
115143
115281
  finalResult = await this.answer(correctionPrompt, [], {
115144
- ...options,
115282
+ ...correctionOptions,
115145
115283
  _schemaFormatted: true,
115146
115284
  _skipValidation: true,
115147
115285
  // Skip validation in recursive correction calls to prevent loops
115148
115286
  _disableTools: true,
115149
115287
  // Only allow attempt_completion - prevent AI from using search/query tools
115150
- _completionPromptProcessed: true
115288
+ _completionPromptProcessed: true,
115151
115289
  // Prevent cascading completion prompts in retry calls
115290
+ _maxIterationsOverride: 3
115291
+ // Correction should complete in 1-2 iterations (issue #447)
115152
115292
  });
115153
115293
  finalResult = cleanSchemaResponse(finalResult);
115154
115294
  validation = validateJsonResponse(finalResult, { debug: this.debug });